OSDN Git Service

2010-05-14 Harsha Jagasia <harsha.jagasia@amd.com>
[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, 2010
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 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62
63 ;; UNSPEC usage:
64
65 (define_constants
66   [; Relocation specifiers
67    (UNSPEC_GOT                  0)
68    (UNSPEC_GOTOFF               1)
69    (UNSPEC_GOTPCREL             2)
70    (UNSPEC_GOTTPOFF             3)
71    (UNSPEC_TPOFF                4)
72    (UNSPEC_NTPOFF               5)
73    (UNSPEC_DTPOFF               6)
74    (UNSPEC_GOTNTPOFF            7)
75    (UNSPEC_INDNTPOFF            8)
76    (UNSPEC_PLTOFF               9)
77    (UNSPEC_MACHOPIC_OFFSET      10)
78
79    ; Prologue support
80    (UNSPEC_STACK_ALLOC          11)
81    (UNSPEC_SET_GOT              12)
82    (UNSPEC_SSE_PROLOGUE_SAVE    13)
83    (UNSPEC_REG_SAVE             14)
84    (UNSPEC_DEF_CFA              15)
85    (UNSPEC_SET_RIP              16)
86    (UNSPEC_SET_GOT_OFFSET       17)
87    (UNSPEC_MEMORY_BLOCKAGE      18)
88    (UNSPEC_SSE_PROLOGUE_SAVE_LOW 19)
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,bdver1"
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 maxmin_int [(smax "maxs") (smin "mins")
718                               (umax "maxu") (umin "minu")])
719 (define_code_attr maxmin_float [(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 logic [(and "and") (ior "or") (xor "xor")])
727
728 ;; Mapping of shift-right operators
729 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730
731 ;; Base name for define_insn
732 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
733
734 ;; Base name for insn mnemonic.
735 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
736
737 ;; Mapping of rotate operators
738 (define_code_iterator any_rotate [rotate rotatert])
739
740 ;; Base name for define_insn
741 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
742
743 ;; Base name for insn mnemonic.
744 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
745
746 ;; Mapping of abs neg operators
747 (define_code_iterator absneg [abs neg])
748
749 ;; Base name for x87 insn mnemonic.
750 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
751
752 ;; Used in signed and unsigned widening multiplications.
753 (define_code_iterator any_extend [sign_extend zero_extend])
754
755 ;; Various insn prefixes for signed and unsigned operations.
756 (define_code_attr u [(sign_extend "") (zero_extend "u")
757                      (div "") (udiv "u")])
758 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
759
760 ;; Used in signed and unsigned divisions.
761 (define_code_iterator any_div [div udiv])
762
763 ;; Instruction prefix for signed and unsigned operations.
764 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
765                              (div "i") (udiv "")])
766
767 ;; All single word integer modes.
768 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
769
770 ;; Single word integer modes without DImode.
771 (define_mode_iterator SWI124 [QI HI SI])
772
773 ;; Single word integer modes without QImode.
774 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
775
776 ;; Single word integer modes without QImode and HImode.
777 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
778
779 ;; All math-dependant single and double word integer modes.
780 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
781                              (HI "TARGET_HIMODE_MATH")
782                              SI DI (TI "TARGET_64BIT")])
783
784 ;; Math-dependant single word integer modes.
785 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
786                             (HI "TARGET_HIMODE_MATH")
787                             SI (DI "TARGET_64BIT")])
788
789 ;; Math-dependant single word integer modes without DImode.
790 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
791                                (HI "TARGET_HIMODE_MATH")
792                                SI])
793
794 ;; Math-dependant single word integer modes without QImode.
795 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
796                                SI (DI "TARGET_64BIT")])
797
798 ;; Double word integer modes.
799 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
800                            (TI "TARGET_64BIT")])
801
802 ;; Double word integer modes as mode attribute.
803 (define_mode_attr DWI [(SI "DI") (DI "TI")])
804 (define_mode_attr dwi [(SI "di") (DI "ti")])
805
806 ;; Half mode for double word integer modes.
807 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
808                             (DI "TARGET_64BIT")])
809
810 ;; Instruction suffix for integer modes.
811 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
812
813 ;; Register class for integer modes.
814 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
815
816 ;; Immediate operand constraint for integer modes.
817 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
818
819 ;; General operand constraint for word modes.
820 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
821
822 ;; Immediate operand constraint for double integer modes.
823 (define_mode_attr di [(SI "iF") (DI "e")])
824
825 ;; Immediate operand constraint for shifts.
826 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
827
828 ;; General operand predicate for integer modes.
829 (define_mode_attr general_operand
830         [(QI "general_operand")
831          (HI "general_operand")
832          (SI "general_operand")
833          (DI "x86_64_general_operand")
834          (TI "x86_64_general_operand")])
835
836 ;; General sign/zero extend operand predicate for integer modes.
837 (define_mode_attr general_szext_operand
838         [(QI "general_operand")
839          (HI "general_operand")
840          (SI "general_operand")
841          (DI "x86_64_szext_general_operand")])
842
843 ;; Operand predicate for shifts.
844 (define_mode_attr shift_operand
845         [(QI "nonimmediate_operand")
846          (HI "nonimmediate_operand")
847          (SI "nonimmediate_operand")
848          (DI "shiftdi_operand")
849          (TI "register_operand")])
850
851 ;; Operand predicate for shift argument.
852 (define_mode_attr shift_immediate_operand
853         [(QI "const_1_to_31_operand")
854          (HI "const_1_to_31_operand")
855          (SI "const_1_to_31_operand")
856          (DI "const_1_to_63_operand")])
857
858 ;; Input operand predicate for arithmetic left shifts.
859 (define_mode_attr ashl_input_operand
860         [(QI "nonimmediate_operand")
861          (HI "nonimmediate_operand")
862          (SI "nonimmediate_operand")
863          (DI "ashldi_input_operand")
864          (TI "reg_or_pm1_operand")])
865
866 ;; SSE and x87 SFmode and DFmode floating point modes
867 (define_mode_iterator MODEF [SF DF])
868
869 ;; All x87 floating point modes
870 (define_mode_iterator X87MODEF [SF DF XF])
871
872 ;; All integer modes handled by x87 fisttp operator.
873 (define_mode_iterator X87MODEI [HI SI DI])
874
875 ;; All integer modes handled by integer x87 operators.
876 (define_mode_iterator X87MODEI12 [HI SI])
877
878 ;; All integer modes handled by SSE cvtts?2si* operators.
879 (define_mode_iterator SSEMODEI24 [SI DI])
880
881 ;; SSE asm suffix for floating point modes
882 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
883
884 ;; SSE vector mode corresponding to a scalar mode
885 (define_mode_attr ssevecmode
886   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
887
888 ;; Instruction suffix for REX 64bit operators.
889 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
890
891 ;; This mode iterator allows :P to be used for patterns that operate on
892 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
893 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
894 \f
895 ;; Scheduling descriptions
896
897 (include "pentium.md")
898 (include "ppro.md")
899 (include "k6.md")
900 (include "athlon.md")
901 (include "geode.md")
902 (include "atom.md")
903
904 \f
905 ;; Operand and operator predicates and constraints
906
907 (include "predicates.md")
908 (include "constraints.md")
909
910 \f
911 ;; Compare and branch/compare and store instructions.
912
913 (define_expand "cbranch<mode>4"
914   [(set (reg:CC FLAGS_REG)
915         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
916                     (match_operand:SDWIM 2 "<general_operand>" "")))
917    (set (pc) (if_then_else
918                (match_operator 0 "comparison_operator"
919                 [(reg:CC FLAGS_REG) (const_int 0)])
920                (label_ref (match_operand 3 "" ""))
921                (pc)))]
922   ""
923 {
924   if (MEM_P (operands[1]) && MEM_P (operands[2]))
925     operands[1] = force_reg (<MODE>mode, operands[1]);
926   ix86_compare_op0 = operands[1];
927   ix86_compare_op1 = operands[2];
928   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
929   DONE;
930 })
931
932 (define_expand "cstore<mode>4"
933   [(set (reg:CC FLAGS_REG)
934         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
935                     (match_operand:SWIM 3 "<general_operand>" "")))
936    (set (match_operand:QI 0 "register_operand" "")
937         (match_operator 1 "comparison_operator"
938           [(reg:CC FLAGS_REG) (const_int 0)]))]
939   ""
940 {
941   if (MEM_P (operands[2]) && MEM_P (operands[3]))
942     operands[2] = force_reg (<MODE>mode, operands[2]);
943   ix86_compare_op0 = operands[2];
944   ix86_compare_op1 = operands[3];
945   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
946   DONE;
947 })
948
949 (define_expand "cmp<mode>_1"
950   [(set (reg:CC FLAGS_REG)
951         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
952                     (match_operand:SWI48 1 "<general_operand>" "")))]
953   ""
954   "")
955
956 (define_insn "*cmp<mode>_ccno_1"
957   [(set (reg FLAGS_REG)
958         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
959                  (match_operand:SWI 1 "const0_operand" "")))]
960   "ix86_match_ccmode (insn, CCNOmode)"
961   "@
962    test{<imodesuffix>}\t%0, %0
963    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
964   [(set_attr "type" "test,icmp")
965    (set_attr "length_immediate" "0,1")
966    (set_attr "mode" "<MODE>")])
967
968 (define_insn "*cmp<mode>_1"
969   [(set (reg FLAGS_REG)
970         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
971                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
972   "ix86_match_ccmode (insn, CCmode)"
973   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
974   [(set_attr "type" "icmp")
975    (set_attr "mode" "<MODE>")])
976
977 (define_insn "*cmp<mode>_minus_1"
978   [(set (reg FLAGS_REG)
979         (compare
980           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
981                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
982           (const_int 0)))]
983   "ix86_match_ccmode (insn, CCGOCmode)"
984   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
985   [(set_attr "type" "icmp")
986    (set_attr "mode" "<MODE>")])
987
988 (define_insn "*cmpqi_ext_1"
989   [(set (reg FLAGS_REG)
990         (compare
991           (match_operand:QI 0 "general_operand" "Qm")
992           (subreg:QI
993             (zero_extract:SI
994               (match_operand 1 "ext_register_operand" "Q")
995               (const_int 8)
996               (const_int 8)) 0)))]
997   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
998   "cmp{b}\t{%h1, %0|%0, %h1}"
999   [(set_attr "type" "icmp")
1000    (set_attr "mode" "QI")])
1001
1002 (define_insn "*cmpqi_ext_1_rex64"
1003   [(set (reg FLAGS_REG)
1004         (compare
1005           (match_operand:QI 0 "register_operand" "Q")
1006           (subreg:QI
1007             (zero_extract:SI
1008               (match_operand 1 "ext_register_operand" "Q")
1009               (const_int 8)
1010               (const_int 8)) 0)))]
1011   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1012   "cmp{b}\t{%h1, %0|%0, %h1}"
1013   [(set_attr "type" "icmp")
1014    (set_attr "mode" "QI")])
1015
1016 (define_insn "*cmpqi_ext_2"
1017   [(set (reg FLAGS_REG)
1018         (compare
1019           (subreg:QI
1020             (zero_extract:SI
1021               (match_operand 0 "ext_register_operand" "Q")
1022               (const_int 8)
1023               (const_int 8)) 0)
1024           (match_operand:QI 1 "const0_operand" "")))]
1025   "ix86_match_ccmode (insn, CCNOmode)"
1026   "test{b}\t%h0, %h0"
1027   [(set_attr "type" "test")
1028    (set_attr "length_immediate" "0")
1029    (set_attr "mode" "QI")])
1030
1031 (define_expand "cmpqi_ext_3"
1032   [(set (reg:CC FLAGS_REG)
1033         (compare:CC
1034           (subreg:QI
1035             (zero_extract:SI
1036               (match_operand 0 "ext_register_operand" "")
1037               (const_int 8)
1038               (const_int 8)) 0)
1039           (match_operand:QI 1 "immediate_operand" "")))]
1040   ""
1041   "")
1042
1043 (define_insn "*cmpqi_ext_3_insn"
1044   [(set (reg FLAGS_REG)
1045         (compare
1046           (subreg:QI
1047             (zero_extract:SI
1048               (match_operand 0 "ext_register_operand" "Q")
1049               (const_int 8)
1050               (const_int 8)) 0)
1051           (match_operand:QI 1 "general_operand" "Qmn")))]
1052   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1053   "cmp{b}\t{%1, %h0|%h0, %1}"
1054   [(set_attr "type" "icmp")
1055    (set_attr "modrm" "1")
1056    (set_attr "mode" "QI")])
1057
1058 (define_insn "*cmpqi_ext_3_insn_rex64"
1059   [(set (reg FLAGS_REG)
1060         (compare
1061           (subreg:QI
1062             (zero_extract:SI
1063               (match_operand 0 "ext_register_operand" "Q")
1064               (const_int 8)
1065               (const_int 8)) 0)
1066           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1067   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1068   "cmp{b}\t{%1, %h0|%h0, %1}"
1069   [(set_attr "type" "icmp")
1070    (set_attr "modrm" "1")
1071    (set_attr "mode" "QI")])
1072
1073 (define_insn "*cmpqi_ext_4"
1074   [(set (reg FLAGS_REG)
1075         (compare
1076           (subreg:QI
1077             (zero_extract:SI
1078               (match_operand 0 "ext_register_operand" "Q")
1079               (const_int 8)
1080               (const_int 8)) 0)
1081           (subreg:QI
1082             (zero_extract:SI
1083               (match_operand 1 "ext_register_operand" "Q")
1084               (const_int 8)
1085               (const_int 8)) 0)))]
1086   "ix86_match_ccmode (insn, CCmode)"
1087   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1088   [(set_attr "type" "icmp")
1089    (set_attr "mode" "QI")])
1090
1091 ;; These implement float point compares.
1092 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1093 ;; which would allow mix and match FP modes on the compares.  Which is what
1094 ;; the old patterns did, but with many more of them.
1095
1096 (define_expand "cbranchxf4"
1097   [(set (reg:CC FLAGS_REG)
1098         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1099                     (match_operand:XF 2 "nonmemory_operand" "")))
1100    (set (pc) (if_then_else
1101               (match_operator 0 "ix86_fp_comparison_operator"
1102                [(reg:CC FLAGS_REG)
1103                 (const_int 0)])
1104               (label_ref (match_operand 3 "" ""))
1105               (pc)))]
1106   "TARGET_80387"
1107 {
1108   ix86_compare_op0 = operands[1];
1109   ix86_compare_op1 = operands[2];
1110   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1111   DONE;
1112 })
1113
1114 (define_expand "cstorexf4"
1115   [(set (reg:CC FLAGS_REG)
1116         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1117                     (match_operand:XF 3 "nonmemory_operand" "")))
1118    (set (match_operand:QI 0 "register_operand" "")
1119               (match_operator 1 "ix86_fp_comparison_operator"
1120                [(reg:CC FLAGS_REG)
1121                 (const_int 0)]))]
1122   "TARGET_80387"
1123 {
1124   ix86_compare_op0 = operands[2];
1125   ix86_compare_op1 = operands[3];
1126   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1127   DONE;
1128 })
1129
1130 (define_expand "cbranch<mode>4"
1131   [(set (reg:CC FLAGS_REG)
1132         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1133                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1134    (set (pc) (if_then_else
1135               (match_operator 0 "ix86_fp_comparison_operator"
1136                [(reg:CC FLAGS_REG)
1137                 (const_int 0)])
1138               (label_ref (match_operand 3 "" ""))
1139               (pc)))]
1140   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1141 {
1142   ix86_compare_op0 = operands[1];
1143   ix86_compare_op1 = operands[2];
1144   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1145   DONE;
1146 })
1147
1148 (define_expand "cstore<mode>4"
1149   [(set (reg:CC FLAGS_REG)
1150         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1151                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1152    (set (match_operand:QI 0 "register_operand" "")
1153               (match_operator 1 "ix86_fp_comparison_operator"
1154                [(reg:CC FLAGS_REG)
1155                 (const_int 0)]))]
1156   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1157 {
1158   ix86_compare_op0 = operands[2];
1159   ix86_compare_op1 = operands[3];
1160   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1161   DONE;
1162 })
1163
1164 (define_expand "cbranchcc4"
1165   [(set (pc) (if_then_else
1166               (match_operator 0 "comparison_operator"
1167                [(match_operand 1 "flags_reg_operand" "")
1168                 (match_operand 2 "const0_operand" "")])
1169               (label_ref (match_operand 3 "" ""))
1170               (pc)))]
1171   ""
1172 {
1173   ix86_compare_op0 = operands[1];
1174   ix86_compare_op1 = operands[2];
1175   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1176   DONE;
1177 })
1178
1179 (define_expand "cstorecc4"
1180   [(set (match_operand:QI 0 "register_operand" "")
1181               (match_operator 1 "comparison_operator"
1182                [(match_operand 2 "flags_reg_operand" "")
1183                 (match_operand 3 "const0_operand" "")]))]
1184   ""
1185 {
1186   ix86_compare_op0 = operands[2];
1187   ix86_compare_op1 = operands[3];
1188   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1189   DONE;
1190 })
1191
1192
1193 ;; FP compares, step 1:
1194 ;; Set the FP condition codes.
1195 ;;
1196 ;; CCFPmode     compare with exceptions
1197 ;; CCFPUmode    compare with no exceptions
1198
1199 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1200 ;; used to manage the reg stack popping would not be preserved.
1201
1202 (define_insn "*cmpfp_0"
1203   [(set (match_operand:HI 0 "register_operand" "=a")
1204         (unspec:HI
1205           [(compare:CCFP
1206              (match_operand 1 "register_operand" "f")
1207              (match_operand 2 "const0_operand" ""))]
1208         UNSPEC_FNSTSW))]
1209   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1210    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1211   "* return output_fp_compare (insn, operands, 0, 0);"
1212   [(set_attr "type" "multi")
1213    (set_attr "unit" "i387")
1214    (set (attr "mode")
1215      (cond [(match_operand:SF 1 "" "")
1216               (const_string "SF")
1217             (match_operand:DF 1 "" "")
1218               (const_string "DF")
1219            ]
1220            (const_string "XF")))])
1221
1222 (define_insn_and_split "*cmpfp_0_cc"
1223   [(set (reg:CCFP FLAGS_REG)
1224         (compare:CCFP
1225           (match_operand 1 "register_operand" "f")
1226           (match_operand 2 "const0_operand" "")))
1227    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1228   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1229    && TARGET_SAHF && !TARGET_CMOVE
1230    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1231   "#"
1232   "&& reload_completed"
1233   [(set (match_dup 0)
1234         (unspec:HI
1235           [(compare:CCFP (match_dup 1)(match_dup 2))]
1236         UNSPEC_FNSTSW))
1237    (set (reg:CC FLAGS_REG)
1238         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1239   ""
1240   [(set_attr "type" "multi")
1241    (set_attr "unit" "i387")
1242    (set (attr "mode")
1243      (cond [(match_operand:SF 1 "" "")
1244               (const_string "SF")
1245             (match_operand:DF 1 "" "")
1246               (const_string "DF")
1247            ]
1248            (const_string "XF")))])
1249
1250 (define_insn "*cmpfp_xf"
1251   [(set (match_operand:HI 0 "register_operand" "=a")
1252         (unspec:HI
1253           [(compare:CCFP
1254              (match_operand:XF 1 "register_operand" "f")
1255              (match_operand:XF 2 "register_operand" "f"))]
1256           UNSPEC_FNSTSW))]
1257   "TARGET_80387"
1258   "* return output_fp_compare (insn, operands, 0, 0);"
1259   [(set_attr "type" "multi")
1260    (set_attr "unit" "i387")
1261    (set_attr "mode" "XF")])
1262
1263 (define_insn_and_split "*cmpfp_xf_cc"
1264   [(set (reg:CCFP FLAGS_REG)
1265         (compare:CCFP
1266           (match_operand:XF 1 "register_operand" "f")
1267           (match_operand:XF 2 "register_operand" "f")))
1268    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1269   "TARGET_80387
1270    && TARGET_SAHF && !TARGET_CMOVE"
1271   "#"
1272   "&& reload_completed"
1273   [(set (match_dup 0)
1274         (unspec:HI
1275           [(compare:CCFP (match_dup 1)(match_dup 2))]
1276         UNSPEC_FNSTSW))
1277    (set (reg:CC FLAGS_REG)
1278         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1279   ""
1280   [(set_attr "type" "multi")
1281    (set_attr "unit" "i387")
1282    (set_attr "mode" "XF")])
1283
1284 (define_insn "*cmpfp_<mode>"
1285   [(set (match_operand:HI 0 "register_operand" "=a")
1286         (unspec:HI
1287           [(compare:CCFP
1288              (match_operand:MODEF 1 "register_operand" "f")
1289              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1290           UNSPEC_FNSTSW))]
1291   "TARGET_80387"
1292   "* return output_fp_compare (insn, operands, 0, 0);"
1293   [(set_attr "type" "multi")
1294    (set_attr "unit" "i387")
1295    (set_attr "mode" "<MODE>")])
1296
1297 (define_insn_and_split "*cmpfp_<mode>_cc"
1298   [(set (reg:CCFP FLAGS_REG)
1299         (compare:CCFP
1300           (match_operand:MODEF 1 "register_operand" "f")
1301           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1302    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1303   "TARGET_80387
1304    && TARGET_SAHF && !TARGET_CMOVE"
1305   "#"
1306   "&& reload_completed"
1307   [(set (match_dup 0)
1308         (unspec:HI
1309           [(compare:CCFP (match_dup 1)(match_dup 2))]
1310         UNSPEC_FNSTSW))
1311    (set (reg:CC FLAGS_REG)
1312         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1313   ""
1314   [(set_attr "type" "multi")
1315    (set_attr "unit" "i387")
1316    (set_attr "mode" "<MODE>")])
1317
1318 (define_insn "*cmpfp_u"
1319   [(set (match_operand:HI 0 "register_operand" "=a")
1320         (unspec:HI
1321           [(compare:CCFPU
1322              (match_operand 1 "register_operand" "f")
1323              (match_operand 2 "register_operand" "f"))]
1324           UNSPEC_FNSTSW))]
1325   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1326    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1327   "* return output_fp_compare (insn, operands, 0, 1);"
1328   [(set_attr "type" "multi")
1329    (set_attr "unit" "i387")
1330    (set (attr "mode")
1331      (cond [(match_operand:SF 1 "" "")
1332               (const_string "SF")
1333             (match_operand:DF 1 "" "")
1334               (const_string "DF")
1335            ]
1336            (const_string "XF")))])
1337
1338 (define_insn_and_split "*cmpfp_u_cc"
1339   [(set (reg:CCFPU FLAGS_REG)
1340         (compare:CCFPU
1341           (match_operand 1 "register_operand" "f")
1342           (match_operand 2 "register_operand" "f")))
1343    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1344   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1345    && TARGET_SAHF && !TARGET_CMOVE
1346    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1347   "#"
1348   "&& reload_completed"
1349   [(set (match_dup 0)
1350         (unspec:HI
1351           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1352         UNSPEC_FNSTSW))
1353    (set (reg:CC FLAGS_REG)
1354         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1355   ""
1356   [(set_attr "type" "multi")
1357    (set_attr "unit" "i387")
1358    (set (attr "mode")
1359      (cond [(match_operand:SF 1 "" "")
1360               (const_string "SF")
1361             (match_operand:DF 1 "" "")
1362               (const_string "DF")
1363            ]
1364            (const_string "XF")))])
1365
1366 (define_insn "*cmpfp_<mode>"
1367   [(set (match_operand:HI 0 "register_operand" "=a")
1368         (unspec:HI
1369           [(compare:CCFP
1370              (match_operand 1 "register_operand" "f")
1371              (match_operator 3 "float_operator"
1372                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1373           UNSPEC_FNSTSW))]
1374   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1375    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1376    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1377   "* return output_fp_compare (insn, operands, 0, 0);"
1378   [(set_attr "type" "multi")
1379    (set_attr "unit" "i387")
1380    (set_attr "fp_int_src" "true")
1381    (set_attr "mode" "<MODE>")])
1382
1383 (define_insn_and_split "*cmpfp_<mode>_cc"
1384   [(set (reg:CCFP FLAGS_REG)
1385         (compare:CCFP
1386           (match_operand 1 "register_operand" "f")
1387           (match_operator 3 "float_operator"
1388             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1389    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1390   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1391    && TARGET_SAHF && !TARGET_CMOVE
1392    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1393    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1394   "#"
1395   "&& reload_completed"
1396   [(set (match_dup 0)
1397         (unspec:HI
1398           [(compare:CCFP
1399              (match_dup 1)
1400              (match_op_dup 3 [(match_dup 2)]))]
1401         UNSPEC_FNSTSW))
1402    (set (reg:CC FLAGS_REG)
1403         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1404   ""
1405   [(set_attr "type" "multi")
1406    (set_attr "unit" "i387")
1407    (set_attr "fp_int_src" "true")
1408    (set_attr "mode" "<MODE>")])
1409
1410 ;; FP compares, step 2
1411 ;; Move the fpsw to ax.
1412
1413 (define_insn "x86_fnstsw_1"
1414   [(set (match_operand:HI 0 "register_operand" "=a")
1415         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1416   "TARGET_80387"
1417   "fnstsw\t%0"
1418   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1419    (set_attr "mode" "SI")
1420    (set_attr "unit" "i387")])
1421
1422 ;; FP compares, step 3
1423 ;; Get ax into flags, general case.
1424
1425 (define_insn "x86_sahf_1"
1426   [(set (reg:CC FLAGS_REG)
1427         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1428                    UNSPEC_SAHF))]
1429   "TARGET_SAHF"
1430 {
1431 #ifdef HAVE_AS_IX86_SAHF
1432   return "sahf";
1433 #else
1434   return ASM_BYTE "0x9e";
1435 #endif
1436 }
1437   [(set_attr "length" "1")
1438    (set_attr "athlon_decode" "vector")
1439    (set_attr "amdfam10_decode" "direct")
1440    (set_attr "mode" "SI")])
1441
1442 ;; Pentium Pro can do steps 1 through 3 in one go.
1443 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1444 (define_insn "*cmpfp_i_mixed"
1445   [(set (reg:CCFP FLAGS_REG)
1446         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1447                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1448   "TARGET_MIX_SSE_I387
1449    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1450    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1451   "* return output_fp_compare (insn, operands, 1, 0);"
1452   [(set_attr "type" "fcmp,ssecomi")
1453    (set_attr "prefix" "orig,maybe_vex")
1454    (set (attr "mode")
1455      (if_then_else (match_operand:SF 1 "" "")
1456         (const_string "SF")
1457         (const_string "DF")))
1458    (set (attr "prefix_rep")
1459         (if_then_else (eq_attr "type" "ssecomi")
1460                       (const_string "0")
1461                       (const_string "*")))
1462    (set (attr "prefix_data16")
1463         (cond [(eq_attr "type" "fcmp")
1464                  (const_string "*")
1465                (eq_attr "mode" "DF")
1466                  (const_string "1")
1467               ]
1468               (const_string "0")))
1469    (set_attr "athlon_decode" "vector")
1470    (set_attr "amdfam10_decode" "direct")])
1471
1472 (define_insn "*cmpfp_i_sse"
1473   [(set (reg:CCFP FLAGS_REG)
1474         (compare:CCFP (match_operand 0 "register_operand" "x")
1475                       (match_operand 1 "nonimmediate_operand" "xm")))]
1476   "TARGET_SSE_MATH
1477    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1478    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1479   "* return output_fp_compare (insn, operands, 1, 0);"
1480   [(set_attr "type" "ssecomi")
1481    (set_attr "prefix" "maybe_vex")
1482    (set (attr "mode")
1483      (if_then_else (match_operand:SF 1 "" "")
1484         (const_string "SF")
1485         (const_string "DF")))
1486    (set_attr "prefix_rep" "0")
1487    (set (attr "prefix_data16")
1488         (if_then_else (eq_attr "mode" "DF")
1489                       (const_string "1")
1490                       (const_string "0")))
1491    (set_attr "athlon_decode" "vector")
1492    (set_attr "amdfam10_decode" "direct")])
1493
1494 (define_insn "*cmpfp_i_i387"
1495   [(set (reg:CCFP FLAGS_REG)
1496         (compare:CCFP (match_operand 0 "register_operand" "f")
1497                       (match_operand 1 "register_operand" "f")))]
1498   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1499    && TARGET_CMOVE
1500    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1501    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1502   "* return output_fp_compare (insn, operands, 1, 0);"
1503   [(set_attr "type" "fcmp")
1504    (set (attr "mode")
1505      (cond [(match_operand:SF 1 "" "")
1506               (const_string "SF")
1507             (match_operand:DF 1 "" "")
1508               (const_string "DF")
1509            ]
1510            (const_string "XF")))
1511    (set_attr "athlon_decode" "vector")
1512    (set_attr "amdfam10_decode" "direct")])
1513
1514 (define_insn "*cmpfp_iu_mixed"
1515   [(set (reg:CCFPU FLAGS_REG)
1516         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1517                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1518   "TARGET_MIX_SSE_I387
1519    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1520    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1521   "* return output_fp_compare (insn, operands, 1, 1);"
1522   [(set_attr "type" "fcmp,ssecomi")
1523    (set_attr "prefix" "orig,maybe_vex")
1524    (set (attr "mode")
1525      (if_then_else (match_operand:SF 1 "" "")
1526         (const_string "SF")
1527         (const_string "DF")))
1528    (set (attr "prefix_rep")
1529         (if_then_else (eq_attr "type" "ssecomi")
1530                       (const_string "0")
1531                       (const_string "*")))
1532    (set (attr "prefix_data16")
1533         (cond [(eq_attr "type" "fcmp")
1534                  (const_string "*")
1535                (eq_attr "mode" "DF")
1536                  (const_string "1")
1537               ]
1538               (const_string "0")))
1539    (set_attr "athlon_decode" "vector")
1540    (set_attr "amdfam10_decode" "direct")])
1541
1542 (define_insn "*cmpfp_iu_sse"
1543   [(set (reg:CCFPU FLAGS_REG)
1544         (compare:CCFPU (match_operand 0 "register_operand" "x")
1545                        (match_operand 1 "nonimmediate_operand" "xm")))]
1546   "TARGET_SSE_MATH
1547    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1548    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1549   "* return output_fp_compare (insn, operands, 1, 1);"
1550   [(set_attr "type" "ssecomi")
1551    (set_attr "prefix" "maybe_vex")
1552    (set (attr "mode")
1553      (if_then_else (match_operand:SF 1 "" "")
1554         (const_string "SF")
1555         (const_string "DF")))
1556    (set_attr "prefix_rep" "0")
1557    (set (attr "prefix_data16")
1558         (if_then_else (eq_attr "mode" "DF")
1559                       (const_string "1")
1560                       (const_string "0")))
1561    (set_attr "athlon_decode" "vector")
1562    (set_attr "amdfam10_decode" "direct")])
1563
1564 (define_insn "*cmpfp_iu_387"
1565   [(set (reg:CCFPU FLAGS_REG)
1566         (compare:CCFPU (match_operand 0 "register_operand" "f")
1567                        (match_operand 1 "register_operand" "f")))]
1568   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1569    && TARGET_CMOVE
1570    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1571    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1572   "* return output_fp_compare (insn, operands, 1, 1);"
1573   [(set_attr "type" "fcmp")
1574    (set (attr "mode")
1575      (cond [(match_operand:SF 1 "" "")
1576               (const_string "SF")
1577             (match_operand:DF 1 "" "")
1578               (const_string "DF")
1579            ]
1580            (const_string "XF")))
1581    (set_attr "athlon_decode" "vector")
1582    (set_attr "amdfam10_decode" "direct")])
1583 \f
1584 ;; Move instructions.
1585
1586 ;; General case of fullword move.
1587
1588 (define_expand "movsi"
1589   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1590         (match_operand:SI 1 "general_operand" ""))]
1591   ""
1592   "ix86_expand_move (SImode, operands); DONE;")
1593
1594 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1595 ;; general_operand.
1596 ;;
1597 ;; %%% We don't use a post-inc memory reference because x86 is not a
1598 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1599 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1600 ;; targets without our curiosities, and it is just as easy to represent
1601 ;; this differently.
1602
1603 (define_insn "*pushsi2"
1604   [(set (match_operand:SI 0 "push_operand" "=<")
1605         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1606   "!TARGET_64BIT"
1607   "push{l}\t%1"
1608   [(set_attr "type" "push")
1609    (set_attr "mode" "SI")])
1610
1611 ;; For 64BIT abi we always round up to 8 bytes.
1612 (define_insn "*pushsi2_rex64"
1613   [(set (match_operand:SI 0 "push_operand" "=X")
1614         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1615   "TARGET_64BIT"
1616   "push{q}\t%q1"
1617   [(set_attr "type" "push")
1618    (set_attr "mode" "SI")])
1619
1620 (define_insn "*pushsi2_prologue"
1621   [(set (match_operand:SI 0 "push_operand" "=<")
1622         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1623    (clobber (mem:BLK (scratch)))]
1624   "!TARGET_64BIT"
1625   "push{l}\t%1"
1626   [(set_attr "type" "push")
1627    (set_attr "mode" "SI")])
1628
1629 (define_insn "*popsi1_epilogue"
1630   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1631         (mem:SI (reg:SI SP_REG)))
1632    (set (reg:SI SP_REG)
1633         (plus:SI (reg:SI SP_REG) (const_int 4)))
1634    (clobber (mem:BLK (scratch)))]
1635   "!TARGET_64BIT"
1636   "pop{l}\t%0"
1637   [(set_attr "type" "pop")
1638    (set_attr "mode" "SI")])
1639
1640 (define_insn "popsi1"
1641   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1642         (mem:SI (reg:SI SP_REG)))
1643    (set (reg:SI SP_REG)
1644         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1645   "!TARGET_64BIT"
1646   "pop{l}\t%0"
1647   [(set_attr "type" "pop")
1648    (set_attr "mode" "SI")])
1649
1650 (define_insn "*movsi_xor"
1651   [(set (match_operand:SI 0 "register_operand" "=r")
1652         (match_operand:SI 1 "const0_operand" ""))
1653    (clobber (reg:CC FLAGS_REG))]
1654   "reload_completed"
1655   "xor{l}\t%0, %0"
1656   [(set_attr "type" "alu1")
1657    (set_attr "mode" "SI")
1658    (set_attr "length_immediate" "0")])
1659
1660 (define_insn "*movsi_or"
1661   [(set (match_operand:SI 0 "register_operand" "=r")
1662         (match_operand:SI 1 "immediate_operand" "i"))
1663    (clobber (reg:CC FLAGS_REG))]
1664   "reload_completed
1665    && operands[1] == constm1_rtx"
1666 {
1667   operands[1] = constm1_rtx;
1668   return "or{l}\t{%1, %0|%0, %1}";
1669 }
1670   [(set_attr "type" "alu1")
1671    (set_attr "mode" "SI")
1672    (set_attr "length_immediate" "1")])
1673
1674 (define_insn "*movsi_1"
1675   [(set (match_operand:SI 0 "nonimmediate_operand"
1676                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1677         (match_operand:SI 1 "general_operand"
1678                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1679   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1680 {
1681   switch (get_attr_type (insn))
1682     {
1683     case TYPE_SSELOG1:
1684       if (get_attr_mode (insn) == MODE_TI)
1685         return "%vpxor\t%0, %d0";
1686       return "%vxorps\t%0, %d0";
1687
1688     case TYPE_SSEMOV:
1689       switch (get_attr_mode (insn))
1690         {
1691         case MODE_TI:
1692           return "%vmovdqa\t{%1, %0|%0, %1}";
1693         case MODE_V4SF:
1694           return "%vmovaps\t{%1, %0|%0, %1}";
1695         case MODE_SI:
1696           return "%vmovd\t{%1, %0|%0, %1}";
1697         case MODE_SF:
1698           return "%vmovss\t{%1, %0|%0, %1}";
1699         default:
1700           gcc_unreachable ();
1701         }
1702
1703     case TYPE_MMX:
1704       return "pxor\t%0, %0";
1705
1706     case TYPE_MMXMOV:
1707       if (get_attr_mode (insn) == MODE_DI)
1708         return "movq\t{%1, %0|%0, %1}";
1709       return "movd\t{%1, %0|%0, %1}";
1710
1711     case TYPE_LEA:
1712       return "lea{l}\t{%1, %0|%0, %1}";
1713
1714     default:
1715       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1716       return "mov{l}\t{%1, %0|%0, %1}";
1717     }
1718 }
1719   [(set (attr "type")
1720      (cond [(eq_attr "alternative" "2")
1721               (const_string "mmx")
1722             (eq_attr "alternative" "3,4,5")
1723               (const_string "mmxmov")
1724             (eq_attr "alternative" "6")
1725               (const_string "sselog1")
1726             (eq_attr "alternative" "7,8,9,10,11")
1727               (const_string "ssemov")
1728             (match_operand:DI 1 "pic_32bit_operand" "")
1729               (const_string "lea")
1730            ]
1731            (const_string "imov")))
1732    (set (attr "prefix")
1733      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1734        (const_string "orig")
1735        (const_string "maybe_vex")))
1736    (set (attr "prefix_data16")
1737      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1738        (const_string "1")
1739        (const_string "*")))
1740    (set (attr "mode")
1741      (cond [(eq_attr "alternative" "2,3")
1742               (const_string "DI")
1743             (eq_attr "alternative" "6,7")
1744               (if_then_else
1745                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1746                 (const_string "V4SF")
1747                 (const_string "TI"))
1748             (and (eq_attr "alternative" "8,9,10,11")
1749                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1750               (const_string "SF")
1751            ]
1752            (const_string "SI")))])
1753
1754 ;; Stores and loads of ax to arbitrary constant address.
1755 ;; We fake an second form of instruction to force reload to load address
1756 ;; into register when rax is not available
1757 (define_insn "*movabssi_1_rex64"
1758   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1759         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1760   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1761   "@
1762    movabs{l}\t{%1, %P0|%P0, %1}
1763    mov{l}\t{%1, %a0|%a0, %1}"
1764   [(set_attr "type" "imov")
1765    (set_attr "modrm" "0,*")
1766    (set_attr "length_address" "8,0")
1767    (set_attr "length_immediate" "0,*")
1768    (set_attr "memory" "store")
1769    (set_attr "mode" "SI")])
1770
1771 (define_insn "*movabssi_2_rex64"
1772   [(set (match_operand:SI 0 "register_operand" "=a,r")
1773         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1774   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1775   "@
1776    movabs{l}\t{%P1, %0|%0, %P1}
1777    mov{l}\t{%a1, %0|%0, %a1}"
1778   [(set_attr "type" "imov")
1779    (set_attr "modrm" "0,*")
1780    (set_attr "length_address" "8,0")
1781    (set_attr "length_immediate" "0")
1782    (set_attr "memory" "load")
1783    (set_attr "mode" "SI")])
1784
1785 (define_insn "*swapsi"
1786   [(set (match_operand:SI 0 "register_operand" "+r")
1787         (match_operand:SI 1 "register_operand" "+r"))
1788    (set (match_dup 1)
1789         (match_dup 0))]
1790   ""
1791   "xchg{l}\t%1, %0"
1792   [(set_attr "type" "imov")
1793    (set_attr "mode" "SI")
1794    (set_attr "pent_pair" "np")
1795    (set_attr "athlon_decode" "vector")
1796    (set_attr "amdfam10_decode" "double")])
1797
1798 (define_expand "movhi"
1799   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1800         (match_operand:HI 1 "general_operand" ""))]
1801   ""
1802   "ix86_expand_move (HImode, operands); DONE;")
1803
1804 (define_insn "*pushhi2"
1805   [(set (match_operand:HI 0 "push_operand" "=X")
1806         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1807   "!TARGET_64BIT"
1808   "push{l}\t%k1"
1809   [(set_attr "type" "push")
1810    (set_attr "mode" "SI")])
1811
1812 ;; For 64BIT abi we always round up to 8 bytes.
1813 (define_insn "*pushhi2_rex64"
1814   [(set (match_operand:HI 0 "push_operand" "=X")
1815         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1816   "TARGET_64BIT"
1817   "push{q}\t%q1"
1818   [(set_attr "type" "push")
1819    (set_attr "mode" "DI")])
1820
1821 (define_insn "*movhi_1"
1822   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1823         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1824   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1825 {
1826   switch (get_attr_type (insn))
1827     {
1828     case TYPE_IMOVX:
1829       /* movzwl is faster than movw on p2 due to partial word stalls,
1830          though not as fast as an aligned movl.  */
1831       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1832     default:
1833       if (get_attr_mode (insn) == MODE_SI)
1834         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1835       else
1836         return "mov{w}\t{%1, %0|%0, %1}";
1837     }
1838 }
1839   [(set (attr "type")
1840      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1841               (const_string "imov")
1842             (and (eq_attr "alternative" "0")
1843                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1844                           (const_int 0))
1845                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1846                           (const_int 0))))
1847               (const_string "imov")
1848             (and (eq_attr "alternative" "1,2")
1849                  (match_operand:HI 1 "aligned_operand" ""))
1850               (const_string "imov")
1851             (and (ne (symbol_ref "TARGET_MOVX")
1852                      (const_int 0))
1853                  (eq_attr "alternative" "0,2"))
1854               (const_string "imovx")
1855            ]
1856            (const_string "imov")))
1857     (set (attr "mode")
1858       (cond [(eq_attr "type" "imovx")
1859                (const_string "SI")
1860              (and (eq_attr "alternative" "1,2")
1861                   (match_operand:HI 1 "aligned_operand" ""))
1862                (const_string "SI")
1863              (and (eq_attr "alternative" "0")
1864                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1865                            (const_int 0))
1866                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1867                            (const_int 0))))
1868                (const_string "SI")
1869             ]
1870             (const_string "HI")))])
1871
1872 ;; Stores and loads of ax to arbitrary constant address.
1873 ;; We fake an second form of instruction to force reload to load address
1874 ;; into register when rax is not available
1875 (define_insn "*movabshi_1_rex64"
1876   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1877         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1878   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1879   "@
1880    movabs{w}\t{%1, %P0|%P0, %1}
1881    mov{w}\t{%1, %a0|%a0, %1}"
1882   [(set_attr "type" "imov")
1883    (set_attr "modrm" "0,*")
1884    (set_attr "length_address" "8,0")
1885    (set_attr "length_immediate" "0,*")
1886    (set_attr "memory" "store")
1887    (set_attr "mode" "HI")])
1888
1889 (define_insn "*movabshi_2_rex64"
1890   [(set (match_operand:HI 0 "register_operand" "=a,r")
1891         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1892   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1893   "@
1894    movabs{w}\t{%P1, %0|%0, %P1}
1895    mov{w}\t{%a1, %0|%0, %a1}"
1896   [(set_attr "type" "imov")
1897    (set_attr "modrm" "0,*")
1898    (set_attr "length_address" "8,0")
1899    (set_attr "length_immediate" "0")
1900    (set_attr "memory" "load")
1901    (set_attr "mode" "HI")])
1902
1903 (define_insn "*swaphi_1"
1904   [(set (match_operand:HI 0 "register_operand" "+r")
1905         (match_operand:HI 1 "register_operand" "+r"))
1906    (set (match_dup 1)
1907         (match_dup 0))]
1908   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1909   "xchg{l}\t%k1, %k0"
1910   [(set_attr "type" "imov")
1911    (set_attr "mode" "SI")
1912    (set_attr "pent_pair" "np")
1913    (set_attr "athlon_decode" "vector")
1914    (set_attr "amdfam10_decode" "double")])
1915
1916 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1917 (define_insn "*swaphi_2"
1918   [(set (match_operand:HI 0 "register_operand" "+r")
1919         (match_operand:HI 1 "register_operand" "+r"))
1920    (set (match_dup 1)
1921         (match_dup 0))]
1922   "TARGET_PARTIAL_REG_STALL"
1923   "xchg{w}\t%1, %0"
1924   [(set_attr "type" "imov")
1925    (set_attr "mode" "HI")
1926    (set_attr "pent_pair" "np")
1927    (set_attr "athlon_decode" "vector")])
1928
1929 (define_expand "movstricthi"
1930   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1931         (match_operand:HI 1 "general_operand" ""))]
1932   ""
1933 {
1934   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1935     FAIL;
1936   /* Don't generate memory->memory moves, go through a register */
1937   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1938     operands[1] = force_reg (HImode, operands[1]);
1939 })
1940
1941 (define_insn "*movstricthi_1"
1942   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1943         (match_operand:HI 1 "general_operand" "rn,m"))]
1944   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1945    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1946   "mov{w}\t{%1, %0|%0, %1}"
1947   [(set_attr "type" "imov")
1948    (set_attr "mode" "HI")])
1949
1950 (define_insn "*movstricthi_xor"
1951   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1952         (match_operand:HI 1 "const0_operand" ""))
1953    (clobber (reg:CC FLAGS_REG))]
1954   "reload_completed"
1955   "xor{w}\t%0, %0"
1956   [(set_attr "type" "alu1")
1957    (set_attr "mode" "HI")
1958    (set_attr "length_immediate" "0")])
1959
1960 (define_expand "movqi"
1961   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1962         (match_operand:QI 1 "general_operand" ""))]
1963   ""
1964   "ix86_expand_move (QImode, operands); DONE;")
1965
1966 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1967 ;; "push a byte".  But actually we use pushl, which has the effect
1968 ;; of rounding the amount pushed up to a word.
1969
1970 (define_insn "*pushqi2"
1971   [(set (match_operand:QI 0 "push_operand" "=X")
1972         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1973   "!TARGET_64BIT"
1974   "push{l}\t%k1"
1975   [(set_attr "type" "push")
1976    (set_attr "mode" "SI")])
1977
1978 ;; For 64BIT abi we always round up to 8 bytes.
1979 (define_insn "*pushqi2_rex64"
1980   [(set (match_operand:QI 0 "push_operand" "=X")
1981         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1982   "TARGET_64BIT"
1983   "push{q}\t%q1"
1984   [(set_attr "type" "push")
1985    (set_attr "mode" "DI")])
1986
1987 ;; Situation is quite tricky about when to choose full sized (SImode) move
1988 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1989 ;; partial register dependency machines (such as AMD Athlon), where QImode
1990 ;; moves issue extra dependency and for partial register stalls machines
1991 ;; that don't use QImode patterns (and QImode move cause stall on the next
1992 ;; instruction).
1993 ;;
1994 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1995 ;; register stall machines with, where we use QImode instructions, since
1996 ;; partial register stall can be caused there.  Then we use movzx.
1997 (define_insn "*movqi_1"
1998   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1999         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2000   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2001 {
2002   switch (get_attr_type (insn))
2003     {
2004     case TYPE_IMOVX:
2005       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2006       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2007     default:
2008       if (get_attr_mode (insn) == MODE_SI)
2009         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2010       else
2011         return "mov{b}\t{%1, %0|%0, %1}";
2012     }
2013 }
2014   [(set (attr "type")
2015      (cond [(and (eq_attr "alternative" "5")
2016                  (not (match_operand:QI 1 "aligned_operand" "")))
2017               (const_string "imovx")
2018             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2019               (const_string "imov")
2020             (and (eq_attr "alternative" "3")
2021                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2022                           (const_int 0))
2023                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2024                           (const_int 0))))
2025               (const_string "imov")
2026             (eq_attr "alternative" "3,5")
2027               (const_string "imovx")
2028             (and (ne (symbol_ref "TARGET_MOVX")
2029                      (const_int 0))
2030                  (eq_attr "alternative" "2"))
2031               (const_string "imovx")
2032            ]
2033            (const_string "imov")))
2034    (set (attr "mode")
2035       (cond [(eq_attr "alternative" "3,4,5")
2036                (const_string "SI")
2037              (eq_attr "alternative" "6")
2038                (const_string "QI")
2039              (eq_attr "type" "imovx")
2040                (const_string "SI")
2041              (and (eq_attr "type" "imov")
2042                   (and (eq_attr "alternative" "0,1")
2043                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2044                                 (const_int 0))
2045                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2046                                      (const_int 0))
2047                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2048                                      (const_int 0))))))
2049                (const_string "SI")
2050              ;; Avoid partial register stalls when not using QImode arithmetic
2051              (and (eq_attr "type" "imov")
2052                   (and (eq_attr "alternative" "0,1")
2053                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2054                                 (const_int 0))
2055                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2056                                 (const_int 0)))))
2057                (const_string "SI")
2058            ]
2059            (const_string "QI")))])
2060
2061 (define_insn "*swapqi_1"
2062   [(set (match_operand:QI 0 "register_operand" "+r")
2063         (match_operand:QI 1 "register_operand" "+r"))
2064    (set (match_dup 1)
2065         (match_dup 0))]
2066   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2067   "xchg{l}\t%k1, %k0"
2068   [(set_attr "type" "imov")
2069    (set_attr "mode" "SI")
2070    (set_attr "pent_pair" "np")
2071    (set_attr "athlon_decode" "vector")
2072    (set_attr "amdfam10_decode" "vector")])
2073
2074 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2075 (define_insn "*swapqi_2"
2076   [(set (match_operand:QI 0 "register_operand" "+q")
2077         (match_operand:QI 1 "register_operand" "+q"))
2078    (set (match_dup 1)
2079         (match_dup 0))]
2080   "TARGET_PARTIAL_REG_STALL"
2081   "xchg{b}\t%1, %0"
2082   [(set_attr "type" "imov")
2083    (set_attr "mode" "QI")
2084    (set_attr "pent_pair" "np")
2085    (set_attr "athlon_decode" "vector")])
2086
2087 (define_expand "movstrictqi"
2088   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2089         (match_operand:QI 1 "general_operand" ""))]
2090   ""
2091 {
2092   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2093     FAIL;
2094   /* Don't generate memory->memory moves, go through a register.  */
2095   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2096     operands[1] = force_reg (QImode, operands[1]);
2097 })
2098
2099 (define_insn "*movstrictqi_1"
2100   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2101         (match_operand:QI 1 "general_operand" "*qn,m"))]
2102   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2103    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2104   "mov{b}\t{%1, %0|%0, %1}"
2105   [(set_attr "type" "imov")
2106    (set_attr "mode" "QI")])
2107
2108 (define_insn "*movstrictqi_xor"
2109   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2110         (match_operand:QI 1 "const0_operand" ""))
2111    (clobber (reg:CC FLAGS_REG))]
2112   "reload_completed"
2113   "xor{b}\t%0, %0"
2114   [(set_attr "type" "alu1")
2115    (set_attr "mode" "QI")
2116    (set_attr "length_immediate" "0")])
2117
2118 (define_insn "*movsi_extv_1"
2119   [(set (match_operand:SI 0 "register_operand" "=R")
2120         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2121                          (const_int 8)
2122                          (const_int 8)))]
2123   ""
2124   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2125   [(set_attr "type" "imovx")
2126    (set_attr "mode" "SI")])
2127
2128 (define_insn "*movhi_extv_1"
2129   [(set (match_operand:HI 0 "register_operand" "=R")
2130         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2131                          (const_int 8)
2132                          (const_int 8)))]
2133   ""
2134   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2135   [(set_attr "type" "imovx")
2136    (set_attr "mode" "SI")])
2137
2138 (define_insn "*movqi_extv_1"
2139   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2140         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2141                          (const_int 8)
2142                          (const_int 8)))]
2143   "!TARGET_64BIT"
2144 {
2145   switch (get_attr_type (insn))
2146     {
2147     case TYPE_IMOVX:
2148       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2149     default:
2150       return "mov{b}\t{%h1, %0|%0, %h1}";
2151     }
2152 }
2153   [(set (attr "type")
2154      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2155                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2156                              (ne (symbol_ref "TARGET_MOVX")
2157                                  (const_int 0))))
2158         (const_string "imovx")
2159         (const_string "imov")))
2160    (set (attr "mode")
2161      (if_then_else (eq_attr "type" "imovx")
2162         (const_string "SI")
2163         (const_string "QI")))])
2164
2165 (define_insn "*movqi_extv_1_rex64"
2166   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2167         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2168                          (const_int 8)
2169                          (const_int 8)))]
2170   "TARGET_64BIT"
2171 {
2172   switch (get_attr_type (insn))
2173     {
2174     case TYPE_IMOVX:
2175       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2176     default:
2177       return "mov{b}\t{%h1, %0|%0, %h1}";
2178     }
2179 }
2180   [(set (attr "type")
2181      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2182                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2183                              (ne (symbol_ref "TARGET_MOVX")
2184                                  (const_int 0))))
2185         (const_string "imovx")
2186         (const_string "imov")))
2187    (set (attr "mode")
2188      (if_then_else (eq_attr "type" "imovx")
2189         (const_string "SI")
2190         (const_string "QI")))])
2191
2192 ;; Stores and loads of ax to arbitrary constant address.
2193 ;; We fake an second form of instruction to force reload to load address
2194 ;; into register when rax is not available
2195 (define_insn "*movabsqi_1_rex64"
2196   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2197         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2198   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2199   "@
2200    movabs{b}\t{%1, %P0|%P0, %1}
2201    mov{b}\t{%1, %a0|%a0, %1}"
2202   [(set_attr "type" "imov")
2203    (set_attr "modrm" "0,*")
2204    (set_attr "length_address" "8,0")
2205    (set_attr "length_immediate" "0,*")
2206    (set_attr "memory" "store")
2207    (set_attr "mode" "QI")])
2208
2209 (define_insn "*movabsqi_2_rex64"
2210   [(set (match_operand:QI 0 "register_operand" "=a,r")
2211         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2212   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2213   "@
2214    movabs{b}\t{%P1, %0|%0, %P1}
2215    mov{b}\t{%a1, %0|%0, %a1}"
2216   [(set_attr "type" "imov")
2217    (set_attr "modrm" "0,*")
2218    (set_attr "length_address" "8,0")
2219    (set_attr "length_immediate" "0")
2220    (set_attr "memory" "load")
2221    (set_attr "mode" "QI")])
2222
2223 (define_insn "*movdi_extzv_1"
2224   [(set (match_operand:DI 0 "register_operand" "=R")
2225         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2226                          (const_int 8)
2227                          (const_int 8)))]
2228   "TARGET_64BIT"
2229   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2230   [(set_attr "type" "imovx")
2231    (set_attr "mode" "SI")])
2232
2233 (define_insn "*movsi_extzv_1"
2234   [(set (match_operand:SI 0 "register_operand" "=R")
2235         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2236                          (const_int 8)
2237                          (const_int 8)))]
2238   ""
2239   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2240   [(set_attr "type" "imovx")
2241    (set_attr "mode" "SI")])
2242
2243 (define_insn "*movqi_extzv_2"
2244   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2245         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2246                                     (const_int 8)
2247                                     (const_int 8)) 0))]
2248   "!TARGET_64BIT"
2249 {
2250   switch (get_attr_type (insn))
2251     {
2252     case TYPE_IMOVX:
2253       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2254     default:
2255       return "mov{b}\t{%h1, %0|%0, %h1}";
2256     }
2257 }
2258   [(set (attr "type")
2259      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2260                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2261                              (ne (symbol_ref "TARGET_MOVX")
2262                                  (const_int 0))))
2263         (const_string "imovx")
2264         (const_string "imov")))
2265    (set (attr "mode")
2266      (if_then_else (eq_attr "type" "imovx")
2267         (const_string "SI")
2268         (const_string "QI")))])
2269
2270 (define_insn "*movqi_extzv_2_rex64"
2271   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2272         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2273                                     (const_int 8)
2274                                     (const_int 8)) 0))]
2275   "TARGET_64BIT"
2276 {
2277   switch (get_attr_type (insn))
2278     {
2279     case TYPE_IMOVX:
2280       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2281     default:
2282       return "mov{b}\t{%h1, %0|%0, %h1}";
2283     }
2284 }
2285   [(set (attr "type")
2286      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2287                         (ne (symbol_ref "TARGET_MOVX")
2288                             (const_int 0)))
2289         (const_string "imovx")
2290         (const_string "imov")))
2291    (set (attr "mode")
2292      (if_then_else (eq_attr "type" "imovx")
2293         (const_string "SI")
2294         (const_string "QI")))])
2295
2296 (define_insn "movsi_insv_1"
2297   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2298                          (const_int 8)
2299                          (const_int 8))
2300         (match_operand:SI 1 "general_operand" "Qmn"))]
2301   "!TARGET_64BIT"
2302   "mov{b}\t{%b1, %h0|%h0, %b1}"
2303   [(set_attr "type" "imov")
2304    (set_attr "mode" "QI")])
2305
2306 (define_insn "*movsi_insv_1_rex64"
2307   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2308                          (const_int 8)
2309                          (const_int 8))
2310         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2311   "TARGET_64BIT"
2312   "mov{b}\t{%b1, %h0|%h0, %b1}"
2313   [(set_attr "type" "imov")
2314    (set_attr "mode" "QI")])
2315
2316 (define_insn "movdi_insv_1_rex64"
2317   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2318                          (const_int 8)
2319                          (const_int 8))
2320         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2321   "TARGET_64BIT"
2322   "mov{b}\t{%b1, %h0|%h0, %b1}"
2323   [(set_attr "type" "imov")
2324    (set_attr "mode" "QI")])
2325
2326 (define_insn "*movqi_insv_2"
2327   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2328                          (const_int 8)
2329                          (const_int 8))
2330         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2331                      (const_int 8)))]
2332   ""
2333   "mov{b}\t{%h1, %h0|%h0, %h1}"
2334   [(set_attr "type" "imov")
2335    (set_attr "mode" "QI")])
2336
2337 (define_expand "movdi"
2338   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2339         (match_operand:DI 1 "general_operand" ""))]
2340   ""
2341   "ix86_expand_move (DImode, operands); DONE;")
2342
2343 (define_insn "*pushdi"
2344   [(set (match_operand:DI 0 "push_operand" "=<")
2345         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2346   "!TARGET_64BIT"
2347   "#")
2348
2349 (define_insn "*pushdi2_rex64"
2350   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2351         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2352   "TARGET_64BIT"
2353   "@
2354    push{q}\t%1
2355    #"
2356   [(set_attr "type" "push,multi")
2357    (set_attr "mode" "DI")])
2358
2359 ;; Convert impossible pushes of immediate to existing instructions.
2360 ;; First try to get scratch register and go through it.  In case this
2361 ;; fails, push sign extended lower part first and then overwrite
2362 ;; upper part by 32bit move.
2363 (define_peephole2
2364   [(match_scratch:DI 2 "r")
2365    (set (match_operand:DI 0 "push_operand" "")
2366         (match_operand:DI 1 "immediate_operand" ""))]
2367   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2368    && !x86_64_immediate_operand (operands[1], DImode)"
2369   [(set (match_dup 2) (match_dup 1))
2370    (set (match_dup 0) (match_dup 2))]
2371   "")
2372
2373 ;; We need to define this as both peepholer and splitter for case
2374 ;; peephole2 pass is not run.
2375 ;; "&& 1" is needed to keep it from matching the previous pattern.
2376 (define_peephole2
2377   [(set (match_operand:DI 0 "push_operand" "")
2378         (match_operand:DI 1 "immediate_operand" ""))]
2379   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2380    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2381   [(set (match_dup 0) (match_dup 1))
2382    (set (match_dup 2) (match_dup 3))]
2383 {
2384   split_di (&operands[1], 1, &operands[2], &operands[3]);
2385
2386   operands[1] = gen_lowpart (DImode, operands[2]);
2387   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2388                                                    GEN_INT (4)));
2389 })
2390
2391 (define_split
2392   [(set (match_operand:DI 0 "push_operand" "")
2393         (match_operand:DI 1 "immediate_operand" ""))]
2394   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2395                     ? epilogue_completed : reload_completed)
2396    && !symbolic_operand (operands[1], DImode)
2397    && !x86_64_immediate_operand (operands[1], DImode)"
2398   [(set (match_dup 0) (match_dup 1))
2399    (set (match_dup 2) (match_dup 3))]
2400 {
2401   split_di (&operands[1], 1, &operands[2], &operands[3]);
2402
2403   operands[1] = gen_lowpart (DImode, operands[2]);
2404   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2405                                                    GEN_INT (4)));
2406 })
2407
2408 (define_insn "*pushdi2_prologue_rex64"
2409   [(set (match_operand:DI 0 "push_operand" "=<")
2410         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2411    (clobber (mem:BLK (scratch)))]
2412   "TARGET_64BIT"
2413   "push{q}\t%1"
2414   [(set_attr "type" "push")
2415    (set_attr "mode" "DI")])
2416
2417 (define_insn "*popdi1_epilogue_rex64"
2418   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2419         (mem:DI (reg:DI SP_REG)))
2420    (set (reg:DI SP_REG)
2421         (plus:DI (reg:DI SP_REG) (const_int 8)))
2422    (clobber (mem:BLK (scratch)))]
2423   "TARGET_64BIT"
2424   "pop{q}\t%0"
2425   [(set_attr "type" "pop")
2426    (set_attr "mode" "DI")])
2427
2428 (define_insn "popdi1"
2429   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2430         (mem:DI (reg:DI SP_REG)))
2431    (set (reg:DI SP_REG)
2432         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2433   "TARGET_64BIT"
2434   "pop{q}\t%0"
2435   [(set_attr "type" "pop")
2436    (set_attr "mode" "DI")])
2437
2438 (define_insn "*movdi_xor_rex64"
2439   [(set (match_operand:DI 0 "register_operand" "=r")
2440         (match_operand:DI 1 "const0_operand" ""))
2441    (clobber (reg:CC FLAGS_REG))]
2442   "TARGET_64BIT
2443    && reload_completed"
2444   "xor{l}\t%k0, %k0";
2445   [(set_attr "type" "alu1")
2446    (set_attr "mode" "SI")
2447    (set_attr "length_immediate" "0")])
2448
2449 (define_insn "*movdi_or_rex64"
2450   [(set (match_operand:DI 0 "register_operand" "=r")
2451         (match_operand:DI 1 "const_int_operand" "i"))
2452    (clobber (reg:CC FLAGS_REG))]
2453   "TARGET_64BIT
2454    && reload_completed
2455    && operands[1] == constm1_rtx"
2456 {
2457   operands[1] = constm1_rtx;
2458   return "or{q}\t{%1, %0|%0, %1}";
2459 }
2460   [(set_attr "type" "alu1")
2461    (set_attr "mode" "DI")
2462    (set_attr "length_immediate" "1")])
2463
2464 (define_insn "*movdi_2"
2465   [(set (match_operand:DI 0 "nonimmediate_operand"
2466                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2467         (match_operand:DI 1 "general_operand"
2468                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2469   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2470   "@
2471    #
2472    #
2473    pxor\t%0, %0
2474    movq\t{%1, %0|%0, %1}
2475    movq\t{%1, %0|%0, %1}
2476    %vpxor\t%0, %d0
2477    %vmovq\t{%1, %0|%0, %1}
2478    %vmovdqa\t{%1, %0|%0, %1}
2479    %vmovq\t{%1, %0|%0, %1}
2480    xorps\t%0, %0
2481    movlps\t{%1, %0|%0, %1}
2482    movaps\t{%1, %0|%0, %1}
2483    movlps\t{%1, %0|%0, %1}"
2484   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2485    (set (attr "prefix")
2486      (if_then_else (eq_attr "alternative" "5,6,7,8")
2487        (const_string "vex")
2488        (const_string "orig")))
2489    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2490
2491 (define_split
2492   [(set (match_operand:DI 0 "push_operand" "")
2493         (match_operand:DI 1 "general_operand" ""))]
2494   "!TARGET_64BIT && reload_completed
2495    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2496   [(const_int 0)]
2497   "ix86_split_long_move (operands); DONE;")
2498
2499 ;; %%% This multiword shite has got to go.
2500 (define_split
2501   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2502         (match_operand:DI 1 "general_operand" ""))]
2503   "!TARGET_64BIT && reload_completed
2504    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2505    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2506   [(const_int 0)]
2507   "ix86_split_long_move (operands); DONE;")
2508
2509 (define_insn "*movdi_1_rex64"
2510   [(set (match_operand:DI 0 "nonimmediate_operand"
2511           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2512         (match_operand:DI 1 "general_operand"
2513           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2514   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2515 {
2516   switch (get_attr_type (insn))
2517     {
2518     case TYPE_SSECVT:
2519       if (SSE_REG_P (operands[0]))
2520         return "movq2dq\t{%1, %0|%0, %1}";
2521       else
2522         return "movdq2q\t{%1, %0|%0, %1}";
2523
2524     case TYPE_SSEMOV:
2525       if (TARGET_AVX)
2526         {
2527           if (get_attr_mode (insn) == MODE_TI)
2528             return "vmovdqa\t{%1, %0|%0, %1}";
2529           else
2530             return "vmovq\t{%1, %0|%0, %1}";
2531         }
2532
2533       if (get_attr_mode (insn) == MODE_TI)
2534         return "movdqa\t{%1, %0|%0, %1}";
2535       /* FALLTHRU */
2536
2537     case TYPE_MMXMOV:
2538       /* Moves from and into integer register is done using movd
2539          opcode with REX prefix.  */
2540       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2541         return "movd\t{%1, %0|%0, %1}";
2542       return "movq\t{%1, %0|%0, %1}";
2543
2544     case TYPE_SSELOG1:
2545       return "%vpxor\t%0, %d0";
2546
2547     case TYPE_MMX:
2548       return "pxor\t%0, %0";
2549
2550     case TYPE_MULTI:
2551       return "#";
2552
2553     case TYPE_LEA:
2554       return "lea{q}\t{%a1, %0|%0, %a1}";
2555
2556     default:
2557       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2558       if (get_attr_mode (insn) == MODE_SI)
2559         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2560       else if (which_alternative == 2)
2561         return "movabs{q}\t{%1, %0|%0, %1}";
2562       else
2563         return "mov{q}\t{%1, %0|%0, %1}";
2564     }
2565 }
2566   [(set (attr "type")
2567      (cond [(eq_attr "alternative" "5")
2568               (const_string "mmx")
2569             (eq_attr "alternative" "6,7,8,9,10")
2570               (const_string "mmxmov")
2571             (eq_attr "alternative" "11")
2572               (const_string "sselog1")
2573             (eq_attr "alternative" "12,13,14,15,16")
2574               (const_string "ssemov")
2575             (eq_attr "alternative" "17,18")
2576               (const_string "ssecvt")
2577             (eq_attr "alternative" "4")
2578               (const_string "multi")
2579             (match_operand:DI 1 "pic_32bit_operand" "")
2580               (const_string "lea")
2581            ]
2582            (const_string "imov")))
2583    (set (attr "modrm")
2584      (if_then_else
2585        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2586          (const_string "0")
2587          (const_string "*")))
2588    (set (attr "length_immediate")
2589      (if_then_else
2590        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2591          (const_string "8")
2592          (const_string "*")))
2593    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2594    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2595    (set (attr "prefix")
2596      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2597        (const_string "maybe_vex")
2598        (const_string "orig")))
2599    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2600
2601 ;; Stores and loads of ax to arbitrary constant address.
2602 ;; We fake an second form of instruction to force reload to load address
2603 ;; into register when rax is not available
2604 (define_insn "*movabsdi_1_rex64"
2605   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2606         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2607   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2608   "@
2609    movabs{q}\t{%1, %P0|%P0, %1}
2610    mov{q}\t{%1, %a0|%a0, %1}"
2611   [(set_attr "type" "imov")
2612    (set_attr "modrm" "0,*")
2613    (set_attr "length_address" "8,0")
2614    (set_attr "length_immediate" "0,*")
2615    (set_attr "memory" "store")
2616    (set_attr "mode" "DI")])
2617
2618 (define_insn "*movabsdi_2_rex64"
2619   [(set (match_operand:DI 0 "register_operand" "=a,r")
2620         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2621   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2622   "@
2623    movabs{q}\t{%P1, %0|%0, %P1}
2624    mov{q}\t{%a1, %0|%0, %a1}"
2625   [(set_attr "type" "imov")
2626    (set_attr "modrm" "0,*")
2627    (set_attr "length_address" "8,0")
2628    (set_attr "length_immediate" "0")
2629    (set_attr "memory" "load")
2630    (set_attr "mode" "DI")])
2631
2632 ;; Convert impossible stores of immediate to existing instructions.
2633 ;; First try to get scratch register and go through it.  In case this
2634 ;; fails, move by 32bit parts.
2635 (define_peephole2
2636   [(match_scratch:DI 2 "r")
2637    (set (match_operand:DI 0 "memory_operand" "")
2638         (match_operand:DI 1 "immediate_operand" ""))]
2639   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2640    && !x86_64_immediate_operand (operands[1], DImode)"
2641   [(set (match_dup 2) (match_dup 1))
2642    (set (match_dup 0) (match_dup 2))]
2643   "")
2644
2645 ;; We need to define this as both peepholer and splitter for case
2646 ;; peephole2 pass is not run.
2647 ;; "&& 1" is needed to keep it from matching the previous pattern.
2648 (define_peephole2
2649   [(set (match_operand:DI 0 "memory_operand" "")
2650         (match_operand:DI 1 "immediate_operand" ""))]
2651   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2652    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2653   [(set (match_dup 2) (match_dup 3))
2654    (set (match_dup 4) (match_dup 5))]
2655   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2656
2657 (define_split
2658   [(set (match_operand:DI 0 "memory_operand" "")
2659         (match_operand:DI 1 "immediate_operand" ""))]
2660   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2661                     ? epilogue_completed : reload_completed)
2662    && !symbolic_operand (operands[1], DImode)
2663    && !x86_64_immediate_operand (operands[1], DImode)"
2664   [(set (match_dup 2) (match_dup 3))
2665    (set (match_dup 4) (match_dup 5))]
2666   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2667
2668 (define_insn "*swapdi_rex64"
2669   [(set (match_operand:DI 0 "register_operand" "+r")
2670         (match_operand:DI 1 "register_operand" "+r"))
2671    (set (match_dup 1)
2672         (match_dup 0))]
2673   "TARGET_64BIT"
2674   "xchg{q}\t%1, %0"
2675   [(set_attr "type" "imov")
2676    (set_attr "mode" "DI")
2677    (set_attr "pent_pair" "np")
2678    (set_attr "athlon_decode" "vector")
2679    (set_attr "amdfam10_decode" "double")])
2680
2681 (define_expand "movoi"
2682   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2683         (match_operand:OI 1 "general_operand" ""))]
2684   "TARGET_AVX"
2685   "ix86_expand_move (OImode, operands); DONE;")
2686
2687 (define_insn "*movoi_internal"
2688   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2689         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2690   "TARGET_AVX
2691    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2692 {
2693   switch (which_alternative)
2694     {
2695     case 0:
2696       return "vxorps\t%0, %0, %0";
2697     case 1:
2698     case 2:
2699       if (misaligned_operand (operands[0], OImode)
2700           || misaligned_operand (operands[1], OImode))
2701         return "vmovdqu\t{%1, %0|%0, %1}";
2702       else
2703         return "vmovdqa\t{%1, %0|%0, %1}";
2704     default:
2705       gcc_unreachable ();
2706     }
2707 }
2708   [(set_attr "type" "sselog1,ssemov,ssemov")
2709    (set_attr "prefix" "vex")
2710    (set_attr "mode" "OI")])
2711
2712 (define_expand "movti"
2713   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2714         (match_operand:TI 1 "nonimmediate_operand" ""))]
2715   "TARGET_SSE || TARGET_64BIT"
2716 {
2717   if (TARGET_64BIT)
2718     ix86_expand_move (TImode, operands);
2719   else if (push_operand (operands[0], TImode))
2720     ix86_expand_push (TImode, operands[1]);
2721   else
2722     ix86_expand_vector_move (TImode, operands);
2723   DONE;
2724 })
2725
2726 (define_insn "*movti_internal"
2727   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2728         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2729   "TARGET_SSE && !TARGET_64BIT
2730    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2731 {
2732   switch (which_alternative)
2733     {
2734     case 0:
2735       if (get_attr_mode (insn) == MODE_V4SF)
2736         return "%vxorps\t%0, %d0";
2737       else
2738         return "%vpxor\t%0, %d0";
2739     case 1:
2740     case 2:
2741       /* TDmode values are passed as TImode on the stack.  Moving them
2742          to stack may result in unaligned memory access.  */
2743       if (misaligned_operand (operands[0], TImode)
2744           || misaligned_operand (operands[1], TImode))
2745         {
2746           if (get_attr_mode (insn) == MODE_V4SF)
2747             return "%vmovups\t{%1, %0|%0, %1}";
2748          else
2749            return "%vmovdqu\t{%1, %0|%0, %1}";
2750         }
2751       else
2752         {
2753           if (get_attr_mode (insn) == MODE_V4SF)
2754             return "%vmovaps\t{%1, %0|%0, %1}";
2755          else
2756            return "%vmovdqa\t{%1, %0|%0, %1}";
2757         }
2758     default:
2759       gcc_unreachable ();
2760     }
2761 }
2762   [(set_attr "type" "sselog1,ssemov,ssemov")
2763    (set_attr "prefix" "maybe_vex")
2764    (set (attr "mode")
2765         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2766                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2767                  (const_string "V4SF")
2768                (and (eq_attr "alternative" "2")
2769                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2770                         (const_int 0)))
2771                  (const_string "V4SF")]
2772               (const_string "TI")))])
2773
2774 (define_insn "*movti_rex64"
2775   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2776         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2777   "TARGET_64BIT
2778    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2779 {
2780   switch (which_alternative)
2781     {
2782     case 0:
2783     case 1:
2784       return "#";
2785     case 2:
2786       if (get_attr_mode (insn) == MODE_V4SF)
2787         return "%vxorps\t%0, %d0";
2788       else
2789         return "%vpxor\t%0, %d0";
2790     case 3:
2791     case 4:
2792       /* TDmode values are passed as TImode on the stack.  Moving them
2793          to stack may result in unaligned memory access.  */
2794       if (misaligned_operand (operands[0], TImode)
2795           || misaligned_operand (operands[1], TImode))
2796         {
2797           if (get_attr_mode (insn) == MODE_V4SF)
2798             return "%vmovups\t{%1, %0|%0, %1}";
2799          else
2800            return "%vmovdqu\t{%1, %0|%0, %1}";
2801         }
2802       else
2803         {
2804           if (get_attr_mode (insn) == MODE_V4SF)
2805             return "%vmovaps\t{%1, %0|%0, %1}";
2806          else
2807            return "%vmovdqa\t{%1, %0|%0, %1}";
2808         }
2809     default:
2810       gcc_unreachable ();
2811     }
2812 }
2813   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2814    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2815    (set (attr "mode")
2816         (cond [(eq_attr "alternative" "2,3")
2817                  (if_then_else
2818                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2819                        (const_int 0))
2820                    (const_string "V4SF")
2821                    (const_string "TI"))
2822                (eq_attr "alternative" "4")
2823                  (if_then_else
2824                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2825                             (const_int 0))
2826                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2827                             (const_int 0)))
2828                    (const_string "V4SF")
2829                    (const_string "TI"))]
2830                (const_string "DI")))])
2831
2832 (define_split
2833   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2834         (match_operand:TI 1 "general_operand" ""))]
2835   "reload_completed && !SSE_REG_P (operands[0])
2836    && !SSE_REG_P (operands[1])"
2837   [(const_int 0)]
2838   "ix86_split_long_move (operands); DONE;")
2839
2840 ;; This expands to what emit_move_complex would generate if we didn't
2841 ;; have a movti pattern.  Having this avoids problems with reload on
2842 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2843 ;; to have around all the time.
2844 (define_expand "movcdi"
2845   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2846         (match_operand:CDI 1 "general_operand" ""))]
2847   ""
2848 {
2849   if (push_operand (operands[0], CDImode))
2850     emit_move_complex_push (CDImode, operands[0], operands[1]);
2851   else
2852     emit_move_complex_parts (operands[0], operands[1]);
2853   DONE;
2854 })
2855
2856 (define_expand "movsf"
2857   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2858         (match_operand:SF 1 "general_operand" ""))]
2859   ""
2860   "ix86_expand_move (SFmode, operands); DONE;")
2861
2862 (define_insn "*pushsf"
2863   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2864         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2865   "!TARGET_64BIT"
2866 {
2867   /* Anything else should be already split before reg-stack.  */
2868   gcc_assert (which_alternative == 1);
2869   return "push{l}\t%1";
2870 }
2871   [(set_attr "type" "multi,push,multi")
2872    (set_attr "unit" "i387,*,*")
2873    (set_attr "mode" "SF,SI,SF")])
2874
2875 (define_insn "*pushsf_rex64"
2876   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2877         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2878   "TARGET_64BIT"
2879 {
2880   /* Anything else should be already split before reg-stack.  */
2881   gcc_assert (which_alternative == 1);
2882   return "push{q}\t%q1";
2883 }
2884   [(set_attr "type" "multi,push,multi")
2885    (set_attr "unit" "i387,*,*")
2886    (set_attr "mode" "SF,DI,SF")])
2887
2888 (define_split
2889   [(set (match_operand:SF 0 "push_operand" "")
2890         (match_operand:SF 1 "memory_operand" ""))]
2891   "reload_completed
2892    && MEM_P (operands[1])
2893    && (operands[2] = find_constant_src (insn))"
2894   [(set (match_dup 0)
2895         (match_dup 2))])
2896
2897 ;; %%% Kill this when call knows how to work this out.
2898 (define_split
2899   [(set (match_operand:SF 0 "push_operand" "")
2900         (match_operand:SF 1 "any_fp_register_operand" ""))]
2901   "!TARGET_64BIT"
2902   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2903    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2904
2905 (define_split
2906   [(set (match_operand:SF 0 "push_operand" "")
2907         (match_operand:SF 1 "any_fp_register_operand" ""))]
2908   "TARGET_64BIT"
2909   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2910    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2911
2912 (define_insn "*movsf_1"
2913   [(set (match_operand:SF 0 "nonimmediate_operand"
2914           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2915         (match_operand:SF 1 "general_operand"
2916           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2917   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2918    && (reload_in_progress || reload_completed
2919        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2920        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2921            && standard_80387_constant_p (operands[1]))
2922        || GET_CODE (operands[1]) != CONST_DOUBLE
2923        || memory_operand (operands[0], SFmode))"
2924 {
2925   switch (which_alternative)
2926     {
2927     case 0:
2928     case 1:
2929       return output_387_reg_move (insn, operands);
2930
2931     case 2:
2932       return standard_80387_constant_opcode (operands[1]);
2933
2934     case 3:
2935     case 4:
2936       return "mov{l}\t{%1, %0|%0, %1}";
2937     case 5:
2938       if (get_attr_mode (insn) == MODE_TI)
2939         return "%vpxor\t%0, %d0";
2940       else
2941         return "%vxorps\t%0, %d0";
2942     case 6:
2943       if (get_attr_mode (insn) == MODE_V4SF)
2944         return "%vmovaps\t{%1, %0|%0, %1}";
2945       else
2946         return "%vmovss\t{%1, %d0|%d0, %1}";
2947     case 7:
2948       if (TARGET_AVX)
2949         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2950                                    : "vmovss\t{%1, %0|%0, %1}";
2951       else
2952         return "movss\t{%1, %0|%0, %1}";
2953     case 8:
2954       return "%vmovss\t{%1, %0|%0, %1}";
2955
2956     case 9: case 10: case 14: case 15:
2957       return "movd\t{%1, %0|%0, %1}";
2958     case 12: case 13:
2959       return "%vmovd\t{%1, %0|%0, %1}";
2960
2961     case 11:
2962       return "movq\t{%1, %0|%0, %1}";
2963
2964     default:
2965       gcc_unreachable ();
2966     }
2967 }
2968   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2969    (set (attr "prefix")
2970      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2971        (const_string "maybe_vex")
2972        (const_string "orig")))
2973    (set (attr "mode")
2974         (cond [(eq_attr "alternative" "3,4,9,10")
2975                  (const_string "SI")
2976                (eq_attr "alternative" "5")
2977                  (if_then_else
2978                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2979                                  (const_int 0))
2980                              (ne (symbol_ref "TARGET_SSE2")
2981                                  (const_int 0)))
2982                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2983                             (const_int 0)))
2984                    (const_string "TI")
2985                    (const_string "V4SF"))
2986                /* For architectures resolving dependencies on
2987                   whole SSE registers use APS move to break dependency
2988                   chains, otherwise use short move to avoid extra work.
2989
2990                   Do the same for architectures resolving dependencies on
2991                   the parts.  While in DF mode it is better to always handle
2992                   just register parts, the SF mode is different due to lack
2993                   of instructions to load just part of the register.  It is
2994                   better to maintain the whole registers in single format
2995                   to avoid problems on using packed logical operations.  */
2996                (eq_attr "alternative" "6")
2997                  (if_then_else
2998                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2999                             (const_int 0))
3000                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3001                             (const_int 0)))
3002                    (const_string "V4SF")
3003                    (const_string "SF"))
3004                (eq_attr "alternative" "11")
3005                  (const_string "DI")]
3006                (const_string "SF")))])
3007
3008 (define_insn "*swapsf"
3009   [(set (match_operand:SF 0 "fp_register_operand" "+f")
3010         (match_operand:SF 1 "fp_register_operand" "+f"))
3011    (set (match_dup 1)
3012         (match_dup 0))]
3013   "reload_completed || TARGET_80387"
3014 {
3015   if (STACK_TOP_P (operands[0]))
3016     return "fxch\t%1";
3017   else
3018     return "fxch\t%0";
3019 }
3020   [(set_attr "type" "fxch")
3021    (set_attr "mode" "SF")])
3022
3023 (define_expand "movdf"
3024   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3025         (match_operand:DF 1 "general_operand" ""))]
3026   ""
3027   "ix86_expand_move (DFmode, operands); DONE;")
3028
3029 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3030 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3031 ;; On the average, pushdf using integers can be still shorter.  Allow this
3032 ;; pattern for optimize_size too.
3033
3034 (define_insn "*pushdf_nointeger"
3035   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3036         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3037   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3038 {
3039   /* This insn should be already split before reg-stack.  */
3040   gcc_unreachable ();
3041 }
3042   [(set_attr "type" "multi")
3043    (set_attr "unit" "i387,*,*,*")
3044    (set_attr "mode" "DF,SI,SI,DF")])
3045
3046 (define_insn "*pushdf_integer"
3047   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3048         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3049   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3050 {
3051   /* This insn should be already split before reg-stack.  */
3052   gcc_unreachable ();
3053 }
3054   [(set_attr "type" "multi")
3055    (set_attr "unit" "i387,*,*")
3056    (set_attr "mode" "DF,SI,DF")])
3057
3058 ;; %%% Kill this when call knows how to work this out.
3059 (define_split
3060   [(set (match_operand:DF 0 "push_operand" "")
3061         (match_operand:DF 1 "any_fp_register_operand" ""))]
3062   "reload_completed"
3063   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3064    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3065   "")
3066
3067 (define_split
3068   [(set (match_operand:DF 0 "push_operand" "")
3069         (match_operand:DF 1 "general_operand" ""))]
3070   "reload_completed"
3071   [(const_int 0)]
3072   "ix86_split_long_move (operands); DONE;")
3073
3074 ;; Moving is usually shorter when only FP registers are used. This separate
3075 ;; movdf pattern avoids the use of integer registers for FP operations
3076 ;; when optimizing for size.
3077
3078 (define_insn "*movdf_nointeger"
3079   [(set (match_operand:DF 0 "nonimmediate_operand"
3080                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3081         (match_operand:DF 1 "general_operand"
3082                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3083   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3084    && ((optimize_function_for_size_p (cfun)
3085        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3086    && (reload_in_progress || reload_completed
3087        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3088        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3089            && optimize_function_for_size_p (cfun)
3090            && !memory_operand (operands[0], DFmode)
3091            && standard_80387_constant_p (operands[1]))
3092        || GET_CODE (operands[1]) != CONST_DOUBLE
3093        || ((optimize_function_for_size_p (cfun)
3094             || !TARGET_MEMORY_MISMATCH_STALL
3095             || reload_in_progress || reload_completed)
3096            && memory_operand (operands[0], DFmode)))"
3097 {
3098   switch (which_alternative)
3099     {
3100     case 0:
3101     case 1:
3102       return output_387_reg_move (insn, operands);
3103
3104     case 2:
3105       return standard_80387_constant_opcode (operands[1]);
3106
3107     case 3:
3108     case 4:
3109       return "#";
3110     case 5:
3111       switch (get_attr_mode (insn))
3112         {
3113         case MODE_V4SF:
3114           return "%vxorps\t%0, %d0";
3115         case MODE_V2DF:
3116           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3117             return "%vxorps\t%0, %d0";
3118           else
3119             return "%vxorpd\t%0, %d0";
3120         case MODE_TI:
3121           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3122             return "%vxorps\t%0, %d0";
3123           else
3124             return "%vpxor\t%0, %d0";
3125         default:
3126           gcc_unreachable ();
3127         }
3128     case 6:
3129     case 7:
3130     case 8:
3131       switch (get_attr_mode (insn))
3132         {
3133         case MODE_V4SF:
3134           return "%vmovaps\t{%1, %0|%0, %1}";
3135         case MODE_V2DF:
3136           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3137             return "%vmovaps\t{%1, %0|%0, %1}";
3138           else
3139             return "%vmovapd\t{%1, %0|%0, %1}";
3140         case MODE_TI:
3141           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3142             return "%vmovaps\t{%1, %0|%0, %1}";
3143           else
3144             return "%vmovdqa\t{%1, %0|%0, %1}";
3145         case MODE_DI:
3146           return "%vmovq\t{%1, %0|%0, %1}";
3147         case MODE_DF:
3148           if (TARGET_AVX)
3149             {
3150               if (REG_P (operands[0]) && REG_P (operands[1]))
3151                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3152               else
3153                 return "vmovsd\t{%1, %0|%0, %1}";
3154             }
3155           else
3156             return "movsd\t{%1, %0|%0, %1}";
3157         case MODE_V1DF:
3158           if (TARGET_AVX)
3159             {
3160               if (REG_P (operands[0]))
3161                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3162               else
3163                 return "vmovlpd\t{%1, %0|%0, %1}";
3164             }
3165           else
3166             return "movlpd\t{%1, %0|%0, %1}";
3167         case MODE_V2SF:
3168           if (TARGET_AVX)
3169             {
3170               if (REG_P (operands[0]))
3171                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3172               else
3173                 return "vmovlps\t{%1, %0|%0, %1}";
3174             }
3175           else
3176             return "movlps\t{%1, %0|%0, %1}";
3177         default:
3178           gcc_unreachable ();
3179         }
3180
3181     default:
3182       gcc_unreachable ();
3183     }
3184 }
3185   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3186    (set (attr "prefix")
3187      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3188        (const_string "orig")
3189        (const_string "maybe_vex")))
3190    (set (attr "prefix_data16")
3191      (if_then_else (eq_attr "mode" "V1DF")
3192        (const_string "1")
3193        (const_string "*")))
3194    (set (attr "mode")
3195         (cond [(eq_attr "alternative" "0,1,2")
3196                  (const_string "DF")
3197                (eq_attr "alternative" "3,4")
3198                  (const_string "SI")
3199
3200                /* For SSE1, we have many fewer alternatives.  */
3201                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3202                  (cond [(eq_attr "alternative" "5,6")
3203                           (const_string "V4SF")
3204                        ]
3205                    (const_string "V2SF"))
3206
3207                /* xorps is one byte shorter.  */
3208                (eq_attr "alternative" "5")
3209                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3210                             (const_int 0))
3211                           (const_string "V4SF")
3212                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3213                             (const_int 0))
3214                           (const_string "TI")
3215                        ]
3216                        (const_string "V2DF"))
3217
3218                /* For architectures resolving dependencies on
3219                   whole SSE registers use APD move to break dependency
3220                   chains, otherwise use short move to avoid extra work.
3221
3222                   movaps encodes one byte shorter.  */
3223                (eq_attr "alternative" "6")
3224                  (cond
3225                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3226                         (const_int 0))
3227                       (const_string "V4SF")
3228                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3229                         (const_int 0))
3230                       (const_string "V2DF")
3231                    ]
3232                    (const_string "DF"))
3233                /* For architectures resolving dependencies on register
3234                   parts we may avoid extra work to zero out upper part
3235                   of register.  */
3236                (eq_attr "alternative" "7")
3237                  (if_then_else
3238                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3239                        (const_int 0))
3240                    (const_string "V1DF")
3241                    (const_string "DF"))
3242               ]
3243               (const_string "DF")))])
3244
3245 (define_insn "*movdf_integer_rex64"
3246   [(set (match_operand:DF 0 "nonimmediate_operand"
3247                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3248         (match_operand:DF 1 "general_operand"
3249                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3250   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3251    && (reload_in_progress || reload_completed
3252        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3253        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3254            && optimize_function_for_size_p (cfun)
3255            && standard_80387_constant_p (operands[1]))
3256        || GET_CODE (operands[1]) != CONST_DOUBLE
3257        || memory_operand (operands[0], DFmode))"
3258 {
3259   switch (which_alternative)
3260     {
3261     case 0:
3262     case 1:
3263       return output_387_reg_move (insn, operands);
3264
3265     case 2:
3266       return standard_80387_constant_opcode (operands[1]);
3267
3268     case 3:
3269     case 4:
3270       return "#";
3271
3272     case 5:
3273       switch (get_attr_mode (insn))
3274         {
3275         case MODE_V4SF:
3276           return "%vxorps\t%0, %d0";
3277         case MODE_V2DF:
3278           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3279             return "%vxorps\t%0, %d0";
3280           else
3281             return "%vxorpd\t%0, %d0";
3282         case MODE_TI:
3283           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3284             return "%vxorps\t%0, %d0";
3285           else
3286             return "%vpxor\t%0, %d0";
3287         default:
3288           gcc_unreachable ();
3289         }
3290     case 6:
3291     case 7:
3292     case 8:
3293       switch (get_attr_mode (insn))
3294         {
3295         case MODE_V4SF:
3296           return "%vmovaps\t{%1, %0|%0, %1}";
3297         case MODE_V2DF:
3298           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3299             return "%vmovaps\t{%1, %0|%0, %1}";
3300           else
3301             return "%vmovapd\t{%1, %0|%0, %1}";
3302         case MODE_TI:
3303           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3304             return "%vmovaps\t{%1, %0|%0, %1}";
3305           else
3306             return "%vmovdqa\t{%1, %0|%0, %1}";
3307         case MODE_DI:
3308           return "%vmovq\t{%1, %0|%0, %1}";
3309         case MODE_DF:
3310           if (TARGET_AVX)
3311             {
3312               if (REG_P (operands[0]) && REG_P (operands[1]))
3313                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3314               else
3315                 return "vmovsd\t{%1, %0|%0, %1}";
3316             }
3317           else
3318             return "movsd\t{%1, %0|%0, %1}";
3319         case MODE_V1DF:
3320           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3321         case MODE_V2SF:
3322           return "%vmovlps\t{%1, %d0|%d0, %1}";
3323         default:
3324           gcc_unreachable ();
3325         }
3326
3327     case 9:
3328     case 10:
3329     return "%vmovd\t{%1, %0|%0, %1}";
3330
3331     default:
3332       gcc_unreachable();
3333     }
3334 }
3335   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3336    (set (attr "prefix")
3337      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3338        (const_string "orig")
3339        (const_string "maybe_vex")))
3340    (set (attr "prefix_data16")
3341      (if_then_else (eq_attr "mode" "V1DF")
3342        (const_string "1")
3343        (const_string "*")))
3344    (set (attr "mode")
3345         (cond [(eq_attr "alternative" "0,1,2")
3346                  (const_string "DF")
3347                (eq_attr "alternative" "3,4,9,10")
3348                  (const_string "DI")
3349
3350                /* For SSE1, we have many fewer alternatives.  */
3351                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3352                  (cond [(eq_attr "alternative" "5,6")
3353                           (const_string "V4SF")
3354                        ]
3355                    (const_string "V2SF"))
3356
3357                /* xorps is one byte shorter.  */
3358                (eq_attr "alternative" "5")
3359                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3360                             (const_int 0))
3361                           (const_string "V4SF")
3362                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3363                             (const_int 0))
3364                           (const_string "TI")
3365                        ]
3366                        (const_string "V2DF"))
3367
3368                /* For architectures resolving dependencies on
3369                   whole SSE registers use APD move to break dependency
3370                   chains, otherwise use short move to avoid extra work.
3371
3372                   movaps encodes one byte shorter.  */
3373                (eq_attr "alternative" "6")
3374                  (cond
3375                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3376                         (const_int 0))
3377                       (const_string "V4SF")
3378                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3379                         (const_int 0))
3380                       (const_string "V2DF")
3381                    ]
3382                    (const_string "DF"))
3383                /* For architectures resolving dependencies on register
3384                   parts we may avoid extra work to zero out upper part
3385                   of register.  */
3386                (eq_attr "alternative" "7")
3387                  (if_then_else
3388                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3389                        (const_int 0))
3390                    (const_string "V1DF")
3391                    (const_string "DF"))
3392               ]
3393               (const_string "DF")))])
3394
3395 (define_insn "*movdf_integer"
3396   [(set (match_operand:DF 0 "nonimmediate_operand"
3397                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3398         (match_operand:DF 1 "general_operand"
3399                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3400   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3401    && optimize_function_for_speed_p (cfun)
3402    && TARGET_INTEGER_DFMODE_MOVES
3403    && (reload_in_progress || reload_completed
3404        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3405        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3406            && optimize_function_for_size_p (cfun)
3407            && standard_80387_constant_p (operands[1]))
3408        || GET_CODE (operands[1]) != CONST_DOUBLE
3409        || memory_operand (operands[0], DFmode))"
3410 {
3411   switch (which_alternative)
3412     {
3413     case 0:
3414     case 1:
3415       return output_387_reg_move (insn, operands);
3416
3417     case 2:
3418       return standard_80387_constant_opcode (operands[1]);
3419
3420     case 3:
3421     case 4:
3422       return "#";
3423
3424     case 5:
3425       switch (get_attr_mode (insn))
3426         {
3427         case MODE_V4SF:
3428           return "xorps\t%0, %0";
3429         case MODE_V2DF:
3430           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3431             return "xorps\t%0, %0";
3432           else
3433             return "xorpd\t%0, %0";
3434         case MODE_TI:
3435           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3436             return "xorps\t%0, %0";
3437           else
3438             return "pxor\t%0, %0";
3439         default:
3440           gcc_unreachable ();
3441         }
3442     case 6:
3443     case 7:
3444     case 8:
3445       switch (get_attr_mode (insn))
3446         {
3447         case MODE_V4SF:
3448           return "movaps\t{%1, %0|%0, %1}";
3449         case MODE_V2DF:
3450           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3451             return "movaps\t{%1, %0|%0, %1}";
3452           else
3453             return "movapd\t{%1, %0|%0, %1}";
3454         case MODE_TI:
3455           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3456             return "movaps\t{%1, %0|%0, %1}";
3457           else
3458             return "movdqa\t{%1, %0|%0, %1}";
3459         case MODE_DI:
3460           return "movq\t{%1, %0|%0, %1}";
3461         case MODE_DF:
3462           return "movsd\t{%1, %0|%0, %1}";
3463         case MODE_V1DF:
3464           return "movlpd\t{%1, %0|%0, %1}";
3465         case MODE_V2SF:
3466           return "movlps\t{%1, %0|%0, %1}";
3467         default:
3468           gcc_unreachable ();
3469         }
3470
3471     default:
3472       gcc_unreachable();
3473     }
3474 }
3475   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3476    (set (attr "prefix_data16")
3477      (if_then_else (eq_attr "mode" "V1DF")
3478        (const_string "1")
3479        (const_string "*")))
3480    (set (attr "mode")
3481         (cond [(eq_attr "alternative" "0,1,2")
3482                  (const_string "DF")
3483                (eq_attr "alternative" "3,4")
3484                  (const_string "SI")
3485
3486                /* For SSE1, we have many fewer alternatives.  */
3487                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3488                  (cond [(eq_attr "alternative" "5,6")
3489                           (const_string "V4SF")
3490                        ]
3491                    (const_string "V2SF"))
3492
3493                /* xorps is one byte shorter.  */
3494                (eq_attr "alternative" "5")
3495                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3496                             (const_int 0))
3497                           (const_string "V4SF")
3498                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3499                             (const_int 0))
3500                           (const_string "TI")
3501                        ]
3502                        (const_string "V2DF"))
3503
3504                /* For architectures resolving dependencies on
3505                   whole SSE registers use APD move to break dependency
3506                   chains, otherwise use short move to avoid extra work.
3507
3508                   movaps encodes one byte shorter.  */
3509                (eq_attr "alternative" "6")
3510                  (cond
3511                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3512                         (const_int 0))
3513                       (const_string "V4SF")
3514                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3515                         (const_int 0))
3516                       (const_string "V2DF")
3517                    ]
3518                    (const_string "DF"))
3519                /* For architectures resolving dependencies on register
3520                   parts we may avoid extra work to zero out upper part
3521                   of register.  */
3522                (eq_attr "alternative" "7")
3523                  (if_then_else
3524                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3525                        (const_int 0))
3526                    (const_string "V1DF")
3527                    (const_string "DF"))
3528               ]
3529               (const_string "DF")))])
3530
3531 (define_split
3532   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3533         (match_operand:DF 1 "general_operand" ""))]
3534   "reload_completed
3535    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3536    && ! (ANY_FP_REG_P (operands[0]) ||
3537          (GET_CODE (operands[0]) == SUBREG
3538           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3539    && ! (ANY_FP_REG_P (operands[1]) ||
3540          (GET_CODE (operands[1]) == SUBREG
3541           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3542   [(const_int 0)]
3543   "ix86_split_long_move (operands); DONE;")
3544
3545 (define_insn "*swapdf"
3546   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3547         (match_operand:DF 1 "fp_register_operand" "+f"))
3548    (set (match_dup 1)
3549         (match_dup 0))]
3550   "reload_completed || TARGET_80387"
3551 {
3552   if (STACK_TOP_P (operands[0]))
3553     return "fxch\t%1";
3554   else
3555     return "fxch\t%0";
3556 }
3557   [(set_attr "type" "fxch")
3558    (set_attr "mode" "DF")])
3559
3560 (define_expand "movxf"
3561   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3562         (match_operand:XF 1 "general_operand" ""))]
3563   ""
3564   "ix86_expand_move (XFmode, operands); DONE;")
3565
3566 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3567 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3568 ;; Pushing using integer instructions is longer except for constants
3569 ;; and direct memory references.
3570 ;; (assuming that any given constant is pushed only once, but this ought to be
3571 ;;  handled elsewhere).
3572
3573 (define_insn "*pushxf_nointeger"
3574   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3575         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3576   "optimize_function_for_size_p (cfun)"
3577 {
3578   /* This insn should be already split before reg-stack.  */
3579   gcc_unreachable ();
3580 }
3581   [(set_attr "type" "multi")
3582    (set_attr "unit" "i387,*,*")
3583    (set_attr "mode" "XF,SI,SI")])
3584
3585 (define_insn "*pushxf_integer"
3586   [(set (match_operand:XF 0 "push_operand" "=<,<")
3587         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3588   "optimize_function_for_speed_p (cfun)"
3589 {
3590   /* This insn should be already split before reg-stack.  */
3591   gcc_unreachable ();
3592 }
3593   [(set_attr "type" "multi")
3594    (set_attr "unit" "i387,*")
3595    (set_attr "mode" "XF,SI")])
3596
3597 (define_split
3598   [(set (match_operand 0 "push_operand" "")
3599         (match_operand 1 "general_operand" ""))]
3600   "reload_completed
3601    && (GET_MODE (operands[0]) == XFmode
3602        || GET_MODE (operands[0]) == DFmode)
3603    && !ANY_FP_REG_P (operands[1])"
3604   [(const_int 0)]
3605   "ix86_split_long_move (operands); DONE;")
3606
3607 (define_split
3608   [(set (match_operand:XF 0 "push_operand" "")
3609         (match_operand:XF 1 "any_fp_register_operand" ""))]
3610   ""
3611   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3612    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3613   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3614
3615 ;; Do not use integer registers when optimizing for size
3616 (define_insn "*movxf_nointeger"
3617   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3618         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3619   "optimize_function_for_size_p (cfun)
3620    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3621    && (reload_in_progress || reload_completed
3622        || standard_80387_constant_p (operands[1])
3623        || GET_CODE (operands[1]) != CONST_DOUBLE
3624        || memory_operand (operands[0], XFmode))"
3625 {
3626   switch (which_alternative)
3627     {
3628     case 0:
3629     case 1:
3630       return output_387_reg_move (insn, operands);
3631
3632     case 2:
3633       return standard_80387_constant_opcode (operands[1]);
3634
3635     case 3: case 4:
3636       return "#";
3637     default:
3638       gcc_unreachable ();
3639     }
3640 }
3641   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3642    (set_attr "mode" "XF,XF,XF,SI,SI")])
3643
3644 (define_insn "*movxf_integer"
3645   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3646         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3647   "optimize_function_for_speed_p (cfun)
3648    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3649    && (reload_in_progress || reload_completed
3650        || GET_CODE (operands[1]) != CONST_DOUBLE
3651        || memory_operand (operands[0], XFmode))"
3652 {
3653   switch (which_alternative)
3654     {
3655     case 0:
3656     case 1:
3657       return output_387_reg_move (insn, operands);
3658
3659     case 2:
3660       return standard_80387_constant_opcode (operands[1]);
3661
3662     case 3: case 4:
3663       return "#";
3664
3665     default:
3666       gcc_unreachable ();
3667     }
3668 }
3669   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3670    (set_attr "mode" "XF,XF,XF,SI,SI")])
3671
3672 (define_expand "movtf"
3673   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3674         (match_operand:TF 1 "nonimmediate_operand" ""))]
3675   "TARGET_SSE2"
3676 {
3677   ix86_expand_move (TFmode, operands);
3678   DONE;
3679 })
3680
3681 (define_insn "*movtf_internal"
3682   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3683         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3684   "TARGET_SSE2
3685    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3686 {
3687   switch (which_alternative)
3688     {
3689     case 0:
3690     case 1:
3691       if (get_attr_mode (insn) == MODE_V4SF)
3692         return "%vmovaps\t{%1, %0|%0, %1}";
3693       else
3694         return "%vmovdqa\t{%1, %0|%0, %1}";
3695     case 2:
3696       if (get_attr_mode (insn) == MODE_V4SF)
3697         return "%vxorps\t%0, %d0";
3698       else
3699         return "%vpxor\t%0, %d0";
3700     case 3:
3701     case 4:
3702         return "#";
3703     default:
3704       gcc_unreachable ();
3705     }
3706 }
3707   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3708    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3709    (set (attr "mode")
3710         (cond [(eq_attr "alternative" "0,2")
3711                  (if_then_else
3712                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3713                        (const_int 0))
3714                    (const_string "V4SF")
3715                    (const_string "TI"))
3716                (eq_attr "alternative" "1")
3717                  (if_then_else
3718                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3719                             (const_int 0))
3720                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3721                             (const_int 0)))
3722                    (const_string "V4SF")
3723                    (const_string "TI"))]
3724                (const_string "DI")))])
3725
3726 (define_insn "*pushtf_sse"
3727   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3728         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3729   "TARGET_SSE2"
3730 {
3731   /* This insn should be already split before reg-stack.  */
3732   gcc_unreachable ();
3733 }
3734   [(set_attr "type" "multi")
3735    (set_attr "unit" "sse,*,*")
3736    (set_attr "mode" "TF,SI,SI")])
3737
3738 (define_split
3739   [(set (match_operand:TF 0 "push_operand" "")
3740         (match_operand:TF 1 "general_operand" ""))]
3741   "TARGET_SSE2 && reload_completed
3742    && !SSE_REG_P (operands[1])"
3743   [(const_int 0)]
3744   "ix86_split_long_move (operands); DONE;")
3745
3746 (define_split
3747   [(set (match_operand:TF 0 "push_operand" "")
3748         (match_operand:TF 1 "any_fp_register_operand" ""))]
3749   "TARGET_SSE2"
3750   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3751    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3752   "")
3753
3754 (define_split
3755   [(set (match_operand 0 "nonimmediate_operand" "")
3756         (match_operand 1 "general_operand" ""))]
3757   "reload_completed
3758    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3759    && GET_MODE (operands[0]) == XFmode
3760    && ! (ANY_FP_REG_P (operands[0]) ||
3761          (GET_CODE (operands[0]) == SUBREG
3762           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3763    && ! (ANY_FP_REG_P (operands[1]) ||
3764          (GET_CODE (operands[1]) == SUBREG
3765           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3766   [(const_int 0)]
3767   "ix86_split_long_move (operands); DONE;")
3768
3769 (define_split
3770   [(set (match_operand 0 "register_operand" "")
3771         (match_operand 1 "memory_operand" ""))]
3772   "reload_completed
3773    && MEM_P (operands[1])
3774    && (GET_MODE (operands[0]) == TFmode
3775        || GET_MODE (operands[0]) == XFmode
3776        || GET_MODE (operands[0]) == SFmode
3777        || GET_MODE (operands[0]) == DFmode)
3778    && (operands[2] = find_constant_src (insn))"
3779   [(set (match_dup 0) (match_dup 2))]
3780 {
3781   rtx c = operands[2];
3782   rtx r = operands[0];
3783
3784   if (GET_CODE (r) == SUBREG)
3785     r = SUBREG_REG (r);
3786
3787   if (SSE_REG_P (r))
3788     {
3789       if (!standard_sse_constant_p (c))
3790         FAIL;
3791     }
3792   else if (FP_REG_P (r))
3793     {
3794       if (!standard_80387_constant_p (c))
3795         FAIL;
3796     }
3797   else if (MMX_REG_P (r))
3798     FAIL;
3799 })
3800
3801 (define_split
3802   [(set (match_operand 0 "register_operand" "")
3803         (float_extend (match_operand 1 "memory_operand" "")))]
3804   "reload_completed
3805    && MEM_P (operands[1])
3806    && (GET_MODE (operands[0]) == TFmode
3807        || GET_MODE (operands[0]) == XFmode
3808        || GET_MODE (operands[0]) == SFmode
3809        || GET_MODE (operands[0]) == DFmode)
3810    && (operands[2] = find_constant_src (insn))"
3811   [(set (match_dup 0) (match_dup 2))]
3812 {
3813   rtx c = operands[2];
3814   rtx r = operands[0];
3815
3816   if (GET_CODE (r) == SUBREG)
3817     r = SUBREG_REG (r);
3818
3819   if (SSE_REG_P (r))
3820     {
3821       if (!standard_sse_constant_p (c))
3822         FAIL;
3823     }
3824   else if (FP_REG_P (r))
3825     {
3826       if (!standard_80387_constant_p (c))
3827         FAIL;
3828     }
3829   else if (MMX_REG_P (r))
3830     FAIL;
3831 })
3832
3833 (define_insn "swapxf"
3834   [(set (match_operand:XF 0 "register_operand" "+f")
3835         (match_operand:XF 1 "register_operand" "+f"))
3836    (set (match_dup 1)
3837         (match_dup 0))]
3838   "TARGET_80387"
3839 {
3840   if (STACK_TOP_P (operands[0]))
3841     return "fxch\t%1";
3842   else
3843     return "fxch\t%0";
3844 }
3845   [(set_attr "type" "fxch")
3846    (set_attr "mode" "XF")])
3847
3848 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3849 (define_split
3850   [(set (match_operand:X87MODEF 0 "register_operand" "")
3851         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3852   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3853    && (standard_80387_constant_p (operands[1]) == 8
3854        || standard_80387_constant_p (operands[1]) == 9)"
3855   [(set (match_dup 0)(match_dup 1))
3856    (set (match_dup 0)
3857         (neg:X87MODEF (match_dup 0)))]
3858 {
3859   REAL_VALUE_TYPE r;
3860
3861   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3862   if (real_isnegzero (&r))
3863     operands[1] = CONST0_RTX (<MODE>mode);
3864   else
3865     operands[1] = CONST1_RTX (<MODE>mode);
3866 })
3867
3868 (define_split
3869   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3870         (match_operand:TF 1 "general_operand" ""))]
3871   "reload_completed
3872    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3873   [(const_int 0)]
3874   "ix86_split_long_move (operands); DONE;")
3875 \f
3876 ;; Zero extension instructions
3877
3878 (define_expand "zero_extendhisi2"
3879   [(set (match_operand:SI 0 "register_operand" "")
3880      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3881   ""
3882 {
3883   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3884     {
3885       operands[1] = force_reg (HImode, operands[1]);
3886       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3887       DONE;
3888     }
3889 })
3890
3891 (define_insn "zero_extendhisi2_and"
3892   [(set (match_operand:SI 0 "register_operand" "=r")
3893      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3894    (clobber (reg:CC FLAGS_REG))]
3895   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3896   "#"
3897   [(set_attr "type" "alu1")
3898    (set_attr "mode" "SI")])
3899
3900 (define_split
3901   [(set (match_operand:SI 0 "register_operand" "")
3902         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3903    (clobber (reg:CC FLAGS_REG))]
3904   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3905    && optimize_function_for_speed_p (cfun)"
3906   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3907               (clobber (reg:CC FLAGS_REG))])]
3908   "")
3909
3910 (define_insn "*zero_extendhisi2_movzwl"
3911   [(set (match_operand:SI 0 "register_operand" "=r")
3912      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3913   "!TARGET_ZERO_EXTEND_WITH_AND
3914    || optimize_function_for_size_p (cfun)"
3915   "movz{wl|x}\t{%1, %0|%0, %1}"
3916   [(set_attr "type" "imovx")
3917    (set_attr "mode" "SI")])
3918
3919 (define_expand "zero_extendqihi2"
3920   [(parallel
3921     [(set (match_operand:HI 0 "register_operand" "")
3922        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3923      (clobber (reg:CC FLAGS_REG))])]
3924   ""
3925   "")
3926
3927 (define_insn "*zero_extendqihi2_and"
3928   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3929      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3930    (clobber (reg:CC FLAGS_REG))]
3931   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3932   "#"
3933   [(set_attr "type" "alu1")
3934    (set_attr "mode" "HI")])
3935
3936 (define_insn "*zero_extendqihi2_movzbw_and"
3937   [(set (match_operand:HI 0 "register_operand" "=r,r")
3938      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3939    (clobber (reg:CC FLAGS_REG))]
3940   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3941   "#"
3942   [(set_attr "type" "imovx,alu1")
3943    (set_attr "mode" "HI")])
3944
3945 ; zero extend to SImode here to avoid partial register stalls
3946 (define_insn "*zero_extendqihi2_movzbl"
3947   [(set (match_operand:HI 0 "register_operand" "=r")
3948      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3949   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3950    && reload_completed"
3951   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3952   [(set_attr "type" "imovx")
3953    (set_attr "mode" "SI")])
3954
3955 ;; For the movzbw case strip only the clobber
3956 (define_split
3957   [(set (match_operand:HI 0 "register_operand" "")
3958         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3959    (clobber (reg:CC FLAGS_REG))]
3960   "reload_completed
3961    && (!TARGET_ZERO_EXTEND_WITH_AND
3962        || optimize_function_for_size_p (cfun))
3963    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3964   [(set (match_operand:HI 0 "register_operand" "")
3965         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3966
3967 ;; When source and destination does not overlap, clear destination
3968 ;; first and then do the movb
3969 (define_split
3970   [(set (match_operand:HI 0 "register_operand" "")
3971         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3972    (clobber (reg:CC FLAGS_REG))]
3973   "reload_completed
3974    && ANY_QI_REG_P (operands[0])
3975    && (TARGET_ZERO_EXTEND_WITH_AND
3976        && optimize_function_for_speed_p (cfun))
3977    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3978   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3979 {
3980   operands[2] = gen_lowpart (QImode, operands[0]);
3981   ix86_expand_clear (operands[0]);
3982 })
3983
3984 ;; Rest is handled by single and.
3985 (define_split
3986   [(set (match_operand:HI 0 "register_operand" "")
3987         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3988    (clobber (reg:CC FLAGS_REG))]
3989   "reload_completed
3990    && true_regnum (operands[0]) == true_regnum (operands[1])"
3991   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3992               (clobber (reg:CC FLAGS_REG))])]
3993   "")
3994
3995 (define_expand "zero_extendqisi2"
3996   [(parallel
3997     [(set (match_operand:SI 0 "register_operand" "")
3998        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3999      (clobber (reg:CC FLAGS_REG))])]
4000   ""
4001   "")
4002
4003 (define_insn "*zero_extendqisi2_and"
4004   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4005      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4006    (clobber (reg:CC FLAGS_REG))]
4007   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4008   "#"
4009   [(set_attr "type" "alu1")
4010    (set_attr "mode" "SI")])
4011
4012 (define_insn "*zero_extendqisi2_movzbl_and"
4013   [(set (match_operand:SI 0 "register_operand" "=r,r")
4014      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4015    (clobber (reg:CC FLAGS_REG))]
4016   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4017   "#"
4018   [(set_attr "type" "imovx,alu1")
4019    (set_attr "mode" "SI")])
4020
4021 (define_insn "*zero_extendqisi2_movzbl"
4022   [(set (match_operand:SI 0 "register_operand" "=r")
4023      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4024   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4025    && reload_completed"
4026   "movz{bl|x}\t{%1, %0|%0, %1}"
4027   [(set_attr "type" "imovx")
4028    (set_attr "mode" "SI")])
4029
4030 ;; For the movzbl case strip only the clobber
4031 (define_split
4032   [(set (match_operand:SI 0 "register_operand" "")
4033         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4034    (clobber (reg:CC FLAGS_REG))]
4035   "reload_completed
4036    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4037    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4038   [(set (match_dup 0)
4039         (zero_extend:SI (match_dup 1)))])
4040
4041 ;; When source and destination does not overlap, clear destination
4042 ;; first and then do the movb
4043 (define_split
4044   [(set (match_operand:SI 0 "register_operand" "")
4045         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4046    (clobber (reg:CC FLAGS_REG))]
4047   "reload_completed
4048    && ANY_QI_REG_P (operands[0])
4049    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4050    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4051    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4052   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4053 {
4054   operands[2] = gen_lowpart (QImode, operands[0]);
4055   ix86_expand_clear (operands[0]);
4056 })
4057
4058 ;; Rest is handled by single and.
4059 (define_split
4060   [(set (match_operand:SI 0 "register_operand" "")
4061         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4062    (clobber (reg:CC FLAGS_REG))]
4063   "reload_completed
4064    && true_regnum (operands[0]) == true_regnum (operands[1])"
4065   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4066               (clobber (reg:CC FLAGS_REG))])]
4067   "")
4068
4069 ;; %%% Kill me once multi-word ops are sane.
4070 (define_expand "zero_extendsidi2"
4071   [(set (match_operand:DI 0 "register_operand" "")
4072      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4073   ""
4074 {
4075   if (!TARGET_64BIT)
4076     {
4077       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4078       DONE;
4079     }
4080 })
4081
4082 (define_insn "zero_extendsidi2_32"
4083   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4084         (zero_extend:DI
4085          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4086    (clobber (reg:CC FLAGS_REG))]
4087   "!TARGET_64BIT"
4088   "@
4089    #
4090    #
4091    #
4092    movd\t{%1, %0|%0, %1}
4093    movd\t{%1, %0|%0, %1}
4094    %vmovd\t{%1, %0|%0, %1}
4095    %vmovd\t{%1, %0|%0, %1}"
4096   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4097    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4098    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4099
4100 (define_insn "zero_extendsidi2_rex64"
4101   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4102      (zero_extend:DI
4103        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4104   "TARGET_64BIT"
4105   "@
4106    mov\t{%k1, %k0|%k0, %k1}
4107    #
4108    movd\t{%1, %0|%0, %1}
4109    movd\t{%1, %0|%0, %1}
4110    %vmovd\t{%1, %0|%0, %1}
4111    %vmovd\t{%1, %0|%0, %1}"
4112   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4113    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4114    (set_attr "prefix_0f" "0,*,*,*,*,*")
4115    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4116
4117 (define_split
4118   [(set (match_operand:DI 0 "memory_operand" "")
4119      (zero_extend:DI (match_dup 0)))]
4120   "TARGET_64BIT"
4121   [(set (match_dup 4) (const_int 0))]
4122   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4123
4124 (define_split
4125   [(set (match_operand:DI 0 "register_operand" "")
4126         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4127    (clobber (reg:CC FLAGS_REG))]
4128   "!TARGET_64BIT && reload_completed
4129    && true_regnum (operands[0]) == true_regnum (operands[1])"
4130   [(set (match_dup 4) (const_int 0))]
4131   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4132
4133 (define_split
4134   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4135         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4136    (clobber (reg:CC FLAGS_REG))]
4137   "!TARGET_64BIT && reload_completed
4138    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4139   [(set (match_dup 3) (match_dup 1))
4140    (set (match_dup 4) (const_int 0))]
4141   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4142
4143 (define_insn "zero_extendhidi2"
4144   [(set (match_operand:DI 0 "register_operand" "=r")
4145      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4146   "TARGET_64BIT"
4147   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4148   [(set_attr "type" "imovx")
4149    (set_attr "mode" "SI")])
4150
4151 (define_insn "zero_extendqidi2"
4152   [(set (match_operand:DI 0 "register_operand" "=r")
4153      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4154   "TARGET_64BIT"
4155   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4156   [(set_attr "type" "imovx")
4157    (set_attr "mode" "SI")])
4158 \f
4159 ;; Sign extension instructions
4160
4161 (define_expand "extendsidi2"
4162   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4163                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4164               (clobber (reg:CC FLAGS_REG))
4165               (clobber (match_scratch:SI 2 ""))])]
4166   ""
4167 {
4168   if (TARGET_64BIT)
4169     {
4170       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4171       DONE;
4172     }
4173 })
4174
4175 (define_insn "*extendsidi2_1"
4176   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4177         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4178    (clobber (reg:CC FLAGS_REG))
4179    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4180   "!TARGET_64BIT"
4181   "#")
4182
4183 (define_insn "extendsidi2_rex64"
4184   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4185         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4186   "TARGET_64BIT"
4187   "@
4188    {cltq|cdqe}
4189    movs{lq|x}\t{%1, %0|%0, %1}"
4190   [(set_attr "type" "imovx")
4191    (set_attr "mode" "DI")
4192    (set_attr "prefix_0f" "0")
4193    (set_attr "modrm" "0,1")])
4194
4195 (define_insn "extendhidi2"
4196   [(set (match_operand:DI 0 "register_operand" "=r")
4197         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4198   "TARGET_64BIT"
4199   "movs{wq|x}\t{%1, %0|%0, %1}"
4200   [(set_attr "type" "imovx")
4201    (set_attr "mode" "DI")])
4202
4203 (define_insn "extendqidi2"
4204   [(set (match_operand:DI 0 "register_operand" "=r")
4205         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4206   "TARGET_64BIT"
4207   "movs{bq|x}\t{%1, %0|%0, %1}"
4208    [(set_attr "type" "imovx")
4209     (set_attr "mode" "DI")])
4210
4211 ;; Extend to memory case when source register does die.
4212 (define_split
4213   [(set (match_operand:DI 0 "memory_operand" "")
4214         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4215    (clobber (reg:CC FLAGS_REG))
4216    (clobber (match_operand:SI 2 "register_operand" ""))]
4217   "(reload_completed
4218     && dead_or_set_p (insn, operands[1])
4219     && !reg_mentioned_p (operands[1], operands[0]))"
4220   [(set (match_dup 3) (match_dup 1))
4221    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4222               (clobber (reg:CC FLAGS_REG))])
4223    (set (match_dup 4) (match_dup 1))]
4224   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4225
4226 ;; Extend to memory case when source register does not die.
4227 (define_split
4228   [(set (match_operand:DI 0 "memory_operand" "")
4229         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4230    (clobber (reg:CC FLAGS_REG))
4231    (clobber (match_operand:SI 2 "register_operand" ""))]
4232   "reload_completed"
4233   [(const_int 0)]
4234 {
4235   split_di (&operands[0], 1, &operands[3], &operands[4]);
4236
4237   emit_move_insn (operands[3], operands[1]);
4238
4239   /* Generate a cltd if possible and doing so it profitable.  */
4240   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4241       && true_regnum (operands[1]) == AX_REG
4242       && true_regnum (operands[2]) == DX_REG)
4243     {
4244       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4245     }
4246   else
4247     {
4248       emit_move_insn (operands[2], operands[1]);
4249       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4250     }
4251   emit_move_insn (operands[4], operands[2]);
4252   DONE;
4253 })
4254
4255 ;; Extend to register case.  Optimize case where source and destination
4256 ;; registers match and cases where we can use cltd.
4257 (define_split
4258   [(set (match_operand:DI 0 "register_operand" "")
4259         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4260    (clobber (reg:CC FLAGS_REG))
4261    (clobber (match_scratch:SI 2 ""))]
4262   "reload_completed"
4263   [(const_int 0)]
4264 {
4265   split_di (&operands[0], 1, &operands[3], &operands[4]);
4266
4267   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4268     emit_move_insn (operands[3], operands[1]);
4269
4270   /* Generate a cltd if possible and doing so it profitable.  */
4271   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4272       && true_regnum (operands[3]) == AX_REG
4273       && true_regnum (operands[4]) == DX_REG)
4274     {
4275       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4276       DONE;
4277     }
4278
4279   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4280     emit_move_insn (operands[4], operands[1]);
4281
4282   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4283   DONE;
4284 })
4285
4286 (define_insn "extendhisi2"
4287   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4288         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4289   ""
4290 {
4291   switch (get_attr_prefix_0f (insn))
4292     {
4293     case 0:
4294       return "{cwtl|cwde}";
4295     default:
4296       return "movs{wl|x}\t{%1, %0|%0, %1}";
4297     }
4298 }
4299   [(set_attr "type" "imovx")
4300    (set_attr "mode" "SI")
4301    (set (attr "prefix_0f")
4302      ;; movsx is short decodable while cwtl is vector decoded.
4303      (if_then_else (and (eq_attr "cpu" "!k6")
4304                         (eq_attr "alternative" "0"))
4305         (const_string "0")
4306         (const_string "1")))
4307    (set (attr "modrm")
4308      (if_then_else (eq_attr "prefix_0f" "0")
4309         (const_string "0")
4310         (const_string "1")))])
4311
4312 (define_insn "*extendhisi2_zext"
4313   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4314         (zero_extend:DI
4315           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4316   "TARGET_64BIT"
4317 {
4318   switch (get_attr_prefix_0f (insn))
4319     {
4320     case 0:
4321       return "{cwtl|cwde}";
4322     default:
4323       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4324     }
4325 }
4326   [(set_attr "type" "imovx")
4327    (set_attr "mode" "SI")
4328    (set (attr "prefix_0f")
4329      ;; movsx is short decodable while cwtl is vector decoded.
4330      (if_then_else (and (eq_attr "cpu" "!k6")
4331                         (eq_attr "alternative" "0"))
4332         (const_string "0")
4333         (const_string "1")))
4334    (set (attr "modrm")
4335      (if_then_else (eq_attr "prefix_0f" "0")
4336         (const_string "0")
4337         (const_string "1")))])
4338
4339 (define_insn "extendqihi2"
4340   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4341         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4342   ""
4343 {
4344   switch (get_attr_prefix_0f (insn))
4345     {
4346     case 0:
4347       return "{cbtw|cbw}";
4348     default:
4349       return "movs{bw|x}\t{%1, %0|%0, %1}";
4350     }
4351 }
4352   [(set_attr "type" "imovx")
4353    (set_attr "mode" "HI")
4354    (set (attr "prefix_0f")
4355      ;; movsx is short decodable while cwtl is vector decoded.
4356      (if_then_else (and (eq_attr "cpu" "!k6")
4357                         (eq_attr "alternative" "0"))
4358         (const_string "0")
4359         (const_string "1")))
4360    (set (attr "modrm")
4361      (if_then_else (eq_attr "prefix_0f" "0")
4362         (const_string "0")
4363         (const_string "1")))])
4364
4365 (define_insn "extendqisi2"
4366   [(set (match_operand:SI 0 "register_operand" "=r")
4367         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4368   ""
4369   "movs{bl|x}\t{%1, %0|%0, %1}"
4370    [(set_attr "type" "imovx")
4371     (set_attr "mode" "SI")])
4372
4373 (define_insn "*extendqisi2_zext"
4374   [(set (match_operand:DI 0 "register_operand" "=r")
4375         (zero_extend:DI
4376           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4377   "TARGET_64BIT"
4378   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4379    [(set_attr "type" "imovx")
4380     (set_attr "mode" "SI")])
4381 \f
4382 ;; Conversions between float and double.
4383
4384 ;; These are all no-ops in the model used for the 80387.  So just
4385 ;; emit moves.
4386
4387 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4388 (define_insn "*dummy_extendsfdf2"
4389   [(set (match_operand:DF 0 "push_operand" "=<")
4390         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4391   "0"
4392   "#")
4393
4394 (define_split
4395   [(set (match_operand:DF 0 "push_operand" "")
4396         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4397   ""
4398   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4399    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4400
4401 (define_insn "*dummy_extendsfxf2"
4402   [(set (match_operand:XF 0 "push_operand" "=<")
4403         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4404   "0"
4405   "#")
4406
4407 (define_split
4408   [(set (match_operand:XF 0 "push_operand" "")
4409         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4410   ""
4411   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4412    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4413   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4414
4415 (define_split
4416   [(set (match_operand:XF 0 "push_operand" "")
4417         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4418   ""
4419   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4420    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4421   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4422
4423 (define_expand "extendsfdf2"
4424   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4425         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4426   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4427 {
4428   /* ??? Needed for compress_float_constant since all fp constants
4429      are LEGITIMATE_CONSTANT_P.  */
4430   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4431     {
4432       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4433           && standard_80387_constant_p (operands[1]) > 0)
4434         {
4435           operands[1] = simplify_const_unary_operation
4436             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4437           emit_move_insn_1 (operands[0], operands[1]);
4438           DONE;
4439         }
4440       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4441     }
4442 })
4443
4444 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4445    cvtss2sd:
4446       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4447       cvtps2pd xmm2,xmm1
4448    We do the conversion post reload to avoid producing of 128bit spills
4449    that might lead to ICE on 32bit target.  The sequence unlikely combine
4450    anyway.  */
4451 (define_split
4452   [(set (match_operand:DF 0 "register_operand" "")
4453         (float_extend:DF
4454           (match_operand:SF 1 "nonimmediate_operand" "")))]
4455   "TARGET_USE_VECTOR_FP_CONVERTS
4456    && optimize_insn_for_speed_p ()
4457    && reload_completed && SSE_REG_P (operands[0])"
4458    [(set (match_dup 2)
4459          (float_extend:V2DF
4460            (vec_select:V2SF
4461              (match_dup 3)
4462              (parallel [(const_int 0) (const_int 1)]))))]
4463 {
4464   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4465   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4466   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4467      Try to avoid move when unpacking can be done in source.  */
4468   if (REG_P (operands[1]))
4469     {
4470       /* If it is unsafe to overwrite upper half of source, we need
4471          to move to destination and unpack there.  */
4472       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4473            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4474           && true_regnum (operands[0]) != true_regnum (operands[1]))
4475         {
4476           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4477           emit_move_insn (tmp, operands[1]);
4478         }
4479       else
4480         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4481       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4482                                              operands[3]));
4483     }
4484   else
4485     emit_insn (gen_vec_setv4sf_0 (operands[3],
4486                                   CONST0_RTX (V4SFmode), operands[1]));
4487 })
4488
4489 (define_insn "*extendsfdf2_mixed"
4490   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4491         (float_extend:DF
4492           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4493   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4494 {
4495   switch (which_alternative)
4496     {
4497     case 0:
4498     case 1:
4499       return output_387_reg_move (insn, operands);
4500
4501     case 2:
4502       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4503
4504     default:
4505       gcc_unreachable ();
4506     }
4507 }
4508   [(set_attr "type" "fmov,fmov,ssecvt")
4509    (set_attr "prefix" "orig,orig,maybe_vex")
4510    (set_attr "mode" "SF,XF,DF")])
4511
4512 (define_insn "*extendsfdf2_sse"
4513   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4514         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4515   "TARGET_SSE2 && TARGET_SSE_MATH"
4516   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4517   [(set_attr "type" "ssecvt")
4518    (set_attr "prefix" "maybe_vex")
4519    (set_attr "mode" "DF")])
4520
4521 (define_insn "*extendsfdf2_i387"
4522   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4523         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4524   "TARGET_80387"
4525   "* return output_387_reg_move (insn, operands);"
4526   [(set_attr "type" "fmov")
4527    (set_attr "mode" "SF,XF")])
4528
4529 (define_expand "extend<mode>xf2"
4530   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4531         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4532   "TARGET_80387"
4533 {
4534   /* ??? Needed for compress_float_constant since all fp constants
4535      are LEGITIMATE_CONSTANT_P.  */
4536   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4537     {
4538       if (standard_80387_constant_p (operands[1]) > 0)
4539         {
4540           operands[1] = simplify_const_unary_operation
4541             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4542           emit_move_insn_1 (operands[0], operands[1]);
4543           DONE;
4544         }
4545       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4546     }
4547 })
4548
4549 (define_insn "*extend<mode>xf2_i387"
4550   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4551         (float_extend:XF
4552           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4553   "TARGET_80387"
4554   "* return output_387_reg_move (insn, operands);"
4555   [(set_attr "type" "fmov")
4556    (set_attr "mode" "<MODE>,XF")])
4557
4558 ;; %%% This seems bad bad news.
4559 ;; This cannot output into an f-reg because there is no way to be sure
4560 ;; of truncating in that case.  Otherwise this is just like a simple move
4561 ;; insn.  So we pretend we can output to a reg in order to get better
4562 ;; register preferencing, but we really use a stack slot.
4563
4564 ;; Conversion from DFmode to SFmode.
4565
4566 (define_expand "truncdfsf2"
4567   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4568         (float_truncate:SF
4569           (match_operand:DF 1 "nonimmediate_operand" "")))]
4570   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4571 {
4572   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4573     ;
4574   else if (flag_unsafe_math_optimizations)
4575     ;
4576   else
4577     {
4578       enum ix86_stack_slot slot = (virtuals_instantiated
4579                                    ? SLOT_TEMP
4580                                    : SLOT_VIRTUAL);
4581       rtx temp = assign_386_stack_local (SFmode, slot);
4582       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4583       DONE;
4584     }
4585 })
4586
4587 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4588    cvtsd2ss:
4589       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4590       cvtpd2ps xmm2,xmm1
4591    We do the conversion post reload to avoid producing of 128bit spills
4592    that might lead to ICE on 32bit target.  The sequence unlikely combine
4593    anyway.  */
4594 (define_split
4595   [(set (match_operand:SF 0 "register_operand" "")
4596         (float_truncate:SF
4597           (match_operand:DF 1 "nonimmediate_operand" "")))]
4598   "TARGET_USE_VECTOR_FP_CONVERTS
4599    && optimize_insn_for_speed_p ()
4600    && reload_completed && SSE_REG_P (operands[0])"
4601    [(set (match_dup 2)
4602          (vec_concat:V4SF
4603            (float_truncate:V2SF
4604              (match_dup 4))
4605            (match_dup 3)))]
4606 {
4607   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4608   operands[3] = CONST0_RTX (V2SFmode);
4609   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4610   /* Use movsd for loading from memory, unpcklpd for registers.
4611      Try to avoid move when unpacking can be done in source, or SSE3
4612      movddup is available.  */
4613   if (REG_P (operands[1]))
4614     {
4615       if (!TARGET_SSE3
4616           && true_regnum (operands[0]) != true_regnum (operands[1])
4617           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4618               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4619         {
4620           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4621           emit_move_insn (tmp, operands[1]);
4622           operands[1] = tmp;
4623         }
4624       else if (!TARGET_SSE3)
4625         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4626       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4627     }
4628   else
4629     emit_insn (gen_sse2_loadlpd (operands[4],
4630                                  CONST0_RTX (V2DFmode), operands[1]));
4631 })
4632
4633 (define_expand "truncdfsf2_with_temp"
4634   [(parallel [(set (match_operand:SF 0 "" "")
4635                    (float_truncate:SF (match_operand:DF 1 "" "")))
4636               (clobber (match_operand:SF 2 "" ""))])]
4637   "")
4638
4639 (define_insn "*truncdfsf_fast_mixed"
4640   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4641         (float_truncate:SF
4642           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4643   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4644 {
4645   switch (which_alternative)
4646     {
4647     case 0:
4648       return output_387_reg_move (insn, operands);
4649     case 1:
4650       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4651     default:
4652       gcc_unreachable ();
4653     }
4654 }
4655   [(set_attr "type" "fmov,ssecvt")
4656    (set_attr "prefix" "orig,maybe_vex")
4657    (set_attr "mode" "SF")])
4658
4659 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4660 ;; because nothing we do here is unsafe.
4661 (define_insn "*truncdfsf_fast_sse"
4662   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4663         (float_truncate:SF
4664           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4665   "TARGET_SSE2 && TARGET_SSE_MATH"
4666   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4667   [(set_attr "type" "ssecvt")
4668    (set_attr "prefix" "maybe_vex")
4669    (set_attr "mode" "SF")])
4670
4671 (define_insn "*truncdfsf_fast_i387"
4672   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4673         (float_truncate:SF
4674           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4675   "TARGET_80387 && flag_unsafe_math_optimizations"
4676   "* return output_387_reg_move (insn, operands);"
4677   [(set_attr "type" "fmov")
4678    (set_attr "mode" "SF")])
4679
4680 (define_insn "*truncdfsf_mixed"
4681   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4682         (float_truncate:SF
4683           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4684    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4685   "TARGET_MIX_SSE_I387"
4686 {
4687   switch (which_alternative)
4688     {
4689     case 0:
4690       return output_387_reg_move (insn, operands);
4691     case 1:
4692       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4693
4694     default:
4695       return "#";
4696     }
4697 }
4698   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4699    (set_attr "unit" "*,*,i387,i387,i387")
4700    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4701    (set_attr "mode" "SF")])
4702
4703 (define_insn "*truncdfsf_i387"
4704   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4705         (float_truncate:SF
4706           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4707    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4708   "TARGET_80387"
4709 {
4710   switch (which_alternative)
4711     {
4712     case 0:
4713       return output_387_reg_move (insn, operands);
4714
4715     default:
4716       return "#";
4717     }
4718 }
4719   [(set_attr "type" "fmov,multi,multi,multi")
4720    (set_attr "unit" "*,i387,i387,i387")
4721    (set_attr "mode" "SF")])
4722
4723 (define_insn "*truncdfsf2_i387_1"
4724   [(set (match_operand:SF 0 "memory_operand" "=m")
4725         (float_truncate:SF
4726           (match_operand:DF 1 "register_operand" "f")))]
4727   "TARGET_80387
4728    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4729    && !TARGET_MIX_SSE_I387"
4730   "* return output_387_reg_move (insn, operands);"
4731   [(set_attr "type" "fmov")
4732    (set_attr "mode" "SF")])
4733
4734 (define_split
4735   [(set (match_operand:SF 0 "register_operand" "")
4736         (float_truncate:SF
4737          (match_operand:DF 1 "fp_register_operand" "")))
4738    (clobber (match_operand 2 "" ""))]
4739   "reload_completed"
4740   [(set (match_dup 2) (match_dup 1))
4741    (set (match_dup 0) (match_dup 2))]
4742 {
4743   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4744 })
4745
4746 ;; Conversion from XFmode to {SF,DF}mode
4747
4748 (define_expand "truncxf<mode>2"
4749   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4750                    (float_truncate:MODEF
4751                      (match_operand:XF 1 "register_operand" "")))
4752               (clobber (match_dup 2))])]
4753   "TARGET_80387"
4754 {
4755   if (flag_unsafe_math_optimizations)
4756     {
4757       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4758       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4759       if (reg != operands[0])
4760         emit_move_insn (operands[0], reg);
4761       DONE;
4762     }
4763   else
4764     {
4765      enum ix86_stack_slot slot = (virtuals_instantiated
4766                                   ? SLOT_TEMP
4767                                   : SLOT_VIRTUAL);
4768       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4769     }
4770 })
4771
4772 (define_insn "*truncxfsf2_mixed"
4773   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4774         (float_truncate:SF
4775           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4776    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4777   "TARGET_80387"
4778 {
4779   gcc_assert (!which_alternative);
4780   return output_387_reg_move (insn, operands);
4781 }
4782   [(set_attr "type" "fmov,multi,multi,multi")
4783    (set_attr "unit" "*,i387,i387,i387")
4784    (set_attr "mode" "SF")])
4785
4786 (define_insn "*truncxfdf2_mixed"
4787   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4788         (float_truncate:DF
4789           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4790    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4791   "TARGET_80387"
4792 {
4793   gcc_assert (!which_alternative);
4794   return output_387_reg_move (insn, operands);
4795 }
4796   [(set_attr "type" "fmov,multi,multi,multi")
4797    (set_attr "unit" "*,i387,i387,i387")
4798    (set_attr "mode" "DF")])
4799
4800 (define_insn "truncxf<mode>2_i387_noop"
4801   [(set (match_operand:MODEF 0 "register_operand" "=f")
4802         (float_truncate:MODEF
4803           (match_operand:XF 1 "register_operand" "f")))]
4804   "TARGET_80387 && flag_unsafe_math_optimizations"
4805   "* return output_387_reg_move (insn, operands);"
4806   [(set_attr "type" "fmov")
4807    (set_attr "mode" "<MODE>")])
4808
4809 (define_insn "*truncxf<mode>2_i387"
4810   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4811         (float_truncate:MODEF
4812           (match_operand:XF 1 "register_operand" "f")))]
4813   "TARGET_80387"
4814   "* return output_387_reg_move (insn, operands);"
4815   [(set_attr "type" "fmov")
4816    (set_attr "mode" "<MODE>")])
4817
4818 (define_split
4819   [(set (match_operand:MODEF 0 "register_operand" "")
4820         (float_truncate:MODEF
4821           (match_operand:XF 1 "register_operand" "")))
4822    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4823   "TARGET_80387 && reload_completed"
4824   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4825    (set (match_dup 0) (match_dup 2))]
4826   "")
4827
4828 (define_split
4829   [(set (match_operand:MODEF 0 "memory_operand" "")
4830         (float_truncate:MODEF
4831           (match_operand:XF 1 "register_operand" "")))
4832    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4833   "TARGET_80387"
4834   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4835   "")
4836 \f
4837 ;; Signed conversion to DImode.
4838
4839 (define_expand "fix_truncxfdi2"
4840   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4841                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4842               (clobber (reg:CC FLAGS_REG))])]
4843   "TARGET_80387"
4844 {
4845   if (TARGET_FISTTP)
4846    {
4847      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4848      DONE;
4849    }
4850 })
4851
4852 (define_expand "fix_trunc<mode>di2"
4853   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4854                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4855               (clobber (reg:CC FLAGS_REG))])]
4856   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4857 {
4858   if (TARGET_FISTTP
4859       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4860    {
4861      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4862      DONE;
4863    }
4864   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4865    {
4866      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4867      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4868      if (out != operands[0])
4869         emit_move_insn (operands[0], out);
4870      DONE;
4871    }
4872 })
4873
4874 ;; Signed conversion to SImode.
4875
4876 (define_expand "fix_truncxfsi2"
4877   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4878                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4879               (clobber (reg:CC FLAGS_REG))])]
4880   "TARGET_80387"
4881 {
4882   if (TARGET_FISTTP)
4883    {
4884      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4885      DONE;
4886    }
4887 })
4888
4889 (define_expand "fix_trunc<mode>si2"
4890   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4891                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4892               (clobber (reg:CC FLAGS_REG))])]
4893   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4894 {
4895   if (TARGET_FISTTP
4896       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4897    {
4898      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4899      DONE;
4900    }
4901   if (SSE_FLOAT_MODE_P (<MODE>mode))
4902    {
4903      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4904      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4905      if (out != operands[0])
4906         emit_move_insn (operands[0], out);
4907      DONE;
4908    }
4909 })
4910
4911 ;; Signed conversion to HImode.
4912
4913 (define_expand "fix_trunc<mode>hi2"
4914   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4915                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4916               (clobber (reg:CC FLAGS_REG))])]
4917   "TARGET_80387
4918    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4919 {
4920   if (TARGET_FISTTP)
4921    {
4922      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4923      DONE;
4924    }
4925 })
4926
4927 ;; Unsigned conversion to SImode.
4928
4929 (define_expand "fixuns_trunc<mode>si2"
4930   [(parallel
4931     [(set (match_operand:SI 0 "register_operand" "")
4932           (unsigned_fix:SI
4933             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4934      (use (match_dup 2))
4935      (clobber (match_scratch:<ssevecmode> 3 ""))
4936      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4937   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4938 {
4939   enum machine_mode mode = <MODE>mode;
4940   enum machine_mode vecmode = <ssevecmode>mode;
4941   REAL_VALUE_TYPE TWO31r;
4942   rtx two31;
4943
4944   if (optimize_insn_for_size_p ())
4945     FAIL;
4946
4947   real_ldexp (&TWO31r, &dconst1, 31);
4948   two31 = const_double_from_real_value (TWO31r, mode);
4949   two31 = ix86_build_const_vector (mode, true, two31);
4950   operands[2] = force_reg (vecmode, two31);
4951 })
4952
4953 (define_insn_and_split "*fixuns_trunc<mode>_1"
4954   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4955         (unsigned_fix:SI
4956           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4957    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4958    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4959    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4960   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4961    && optimize_function_for_speed_p (cfun)"
4962   "#"
4963   "&& reload_completed"
4964   [(const_int 0)]
4965 {
4966   ix86_split_convert_uns_si_sse (operands);
4967   DONE;
4968 })
4969
4970 ;; Unsigned conversion to HImode.
4971 ;; Without these patterns, we'll try the unsigned SI conversion which
4972 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4973
4974 (define_expand "fixuns_trunc<mode>hi2"
4975   [(set (match_dup 2)
4976         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4977    (set (match_operand:HI 0 "nonimmediate_operand" "")
4978         (subreg:HI (match_dup 2) 0))]
4979   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4980   "operands[2] = gen_reg_rtx (SImode);")
4981
4982 ;; When SSE is available, it is always faster to use it!
4983 (define_insn "fix_trunc<mode>di_sse"
4984   [(set (match_operand:DI 0 "register_operand" "=r,r")
4985         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4986   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4987    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4988   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4989   [(set_attr "type" "sseicvt")
4990    (set_attr "prefix" "maybe_vex")
4991    (set_attr "prefix_rex" "1")
4992    (set_attr "mode" "<MODE>")
4993    (set_attr "athlon_decode" "double,vector")
4994    (set_attr "amdfam10_decode" "double,double")])
4995
4996 (define_insn "fix_trunc<mode>si_sse"
4997   [(set (match_operand:SI 0 "register_operand" "=r,r")
4998         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4999   "SSE_FLOAT_MODE_P (<MODE>mode)
5000    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5001   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5002   [(set_attr "type" "sseicvt")
5003    (set_attr "prefix" "maybe_vex")
5004    (set_attr "mode" "<MODE>")
5005    (set_attr "athlon_decode" "double,vector")
5006    (set_attr "amdfam10_decode" "double,double")])
5007
5008 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5009 (define_peephole2
5010   [(set (match_operand:MODEF 0 "register_operand" "")
5011         (match_operand:MODEF 1 "memory_operand" ""))
5012    (set (match_operand:SSEMODEI24 2 "register_operand" "")
5013         (fix:SSEMODEI24 (match_dup 0)))]
5014   "TARGET_SHORTEN_X87_SSE
5015    && peep2_reg_dead_p (2, operands[0])"
5016   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5017   "")
5018
5019 ;; Avoid vector decoded forms of the instruction.
5020 (define_peephole2
5021   [(match_scratch:DF 2 "Y2")
5022    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5023         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5024   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5025   [(set (match_dup 2) (match_dup 1))
5026    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5027   "")
5028
5029 (define_peephole2
5030   [(match_scratch:SF 2 "x")
5031    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5032         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5033   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5034   [(set (match_dup 2) (match_dup 1))
5035    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5036   "")
5037
5038 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5039   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5040         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5041   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5042    && TARGET_FISTTP
5043    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5044          && (TARGET_64BIT || <MODE>mode != DImode))
5045         && TARGET_SSE_MATH)
5046    && can_create_pseudo_p ()"
5047   "#"
5048   "&& 1"
5049   [(const_int 0)]
5050 {
5051   if (memory_operand (operands[0], VOIDmode))
5052     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5053   else
5054     {
5055       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5056       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5057                                                             operands[1],
5058                                                             operands[2]));
5059     }
5060   DONE;
5061 }
5062   [(set_attr "type" "fisttp")
5063    (set_attr "mode" "<MODE>")])
5064
5065 (define_insn "fix_trunc<mode>_i387_fisttp"
5066   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5067         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5068    (clobber (match_scratch:XF 2 "=&1f"))]
5069   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5070    && TARGET_FISTTP
5071    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5072          && (TARGET_64BIT || <MODE>mode != DImode))
5073         && TARGET_SSE_MATH)"
5074   "* return output_fix_trunc (insn, operands, 1);"
5075   [(set_attr "type" "fisttp")
5076    (set_attr "mode" "<MODE>")])
5077
5078 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5079   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5080         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5081    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5082    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5083   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5084    && TARGET_FISTTP
5085    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5086         && (TARGET_64BIT || <MODE>mode != DImode))
5087         && TARGET_SSE_MATH)"
5088   "#"
5089   [(set_attr "type" "fisttp")
5090    (set_attr "mode" "<MODE>")])
5091
5092 (define_split
5093   [(set (match_operand:X87MODEI 0 "register_operand" "")
5094         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5095    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5096    (clobber (match_scratch 3 ""))]
5097   "reload_completed"
5098   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5099               (clobber (match_dup 3))])
5100    (set (match_dup 0) (match_dup 2))]
5101   "")
5102
5103 (define_split
5104   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5105         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5106    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5107    (clobber (match_scratch 3 ""))]
5108   "reload_completed"
5109   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5110               (clobber (match_dup 3))])]
5111   "")
5112
5113 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5114 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5115 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5116 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5117 ;; function in i386.c.
5118 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5119   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5120         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5121    (clobber (reg:CC FLAGS_REG))]
5122   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5123    && !TARGET_FISTTP
5124    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5125          && (TARGET_64BIT || <MODE>mode != DImode))
5126    && can_create_pseudo_p ()"
5127   "#"
5128   "&& 1"
5129   [(const_int 0)]
5130 {
5131   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5132
5133   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5134   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5135   if (memory_operand (operands[0], VOIDmode))
5136     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5137                                          operands[2], operands[3]));
5138   else
5139     {
5140       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5141       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5142                                                      operands[2], operands[3],
5143                                                      operands[4]));
5144     }
5145   DONE;
5146 }
5147   [(set_attr "type" "fistp")
5148    (set_attr "i387_cw" "trunc")
5149    (set_attr "mode" "<MODE>")])
5150
5151 (define_insn "fix_truncdi_i387"
5152   [(set (match_operand:DI 0 "memory_operand" "=m")
5153         (fix:DI (match_operand 1 "register_operand" "f")))
5154    (use (match_operand:HI 2 "memory_operand" "m"))
5155    (use (match_operand:HI 3 "memory_operand" "m"))
5156    (clobber (match_scratch:XF 4 "=&1f"))]
5157   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5158    && !TARGET_FISTTP
5159    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5160   "* return output_fix_trunc (insn, operands, 0);"
5161   [(set_attr "type" "fistp")
5162    (set_attr "i387_cw" "trunc")
5163    (set_attr "mode" "DI")])
5164
5165 (define_insn "fix_truncdi_i387_with_temp"
5166   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5167         (fix:DI (match_operand 1 "register_operand" "f,f")))
5168    (use (match_operand:HI 2 "memory_operand" "m,m"))
5169    (use (match_operand:HI 3 "memory_operand" "m,m"))
5170    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5171    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5172   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5173    && !TARGET_FISTTP
5174    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5175   "#"
5176   [(set_attr "type" "fistp")
5177    (set_attr "i387_cw" "trunc")
5178    (set_attr "mode" "DI")])
5179
5180 (define_split
5181   [(set (match_operand:DI 0 "register_operand" "")
5182         (fix:DI (match_operand 1 "register_operand" "")))
5183    (use (match_operand:HI 2 "memory_operand" ""))
5184    (use (match_operand:HI 3 "memory_operand" ""))
5185    (clobber (match_operand:DI 4 "memory_operand" ""))
5186    (clobber (match_scratch 5 ""))]
5187   "reload_completed"
5188   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5189               (use (match_dup 2))
5190               (use (match_dup 3))
5191               (clobber (match_dup 5))])
5192    (set (match_dup 0) (match_dup 4))]
5193   "")
5194
5195 (define_split
5196   [(set (match_operand:DI 0 "memory_operand" "")
5197         (fix:DI (match_operand 1 "register_operand" "")))
5198    (use (match_operand:HI 2 "memory_operand" ""))
5199    (use (match_operand:HI 3 "memory_operand" ""))
5200    (clobber (match_operand:DI 4 "memory_operand" ""))
5201    (clobber (match_scratch 5 ""))]
5202   "reload_completed"
5203   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5204               (use (match_dup 2))
5205               (use (match_dup 3))
5206               (clobber (match_dup 5))])]
5207   "")
5208
5209 (define_insn "fix_trunc<mode>_i387"
5210   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5211         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5212    (use (match_operand:HI 2 "memory_operand" "m"))
5213    (use (match_operand:HI 3 "memory_operand" "m"))]
5214   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5215    && !TARGET_FISTTP
5216    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5217   "* return output_fix_trunc (insn, operands, 0);"
5218   [(set_attr "type" "fistp")
5219    (set_attr "i387_cw" "trunc")
5220    (set_attr "mode" "<MODE>")])
5221
5222 (define_insn "fix_trunc<mode>_i387_with_temp"
5223   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5224         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5225    (use (match_operand:HI 2 "memory_operand" "m,m"))
5226    (use (match_operand:HI 3 "memory_operand" "m,m"))
5227    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5228   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5229    && !TARGET_FISTTP
5230    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5231   "#"
5232   [(set_attr "type" "fistp")
5233    (set_attr "i387_cw" "trunc")
5234    (set_attr "mode" "<MODE>")])
5235
5236 (define_split
5237   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5238         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5239    (use (match_operand:HI 2 "memory_operand" ""))
5240    (use (match_operand:HI 3 "memory_operand" ""))
5241    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5242   "reload_completed"
5243   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5244               (use (match_dup 2))
5245               (use (match_dup 3))])
5246    (set (match_dup 0) (match_dup 4))]
5247   "")
5248
5249 (define_split
5250   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5251         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5252    (use (match_operand:HI 2 "memory_operand" ""))
5253    (use (match_operand:HI 3 "memory_operand" ""))
5254    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5255   "reload_completed"
5256   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5257               (use (match_dup 2))
5258               (use (match_dup 3))])]
5259   "")
5260
5261 (define_insn "x86_fnstcw_1"
5262   [(set (match_operand:HI 0 "memory_operand" "=m")
5263         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5264   "TARGET_80387"
5265   "fnstcw\t%0"
5266   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5267    (set_attr "mode" "HI")
5268    (set_attr "unit" "i387")])
5269
5270 (define_insn "x86_fldcw_1"
5271   [(set (reg:HI FPCR_REG)
5272         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5273   "TARGET_80387"
5274   "fldcw\t%0"
5275   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5276    (set_attr "mode" "HI")
5277    (set_attr "unit" "i387")
5278    (set_attr "athlon_decode" "vector")
5279    (set_attr "amdfam10_decode" "vector")])
5280 \f
5281 ;; Conversion between fixed point and floating point.
5282
5283 ;; Even though we only accept memory inputs, the backend _really_
5284 ;; wants to be able to do this between registers.
5285
5286 (define_expand "floathi<mode>2"
5287   [(set (match_operand:X87MODEF 0 "register_operand" "")
5288         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5289   "TARGET_80387
5290    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5291        || TARGET_MIX_SSE_I387)"
5292   "")
5293
5294 ;; Pre-reload splitter to add memory clobber to the pattern.
5295 (define_insn_and_split "*floathi<mode>2_1"
5296   [(set (match_operand:X87MODEF 0 "register_operand" "")
5297         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5298   "TARGET_80387
5299    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5300        || TARGET_MIX_SSE_I387)
5301    && can_create_pseudo_p ()"
5302   "#"
5303   "&& 1"
5304   [(parallel [(set (match_dup 0)
5305               (float:X87MODEF (match_dup 1)))
5306    (clobber (match_dup 2))])]
5307   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5308
5309 (define_insn "*floathi<mode>2_i387_with_temp"
5310   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5311         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5312   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5313   "TARGET_80387
5314    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5315        || TARGET_MIX_SSE_I387)"
5316   "#"
5317   [(set_attr "type" "fmov,multi")
5318    (set_attr "mode" "<MODE>")
5319    (set_attr "unit" "*,i387")
5320    (set_attr "fp_int_src" "true")])
5321
5322 (define_insn "*floathi<mode>2_i387"
5323   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5324         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5325   "TARGET_80387
5326    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5327        || TARGET_MIX_SSE_I387)"
5328   "fild%Z1\t%1"
5329   [(set_attr "type" "fmov")
5330    (set_attr "mode" "<MODE>")
5331    (set_attr "fp_int_src" "true")])
5332
5333 (define_split
5334   [(set (match_operand:X87MODEF 0 "register_operand" "")
5335         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5336    (clobber (match_operand:HI 2 "memory_operand" ""))]
5337   "TARGET_80387
5338    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5339        || TARGET_MIX_SSE_I387)
5340    && reload_completed"
5341   [(set (match_dup 2) (match_dup 1))
5342    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5343   "")
5344
5345 (define_split
5346   [(set (match_operand:X87MODEF 0 "register_operand" "")
5347         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5348    (clobber (match_operand:HI 2 "memory_operand" ""))]
5349    "TARGET_80387
5350     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5351         || TARGET_MIX_SSE_I387)
5352     && reload_completed"
5353   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5354   "")
5355
5356 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5357   [(set (match_operand:X87MODEF 0 "register_operand" "")
5358         (float:X87MODEF
5359           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5360   "TARGET_80387
5361    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5362        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5363 {
5364   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5365         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5366       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5367     {
5368       rtx reg = gen_reg_rtx (XFmode);
5369       rtx insn;
5370
5371       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5372
5373       if (<X87MODEF:MODE>mode == SFmode)
5374         insn = gen_truncxfsf2 (operands[0], reg);
5375       else if (<X87MODEF:MODE>mode == DFmode)
5376         insn = gen_truncxfdf2 (operands[0], reg);
5377       else
5378         gcc_unreachable ();
5379
5380       emit_insn (insn);
5381       DONE;
5382     }
5383 })
5384
5385 ;; Pre-reload splitter to add memory clobber to the pattern.
5386 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5387   [(set (match_operand:X87MODEF 0 "register_operand" "")
5388         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5389   "((TARGET_80387
5390      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5391      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5392            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5393          || TARGET_MIX_SSE_I387))
5394     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5395         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5396         && ((<SSEMODEI24:MODE>mode == SImode
5397              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5398              && optimize_function_for_speed_p (cfun)
5399              && flag_trapping_math)
5400             || !(TARGET_INTER_UNIT_CONVERSIONS
5401                  || optimize_function_for_size_p (cfun)))))
5402    && can_create_pseudo_p ()"
5403   "#"
5404   "&& 1"
5405   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5406               (clobber (match_dup 2))])]
5407 {
5408   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5409
5410   /* Avoid store forwarding (partial memory) stall penalty
5411      by passing DImode value through XMM registers.  */
5412   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5413       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5414       && optimize_function_for_speed_p (cfun))
5415     {
5416       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5417                                                             operands[1],
5418                                                             operands[2]));
5419       DONE;
5420     }
5421 })
5422
5423 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5424   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5425         (float:MODEF
5426           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5427    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5428   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5429    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5430   "#"
5431   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5432    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5433    (set_attr "unit" "*,i387,*,*,*")
5434    (set_attr "athlon_decode" "*,*,double,direct,double")
5435    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5436    (set_attr "fp_int_src" "true")])
5437
5438 (define_insn "*floatsi<mode>2_vector_mixed"
5439   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5440         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5441   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5442    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5443   "@
5444    fild%Z1\t%1
5445    #"
5446   [(set_attr "type" "fmov,sseicvt")
5447    (set_attr "mode" "<MODE>,<ssevecmode>")
5448    (set_attr "unit" "i387,*")
5449    (set_attr "athlon_decode" "*,direct")
5450    (set_attr "amdfam10_decode" "*,double")
5451    (set_attr "fp_int_src" "true")])
5452
5453 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5454   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5455         (float:MODEF
5456           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5457   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5458   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5459    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5460   "#"
5461   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5462    (set_attr "mode" "<MODEF:MODE>")
5463    (set_attr "unit" "*,i387,*,*")
5464    (set_attr "athlon_decode" "*,*,double,direct")
5465    (set_attr "amdfam10_decode" "*,*,vector,double")
5466    (set_attr "fp_int_src" "true")])
5467
5468 (define_split
5469   [(set (match_operand:MODEF 0 "register_operand" "")
5470         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5471    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5472   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5473    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5474    && TARGET_INTER_UNIT_CONVERSIONS
5475    && reload_completed
5476    && (SSE_REG_P (operands[0])
5477        || (GET_CODE (operands[0]) == SUBREG
5478            && SSE_REG_P (operands[0])))"
5479   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5480   "")
5481
5482 (define_split
5483   [(set (match_operand:MODEF 0 "register_operand" "")
5484         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5485    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5486   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5487    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5488    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5489    && reload_completed
5490    && (SSE_REG_P (operands[0])
5491        || (GET_CODE (operands[0]) == SUBREG
5492            && SSE_REG_P (operands[0])))"
5493   [(set (match_dup 2) (match_dup 1))
5494    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5495   "")
5496
5497 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5498   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5499         (float:MODEF
5500           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5501   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5502    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5503    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5504   "@
5505    fild%Z1\t%1
5506    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5507    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5508   [(set_attr "type" "fmov,sseicvt,sseicvt")
5509    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5510    (set_attr "mode" "<MODEF:MODE>")
5511    (set (attr "prefix_rex")
5512      (if_then_else
5513        (and (eq_attr "prefix" "maybe_vex")
5514             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5515        (const_string "1")
5516        (const_string "*")))
5517    (set_attr "unit" "i387,*,*")
5518    (set_attr "athlon_decode" "*,double,direct")
5519    (set_attr "amdfam10_decode" "*,vector,double")
5520    (set_attr "fp_int_src" "true")])
5521
5522 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5523   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5524         (float:MODEF
5525           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5526   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5527    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5528    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5529   "@
5530    fild%Z1\t%1
5531    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5532   [(set_attr "type" "fmov,sseicvt")
5533    (set_attr "prefix" "orig,maybe_vex")
5534    (set_attr "mode" "<MODEF:MODE>")
5535    (set (attr "prefix_rex")
5536      (if_then_else
5537        (and (eq_attr "prefix" "maybe_vex")
5538             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5539        (const_string "1")
5540        (const_string "*")))
5541    (set_attr "athlon_decode" "*,direct")
5542    (set_attr "amdfam10_decode" "*,double")
5543    (set_attr "fp_int_src" "true")])
5544
5545 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5546   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5547         (float:MODEF
5548           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5549    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5550   "TARGET_SSE2 && TARGET_SSE_MATH
5551    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5552   "#"
5553   [(set_attr "type" "sseicvt")
5554    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5555    (set_attr "athlon_decode" "double,direct,double")
5556    (set_attr "amdfam10_decode" "vector,double,double")
5557    (set_attr "fp_int_src" "true")])
5558
5559 (define_insn "*floatsi<mode>2_vector_sse"
5560   [(set (match_operand:MODEF 0 "register_operand" "=x")
5561         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5562   "TARGET_SSE2 && TARGET_SSE_MATH
5563    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5564   "#"
5565   [(set_attr "type" "sseicvt")
5566    (set_attr "mode" "<MODE>")
5567    (set_attr "athlon_decode" "direct")
5568    (set_attr "amdfam10_decode" "double")
5569    (set_attr "fp_int_src" "true")])
5570
5571 (define_split
5572   [(set (match_operand:MODEF 0 "register_operand" "")
5573         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5574    (clobber (match_operand:SI 2 "memory_operand" ""))]
5575   "TARGET_SSE2 && TARGET_SSE_MATH
5576    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5577    && reload_completed
5578    && (SSE_REG_P (operands[0])
5579        || (GET_CODE (operands[0]) == SUBREG
5580            && SSE_REG_P (operands[0])))"
5581   [(const_int 0)]
5582 {
5583   rtx op1 = operands[1];
5584
5585   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5586                                      <MODE>mode, 0);
5587   if (GET_CODE (op1) == SUBREG)
5588     op1 = SUBREG_REG (op1);
5589
5590   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5591     {
5592       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5593       emit_insn (gen_sse2_loadld (operands[4],
5594                                   CONST0_RTX (V4SImode), operands[1]));
5595     }
5596   /* We can ignore possible trapping value in the
5597      high part of SSE register for non-trapping math. */
5598   else if (SSE_REG_P (op1) && !flag_trapping_math)
5599     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5600   else
5601     {
5602       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5603       emit_move_insn (operands[2], operands[1]);
5604       emit_insn (gen_sse2_loadld (operands[4],
5605                                   CONST0_RTX (V4SImode), operands[2]));
5606     }
5607   emit_insn
5608     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5609   DONE;
5610 })
5611
5612 (define_split
5613   [(set (match_operand:MODEF 0 "register_operand" "")
5614         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5615    (clobber (match_operand:SI 2 "memory_operand" ""))]
5616   "TARGET_SSE2 && TARGET_SSE_MATH
5617    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5618    && reload_completed
5619    && (SSE_REG_P (operands[0])
5620        || (GET_CODE (operands[0]) == SUBREG
5621            && SSE_REG_P (operands[0])))"
5622   [(const_int 0)]
5623 {
5624   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5625                                      <MODE>mode, 0);
5626   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5627
5628   emit_insn (gen_sse2_loadld (operands[4],
5629                               CONST0_RTX (V4SImode), operands[1]));
5630   emit_insn
5631     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5632   DONE;
5633 })
5634
5635 (define_split
5636   [(set (match_operand:MODEF 0 "register_operand" "")
5637         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5638   "TARGET_SSE2 && TARGET_SSE_MATH
5639    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5640    && reload_completed
5641    && (SSE_REG_P (operands[0])
5642        || (GET_CODE (operands[0]) == SUBREG
5643            && SSE_REG_P (operands[0])))"
5644   [(const_int 0)]
5645 {
5646   rtx op1 = operands[1];
5647
5648   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5649                                      <MODE>mode, 0);
5650   if (GET_CODE (op1) == SUBREG)
5651     op1 = SUBREG_REG (op1);
5652
5653   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5654     {
5655       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5656       emit_insn (gen_sse2_loadld (operands[4],
5657                                   CONST0_RTX (V4SImode), operands[1]));
5658     }
5659   /* We can ignore possible trapping value in the
5660      high part of SSE register for non-trapping math. */
5661   else if (SSE_REG_P (op1) && !flag_trapping_math)
5662     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5663   else
5664     gcc_unreachable ();
5665   emit_insn
5666     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5667   DONE;
5668 })
5669
5670 (define_split
5671   [(set (match_operand:MODEF 0 "register_operand" "")
5672         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5673   "TARGET_SSE2 && TARGET_SSE_MATH
5674    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5675    && reload_completed
5676    && (SSE_REG_P (operands[0])
5677        || (GET_CODE (operands[0]) == SUBREG
5678            && SSE_REG_P (operands[0])))"
5679   [(const_int 0)]
5680 {
5681   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5682                                      <MODE>mode, 0);
5683   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5684
5685   emit_insn (gen_sse2_loadld (operands[4],
5686                               CONST0_RTX (V4SImode), operands[1]));
5687   emit_insn
5688     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5689   DONE;
5690 })
5691
5692 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5693   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5694         (float:MODEF
5695           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5696   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5697   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5698    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5699   "#"
5700   [(set_attr "type" "sseicvt")
5701    (set_attr "mode" "<MODEF:MODE>")
5702    (set_attr "athlon_decode" "double,direct")
5703    (set_attr "amdfam10_decode" "vector,double")
5704    (set_attr "fp_int_src" "true")])
5705
5706 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5707   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5708         (float:MODEF
5709           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5710   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5711    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5712    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5713   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5714   [(set_attr "type" "sseicvt")
5715    (set_attr "prefix" "maybe_vex")
5716    (set_attr "mode" "<MODEF:MODE>")
5717    (set (attr "prefix_rex")
5718      (if_then_else
5719        (and (eq_attr "prefix" "maybe_vex")
5720             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5721        (const_string "1")
5722        (const_string "*")))
5723    (set_attr "athlon_decode" "double,direct")
5724    (set_attr "amdfam10_decode" "vector,double")
5725    (set_attr "fp_int_src" "true")])
5726
5727 (define_split
5728   [(set (match_operand:MODEF 0 "register_operand" "")
5729         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5730    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5731   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5732    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5733    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5734    && reload_completed
5735    && (SSE_REG_P (operands[0])
5736        || (GET_CODE (operands[0]) == SUBREG
5737            && SSE_REG_P (operands[0])))"
5738   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5739   "")
5740
5741 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5742   [(set (match_operand:MODEF 0 "register_operand" "=x")
5743         (float:MODEF
5744           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5745   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5746    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5747    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5748   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5749   [(set_attr "type" "sseicvt")
5750    (set_attr "prefix" "maybe_vex")
5751    (set_attr "mode" "<MODEF:MODE>")
5752    (set (attr "prefix_rex")
5753      (if_then_else
5754        (and (eq_attr "prefix" "maybe_vex")
5755             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5756        (const_string "1")
5757        (const_string "*")))
5758    (set_attr "athlon_decode" "direct")
5759    (set_attr "amdfam10_decode" "double")
5760    (set_attr "fp_int_src" "true")])
5761
5762 (define_split
5763   [(set (match_operand:MODEF 0 "register_operand" "")
5764         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5765    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5766   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5767    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5768    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5769    && reload_completed
5770    && (SSE_REG_P (operands[0])
5771        || (GET_CODE (operands[0]) == SUBREG
5772            && SSE_REG_P (operands[0])))"
5773   [(set (match_dup 2) (match_dup 1))
5774    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5775   "")
5776
5777 (define_split
5778   [(set (match_operand:MODEF 0 "register_operand" "")
5779         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5780    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5781   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5782    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5783    && reload_completed
5784    && (SSE_REG_P (operands[0])
5785        || (GET_CODE (operands[0]) == SUBREG
5786            && SSE_REG_P (operands[0])))"
5787   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5788   "")
5789
5790 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5791   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5792         (float:X87MODEF
5793           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5794   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5795   "TARGET_80387
5796    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5797   "@
5798    fild%Z1\t%1
5799    #"
5800   [(set_attr "type" "fmov,multi")
5801    (set_attr "mode" "<X87MODEF:MODE>")
5802    (set_attr "unit" "*,i387")
5803    (set_attr "fp_int_src" "true")])
5804
5805 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5806   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5807         (float:X87MODEF
5808           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5809   "TARGET_80387
5810    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5811   "fild%Z1\t%1"
5812   [(set_attr "type" "fmov")
5813    (set_attr "mode" "<X87MODEF:MODE>")
5814    (set_attr "fp_int_src" "true")])
5815
5816 (define_split
5817   [(set (match_operand:X87MODEF 0 "register_operand" "")
5818         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5819    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5820   "TARGET_80387
5821    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5822    && reload_completed
5823    && FP_REG_P (operands[0])"
5824   [(set (match_dup 2) (match_dup 1))
5825    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5826   "")
5827
5828 (define_split
5829   [(set (match_operand:X87MODEF 0 "register_operand" "")
5830         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5831    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5832   "TARGET_80387
5833    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5834    && reload_completed
5835    && FP_REG_P (operands[0])"
5836   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5837   "")
5838
5839 ;; Avoid store forwarding (partial memory) stall penalty
5840 ;; by passing DImode value through XMM registers.  */
5841
5842 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5843   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5844         (float:X87MODEF
5845           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5846    (clobber (match_scratch:V4SI 3 "=X,x"))
5847    (clobber (match_scratch:V4SI 4 "=X,x"))
5848    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5849   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5850    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5851    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5852   "#"
5853   [(set_attr "type" "multi")
5854    (set_attr "mode" "<X87MODEF:MODE>")
5855    (set_attr "unit" "i387")
5856    (set_attr "fp_int_src" "true")])
5857
5858 (define_split
5859   [(set (match_operand:X87MODEF 0 "register_operand" "")
5860         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5861    (clobber (match_scratch:V4SI 3 ""))
5862    (clobber (match_scratch:V4SI 4 ""))
5863    (clobber (match_operand:DI 2 "memory_operand" ""))]
5864   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5865    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5866    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5867    && reload_completed
5868    && FP_REG_P (operands[0])"
5869   [(set (match_dup 2) (match_dup 3))
5870    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5871 {
5872   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5873      Assemble the 64-bit DImode value in an xmm register.  */
5874   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5875                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5876   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5877                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5878   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5879                                          operands[4]));
5880
5881   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5882 })
5883
5884 (define_split
5885   [(set (match_operand:X87MODEF 0 "register_operand" "")
5886         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5887    (clobber (match_scratch:V4SI 3 ""))
5888    (clobber (match_scratch:V4SI 4 ""))
5889    (clobber (match_operand:DI 2 "memory_operand" ""))]
5890   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5891    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5892    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5893    && reload_completed
5894    && FP_REG_P (operands[0])"
5895   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5896   "")
5897
5898 ;; Avoid store forwarding (partial memory) stall penalty by extending
5899 ;; SImode value to DImode through XMM register instead of pushing two
5900 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5901 ;; targets benefit from this optimization. Also note that fild
5902 ;; loads from memory only.
5903
5904 (define_insn "*floatunssi<mode>2_1"
5905   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5906         (unsigned_float:X87MODEF
5907           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5908    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5909    (clobber (match_scratch:SI 3 "=X,x"))]
5910   "!TARGET_64BIT
5911    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5912    && TARGET_SSE"
5913   "#"
5914   [(set_attr "type" "multi")
5915    (set_attr "mode" "<MODE>")])
5916
5917 (define_split
5918   [(set (match_operand:X87MODEF 0 "register_operand" "")
5919         (unsigned_float:X87MODEF
5920           (match_operand:SI 1 "register_operand" "")))
5921    (clobber (match_operand:DI 2 "memory_operand" ""))
5922    (clobber (match_scratch:SI 3 ""))]
5923   "!TARGET_64BIT
5924    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5925    && TARGET_SSE
5926    && reload_completed"
5927   [(set (match_dup 2) (match_dup 1))
5928    (set (match_dup 0)
5929         (float:X87MODEF (match_dup 2)))]
5930   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5931
5932 (define_split
5933   [(set (match_operand:X87MODEF 0 "register_operand" "")
5934         (unsigned_float:X87MODEF
5935           (match_operand:SI 1 "memory_operand" "")))
5936    (clobber (match_operand:DI 2 "memory_operand" ""))
5937    (clobber (match_scratch:SI 3 ""))]
5938   "!TARGET_64BIT
5939    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5940    && TARGET_SSE
5941    && reload_completed"
5942   [(set (match_dup 2) (match_dup 3))
5943    (set (match_dup 0)
5944         (float:X87MODEF (match_dup 2)))]
5945 {
5946   emit_move_insn (operands[3], operands[1]);
5947   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5948 })
5949
5950 (define_expand "floatunssi<mode>2"
5951   [(parallel
5952      [(set (match_operand:X87MODEF 0 "register_operand" "")
5953            (unsigned_float:X87MODEF
5954              (match_operand:SI 1 "nonimmediate_operand" "")))
5955       (clobber (match_dup 2))
5956       (clobber (match_scratch:SI 3 ""))])]
5957   "!TARGET_64BIT
5958    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5959         && TARGET_SSE)
5960        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5961 {
5962   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5963     {
5964       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5965       DONE;
5966     }
5967   else
5968     {
5969       enum ix86_stack_slot slot = (virtuals_instantiated
5970                                    ? SLOT_TEMP
5971                                    : SLOT_VIRTUAL);
5972       operands[2] = assign_386_stack_local (DImode, slot);
5973     }
5974 })
5975
5976 (define_expand "floatunsdisf2"
5977   [(use (match_operand:SF 0 "register_operand" ""))
5978    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5979   "TARGET_64BIT && TARGET_SSE_MATH"
5980   "x86_emit_floatuns (operands); DONE;")
5981
5982 (define_expand "floatunsdidf2"
5983   [(use (match_operand:DF 0 "register_operand" ""))
5984    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5985   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5986    && TARGET_SSE2 && TARGET_SSE_MATH"
5987 {
5988   if (TARGET_64BIT)
5989     x86_emit_floatuns (operands);
5990   else
5991     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5992   DONE;
5993 })
5994 \f
5995 ;; Add instructions
5996
5997 (define_expand "add<mode>3"
5998   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5999         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6000                     (match_operand:SDWIM 2 "<general_operand>" "")))]
6001   ""
6002   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6003
6004 (define_insn_and_split "*add<dwi>3_doubleword"
6005   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6006         (plus:<DWI>
6007           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6008           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6009    (clobber (reg:CC FLAGS_REG))]
6010   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6011   "#"
6012   "reload_completed"
6013   [(parallel [(set (reg:CC FLAGS_REG)
6014                    (unspec:CC [(match_dup 1) (match_dup 2)]
6015                               UNSPEC_ADD_CARRY))
6016               (set (match_dup 0)
6017                    (plus:DWIH (match_dup 1) (match_dup 2)))])
6018    (parallel [(set (match_dup 3)
6019                    (plus:DWIH
6020                      (match_dup 4)
6021                      (plus:DWIH
6022                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6023                        (match_dup 5))))
6024               (clobber (reg:CC FLAGS_REG))])]
6025   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6026
6027 (define_insn "*add<mode>3_cc"
6028   [(set (reg:CC FLAGS_REG)
6029         (unspec:CC
6030           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6031            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
6032           UNSPEC_ADD_CARRY))
6033    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6034         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6035   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6036   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6037   [(set_attr "type" "alu")
6038    (set_attr "mode" "<MODE>")])
6039
6040 (define_insn "addqi3_cc"
6041   [(set (reg:CC FLAGS_REG)
6042         (unspec:CC
6043           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6044            (match_operand:QI 2 "general_operand" "qn,qm")]
6045           UNSPEC_ADD_CARRY))
6046    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6047         (plus:QI (match_dup 1) (match_dup 2)))]
6048   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6049   "add{b}\t{%2, %0|%0, %2}"
6050   [(set_attr "type" "alu")
6051    (set_attr "mode" "QI")])
6052
6053 (define_insn "*lea_1"
6054   [(set (match_operand:DWIH 0 "register_operand" "=r")
6055         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6056   ""
6057   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6058   [(set_attr "type" "lea")
6059    (set_attr "mode" "<MODE>")])
6060
6061 (define_insn "*lea_2"
6062   [(set (match_operand:SI 0 "register_operand" "=r")
6063         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6064   "TARGET_64BIT"
6065   "lea{l}\t{%a1, %0|%0, %a1}"
6066   [(set_attr "type" "lea")
6067    (set_attr "mode" "SI")])
6068
6069 (define_insn "*lea_2_zext"
6070   [(set (match_operand:DI 0 "register_operand" "=r")
6071         (zero_extend:DI
6072           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6073   "TARGET_64BIT"
6074   "lea{l}\t{%a1, %k0|%k0, %a1}"
6075   [(set_attr "type" "lea")
6076    (set_attr "mode" "SI")])
6077
6078 (define_insn "*add<mode>_1"
6079   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6080         (plus:SWI48
6081           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6082           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6083    (clobber (reg:CC FLAGS_REG))]
6084   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6085 {
6086   switch (get_attr_type (insn))
6087     {
6088     case TYPE_LEA:
6089       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6090       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6091
6092     case TYPE_INCDEC:
6093       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6094       if (operands[2] == const1_rtx)
6095         return "inc{<imodesuffix>}\t%0";
6096       else
6097         {
6098           gcc_assert (operands[2] == constm1_rtx);
6099           return "dec{<imodesuffix>}\t%0";
6100         }
6101
6102     default:
6103       /* Use add as much as possible to replace lea for AGU optimization. */
6104       if (which_alternative == 2 && TARGET_OPT_AGU)
6105         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6106         
6107       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6108       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6109         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6110
6111       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6112     }
6113 }
6114   [(set (attr "type")
6115      (cond [(and (eq_attr "alternative" "2") 
6116                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6117               (const_string "lea")
6118             (eq_attr "alternative" "3")
6119               (const_string "lea")
6120             ; Current assemblers are broken and do not allow @GOTOFF in
6121             ; ought but a memory context.
6122             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6123               (const_string "lea")
6124             (match_operand:SWI48 2 "incdec_operand" "")
6125               (const_string "incdec")
6126            ]
6127            (const_string "alu")))
6128    (set (attr "length_immediate")
6129       (if_then_else
6130         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6131         (const_string "1")
6132         (const_string "*")))
6133    (set_attr "mode" "<MODE>")])
6134
6135 ;; It may seem that nonimmediate operand is proper one for operand 1.
6136 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6137 ;; we take care in ix86_binary_operator_ok to not allow two memory
6138 ;; operands so proper swapping will be done in reload.  This allow
6139 ;; patterns constructed from addsi_1 to match.
6140
6141 (define_insn "*addsi_1_zext"
6142   [(set (match_operand:DI 0 "register_operand" "=r,r")
6143         (zero_extend:DI
6144           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6145                    (match_operand:SI 2 "general_operand" "g,li"))))
6146    (clobber (reg:CC FLAGS_REG))]
6147   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6148 {
6149   switch (get_attr_type (insn))
6150     {
6151     case TYPE_LEA:
6152       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6153       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6154
6155     case TYPE_INCDEC:
6156       if (operands[2] == const1_rtx)
6157         return "inc{l}\t%k0";
6158       else
6159         {
6160           gcc_assert (operands[2] == constm1_rtx);
6161           return "dec{l}\t%k0";
6162         }
6163
6164     default:
6165       if (x86_maybe_negate_const_int (&operands[2], SImode))
6166         return "sub{l}\t{%2, %k0|%k0, %2}";
6167
6168       return "add{l}\t{%2, %k0|%k0, %2}";
6169     }
6170 }
6171   [(set (attr "type")
6172      (cond [(eq_attr "alternative" "1")
6173               (const_string "lea")
6174             ; Current assemblers are broken and do not allow @GOTOFF in
6175             ; ought but a memory context.
6176             (match_operand:SI 2 "pic_symbolic_operand" "")
6177               (const_string "lea")
6178             (match_operand:SI 2 "incdec_operand" "")
6179               (const_string "incdec")
6180            ]
6181            (const_string "alu")))
6182    (set (attr "length_immediate")
6183       (if_then_else
6184         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6185         (const_string "1")
6186         (const_string "*")))
6187    (set_attr "mode" "SI")])
6188
6189 (define_insn "*addhi_1"
6190   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6191         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6192                  (match_operand:HI 2 "general_operand" "rn,rm")))
6193    (clobber (reg:CC FLAGS_REG))]
6194   "TARGET_PARTIAL_REG_STALL
6195    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6196 {
6197   switch (get_attr_type (insn))
6198     {
6199     case TYPE_INCDEC:
6200       if (operands[2] == const1_rtx)
6201         return "inc{w}\t%0";
6202       else
6203         {
6204           gcc_assert (operands[2] == constm1_rtx);
6205           return "dec{w}\t%0";
6206         }
6207
6208     default:
6209       if (x86_maybe_negate_const_int (&operands[2], HImode))
6210         return "sub{w}\t{%2, %0|%0, %2}";
6211
6212       return "add{w}\t{%2, %0|%0, %2}";
6213     }
6214 }
6215   [(set (attr "type")
6216      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6217         (const_string "incdec")
6218         (const_string "alu")))
6219    (set (attr "length_immediate")
6220       (if_then_else
6221         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6222         (const_string "1")
6223         (const_string "*")))
6224    (set_attr "mode" "HI")])
6225
6226 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6227 ;; type optimizations enabled by define-splits.  This is not important
6228 ;; for PII, and in fact harmful because of partial register stalls.
6229
6230 (define_insn "*addhi_1_lea"
6231   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6232         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6233                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6234    (clobber (reg:CC FLAGS_REG))]
6235   "!TARGET_PARTIAL_REG_STALL
6236    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6237 {
6238   switch (get_attr_type (insn))
6239     {
6240     case TYPE_LEA:
6241       return "#";
6242     case TYPE_INCDEC:
6243       if (operands[2] == const1_rtx)
6244         return "inc{w}\t%0";
6245       else
6246         {
6247           gcc_assert (operands[2] == constm1_rtx);
6248           return "dec{w}\t%0";
6249         }
6250
6251     default:
6252       if (x86_maybe_negate_const_int (&operands[2], HImode))
6253         return "sub{w}\t{%2, %0|%0, %2}";
6254
6255       return "add{w}\t{%2, %0|%0, %2}";
6256     }
6257 }
6258   [(set (attr "type")
6259      (if_then_else (eq_attr "alternative" "2")
6260         (const_string "lea")
6261         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6262            (const_string "incdec")
6263            (const_string "alu"))))
6264    (set (attr "length_immediate")
6265       (if_then_else
6266         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6267         (const_string "1")
6268         (const_string "*")))
6269    (set_attr "mode" "HI,HI,SI")])
6270
6271 (define_insn "*addqi_1"
6272   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6273         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6274                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6275    (clobber (reg:CC FLAGS_REG))]
6276   "TARGET_PARTIAL_REG_STALL
6277    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6278 {
6279   int widen = (which_alternative == 2);
6280   switch (get_attr_type (insn))
6281     {
6282     case TYPE_INCDEC:
6283       if (operands[2] == const1_rtx)
6284         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6285       else
6286         {
6287           gcc_assert (operands[2] == constm1_rtx);
6288           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6289         }
6290
6291     default:
6292       if (x86_maybe_negate_const_int (&operands[2], QImode))
6293         {
6294           if (widen)
6295             return "sub{l}\t{%2, %k0|%k0, %2}";
6296           else
6297             return "sub{b}\t{%2, %0|%0, %2}";
6298         }
6299       if (widen)
6300         return "add{l}\t{%k2, %k0|%k0, %k2}";
6301       else
6302         return "add{b}\t{%2, %0|%0, %2}";
6303     }
6304 }
6305   [(set (attr "type")
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")])
6315
6316 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6317 (define_insn "*addqi_1_lea"
6318   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6319         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6320                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6321    (clobber (reg:CC FLAGS_REG))]
6322   "!TARGET_PARTIAL_REG_STALL
6323    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6324 {
6325   int widen = (which_alternative == 2);
6326   switch (get_attr_type (insn))
6327     {
6328     case TYPE_LEA:
6329       return "#";
6330     case TYPE_INCDEC:
6331       if (operands[2] == const1_rtx)
6332         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6333       else
6334         {
6335           gcc_assert (operands[2] == constm1_rtx);
6336           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6337         }
6338
6339     default:
6340       if (x86_maybe_negate_const_int (&operands[2], QImode))
6341         {
6342           if (widen)
6343             return "sub{l}\t{%2, %k0|%k0, %2}";
6344           else
6345             return "sub{b}\t{%2, %0|%0, %2}";
6346         }
6347       if (widen)
6348         return "add{l}\t{%k2, %k0|%k0, %k2}";
6349       else
6350         return "add{b}\t{%2, %0|%0, %2}";
6351     }
6352 }
6353   [(set (attr "type")
6354      (if_then_else (eq_attr "alternative" "3")
6355         (const_string "lea")
6356         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6357            (const_string "incdec")
6358            (const_string "alu"))))
6359    (set (attr "length_immediate")
6360       (if_then_else
6361         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6362         (const_string "1")
6363         (const_string "*")))
6364    (set_attr "mode" "QI,QI,SI,SI")])
6365
6366 (define_insn "*addqi_1_slp"
6367   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6368         (plus:QI (match_dup 0)
6369                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6370    (clobber (reg:CC FLAGS_REG))]
6371   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6372    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6373 {
6374   switch (get_attr_type (insn))
6375     {
6376     case TYPE_INCDEC:
6377       if (operands[1] == const1_rtx)
6378         return "inc{b}\t%0";
6379       else
6380         {
6381           gcc_assert (operands[1] == constm1_rtx);
6382           return "dec{b}\t%0";
6383         }
6384
6385     default:
6386       if (x86_maybe_negate_const_int (&operands[1], QImode))
6387         return "sub{b}\t{%1, %0|%0, %1}";
6388
6389       return "add{b}\t{%1, %0|%0, %1}";
6390     }
6391 }
6392   [(set (attr "type")
6393      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6394         (const_string "incdec")
6395         (const_string "alu1")))
6396    (set (attr "memory")
6397      (if_then_else (match_operand 1 "memory_operand" "")
6398         (const_string "load")
6399         (const_string "none")))
6400    (set_attr "mode" "QI")])
6401
6402 (define_insn "*add<mode>_2"
6403   [(set (reg FLAGS_REG)
6404         (compare
6405           (plus:SWI48
6406             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6407             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6408           (const_int 0)))
6409    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6410         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6411   "ix86_match_ccmode (insn, CCGOCmode)
6412    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6413    /* Current assemblers are broken and do not allow @GOTOFF in
6414       ought but a memory context.  */
6415    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6416 {
6417   switch (get_attr_type (insn))
6418     {
6419     case TYPE_INCDEC:
6420       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6421       if (operands[2] == const1_rtx)
6422         return "inc{<imodesuffix>}\t%0";
6423       else
6424         {
6425           gcc_assert (operands[2] == constm1_rtx);
6426           return "dec{<imodesuffix>}\t%0";
6427         }
6428
6429     default:
6430       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6431       /* ???? In DImode, we ought to handle there the 32bit case too
6432          - do we need new constraint?  */
6433       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6434         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6435
6436       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6437     }
6438 }
6439   [(set (attr "type")
6440      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6441         (const_string "incdec")
6442         (const_string "alu")))
6443    (set (attr "length_immediate")
6444       (if_then_else
6445         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6446         (const_string "1")
6447         (const_string "*")))
6448    (set_attr "mode" "<MODE>")])
6449
6450 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6451 (define_insn "*addsi_2_zext"
6452   [(set (reg FLAGS_REG)
6453         (compare
6454           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6455                    (match_operand:SI 2 "general_operand" "g"))
6456           (const_int 0)))
6457    (set (match_operand:DI 0 "register_operand" "=r")
6458         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6459   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6460    && ix86_binary_operator_ok (PLUS, SImode, operands)
6461    /* Current assemblers are broken and do not allow @GOTOFF in
6462       ought but a memory context.  */
6463    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6464 {
6465   switch (get_attr_type (insn))
6466     {
6467     case TYPE_INCDEC:
6468       if (operands[2] == const1_rtx)
6469         return "inc{l}\t%k0";
6470       else
6471         {
6472           gcc_assert (operands[2] == constm1_rtx);
6473           return "dec{l}\t%k0";
6474         }
6475
6476     default:
6477       if (x86_maybe_negate_const_int (&operands[2], SImode))
6478         return "sub{l}\t{%2, %k0|%k0, %2}";
6479
6480       return "add{l}\t{%2, %k0|%k0, %2}";
6481     }
6482 }
6483   [(set (attr "type")
6484      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6485         (const_string "incdec")
6486         (const_string "alu")))
6487    (set (attr "length_immediate")
6488       (if_then_else
6489         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6490         (const_string "1")
6491         (const_string "*")))
6492    (set_attr "mode" "SI")])
6493
6494 (define_insn "*addhi_2"
6495   [(set (reg FLAGS_REG)
6496         (compare
6497           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6498                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6499           (const_int 0)))
6500    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6501         (plus:HI (match_dup 1) (match_dup 2)))]
6502   "ix86_match_ccmode (insn, CCGOCmode)
6503    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6504 {
6505   switch (get_attr_type (insn))
6506     {
6507     case TYPE_INCDEC:
6508       if (operands[2] == const1_rtx)
6509         return "inc{w}\t%0";
6510       else
6511         {
6512           gcc_assert (operands[2] == constm1_rtx);
6513           return "dec{w}\t%0";
6514         }
6515
6516     default:
6517       if (x86_maybe_negate_const_int (&operands[2], HImode))
6518         return "sub{w}\t{%2, %0|%0, %2}";
6519
6520       return "add{w}\t{%2, %0|%0, %2}";
6521     }
6522 }
6523   [(set (attr "type")
6524      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6525         (const_string "incdec")
6526         (const_string "alu")))
6527    (set (attr "length_immediate")
6528       (if_then_else
6529         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6530         (const_string "1")
6531         (const_string "*")))
6532    (set_attr "mode" "HI")])
6533
6534 (define_insn "*addqi_2"
6535   [(set (reg FLAGS_REG)
6536         (compare
6537           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6538                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6539           (const_int 0)))
6540    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6541         (plus:QI (match_dup 1) (match_dup 2)))]
6542   "ix86_match_ccmode (insn, CCGOCmode)
6543    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6544 {
6545   switch (get_attr_type (insn))
6546     {
6547     case TYPE_INCDEC:
6548       if (operands[2] == const1_rtx)
6549         return "inc{b}\t%0";
6550       else
6551         {
6552           gcc_assert (operands[2] == constm1_rtx
6553                       || (CONST_INT_P (operands[2])
6554                           && INTVAL (operands[2]) == 255));
6555           return "dec{b}\t%0";
6556         }
6557
6558     default:
6559       if (x86_maybe_negate_const_int (&operands[2], QImode))
6560         return "sub{b}\t{%2, %0|%0, %2}";
6561
6562       return "add{b}\t{%2, %0|%0, %2}";
6563     }
6564 }
6565   [(set (attr "type")
6566      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6567         (const_string "incdec")
6568         (const_string "alu")))
6569    (set_attr "mode" "QI")])
6570
6571 (define_insn "*add<mode>_3"
6572   [(set (reg FLAGS_REG)
6573         (compare
6574           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6575           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6576    (clobber (match_scratch:SWI48 0 "=r"))]
6577   "ix86_match_ccmode (insn, CCZmode)
6578    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6579    /* Current assemblers are broken and do not allow @GOTOFF in
6580       ought but a memory context.  */
6581    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6582 {
6583   switch (get_attr_type (insn))
6584     {
6585     case TYPE_INCDEC:
6586       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6587       if (operands[2] == const1_rtx)
6588         return "inc{<imodesuffix>}\t%0";
6589       else
6590         {
6591           gcc_assert (operands[2] == constm1_rtx);
6592           return "dec{<imodesuffix>}\t%0";
6593         }
6594
6595     default:
6596       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6597       /* ???? In DImode, we ought to handle there the 32bit case too
6598          - do we need new constraint?  */
6599       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6600         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6601
6602       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6603     }
6604 }
6605   [(set (attr "type")
6606      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6607         (const_string "incdec")
6608         (const_string "alu")))
6609    (set (attr "length_immediate")
6610       (if_then_else
6611         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6612         (const_string "1")
6613         (const_string "*")))
6614    (set_attr "mode" "<MODE>")])
6615
6616 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6617 (define_insn "*addsi_3_zext"
6618   [(set (reg FLAGS_REG)
6619         (compare
6620           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6621           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6622    (set (match_operand:DI 0 "register_operand" "=r")
6623         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6624   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6625    && ix86_binary_operator_ok (PLUS, SImode, operands)
6626    /* Current assemblers are broken and do not allow @GOTOFF in
6627       ought but a memory context.  */
6628    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6629 {
6630   switch (get_attr_type (insn))
6631     {
6632     case TYPE_INCDEC:
6633       if (operands[2] == const1_rtx)
6634         return "inc{l}\t%k0";
6635       else
6636         {
6637           gcc_assert (operands[2] == constm1_rtx);
6638           return "dec{l}\t%k0";
6639         }
6640
6641     default:
6642       if (x86_maybe_negate_const_int (&operands[2], SImode))
6643         return "sub{l}\t{%2, %k0|%k0, %2}";
6644
6645       return "add{l}\t{%2, %k0|%k0, %2}";
6646     }
6647 }
6648   [(set (attr "type")
6649      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6650         (const_string "incdec")
6651         (const_string "alu")))
6652    (set (attr "length_immediate")
6653       (if_then_else
6654         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6655         (const_string "1")
6656         (const_string "*")))
6657    (set_attr "mode" "SI")])
6658
6659 (define_insn "*addhi_3"
6660   [(set (reg FLAGS_REG)
6661         (compare
6662           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6663           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6664    (clobber (match_scratch:HI 0 "=r"))]
6665   "ix86_match_ccmode (insn, CCZmode)
6666    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6667 {
6668   switch (get_attr_type (insn))
6669     {
6670     case TYPE_INCDEC:
6671       if (operands[2] == const1_rtx)
6672         return "inc{w}\t%0";
6673       else
6674         {
6675           gcc_assert (operands[2] == constm1_rtx);
6676           return "dec{w}\t%0";
6677         }
6678
6679     default:
6680       if (x86_maybe_negate_const_int (&operands[2], HImode))
6681         return "sub{w}\t{%2, %0|%0, %2}";
6682
6683       return "add{w}\t{%2, %0|%0, %2}";
6684     }
6685 }
6686   [(set (attr "type")
6687      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6688         (const_string "incdec")
6689         (const_string "alu")))
6690    (set (attr "length_immediate")
6691       (if_then_else
6692         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6693         (const_string "1")
6694         (const_string "*")))
6695    (set_attr "mode" "HI")])
6696
6697 (define_insn "*addqi_3"
6698   [(set (reg FLAGS_REG)
6699         (compare
6700           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6701           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6702    (clobber (match_scratch:QI 0 "=q"))]
6703   "ix86_match_ccmode (insn, CCZmode)
6704    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6705 {
6706   switch (get_attr_type (insn))
6707     {
6708     case TYPE_INCDEC:
6709       if (operands[2] == const1_rtx)
6710         return "inc{b}\t%0";
6711       else
6712         {
6713           gcc_assert (operands[2] == constm1_rtx
6714                       || (CONST_INT_P (operands[2])
6715                           && INTVAL (operands[2]) == 255));
6716           return "dec{b}\t%0";
6717         }
6718
6719     default:
6720       if (x86_maybe_negate_const_int (&operands[2], QImode))
6721         return "sub{b}\t{%2, %0|%0, %2}";
6722
6723       return "add{b}\t{%2, %0|%0, %2}";
6724     }
6725 }
6726   [(set (attr "type")
6727      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6728         (const_string "incdec")
6729         (const_string "alu")))
6730    (set_attr "mode" "QI")])
6731
6732 ; For comparisons against 1, -1 and 128, we may generate better code
6733 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6734 ; is matched then.  We can't accept general immediate, because for
6735 ; case of overflows,  the result is messed up.
6736 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6737 ; only for comparisons not depending on it.
6738
6739 (define_insn "*adddi_4"
6740   [(set (reg FLAGS_REG)
6741         (compare
6742           (match_operand:DI 1 "nonimmediate_operand" "0")
6743           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6744    (clobber (match_scratch:DI 0 "=rm"))]
6745   "TARGET_64BIT
6746    && ix86_match_ccmode (insn, CCGCmode)"
6747 {
6748   switch (get_attr_type (insn))
6749     {
6750     case TYPE_INCDEC:
6751       if (operands[2] == constm1_rtx)
6752         return "inc{q}\t%0";
6753       else
6754         {
6755           gcc_assert (operands[2] == const1_rtx);
6756           return "dec{q}\t%0";
6757         }
6758
6759     default:
6760       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6761       if (x86_maybe_negate_const_int (&operands[2], DImode))
6762         return "add{q}\t{%2, %0|%0, %2}";
6763
6764       return "sub{q}\t{%2, %0|%0, %2}";
6765     }
6766 }
6767   [(set (attr "type")
6768      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6769         (const_string "incdec")
6770         (const_string "alu")))
6771    (set (attr "length_immediate")
6772       (if_then_else
6773         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6774         (const_string "1")
6775         (const_string "*")))
6776    (set_attr "mode" "DI")])
6777
6778 ; For comparisons against 1, -1 and 128, we may generate better code
6779 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6780 ; is matched then.  We can't accept general immediate, because for
6781 ; case of overflows,  the result is messed up.
6782 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6783 ; only for comparisons not depending on it.
6784
6785 (define_insn "*addsi_4"
6786   [(set (reg FLAGS_REG)
6787         (compare
6788           (match_operand:SI 1 "nonimmediate_operand" "0")
6789           (match_operand:SI 2 "const_int_operand" "n")))
6790    (clobber (match_scratch:SI 0 "=rm"))]
6791   "ix86_match_ccmode (insn, CCGCmode)"
6792 {
6793   switch (get_attr_type (insn))
6794     {
6795     case TYPE_INCDEC:
6796       if (operands[2] == constm1_rtx)
6797         return "inc{l}\t%0";
6798       else
6799         {
6800           gcc_assert (operands[2] == const1_rtx);
6801           return "dec{l}\t%0";
6802         }
6803
6804     default:
6805       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6806       if (x86_maybe_negate_const_int (&operands[2], SImode))
6807         return "add{l}\t{%2, %0|%0, %2}";
6808
6809       return "sub{l}\t{%2, %0|%0, %2}";
6810     }
6811 }
6812   [(set (attr "type")
6813      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6814         (const_string "incdec")
6815         (const_string "alu")))
6816    (set (attr "length_immediate")
6817       (if_then_else
6818         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6819         (const_string "1")
6820         (const_string "*")))
6821    (set_attr "mode" "SI")])
6822
6823 ; See comments above addsi_4 for details.
6824
6825 (define_insn "*addhi_4"
6826   [(set (reg FLAGS_REG)
6827         (compare
6828           (match_operand:HI 1 "nonimmediate_operand" "0")
6829           (match_operand:HI 2 "const_int_operand" "n")))
6830    (clobber (match_scratch:HI 0 "=rm"))]
6831   "ix86_match_ccmode (insn, CCGCmode)"
6832 {
6833   switch (get_attr_type (insn))
6834     {
6835     case TYPE_INCDEC:
6836       if (operands[2] == constm1_rtx)
6837         return "inc{w}\t%0";
6838       else
6839         {
6840           gcc_assert (operands[2] == const1_rtx);
6841           return "dec{w}\t%0";
6842         }
6843
6844     default:
6845       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6846       if (x86_maybe_negate_const_int (&operands[2], HImode))
6847         return "add{w}\t{%2, %0|%0, %2}";
6848
6849       return "sub{w}\t{%2, %0|%0, %2}";
6850     }
6851 }
6852   [(set (attr "type")
6853      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6854         (const_string "incdec")
6855         (const_string "alu")))
6856    (set (attr "length_immediate")
6857       (if_then_else
6858         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6859         (const_string "1")
6860         (const_string "*")))
6861    (set_attr "mode" "HI")])
6862
6863 ; See comments above addsi_4 for details.
6864
6865 (define_insn "*addqi_4"
6866   [(set (reg FLAGS_REG)
6867         (compare
6868           (match_operand:QI 1 "nonimmediate_operand" "0")
6869           (match_operand:QI 2 "const_int_operand" "n")))
6870    (clobber (match_scratch:QI 0 "=qm"))]
6871   "ix86_match_ccmode (insn, CCGCmode)"
6872 {
6873   switch (get_attr_type (insn))
6874     {
6875     case TYPE_INCDEC:
6876       if (operands[2] == constm1_rtx
6877           || (CONST_INT_P (operands[2])
6878               && INTVAL (operands[2]) == 255))
6879         return "inc{b}\t%0";
6880       else
6881         {
6882           gcc_assert (operands[2] == const1_rtx);
6883           return "dec{b}\t%0";
6884         }
6885
6886     default:
6887       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6888       if (x86_maybe_negate_const_int (&operands[2], QImode))
6889         return "add{b}\t{%2, %0|%0, %2}";
6890
6891       return "sub{b}\t{%2, %0|%0, %2}";
6892     }
6893 }
6894   [(set (attr "type")
6895      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6896         (const_string "incdec")
6897         (const_string "alu")))
6898    (set_attr "mode" "QI")])
6899
6900 (define_insn "*add<mode>_5"
6901   [(set (reg FLAGS_REG)
6902         (compare
6903           (plus:SWI48
6904             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6905             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6906           (const_int 0)))
6907    (clobber (match_scratch:SWI48 0 "=r"))]
6908   "ix86_match_ccmode (insn, CCGOCmode)
6909    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6910    /* Current assemblers are broken and do not allow @GOTOFF in
6911       ought but a memory context.  */
6912    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6913 {
6914   switch (get_attr_type (insn))
6915     {
6916     case TYPE_INCDEC:
6917       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6918       if (operands[2] == const1_rtx)
6919         return "inc{<imodesuffix>}\t%0";
6920       else
6921         {
6922           gcc_assert (operands[2] == constm1_rtx);
6923           return "dec{<imodesuffix>}\t%0";
6924         }
6925
6926     default:
6927       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6928       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6929         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6930
6931       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6932     }
6933 }
6934   [(set (attr "type")
6935      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6936         (const_string "incdec")
6937         (const_string "alu")))
6938    (set (attr "length_immediate")
6939       (if_then_else
6940         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6941         (const_string "1")
6942         (const_string "*")))
6943    (set_attr "mode" "<MODE>")])
6944
6945 (define_insn "*addhi_5"
6946   [(set (reg FLAGS_REG)
6947         (compare
6948           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6949                    (match_operand:HI 2 "general_operand" "rmn"))
6950           (const_int 0)))
6951    (clobber (match_scratch:HI 0 "=r"))]
6952   "ix86_match_ccmode (insn, CCGOCmode)
6953    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6954 {
6955   switch (get_attr_type (insn))
6956     {
6957     case TYPE_INCDEC:
6958       if (operands[2] == const1_rtx)
6959         return "inc{w}\t%0";
6960       else
6961         {
6962           gcc_assert (operands[2] == constm1_rtx);
6963           return "dec{w}\t%0";
6964         }
6965
6966     default:
6967       if (x86_maybe_negate_const_int (&operands[2], HImode))
6968         return "sub{w}\t{%2, %0|%0, %2}";
6969
6970       return "add{w}\t{%2, %0|%0, %2}";
6971     }
6972 }
6973   [(set (attr "type")
6974      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6975         (const_string "incdec")
6976         (const_string "alu")))
6977    (set (attr "length_immediate")
6978       (if_then_else
6979         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6980         (const_string "1")
6981         (const_string "*")))
6982    (set_attr "mode" "HI")])
6983
6984 (define_insn "*addqi_5"
6985   [(set (reg FLAGS_REG)
6986         (compare
6987           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6988                    (match_operand:QI 2 "general_operand" "qmn"))
6989           (const_int 0)))
6990    (clobber (match_scratch:QI 0 "=q"))]
6991   "ix86_match_ccmode (insn, CCGOCmode)
6992    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6993 {
6994   switch (get_attr_type (insn))
6995     {
6996     case TYPE_INCDEC:
6997       if (operands[2] == const1_rtx)
6998         return "inc{b}\t%0";
6999       else
7000         {
7001           gcc_assert (operands[2] == constm1_rtx
7002                       || (CONST_INT_P (operands[2])
7003                           && INTVAL (operands[2]) == 255));
7004           return "dec{b}\t%0";
7005         }
7006
7007     default:
7008       if (x86_maybe_negate_const_int (&operands[2], QImode))
7009         return "sub{b}\t{%2, %0|%0, %2}";
7010
7011       return "add{b}\t{%2, %0|%0, %2}";
7012     }
7013 }
7014   [(set (attr "type")
7015      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7016         (const_string "incdec")
7017         (const_string "alu")))
7018    (set_attr "mode" "QI")])
7019
7020 (define_insn "*addqi_ext_1_rex64"
7021   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7022                          (const_int 8)
7023                          (const_int 8))
7024         (plus:SI
7025           (zero_extract:SI
7026             (match_operand 1 "ext_register_operand" "0")
7027             (const_int 8)
7028             (const_int 8))
7029           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7030    (clobber (reg:CC FLAGS_REG))]
7031   "TARGET_64BIT"
7032 {
7033   switch (get_attr_type (insn))
7034     {
7035     case TYPE_INCDEC:
7036       if (operands[2] == const1_rtx)
7037         return "inc{b}\t%h0";
7038       else
7039         {
7040           gcc_assert (operands[2] == constm1_rtx
7041                       || (CONST_INT_P (operands[2])
7042                           && INTVAL (operands[2]) == 255));
7043           return "dec{b}\t%h0";
7044         }
7045
7046     default:
7047       return "add{b}\t{%2, %h0|%h0, %2}";
7048     }
7049 }
7050   [(set (attr "type")
7051      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7052         (const_string "incdec")
7053         (const_string "alu")))
7054    (set_attr "modrm" "1")
7055    (set_attr "mode" "QI")])
7056
7057 (define_insn "addqi_ext_1"
7058   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7059                          (const_int 8)
7060                          (const_int 8))
7061         (plus:SI
7062           (zero_extract:SI
7063             (match_operand 1 "ext_register_operand" "0")
7064             (const_int 8)
7065             (const_int 8))
7066           (match_operand:QI 2 "general_operand" "Qmn")))
7067    (clobber (reg:CC FLAGS_REG))]
7068   "!TARGET_64BIT"
7069 {
7070   switch (get_attr_type (insn))
7071     {
7072     case TYPE_INCDEC:
7073       if (operands[2] == const1_rtx)
7074         return "inc{b}\t%h0";
7075       else
7076         {
7077           gcc_assert (operands[2] == constm1_rtx
7078                       || (CONST_INT_P (operands[2])
7079                           && INTVAL (operands[2]) == 255));
7080           return "dec{b}\t%h0";
7081         }
7082
7083     default:
7084       return "add{b}\t{%2, %h0|%h0, %2}";
7085     }
7086 }
7087   [(set (attr "type")
7088      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7089         (const_string "incdec")
7090         (const_string "alu")))
7091    (set_attr "modrm" "1")
7092    (set_attr "mode" "QI")])
7093
7094 (define_insn "*addqi_ext_2"
7095   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7096                          (const_int 8)
7097                          (const_int 8))
7098         (plus:SI
7099           (zero_extract:SI
7100             (match_operand 1 "ext_register_operand" "%0")
7101             (const_int 8)
7102             (const_int 8))
7103           (zero_extract:SI
7104             (match_operand 2 "ext_register_operand" "Q")
7105             (const_int 8)
7106             (const_int 8))))
7107    (clobber (reg:CC FLAGS_REG))]
7108   ""
7109   "add{b}\t{%h2, %h0|%h0, %h2}"
7110   [(set_attr "type" "alu")
7111    (set_attr "mode" "QI")])
7112
7113 ;; The lea patterns for non-Pmodes needs to be matched by
7114 ;; several insns converted to real lea by splitters.
7115
7116 (define_insn_and_split "*lea_general_1"
7117   [(set (match_operand 0 "register_operand" "=r")
7118         (plus (plus (match_operand 1 "index_register_operand" "l")
7119                     (match_operand 2 "register_operand" "r"))
7120               (match_operand 3 "immediate_operand" "i")))]
7121   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7122     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7123    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7124    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7125    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7126    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7127        || GET_MODE (operands[3]) == VOIDmode)"
7128   "#"
7129   "&& reload_completed"
7130   [(const_int 0)]
7131 {
7132   rtx pat;
7133   operands[0] = gen_lowpart (SImode, operands[0]);
7134   operands[1] = gen_lowpart (Pmode, operands[1]);
7135   operands[2] = gen_lowpart (Pmode, operands[2]);
7136   operands[3] = gen_lowpart (Pmode, operands[3]);
7137   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7138                       operands[3]);
7139   if (Pmode != SImode)
7140     pat = gen_rtx_SUBREG (SImode, pat, 0);
7141   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7142   DONE;
7143 }
7144   [(set_attr "type" "lea")
7145    (set_attr "mode" "SI")])
7146
7147 (define_insn_and_split "*lea_general_1_zext"
7148   [(set (match_operand:DI 0 "register_operand" "=r")
7149         (zero_extend:DI
7150           (plus:SI (plus:SI
7151                      (match_operand:SI 1 "index_register_operand" "l")
7152                      (match_operand:SI 2 "register_operand" "r"))
7153                    (match_operand:SI 3 "immediate_operand" "i"))))]
7154   "TARGET_64BIT"
7155   "#"
7156   "&& reload_completed"
7157   [(set (match_dup 0)
7158         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7159                                                      (match_dup 2))
7160                                             (match_dup 3)) 0)))]
7161 {
7162   operands[1] = gen_lowpart (Pmode, operands[1]);
7163   operands[2] = gen_lowpart (Pmode, operands[2]);
7164   operands[3] = gen_lowpart (Pmode, operands[3]);
7165 }
7166   [(set_attr "type" "lea")
7167    (set_attr "mode" "SI")])
7168
7169 (define_insn_and_split "*lea_general_2"
7170   [(set (match_operand 0 "register_operand" "=r")
7171         (plus (mult (match_operand 1 "index_register_operand" "l")
7172                     (match_operand 2 "const248_operand" "i"))
7173               (match_operand 3 "nonmemory_operand" "ri")))]
7174   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7175     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7176    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7177    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7178    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7179        || GET_MODE (operands[3]) == VOIDmode)"
7180   "#"
7181   "&& reload_completed"
7182   [(const_int 0)]
7183 {
7184   rtx pat;
7185   operands[0] = gen_lowpart (SImode, operands[0]);
7186   operands[1] = gen_lowpart (Pmode, operands[1]);
7187   operands[3] = gen_lowpart (Pmode, operands[3]);
7188   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7189                       operands[3]);
7190   if (Pmode != SImode)
7191     pat = gen_rtx_SUBREG (SImode, pat, 0);
7192   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7193   DONE;
7194 }
7195   [(set_attr "type" "lea")
7196    (set_attr "mode" "SI")])
7197
7198 (define_insn_and_split "*lea_general_2_zext"
7199   [(set (match_operand:DI 0 "register_operand" "=r")
7200         (zero_extend:DI
7201           (plus:SI (mult:SI
7202                      (match_operand:SI 1 "index_register_operand" "l")
7203                      (match_operand:SI 2 "const248_operand" "n"))
7204                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7205   "TARGET_64BIT"
7206   "#"
7207   "&& reload_completed"
7208   [(set (match_dup 0)
7209         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7210                                                      (match_dup 2))
7211                                             (match_dup 3)) 0)))]
7212 {
7213   operands[1] = gen_lowpart (Pmode, operands[1]);
7214   operands[3] = gen_lowpart (Pmode, operands[3]);
7215 }
7216   [(set_attr "type" "lea")
7217    (set_attr "mode" "SI")])
7218
7219 (define_insn_and_split "*lea_general_3"
7220   [(set (match_operand 0 "register_operand" "=r")
7221         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7222                           (match_operand 2 "const248_operand" "i"))
7223                     (match_operand 3 "register_operand" "r"))
7224               (match_operand 4 "immediate_operand" "i")))]
7225   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7226     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7227    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7228    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7229    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7230   "#"
7231   "&& reload_completed"
7232   [(const_int 0)]
7233 {
7234   rtx pat;
7235   operands[0] = gen_lowpart (SImode, operands[0]);
7236   operands[1] = gen_lowpart (Pmode, operands[1]);
7237   operands[3] = gen_lowpart (Pmode, operands[3]);
7238   operands[4] = gen_lowpart (Pmode, operands[4]);
7239   pat = gen_rtx_PLUS (Pmode,
7240                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7241                                                          operands[2]),
7242                                     operands[3]),
7243                       operands[4]);
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_3_zext"
7253   [(set (match_operand:DI 0 "register_operand" "=r")
7254         (zero_extend:DI
7255           (plus:SI (plus:SI
7256                      (mult:SI
7257                        (match_operand:SI 1 "index_register_operand" "l")
7258                        (match_operand:SI 2 "const248_operand" "n"))
7259                      (match_operand:SI 3 "register_operand" "r"))
7260                    (match_operand:SI 4 "immediate_operand" "i"))))]
7261   "TARGET_64BIT"
7262   "#"
7263   "&& reload_completed"
7264   [(set (match_dup 0)
7265         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7266                                                               (match_dup 2))
7267                                                      (match_dup 3))
7268                                             (match_dup 4)) 0)))]
7269 {
7270   operands[1] = gen_lowpart (Pmode, operands[1]);
7271   operands[3] = gen_lowpart (Pmode, operands[3]);
7272   operands[4] = gen_lowpart (Pmode, operands[4]);
7273 }
7274   [(set_attr "type" "lea")
7275    (set_attr "mode" "SI")])
7276
7277 ;; Convert lea to the lea pattern to avoid flags dependency.
7278 (define_split
7279   [(set (match_operand:DI 0 "register_operand" "")
7280         (plus:DI (match_operand:DI 1 "register_operand" "")
7281                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7282    (clobber (reg:CC FLAGS_REG))]
7283   "TARGET_64BIT && reload_completed 
7284    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7285   [(set (match_dup 0)
7286         (plus:DI (match_dup 1)
7287                  (match_dup 2)))]
7288   "")
7289
7290 ;; Convert lea to the lea pattern to avoid flags dependency.
7291 (define_split
7292   [(set (match_operand 0 "register_operand" "")
7293         (plus (match_operand 1 "register_operand" "")
7294               (match_operand 2 "nonmemory_operand" "")))
7295    (clobber (reg:CC FLAGS_REG))]
7296   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7297   [(const_int 0)]
7298 {
7299   rtx pat;
7300   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7301      may confuse gen_lowpart.  */
7302   if (GET_MODE (operands[0]) != Pmode)
7303     {
7304       operands[1] = gen_lowpart (Pmode, operands[1]);
7305       operands[2] = gen_lowpart (Pmode, operands[2]);
7306     }
7307   operands[0] = gen_lowpart (SImode, operands[0]);
7308   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7309   if (Pmode != SImode)
7310     pat = gen_rtx_SUBREG (SImode, pat, 0);
7311   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7312   DONE;
7313 })
7314
7315 ;; Convert lea to the lea pattern to avoid flags dependency.
7316 (define_split
7317   [(set (match_operand:DI 0 "register_operand" "")
7318         (zero_extend:DI
7319           (plus:SI (match_operand:SI 1 "register_operand" "")
7320                    (match_operand:SI 2 "nonmemory_operand" ""))))
7321    (clobber (reg:CC FLAGS_REG))]
7322   "TARGET_64BIT && reload_completed
7323    && true_regnum (operands[0]) != true_regnum (operands[1])"
7324   [(set (match_dup 0)
7325         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7326 {
7327   operands[1] = gen_lowpart (Pmode, operands[1]);
7328   operands[2] = gen_lowpart (Pmode, operands[2]);
7329 })
7330 \f
7331 ;; Subtract instructions
7332
7333 (define_expand "sub<mode>3"
7334   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7335         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7336                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7337   ""
7338   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7339
7340 (define_insn_and_split "*sub<dwi>3_doubleword"
7341   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7342         (minus:<DWI>
7343           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7344           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7345    (clobber (reg:CC FLAGS_REG))]
7346   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7347   "#"
7348   "reload_completed"
7349   [(parallel [(set (reg:CC FLAGS_REG)
7350                    (compare:CC (match_dup 1) (match_dup 2)))
7351               (set (match_dup 0)
7352                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7353    (parallel [(set (match_dup 3)
7354                    (minus:DWIH
7355                      (match_dup 4)
7356                      (plus:DWIH
7357                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7358                        (match_dup 5))))
7359               (clobber (reg:CC FLAGS_REG))])]
7360   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7361
7362 (define_insn "*sub<mode>_1"
7363   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7364         (minus:SWI
7365           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7366           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7367    (clobber (reg:CC FLAGS_REG))]
7368   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7369   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7370   [(set_attr "type" "alu")
7371    (set_attr "mode" "<MODE>")])
7372
7373 (define_insn "*subsi_1_zext"
7374   [(set (match_operand:DI 0 "register_operand" "=r")
7375         (zero_extend:DI
7376           (minus:SI (match_operand:SI 1 "register_operand" "0")
7377                     (match_operand:SI 2 "general_operand" "g"))))
7378    (clobber (reg:CC FLAGS_REG))]
7379   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7380   "sub{l}\t{%2, %k0|%k0, %2}"
7381   [(set_attr "type" "alu")
7382    (set_attr "mode" "SI")])
7383
7384 (define_insn "*subqi_1_slp"
7385   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7386         (minus:QI (match_dup 0)
7387                   (match_operand:QI 1 "general_operand" "qn,qm")))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7390    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7391   "sub{b}\t{%1, %0|%0, %1}"
7392   [(set_attr "type" "alu1")
7393    (set_attr "mode" "QI")])
7394
7395 (define_insn "*sub<mode>_2"
7396   [(set (reg FLAGS_REG)
7397         (compare
7398           (minus:SWI
7399             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7400             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7401           (const_int 0)))
7402    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7403         (minus:SWI (match_dup 1) (match_dup 2)))]
7404   "ix86_match_ccmode (insn, CCGOCmode)
7405    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7406   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7407   [(set_attr "type" "alu")
7408    (set_attr "mode" "<MODE>")])
7409
7410 (define_insn "*subsi_2_zext"
7411   [(set (reg FLAGS_REG)
7412         (compare
7413           (minus:SI (match_operand:SI 1 "register_operand" "0")
7414                     (match_operand:SI 2 "general_operand" "g"))
7415           (const_int 0)))
7416    (set (match_operand:DI 0 "register_operand" "=r")
7417         (zero_extend:DI
7418           (minus:SI (match_dup 1)
7419                     (match_dup 2))))]
7420   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7421    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7422   "sub{l}\t{%2, %k0|%k0, %2}"
7423   [(set_attr "type" "alu")
7424    (set_attr "mode" "SI")])
7425
7426 (define_insn "*sub<mode>_3"
7427   [(set (reg FLAGS_REG)
7428         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7429                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7430    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7431         (minus:SWI (match_dup 1) (match_dup 2)))]
7432   "ix86_match_ccmode (insn, CCmode)
7433    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7434   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7435   [(set_attr "type" "alu")
7436    (set_attr "mode" "<MODE>")])
7437
7438 (define_insn "*subsi_3_zext"
7439   [(set (reg FLAGS_REG)
7440         (compare (match_operand:SI 1 "register_operand" "0")
7441                  (match_operand:SI 2 "general_operand" "g")))
7442    (set (match_operand:DI 0 "register_operand" "=r")
7443         (zero_extend:DI
7444           (minus:SI (match_dup 1)
7445                     (match_dup 2))))]
7446   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7447    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7448   "sub{l}\t{%2, %1|%1, %2}"
7449   [(set_attr "type" "alu")
7450    (set_attr "mode" "SI")])
7451 \f
7452 ;; Add with carry and subtract with borrow
7453
7454 (define_expand "<plusminus_insn><mode>3_carry"
7455   [(parallel
7456     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7457           (plusminus:SWI
7458             (match_operand:SWI 1 "nonimmediate_operand" "")
7459             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7460                        [(match_operand 3 "flags_reg_operand" "")
7461                         (const_int 0)])
7462                       (match_operand:SWI 2 "<general_operand>" ""))))
7463      (clobber (reg:CC FLAGS_REG))])]
7464   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7465   "")
7466
7467 (define_insn "*<plusminus_insn><mode>3_carry"
7468   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7469         (plusminus:SWI
7470           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7471           (plus:SWI
7472             (match_operator 3 "ix86_carry_flag_operator"
7473              [(reg FLAGS_REG) (const_int 0)])
7474             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7475    (clobber (reg:CC FLAGS_REG))]
7476   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7477   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7478   [(set_attr "type" "alu")
7479    (set_attr "use_carry" "1")
7480    (set_attr "pent_pair" "pu")
7481    (set_attr "mode" "<MODE>")])
7482
7483 (define_insn "*addsi3_carry_zext"
7484   [(set (match_operand:DI 0 "register_operand" "=r")
7485         (zero_extend:DI
7486           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7487                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7488                              [(reg FLAGS_REG) (const_int 0)])
7489                             (match_operand:SI 2 "general_operand" "g")))))
7490    (clobber (reg:CC FLAGS_REG))]
7491   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7492   "adc{l}\t{%2, %k0|%k0, %2}"
7493   [(set_attr "type" "alu")
7494    (set_attr "use_carry" "1")
7495    (set_attr "pent_pair" "pu")
7496    (set_attr "mode" "SI")])
7497
7498 (define_insn "*subsi3_carry_zext"
7499   [(set (match_operand:DI 0 "register_operand" "=r")
7500         (zero_extend:DI
7501           (minus:SI (match_operand:SI 1 "register_operand" "0")
7502                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7503                               [(reg FLAGS_REG) (const_int 0)])
7504                              (match_operand:SI 2 "general_operand" "g")))))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7507   "sbb{l}\t{%2, %k0|%k0, %2}"
7508   [(set_attr "type" "alu")
7509    (set_attr "pent_pair" "pu")
7510    (set_attr "mode" "SI")])
7511 \f
7512 ;; Overflow setting add and subtract instructions
7513
7514 (define_insn "*add<mode>3_cconly_overflow"
7515   [(set (reg:CCC FLAGS_REG)
7516         (compare:CCC
7517           (plus:SWI
7518             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7519             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7520           (match_dup 1)))
7521    (clobber (match_scratch:SWI 0 "=<r>"))]
7522   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7523   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7524   [(set_attr "type" "alu")
7525    (set_attr "mode" "<MODE>")])
7526
7527 (define_insn "*sub<mode>3_cconly_overflow"
7528   [(set (reg:CCC FLAGS_REG)
7529         (compare:CCC
7530           (minus:SWI
7531             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7532             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7533           (match_dup 0)))]
7534   ""
7535   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7536   [(set_attr "type" "icmp")
7537    (set_attr "mode" "<MODE>")])
7538
7539 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7540   [(set (reg:CCC FLAGS_REG)
7541         (compare:CCC
7542             (plusminus:SWI
7543                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7544                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7545             (match_dup 1)))
7546    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7547         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7548   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7549   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7550   [(set_attr "type" "alu")
7551    (set_attr "mode" "<MODE>")])
7552
7553 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7554   [(set (reg:CCC FLAGS_REG)
7555         (compare:CCC
7556           (plusminus:SI
7557             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7558             (match_operand:SI 2 "general_operand" "g"))
7559           (match_dup 1)))
7560    (set (match_operand:DI 0 "register_operand" "=r")
7561         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7562   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7563   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7564   [(set_attr "type" "alu")
7565    (set_attr "mode" "SI")])
7566
7567 ;; The patterns that match these are at the end of this file.
7568
7569 (define_expand "<plusminus_insn>xf3"
7570   [(set (match_operand:XF 0 "register_operand" "")
7571         (plusminus:XF
7572           (match_operand:XF 1 "register_operand" "")
7573           (match_operand:XF 2 "register_operand" "")))]
7574   "TARGET_80387"
7575   "")
7576
7577 (define_expand "<plusminus_insn><mode>3"
7578   [(set (match_operand:MODEF 0 "register_operand" "")
7579         (plusminus:MODEF
7580           (match_operand:MODEF 1 "register_operand" "")
7581           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7582   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7583     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7584   "")
7585 \f
7586 ;; Multiply instructions
7587
7588 (define_expand "mul<mode>3"
7589   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7590                    (mult:SWIM248
7591                      (match_operand:SWIM248 1 "register_operand" "")
7592                      (match_operand:SWIM248 2 "<general_operand>" "")))
7593               (clobber (reg:CC FLAGS_REG))])]
7594   ""
7595   "")
7596
7597 (define_expand "mulqi3"
7598   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7599                    (mult:QI
7600                      (match_operand:QI 1 "register_operand" "")
7601                      (match_operand:QI 2 "nonimmediate_operand" "")))
7602               (clobber (reg:CC FLAGS_REG))])]
7603   "TARGET_QIMODE_MATH"
7604   "")
7605
7606 ;; On AMDFAM10
7607 ;; IMUL reg32/64, reg32/64, imm8        Direct
7608 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7609 ;; IMUL reg32/64, reg32/64, imm32       Direct
7610 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7611 ;; IMUL reg32/64, reg32/64              Direct
7612 ;; IMUL reg32/64, mem32/64              Direct
7613
7614 (define_insn "*mul<mode>3_1"
7615   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7616         (mult:SWI48
7617           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7618           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7619    (clobber (reg:CC FLAGS_REG))]
7620   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7621   "@
7622    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7623    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7624    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7625   [(set_attr "type" "imul")
7626    (set_attr "prefix_0f" "0,0,1")
7627    (set (attr "athlon_decode")
7628         (cond [(eq_attr "cpu" "athlon")
7629                   (const_string "vector")
7630                (eq_attr "alternative" "1")
7631                   (const_string "vector")
7632                (and (eq_attr "alternative" "2")
7633                     (match_operand 1 "memory_operand" ""))
7634                   (const_string "vector")]
7635               (const_string "direct")))
7636    (set (attr "amdfam10_decode")
7637         (cond [(and (eq_attr "alternative" "0,1")
7638                     (match_operand 1 "memory_operand" ""))
7639                   (const_string "vector")]
7640               (const_string "direct")))
7641    (set_attr "mode" "<MODE>")])
7642
7643 (define_insn "*mulsi3_1_zext"
7644   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7645         (zero_extend:DI
7646           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7647                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7648    (clobber (reg:CC FLAGS_REG))]
7649   "TARGET_64BIT
7650    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7651   "@
7652    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7653    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7654    imul{l}\t{%2, %k0|%k0, %2}"
7655   [(set_attr "type" "imul")
7656    (set_attr "prefix_0f" "0,0,1")
7657    (set (attr "athlon_decode")
7658         (cond [(eq_attr "cpu" "athlon")
7659                   (const_string "vector")
7660                (eq_attr "alternative" "1")
7661                   (const_string "vector")
7662                (and (eq_attr "alternative" "2")
7663                     (match_operand 1 "memory_operand" ""))
7664                   (const_string "vector")]
7665               (const_string "direct")))
7666    (set (attr "amdfam10_decode")
7667         (cond [(and (eq_attr "alternative" "0,1")
7668                     (match_operand 1 "memory_operand" ""))
7669                   (const_string "vector")]
7670               (const_string "direct")))
7671    (set_attr "mode" "SI")])
7672
7673 ;; On AMDFAM10
7674 ;; IMUL reg16, reg16, imm8      VectorPath
7675 ;; IMUL reg16, mem16, imm8      VectorPath
7676 ;; IMUL reg16, reg16, imm16     VectorPath
7677 ;; IMUL reg16, mem16, imm16     VectorPath
7678 ;; IMUL reg16, reg16            Direct
7679 ;; IMUL reg16, mem16            Direct
7680
7681 (define_insn "*mulhi3_1"
7682   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7683         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7684                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7685    (clobber (reg:CC FLAGS_REG))]
7686   "TARGET_HIMODE_MATH
7687    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7688   "@
7689    imul{w}\t{%2, %1, %0|%0, %1, %2}
7690    imul{w}\t{%2, %1, %0|%0, %1, %2}
7691    imul{w}\t{%2, %0|%0, %2}"
7692   [(set_attr "type" "imul")
7693    (set_attr "prefix_0f" "0,0,1")
7694    (set (attr "athlon_decode")
7695         (cond [(eq_attr "cpu" "athlon")
7696                   (const_string "vector")
7697                (eq_attr "alternative" "1,2")
7698                   (const_string "vector")]
7699               (const_string "direct")))
7700    (set (attr "amdfam10_decode")
7701         (cond [(eq_attr "alternative" "0,1")
7702                   (const_string "vector")]
7703               (const_string "direct")))
7704    (set_attr "mode" "HI")])
7705
7706 ;;On AMDFAM10
7707 ;; MUL reg8     Direct
7708 ;; MUL mem8     Direct
7709
7710 (define_insn "*mulqi3_1"
7711   [(set (match_operand:QI 0 "register_operand" "=a")
7712         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7713                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7714    (clobber (reg:CC FLAGS_REG))]
7715   "TARGET_QIMODE_MATH
7716    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7717   "mul{b}\t%2"
7718   [(set_attr "type" "imul")
7719    (set_attr "length_immediate" "0")
7720    (set (attr "athlon_decode")
7721      (if_then_else (eq_attr "cpu" "athlon")
7722         (const_string "vector")
7723         (const_string "direct")))
7724    (set_attr "amdfam10_decode" "direct")
7725    (set_attr "mode" "QI")])
7726
7727 (define_expand "<u>mul<mode><dwi>3"
7728   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7729                    (mult:<DWI>
7730                      (any_extend:<DWI>
7731                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7732                      (any_extend:<DWI>
7733                        (match_operand:DWIH 2 "register_operand" ""))))
7734               (clobber (reg:CC FLAGS_REG))])]
7735   ""
7736   "")
7737
7738 (define_expand "<u>mulqihi3"
7739   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7740                    (mult:HI
7741                      (any_extend:HI
7742                        (match_operand:QI 1 "nonimmediate_operand" ""))
7743                      (any_extend:HI
7744                        (match_operand:QI 2 "register_operand" ""))))
7745               (clobber (reg:CC FLAGS_REG))])]
7746   "TARGET_QIMODE_MATH"
7747   "")
7748
7749 (define_insn "*<u>mul<mode><dwi>3_1"
7750   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7751         (mult:<DWI>
7752           (any_extend:<DWI>
7753             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7754           (any_extend:<DWI>
7755             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7756    (clobber (reg:CC FLAGS_REG))]
7757   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7758   "<sgnprefix>mul{<imodesuffix>}\t%2"
7759   [(set_attr "type" "imul")
7760    (set_attr "length_immediate" "0")
7761    (set (attr "athlon_decode")
7762      (if_then_else (eq_attr "cpu" "athlon")
7763         (const_string "vector")
7764         (const_string "double")))
7765    (set_attr "amdfam10_decode" "double")
7766    (set_attr "mode" "<MODE>")])
7767
7768 (define_insn "*<u>mulqihi3_1"
7769   [(set (match_operand:HI 0 "register_operand" "=a")
7770         (mult:HI
7771           (any_extend:HI
7772             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7773           (any_extend:HI
7774             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7775    (clobber (reg:CC FLAGS_REG))]
7776   "TARGET_QIMODE_MATH
7777    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7778   "<sgnprefix>mul{b}\t%2"
7779   [(set_attr "type" "imul")
7780    (set_attr "length_immediate" "0")
7781    (set (attr "athlon_decode")
7782      (if_then_else (eq_attr "cpu" "athlon")
7783         (const_string "vector")
7784         (const_string "direct")))
7785    (set_attr "amdfam10_decode" "direct")
7786    (set_attr "mode" "QI")])
7787
7788 (define_expand "<s>mul<mode>3_highpart"
7789   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7790                    (truncate:SWI48
7791                      (lshiftrt:<DWI>
7792                        (mult:<DWI>
7793                          (any_extend:<DWI>
7794                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7795                          (any_extend:<DWI>
7796                            (match_operand:SWI48 2 "register_operand" "")))
7797                        (match_dup 4))))
7798               (clobber (match_scratch:SWI48 3 ""))
7799               (clobber (reg:CC FLAGS_REG))])]
7800   ""
7801   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7802
7803 (define_insn "*<s>muldi3_highpart_1"
7804   [(set (match_operand:DI 0 "register_operand" "=d")
7805         (truncate:DI
7806           (lshiftrt:TI
7807             (mult:TI
7808               (any_extend:TI
7809                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7810               (any_extend:TI
7811                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7812             (const_int 64))))
7813    (clobber (match_scratch:DI 3 "=1"))
7814    (clobber (reg:CC FLAGS_REG))]
7815   "TARGET_64BIT
7816    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7817   "<sgnprefix>mul{q}\t%2"
7818   [(set_attr "type" "imul")
7819    (set_attr "length_immediate" "0")
7820    (set (attr "athlon_decode")
7821      (if_then_else (eq_attr "cpu" "athlon")
7822         (const_string "vector")
7823         (const_string "double")))
7824    (set_attr "amdfam10_decode" "double")
7825    (set_attr "mode" "DI")])
7826
7827 (define_insn "*<s>mulsi3_highpart_1"
7828   [(set (match_operand:SI 0 "register_operand" "=d")
7829         (truncate:SI
7830           (lshiftrt:DI
7831             (mult:DI
7832               (any_extend:DI
7833                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7834               (any_extend:DI
7835                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7836             (const_int 32))))
7837    (clobber (match_scratch:SI 3 "=1"))
7838    (clobber (reg:CC FLAGS_REG))]
7839   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7840   "<sgnprefix>mul{l}\t%2"
7841   [(set_attr "type" "imul")
7842    (set_attr "length_immediate" "0")
7843    (set (attr "athlon_decode")
7844      (if_then_else (eq_attr "cpu" "athlon")
7845         (const_string "vector")
7846         (const_string "double")))
7847    (set_attr "amdfam10_decode" "double")
7848    (set_attr "mode" "SI")])
7849
7850 (define_insn "*<s>mulsi3_highpart_zext"
7851   [(set (match_operand:DI 0 "register_operand" "=d")
7852         (zero_extend:DI (truncate:SI
7853           (lshiftrt:DI
7854             (mult:DI (any_extend:DI
7855                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7856                      (any_extend:DI
7857                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7858             (const_int 32)))))
7859    (clobber (match_scratch:SI 3 "=1"))
7860    (clobber (reg:CC FLAGS_REG))]
7861   "TARGET_64BIT
7862    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7863   "<sgnprefix>mul{l}\t%2"
7864   [(set_attr "type" "imul")
7865    (set_attr "length_immediate" "0")
7866    (set (attr "athlon_decode")
7867      (if_then_else (eq_attr "cpu" "athlon")
7868         (const_string "vector")
7869         (const_string "double")))
7870    (set_attr "amdfam10_decode" "double")
7871    (set_attr "mode" "SI")])
7872
7873 ;; The patterns that match these are at the end of this file.
7874
7875 (define_expand "mulxf3"
7876   [(set (match_operand:XF 0 "register_operand" "")
7877         (mult:XF (match_operand:XF 1 "register_operand" "")
7878                  (match_operand:XF 2 "register_operand" "")))]
7879   "TARGET_80387"
7880   "")
7881
7882 (define_expand "mul<mode>3"
7883   [(set (match_operand:MODEF 0 "register_operand" "")
7884         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7885                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7886   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7887     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7888   "")
7889 \f
7890 ;; Divide instructions
7891
7892 (define_insn "<u>divqi3"
7893   [(set (match_operand:QI 0 "register_operand" "=a")
7894         (any_div:QI
7895           (match_operand:HI 1 "register_operand" "0")
7896           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7897    (clobber (reg:CC FLAGS_REG))]
7898   "TARGET_QIMODE_MATH"
7899   "<sgnprefix>div{b}\t%2"
7900   [(set_attr "type" "idiv")
7901    (set_attr "mode" "QI")])
7902
7903 ;; The patterns that match these are at the end of this file.
7904
7905 (define_expand "divxf3"
7906   [(set (match_operand:XF 0 "register_operand" "")
7907         (div:XF (match_operand:XF 1 "register_operand" "")
7908                 (match_operand:XF 2 "register_operand" "")))]
7909   "TARGET_80387"
7910   "")
7911
7912 (define_expand "divdf3"
7913   [(set (match_operand:DF 0 "register_operand" "")
7914         (div:DF (match_operand:DF 1 "register_operand" "")
7915                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7916    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7917     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7918    "")
7919
7920 (define_expand "divsf3"
7921   [(set (match_operand:SF 0 "register_operand" "")
7922         (div:SF (match_operand:SF 1 "register_operand" "")
7923                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7924   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7925     || TARGET_SSE_MATH"
7926 {
7927   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7928       && flag_finite_math_only && !flag_trapping_math
7929       && flag_unsafe_math_optimizations)
7930     {
7931       ix86_emit_swdivsf (operands[0], operands[1],
7932                          operands[2], SFmode);
7933       DONE;
7934     }
7935 })
7936 \f
7937 ;; Divmod instructions.
7938
7939 (define_expand "divmod<mode>4"
7940   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7941                    (div:SWIM248
7942                      (match_operand:SWIM248 1 "register_operand" "")
7943                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7944               (set (match_operand:SWIM248 3 "register_operand" "")
7945                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7946               (clobber (reg:CC FLAGS_REG))])]
7947   ""
7948   "")
7949
7950 (define_insn_and_split "*divmod<mode>4"
7951   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7952         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7953                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7954    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7955         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7956    (clobber (reg:CC FLAGS_REG))]
7957   ""
7958   "#"
7959   "reload_completed"
7960   [(parallel [(set (match_dup 1)
7961                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7962               (clobber (reg:CC FLAGS_REG))])
7963    (parallel [(set (match_dup 0)
7964                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7965               (set (match_dup 1)
7966                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7967               (use (match_dup 1))
7968               (clobber (reg:CC FLAGS_REG))])]
7969 {
7970   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7971
7972   if (<MODE>mode != HImode
7973       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7974     operands[4] = operands[2];
7975   else
7976     {
7977       /* Avoid use of cltd in favor of a mov+shift.  */
7978       emit_move_insn (operands[1], operands[2]);
7979       operands[4] = operands[1];
7980     }
7981 }
7982   [(set_attr "type" "multi")
7983    (set_attr "mode" "<MODE>")])
7984
7985 (define_insn "*divmod<mode>4_noext"
7986   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7987         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7988                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7989    (set (match_operand:SWIM248 1 "register_operand" "=d")
7990         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7991    (use (match_operand:SWIM248 4 "register_operand" "1"))
7992    (clobber (reg:CC FLAGS_REG))]
7993   ""
7994   "idiv{<imodesuffix>}\t%3"
7995   [(set_attr "type" "idiv")
7996    (set_attr "mode" "<MODE>")])
7997
7998 (define_expand "udivmod<mode>4"
7999   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8000                    (udiv:SWIM248
8001                      (match_operand:SWIM248 1 "register_operand" "")
8002                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8003               (set (match_operand:SWIM248 3 "register_operand" "")
8004                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8005               (clobber (reg:CC FLAGS_REG))])]
8006   ""
8007   "")
8008
8009 (define_insn_and_split "*udivmod<mode>4"
8010   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8011         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8012                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8013    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8014         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8015    (clobber (reg:CC FLAGS_REG))]
8016   ""
8017   "#"
8018   "reload_completed"
8019   [(set (match_dup 1) (const_int 0))
8020    (parallel [(set (match_dup 0)
8021                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8022               (set (match_dup 1)
8023                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8024               (use (match_dup 1))
8025               (clobber (reg:CC FLAGS_REG))])]
8026   ""
8027   [(set_attr "type" "multi")
8028    (set_attr "mode" "<MODE>")])
8029
8030 (define_insn "*udivmod<mode>4_noext"
8031   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8032         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8033                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8034    (set (match_operand:SWIM248 1 "register_operand" "=d")
8035         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8036    (use (match_operand:SWIM248 4 "register_operand" "1"))
8037    (clobber (reg:CC FLAGS_REG))]
8038   ""
8039   "div{<imodesuffix>}\t%3"
8040   [(set_attr "type" "idiv")
8041    (set_attr "mode" "<MODE>")])
8042
8043 ;; We cannot use div/idiv for double division, because it causes
8044 ;; "division by zero" on the overflow and that's not what we expect
8045 ;; from truncate.  Because true (non truncating) double division is
8046 ;; never generated, we can't create this insn anyway.
8047 ;
8048 ;(define_insn ""
8049 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8050 ;       (truncate:SI
8051 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8052 ;                  (zero_extend:DI
8053 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8054 ;   (set (match_operand:SI 3 "register_operand" "=d")
8055 ;       (truncate:SI
8056 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8057 ;   (clobber (reg:CC FLAGS_REG))]
8058 ;  ""
8059 ;  "div{l}\t{%2, %0|%0, %2}"
8060 ;  [(set_attr "type" "idiv")])
8061 \f
8062 ;;- Logical AND instructions
8063
8064 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8065 ;; Note that this excludes ah.
8066
8067 (define_expand "testsi_ccno_1"
8068   [(set (reg:CCNO FLAGS_REG)
8069         (compare:CCNO
8070           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8071                   (match_operand:SI 1 "nonmemory_operand" ""))
8072           (const_int 0)))]
8073   ""
8074   "")
8075
8076 (define_expand "testqi_ccz_1"
8077   [(set (reg:CCZ FLAGS_REG)
8078         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8079                              (match_operand:QI 1 "nonmemory_operand" ""))
8080                  (const_int 0)))]
8081   ""
8082   "")
8083
8084 (define_insn "*testdi_1"
8085   [(set (reg FLAGS_REG)
8086         (compare
8087          (and:DI
8088           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8089           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8090          (const_int 0)))]
8091   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8092    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8093   "@
8094    test{l}\t{%k1, %k0|%k0, %k1}
8095    test{l}\t{%k1, %k0|%k0, %k1}
8096    test{q}\t{%1, %0|%0, %1}
8097    test{q}\t{%1, %0|%0, %1}
8098    test{q}\t{%1, %0|%0, %1}"
8099   [(set_attr "type" "test")
8100    (set_attr "modrm" "0,1,0,1,1")
8101    (set_attr "mode" "SI,SI,DI,DI,DI")])
8102
8103 (define_insn "*testqi_1_maybe_si"
8104   [(set (reg FLAGS_REG)
8105         (compare
8106           (and:QI
8107             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8108             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8109           (const_int 0)))]
8110    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8111     && ix86_match_ccmode (insn,
8112                          CONST_INT_P (operands[1])
8113                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8114 {
8115   if (which_alternative == 3)
8116     {
8117       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8118         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8119       return "test{l}\t{%1, %k0|%k0, %1}";
8120     }
8121   return "test{b}\t{%1, %0|%0, %1}";
8122 }
8123   [(set_attr "type" "test")
8124    (set_attr "modrm" "0,1,1,1")
8125    (set_attr "mode" "QI,QI,QI,SI")
8126    (set_attr "pent_pair" "uv,np,uv,np")])
8127
8128 (define_insn "*test<mode>_1"
8129   [(set (reg FLAGS_REG)
8130         (compare
8131          (and:SWI124
8132           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8133           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8134          (const_int 0)))]
8135   "ix86_match_ccmode (insn, CCNOmode)
8136    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8137   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8138   [(set_attr "type" "test")
8139    (set_attr "modrm" "0,1,1")
8140    (set_attr "mode" "<MODE>")
8141    (set_attr "pent_pair" "uv,np,uv")])
8142
8143 (define_expand "testqi_ext_ccno_0"
8144   [(set (reg:CCNO FLAGS_REG)
8145         (compare:CCNO
8146           (and:SI
8147             (zero_extract:SI
8148               (match_operand 0 "ext_register_operand" "")
8149               (const_int 8)
8150               (const_int 8))
8151             (match_operand 1 "const_int_operand" ""))
8152           (const_int 0)))]
8153   ""
8154   "")
8155
8156 (define_insn "*testqi_ext_0"
8157   [(set (reg FLAGS_REG)
8158         (compare
8159           (and:SI
8160             (zero_extract:SI
8161               (match_operand 0 "ext_register_operand" "Q")
8162               (const_int 8)
8163               (const_int 8))
8164             (match_operand 1 "const_int_operand" "n"))
8165           (const_int 0)))]
8166   "ix86_match_ccmode (insn, CCNOmode)"
8167   "test{b}\t{%1, %h0|%h0, %1}"
8168   [(set_attr "type" "test")
8169    (set_attr "mode" "QI")
8170    (set_attr "length_immediate" "1")
8171    (set_attr "modrm" "1")
8172    (set_attr "pent_pair" "np")])
8173
8174 (define_insn "*testqi_ext_1_rex64"
8175   [(set (reg FLAGS_REG)
8176         (compare
8177           (and:SI
8178             (zero_extract:SI
8179               (match_operand 0 "ext_register_operand" "Q")
8180               (const_int 8)
8181               (const_int 8))
8182             (zero_extend:SI
8183               (match_operand:QI 1 "register_operand" "Q")))
8184           (const_int 0)))]
8185   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8186   "test{b}\t{%1, %h0|%h0, %1}"
8187   [(set_attr "type" "test")
8188    (set_attr "mode" "QI")])
8189
8190 (define_insn "*testqi_ext_1"
8191   [(set (reg FLAGS_REG)
8192         (compare
8193           (and:SI
8194             (zero_extract:SI
8195               (match_operand 0 "ext_register_operand" "Q")
8196               (const_int 8)
8197               (const_int 8))
8198             (zero_extend:SI
8199               (match_operand:QI 1 "general_operand" "Qm")))
8200           (const_int 0)))]
8201   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8202   "test{b}\t{%1, %h0|%h0, %1}"
8203   [(set_attr "type" "test")
8204    (set_attr "mode" "QI")])
8205
8206 (define_insn "*testqi_ext_2"
8207   [(set (reg FLAGS_REG)
8208         (compare
8209           (and:SI
8210             (zero_extract:SI
8211               (match_operand 0 "ext_register_operand" "Q")
8212               (const_int 8)
8213               (const_int 8))
8214             (zero_extract:SI
8215               (match_operand 1 "ext_register_operand" "Q")
8216               (const_int 8)
8217               (const_int 8)))
8218           (const_int 0)))]
8219   "ix86_match_ccmode (insn, CCNOmode)"
8220   "test{b}\t{%h1, %h0|%h0, %h1}"
8221   [(set_attr "type" "test")
8222    (set_attr "mode" "QI")])
8223
8224 (define_insn "*testqi_ext_3_rex64"
8225   [(set (reg FLAGS_REG)
8226         (compare (zero_extract:DI
8227                    (match_operand 0 "nonimmediate_operand" "rm")
8228                    (match_operand:DI 1 "const_int_operand" "")
8229                    (match_operand:DI 2 "const_int_operand" ""))
8230                  (const_int 0)))]
8231   "TARGET_64BIT
8232    && ix86_match_ccmode (insn, CCNOmode)
8233    && INTVAL (operands[1]) > 0
8234    && INTVAL (operands[2]) >= 0
8235    /* Ensure that resulting mask is zero or sign extended operand.  */
8236    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8237        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8238            && INTVAL (operands[1]) > 32))
8239    && (GET_MODE (operands[0]) == SImode
8240        || GET_MODE (operands[0]) == DImode
8241        || GET_MODE (operands[0]) == HImode
8242        || GET_MODE (operands[0]) == QImode)"
8243   "#")
8244
8245 ;; Combine likes to form bit extractions for some tests.  Humor it.
8246 (define_insn "*testqi_ext_3"
8247   [(set (reg FLAGS_REG)
8248         (compare (zero_extract:SI
8249                    (match_operand 0 "nonimmediate_operand" "rm")
8250                    (match_operand:SI 1 "const_int_operand" "")
8251                    (match_operand:SI 2 "const_int_operand" ""))
8252                  (const_int 0)))]
8253   "ix86_match_ccmode (insn, CCNOmode)
8254    && INTVAL (operands[1]) > 0
8255    && INTVAL (operands[2]) >= 0
8256    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8257    && (GET_MODE (operands[0]) == SImode
8258        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8259        || GET_MODE (operands[0]) == HImode
8260        || GET_MODE (operands[0]) == QImode)"
8261   "#")
8262
8263 (define_split
8264   [(set (match_operand 0 "flags_reg_operand" "")
8265         (match_operator 1 "compare_operator"
8266           [(zero_extract
8267              (match_operand 2 "nonimmediate_operand" "")
8268              (match_operand 3 "const_int_operand" "")
8269              (match_operand 4 "const_int_operand" ""))
8270            (const_int 0)]))]
8271   "ix86_match_ccmode (insn, CCNOmode)"
8272   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8273 {
8274   rtx val = operands[2];
8275   HOST_WIDE_INT len = INTVAL (operands[3]);
8276   HOST_WIDE_INT pos = INTVAL (operands[4]);
8277   HOST_WIDE_INT mask;
8278   enum machine_mode mode, submode;
8279
8280   mode = GET_MODE (val);
8281   if (MEM_P (val))
8282     {
8283       /* ??? Combine likes to put non-volatile mem extractions in QImode
8284          no matter the size of the test.  So find a mode that works.  */
8285       if (! MEM_VOLATILE_P (val))
8286         {
8287           mode = smallest_mode_for_size (pos + len, MODE_INT);
8288           val = adjust_address (val, mode, 0);
8289         }
8290     }
8291   else if (GET_CODE (val) == SUBREG
8292            && (submode = GET_MODE (SUBREG_REG (val)),
8293                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8294            && pos + len <= GET_MODE_BITSIZE (submode)
8295            && GET_MODE_CLASS (submode) == MODE_INT)
8296     {
8297       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8298       mode = submode;
8299       val = SUBREG_REG (val);
8300     }
8301   else if (mode == HImode && pos + len <= 8)
8302     {
8303       /* Small HImode tests can be converted to QImode.  */
8304       mode = QImode;
8305       val = gen_lowpart (QImode, val);
8306     }
8307
8308   if (len == HOST_BITS_PER_WIDE_INT)
8309     mask = -1;
8310   else
8311     mask = ((HOST_WIDE_INT)1 << len) - 1;
8312   mask <<= pos;
8313
8314   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8315 })
8316
8317 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8318 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8319 ;; this is relatively important trick.
8320 ;; Do the conversion only post-reload to avoid limiting of the register class
8321 ;; to QI regs.
8322 (define_split
8323   [(set (match_operand 0 "flags_reg_operand" "")
8324         (match_operator 1 "compare_operator"
8325           [(and (match_operand 2 "register_operand" "")
8326                 (match_operand 3 "const_int_operand" ""))
8327            (const_int 0)]))]
8328    "reload_completed
8329     && QI_REG_P (operands[2])
8330     && GET_MODE (operands[2]) != QImode
8331     && ((ix86_match_ccmode (insn, CCZmode)
8332          && !(INTVAL (operands[3]) & ~(255 << 8)))
8333         || (ix86_match_ccmode (insn, CCNOmode)
8334             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8335   [(set (match_dup 0)
8336         (match_op_dup 1
8337           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8338                    (match_dup 3))
8339            (const_int 0)]))]
8340   "operands[2] = gen_lowpart (SImode, operands[2]);
8341    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8342
8343 (define_split
8344   [(set (match_operand 0 "flags_reg_operand" "")
8345         (match_operator 1 "compare_operator"
8346           [(and (match_operand 2 "nonimmediate_operand" "")
8347                 (match_operand 3 "const_int_operand" ""))
8348            (const_int 0)]))]
8349    "reload_completed
8350     && GET_MODE (operands[2]) != QImode
8351     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8352     && ((ix86_match_ccmode (insn, CCZmode)
8353          && !(INTVAL (operands[3]) & ~255))
8354         || (ix86_match_ccmode (insn, CCNOmode)
8355             && !(INTVAL (operands[3]) & ~127)))"
8356   [(set (match_dup 0)
8357         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8358                          (const_int 0)]))]
8359   "operands[2] = gen_lowpart (QImode, operands[2]);
8360    operands[3] = gen_lowpart (QImode, operands[3]);")
8361
8362 ;; %%% This used to optimize known byte-wide and operations to memory,
8363 ;; and sometimes to QImode registers.  If this is considered useful,
8364 ;; it should be done with splitters.
8365
8366 (define_expand "and<mode>3"
8367   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8368         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8369                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8370   ""
8371   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8372
8373 (define_insn "*anddi_1"
8374   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8375         (and:DI
8376          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8377          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8378    (clobber (reg:CC FLAGS_REG))]
8379   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8380 {
8381   switch (get_attr_type (insn))
8382     {
8383     case TYPE_IMOVX:
8384       {
8385         enum machine_mode mode;
8386
8387         gcc_assert (CONST_INT_P (operands[2]));
8388         if (INTVAL (operands[2]) == 0xff)
8389           mode = QImode;
8390         else
8391           {
8392             gcc_assert (INTVAL (operands[2]) == 0xffff);
8393             mode = HImode;
8394           }
8395
8396         operands[1] = gen_lowpart (mode, operands[1]);
8397         if (mode == QImode)
8398           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8399         else
8400           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8401       }
8402
8403     default:
8404       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8405       if (get_attr_mode (insn) == MODE_SI)
8406         return "and{l}\t{%k2, %k0|%k0, %k2}";
8407       else
8408         return "and{q}\t{%2, %0|%0, %2}";
8409     }
8410 }
8411   [(set_attr "type" "alu,alu,alu,imovx")
8412    (set_attr "length_immediate" "*,*,*,0")
8413    (set (attr "prefix_rex")
8414      (if_then_else
8415        (and (eq_attr "type" "imovx")
8416             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8417                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8418        (const_string "1")
8419        (const_string "*")))
8420    (set_attr "mode" "SI,DI,DI,SI")])
8421
8422 (define_insn "*andsi_1"
8423   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8424         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8425                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8426    (clobber (reg:CC FLAGS_REG))]
8427   "ix86_binary_operator_ok (AND, SImode, operands)"
8428 {
8429   switch (get_attr_type (insn))
8430     {
8431     case TYPE_IMOVX:
8432       {
8433         enum machine_mode mode;
8434
8435         gcc_assert (CONST_INT_P (operands[2]));
8436         if (INTVAL (operands[2]) == 0xff)
8437           mode = QImode;
8438         else
8439           {
8440             gcc_assert (INTVAL (operands[2]) == 0xffff);
8441             mode = HImode;
8442           }
8443
8444         operands[1] = gen_lowpart (mode, operands[1]);
8445         if (mode == QImode)
8446           return "movz{bl|x}\t{%1, %0|%0, %1}";
8447         else
8448           return "movz{wl|x}\t{%1, %0|%0, %1}";
8449       }
8450
8451     default:
8452       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8453       return "and{l}\t{%2, %0|%0, %2}";
8454     }
8455 }
8456   [(set_attr "type" "alu,alu,imovx")
8457    (set (attr "prefix_rex")
8458      (if_then_else
8459        (and (eq_attr "type" "imovx")
8460             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8461                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8462        (const_string "1")
8463        (const_string "*")))
8464    (set_attr "length_immediate" "*,*,0")
8465    (set_attr "mode" "SI")])
8466
8467 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8468 (define_insn "*andsi_1_zext"
8469   [(set (match_operand:DI 0 "register_operand" "=r")
8470         (zero_extend:DI
8471           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8472                   (match_operand:SI 2 "general_operand" "g"))))
8473    (clobber (reg:CC FLAGS_REG))]
8474   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8475   "and{l}\t{%2, %k0|%k0, %2}"
8476   [(set_attr "type" "alu")
8477    (set_attr "mode" "SI")])
8478
8479 (define_insn "*andhi_1"
8480   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8481         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8482                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8483    (clobber (reg:CC FLAGS_REG))]
8484   "ix86_binary_operator_ok (AND, HImode, operands)"
8485 {
8486   switch (get_attr_type (insn))
8487     {
8488     case TYPE_IMOVX:
8489       gcc_assert (CONST_INT_P (operands[2]));
8490       gcc_assert (INTVAL (operands[2]) == 0xff);
8491       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8492
8493     default:
8494       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8495
8496       return "and{w}\t{%2, %0|%0, %2}";
8497     }
8498 }
8499   [(set_attr "type" "alu,alu,imovx")
8500    (set_attr "length_immediate" "*,*,0")
8501    (set (attr "prefix_rex")
8502      (if_then_else
8503        (and (eq_attr "type" "imovx")
8504             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8505        (const_string "1")
8506        (const_string "*")))
8507    (set_attr "mode" "HI,HI,SI")])
8508
8509 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8510 (define_insn "*andqi_1"
8511   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8512         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8513                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8514    (clobber (reg:CC FLAGS_REG))]
8515   "ix86_binary_operator_ok (AND, QImode, operands)"
8516   "@
8517    and{b}\t{%2, %0|%0, %2}
8518    and{b}\t{%2, %0|%0, %2}
8519    and{l}\t{%k2, %k0|%k0, %k2}"
8520   [(set_attr "type" "alu")
8521    (set_attr "mode" "QI,QI,SI")])
8522
8523 (define_insn "*andqi_1_slp"
8524   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8525         (and:QI (match_dup 0)
8526                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8527    (clobber (reg:CC FLAGS_REG))]
8528   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8529    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8530   "and{b}\t{%1, %0|%0, %1}"
8531   [(set_attr "type" "alu1")
8532    (set_attr "mode" "QI")])
8533
8534 (define_split
8535   [(set (match_operand 0 "register_operand" "")
8536         (and (match_dup 0)
8537              (const_int -65536)))
8538    (clobber (reg:CC FLAGS_REG))]
8539   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8540     || optimize_function_for_size_p (cfun)"
8541   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8542   "operands[1] = gen_lowpart (HImode, operands[0]);")
8543
8544 (define_split
8545   [(set (match_operand 0 "ext_register_operand" "")
8546         (and (match_dup 0)
8547              (const_int -256)))
8548    (clobber (reg:CC FLAGS_REG))]
8549   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8550    && reload_completed"
8551   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8552   "operands[1] = gen_lowpart (QImode, operands[0]);")
8553
8554 (define_split
8555   [(set (match_operand 0 "ext_register_operand" "")
8556         (and (match_dup 0)
8557              (const_int -65281)))
8558    (clobber (reg:CC FLAGS_REG))]
8559   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8560    && reload_completed"
8561   [(parallel [(set (zero_extract:SI (match_dup 0)
8562                                     (const_int 8)
8563                                     (const_int 8))
8564                    (xor:SI
8565                      (zero_extract:SI (match_dup 0)
8566                                       (const_int 8)
8567                                       (const_int 8))
8568                      (zero_extract:SI (match_dup 0)
8569                                       (const_int 8)
8570                                       (const_int 8))))
8571               (clobber (reg:CC FLAGS_REG))])]
8572   "operands[0] = gen_lowpart (SImode, operands[0]);")
8573
8574 (define_insn "*anddi_2"
8575   [(set (reg FLAGS_REG)
8576         (compare
8577          (and:DI
8578           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8579           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8580          (const_int 0)))
8581    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8582         (and:DI (match_dup 1) (match_dup 2)))]
8583   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8584    && ix86_binary_operator_ok (AND, DImode, operands)"
8585   "@
8586    and{l}\t{%k2, %k0|%k0, %k2}
8587    and{q}\t{%2, %0|%0, %2}
8588    and{q}\t{%2, %0|%0, %2}"
8589   [(set_attr "type" "alu")
8590    (set_attr "mode" "SI,DI,DI")])
8591
8592 (define_insn "*andqi_2_maybe_si"
8593   [(set (reg FLAGS_REG)
8594         (compare (and:QI
8595                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8596                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8597                  (const_int 0)))
8598    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8599         (and:QI (match_dup 1) (match_dup 2)))]
8600   "ix86_binary_operator_ok (AND, QImode, operands)
8601    && ix86_match_ccmode (insn,
8602                          CONST_INT_P (operands[2])
8603                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8604 {
8605   if (which_alternative == 2)
8606     {
8607       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8608         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8609       return "and{l}\t{%2, %k0|%k0, %2}";
8610     }
8611   return "and{b}\t{%2, %0|%0, %2}";
8612 }
8613   [(set_attr "type" "alu")
8614    (set_attr "mode" "QI,QI,SI")])
8615
8616 (define_insn "*and<mode>_2"
8617   [(set (reg FLAGS_REG)
8618         (compare (and:SWI124
8619                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8620                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8621                  (const_int 0)))
8622    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8623         (and:SWI124 (match_dup 1) (match_dup 2)))]
8624   "ix86_match_ccmode (insn, CCNOmode)
8625    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8626   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8627   [(set_attr "type" "alu")
8628    (set_attr "mode" "<MODE>")])
8629
8630 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8631 (define_insn "*andsi_2_zext"
8632   [(set (reg FLAGS_REG)
8633         (compare (and:SI
8634                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8635                   (match_operand:SI 2 "general_operand" "g"))
8636                  (const_int 0)))
8637    (set (match_operand:DI 0 "register_operand" "=r")
8638         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8639   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8640    && ix86_binary_operator_ok (AND, SImode, operands)"
8641   "and{l}\t{%2, %k0|%k0, %2}"
8642   [(set_attr "type" "alu")
8643    (set_attr "mode" "SI")])
8644
8645 (define_insn "*andqi_2_slp"
8646   [(set (reg FLAGS_REG)
8647         (compare (and:QI
8648                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8649                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8650                  (const_int 0)))
8651    (set (strict_low_part (match_dup 0))
8652         (and:QI (match_dup 0) (match_dup 1)))]
8653   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8654    && ix86_match_ccmode (insn, CCNOmode)
8655    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8656   "and{b}\t{%1, %0|%0, %1}"
8657   [(set_attr "type" "alu1")
8658    (set_attr "mode" "QI")])
8659
8660 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8661 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8662 ;; for a QImode operand, which of course failed.
8663 (define_insn "andqi_ext_0"
8664   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8665                          (const_int 8)
8666                          (const_int 8))
8667         (and:SI
8668           (zero_extract:SI
8669             (match_operand 1 "ext_register_operand" "0")
8670             (const_int 8)
8671             (const_int 8))
8672           (match_operand 2 "const_int_operand" "n")))
8673    (clobber (reg:CC FLAGS_REG))]
8674   ""
8675   "and{b}\t{%2, %h0|%h0, %2}"
8676   [(set_attr "type" "alu")
8677    (set_attr "length_immediate" "1")
8678    (set_attr "modrm" "1")
8679    (set_attr "mode" "QI")])
8680
8681 ;; Generated by peephole translating test to and.  This shows up
8682 ;; often in fp comparisons.
8683 (define_insn "*andqi_ext_0_cc"
8684   [(set (reg FLAGS_REG)
8685         (compare
8686           (and:SI
8687             (zero_extract:SI
8688               (match_operand 1 "ext_register_operand" "0")
8689               (const_int 8)
8690               (const_int 8))
8691             (match_operand 2 "const_int_operand" "n"))
8692           (const_int 0)))
8693    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8694                          (const_int 8)
8695                          (const_int 8))
8696         (and:SI
8697           (zero_extract:SI
8698             (match_dup 1)
8699             (const_int 8)
8700             (const_int 8))
8701           (match_dup 2)))]
8702   "ix86_match_ccmode (insn, CCNOmode)"
8703   "and{b}\t{%2, %h0|%h0, %2}"
8704   [(set_attr "type" "alu")
8705    (set_attr "length_immediate" "1")
8706    (set_attr "modrm" "1")
8707    (set_attr "mode" "QI")])
8708
8709 (define_insn "*andqi_ext_1_rex64"
8710   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8711                          (const_int 8)
8712                          (const_int 8))
8713         (and:SI
8714           (zero_extract:SI
8715             (match_operand 1 "ext_register_operand" "0")
8716             (const_int 8)
8717             (const_int 8))
8718           (zero_extend:SI
8719             (match_operand 2 "ext_register_operand" "Q"))))
8720    (clobber (reg:CC FLAGS_REG))]
8721   "TARGET_64BIT"
8722   "and{b}\t{%2, %h0|%h0, %2}"
8723   [(set_attr "type" "alu")
8724    (set_attr "length_immediate" "0")
8725    (set_attr "mode" "QI")])
8726
8727 (define_insn "*andqi_ext_1"
8728   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8729                          (const_int 8)
8730                          (const_int 8))
8731         (and:SI
8732           (zero_extract:SI
8733             (match_operand 1 "ext_register_operand" "0")
8734             (const_int 8)
8735             (const_int 8))
8736           (zero_extend:SI
8737             (match_operand:QI 2 "general_operand" "Qm"))))
8738    (clobber (reg:CC FLAGS_REG))]
8739   "!TARGET_64BIT"
8740   "and{b}\t{%2, %h0|%h0, %2}"
8741   [(set_attr "type" "alu")
8742    (set_attr "length_immediate" "0")
8743    (set_attr "mode" "QI")])
8744
8745 (define_insn "*andqi_ext_2"
8746   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8747                          (const_int 8)
8748                          (const_int 8))
8749         (and:SI
8750           (zero_extract:SI
8751             (match_operand 1 "ext_register_operand" "%0")
8752             (const_int 8)
8753             (const_int 8))
8754           (zero_extract:SI
8755             (match_operand 2 "ext_register_operand" "Q")
8756             (const_int 8)
8757             (const_int 8))))
8758    (clobber (reg:CC FLAGS_REG))]
8759   ""
8760   "and{b}\t{%h2, %h0|%h0, %h2}"
8761   [(set_attr "type" "alu")
8762    (set_attr "length_immediate" "0")
8763    (set_attr "mode" "QI")])
8764
8765 ;; Convert wide AND instructions with immediate operand to shorter QImode
8766 ;; equivalents when possible.
8767 ;; Don't do the splitting with memory operands, since it introduces risk
8768 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8769 ;; for size, but that can (should?) be handled by generic code instead.
8770 (define_split
8771   [(set (match_operand 0 "register_operand" "")
8772         (and (match_operand 1 "register_operand" "")
8773              (match_operand 2 "const_int_operand" "")))
8774    (clobber (reg:CC FLAGS_REG))]
8775    "reload_completed
8776     && QI_REG_P (operands[0])
8777     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8778     && !(~INTVAL (operands[2]) & ~(255 << 8))
8779     && GET_MODE (operands[0]) != QImode"
8780   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8781                    (and:SI (zero_extract:SI (match_dup 1)
8782                                             (const_int 8) (const_int 8))
8783                            (match_dup 2)))
8784               (clobber (reg:CC FLAGS_REG))])]
8785   "operands[0] = gen_lowpart (SImode, operands[0]);
8786    operands[1] = gen_lowpart (SImode, operands[1]);
8787    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8788
8789 ;; Since AND can be encoded with sign extended immediate, this is only
8790 ;; profitable when 7th bit is not set.
8791 (define_split
8792   [(set (match_operand 0 "register_operand" "")
8793         (and (match_operand 1 "general_operand" "")
8794              (match_operand 2 "const_int_operand" "")))
8795    (clobber (reg:CC FLAGS_REG))]
8796    "reload_completed
8797     && ANY_QI_REG_P (operands[0])
8798     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8799     && !(~INTVAL (operands[2]) & ~255)
8800     && !(INTVAL (operands[2]) & 128)
8801     && GET_MODE (operands[0]) != QImode"
8802   [(parallel [(set (strict_low_part (match_dup 0))
8803                    (and:QI (match_dup 1)
8804                            (match_dup 2)))
8805               (clobber (reg:CC FLAGS_REG))])]
8806   "operands[0] = gen_lowpart (QImode, operands[0]);
8807    operands[1] = gen_lowpart (QImode, operands[1]);
8808    operands[2] = gen_lowpart (QImode, operands[2]);")
8809 \f
8810 ;; Logical inclusive and exclusive OR instructions
8811
8812 ;; %%% This used to optimize known byte-wide and operations to memory.
8813 ;; If this is considered useful, it should be done with splitters.
8814
8815 (define_expand "<code><mode>3"
8816   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8817         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8818                      (match_operand:SWIM 2 "<general_operand>" "")))]
8819   ""
8820   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8821
8822 (define_insn "*<code><mode>_1"
8823   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8824         (any_or:SWI248
8825          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8826          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8827    (clobber (reg:CC FLAGS_REG))]
8828   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8829   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "mode" "<MODE>")])
8832
8833 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8834 (define_insn "*<code>qi_1"
8835   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8836         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8837                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8838    (clobber (reg:CC FLAGS_REG))]
8839   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8840   "@
8841    <logic>{b}\t{%2, %0|%0, %2}
8842    <logic>{b}\t{%2, %0|%0, %2}
8843    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8844   [(set_attr "type" "alu")
8845    (set_attr "mode" "QI,QI,SI")])
8846
8847 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8848 (define_insn "*<code>si_1_zext"
8849   [(set (match_operand:DI 0 "register_operand" "=r")
8850         (zero_extend:DI
8851          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8852                     (match_operand:SI 2 "general_operand" "g"))))
8853    (clobber (reg:CC FLAGS_REG))]
8854   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8855   "<logic>{l}\t{%2, %k0|%k0, %2}"
8856   [(set_attr "type" "alu")
8857    (set_attr "mode" "SI")])
8858
8859 (define_insn "*<code>si_1_zext_imm"
8860   [(set (match_operand:DI 0 "register_operand" "=r")
8861         (any_or:DI
8862          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8863          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8864    (clobber (reg:CC FLAGS_REG))]
8865   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8866   "<logic>{l}\t{%2, %k0|%k0, %2}"
8867   [(set_attr "type" "alu")
8868    (set_attr "mode" "SI")])
8869
8870 (define_insn "*<code>qi_1_slp"
8871   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8872         (any_or:QI (match_dup 0)
8873                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8874    (clobber (reg:CC FLAGS_REG))]
8875   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8876    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8877   "<logic>{b}\t{%1, %0|%0, %1}"
8878   [(set_attr "type" "alu1")
8879    (set_attr "mode" "QI")])
8880
8881 (define_insn "*<code><mode>_2"
8882   [(set (reg FLAGS_REG)
8883         (compare (any_or:SWI
8884                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8885                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8886                  (const_int 0)))
8887    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8888         (any_or:SWI (match_dup 1) (match_dup 2)))]
8889   "ix86_match_ccmode (insn, CCNOmode)
8890    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8891   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8892   [(set_attr "type" "alu")
8893    (set_attr "mode" "<MODE>")])
8894
8895 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8896 ;; ??? Special case for immediate operand is missing - it is tricky.
8897 (define_insn "*<code>si_2_zext"
8898   [(set (reg FLAGS_REG)
8899         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8900                             (match_operand:SI 2 "general_operand" "g"))
8901                  (const_int 0)))
8902    (set (match_operand:DI 0 "register_operand" "=r")
8903         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8904   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8905    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8906   "<logic>{l}\t{%2, %k0|%k0, %2}"
8907   [(set_attr "type" "alu")
8908    (set_attr "mode" "SI")])
8909
8910 (define_insn "*<code>si_2_zext_imm"
8911   [(set (reg FLAGS_REG)
8912         (compare (any_or:SI
8913                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8914                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8915                  (const_int 0)))
8916    (set (match_operand:DI 0 "register_operand" "=r")
8917         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8918   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8919    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8920   "<logic>{l}\t{%2, %k0|%k0, %2}"
8921   [(set_attr "type" "alu")
8922    (set_attr "mode" "SI")])
8923
8924 (define_insn "*<code>qi_2_slp"
8925   [(set (reg FLAGS_REG)
8926         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8927                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8928                  (const_int 0)))
8929    (set (strict_low_part (match_dup 0))
8930         (any_or:QI (match_dup 0) (match_dup 1)))]
8931   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8932    && ix86_match_ccmode (insn, CCNOmode)
8933    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8934   "<logic>{b}\t{%1, %0|%0, %1}"
8935   [(set_attr "type" "alu1")
8936    (set_attr "mode" "QI")])
8937
8938 (define_insn "*<code><mode>_3"
8939   [(set (reg FLAGS_REG)
8940         (compare (any_or:SWI
8941                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8942                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8943                  (const_int 0)))
8944    (clobber (match_scratch:SWI 0 "=<r>"))]
8945   "ix86_match_ccmode (insn, CCNOmode)
8946    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8947   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8948   [(set_attr "type" "alu")
8949    (set_attr "mode" "<MODE>")])
8950
8951 (define_insn "*<code>qi_ext_0"
8952   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8953                          (const_int 8)
8954                          (const_int 8))
8955         (any_or:SI
8956           (zero_extract:SI
8957             (match_operand 1 "ext_register_operand" "0")
8958             (const_int 8)
8959             (const_int 8))
8960           (match_operand 2 "const_int_operand" "n")))
8961    (clobber (reg:CC FLAGS_REG))]
8962   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8963   "<logic>{b}\t{%2, %h0|%h0, %2}"
8964   [(set_attr "type" "alu")
8965    (set_attr "length_immediate" "1")
8966    (set_attr "modrm" "1")
8967    (set_attr "mode" "QI")])
8968
8969 (define_insn "*<code>qi_ext_1_rex64"
8970   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8971                          (const_int 8)
8972                          (const_int 8))
8973         (any_or:SI
8974           (zero_extract:SI
8975             (match_operand 1 "ext_register_operand" "0")
8976             (const_int 8)
8977             (const_int 8))
8978           (zero_extend:SI
8979             (match_operand 2 "ext_register_operand" "Q"))))
8980    (clobber (reg:CC FLAGS_REG))]
8981   "TARGET_64BIT
8982    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8983   "<logic>{b}\t{%2, %h0|%h0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "length_immediate" "0")
8986    (set_attr "mode" "QI")])
8987
8988 (define_insn "*<code>qi_ext_1"
8989   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8990                          (const_int 8)
8991                          (const_int 8))
8992         (any_or:SI
8993           (zero_extract:SI
8994             (match_operand 1 "ext_register_operand" "0")
8995             (const_int 8)
8996             (const_int 8))
8997           (zero_extend:SI
8998             (match_operand:QI 2 "general_operand" "Qm"))))
8999    (clobber (reg:CC FLAGS_REG))]
9000   "!TARGET_64BIT
9001    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9002   "<logic>{b}\t{%2, %h0|%h0, %2}"
9003   [(set_attr "type" "alu")
9004    (set_attr "length_immediate" "0")
9005    (set_attr "mode" "QI")])
9006
9007 (define_insn "*<code>qi_ext_2"
9008   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9009                          (const_int 8)
9010                          (const_int 8))
9011         (any_or:SI
9012           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9013                            (const_int 8)
9014                            (const_int 8))
9015           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9016                            (const_int 8)
9017                            (const_int 8))))
9018    (clobber (reg:CC FLAGS_REG))]
9019   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9020   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9021   [(set_attr "type" "alu")
9022    (set_attr "length_immediate" "0")
9023    (set_attr "mode" "QI")])
9024
9025 (define_split
9026   [(set (match_operand 0 "register_operand" "")
9027         (any_or (match_operand 1 "register_operand" "")
9028                 (match_operand 2 "const_int_operand" "")))
9029    (clobber (reg:CC FLAGS_REG))]
9030    "reload_completed
9031     && QI_REG_P (operands[0])
9032     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9033     && !(INTVAL (operands[2]) & ~(255 << 8))
9034     && GET_MODE (operands[0]) != QImode"
9035   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9036                    (any_or:SI (zero_extract:SI (match_dup 1)
9037                                                (const_int 8) (const_int 8))
9038                               (match_dup 2)))
9039               (clobber (reg:CC FLAGS_REG))])]
9040   "operands[0] = gen_lowpart (SImode, operands[0]);
9041    operands[1] = gen_lowpart (SImode, operands[1]);
9042    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9043
9044 ;; Since OR can be encoded with sign extended immediate, this is only
9045 ;; profitable when 7th bit is set.
9046 (define_split
9047   [(set (match_operand 0 "register_operand" "")
9048         (any_or (match_operand 1 "general_operand" "")
9049                 (match_operand 2 "const_int_operand" "")))
9050    (clobber (reg:CC FLAGS_REG))]
9051    "reload_completed
9052     && ANY_QI_REG_P (operands[0])
9053     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9054     && !(INTVAL (operands[2]) & ~255)
9055     && (INTVAL (operands[2]) & 128)
9056     && GET_MODE (operands[0]) != QImode"
9057   [(parallel [(set (strict_low_part (match_dup 0))
9058                    (any_or:QI (match_dup 1)
9059                               (match_dup 2)))
9060               (clobber (reg:CC FLAGS_REG))])]
9061   "operands[0] = gen_lowpart (QImode, operands[0]);
9062    operands[1] = gen_lowpart (QImode, operands[1]);
9063    operands[2] = gen_lowpart (QImode, operands[2]);")
9064
9065 (define_expand "xorqi_cc_ext_1"
9066   [(parallel [
9067      (set (reg:CCNO FLAGS_REG)
9068           (compare:CCNO
9069             (xor:SI
9070               (zero_extract:SI
9071                 (match_operand 1 "ext_register_operand" "")
9072                 (const_int 8)
9073                 (const_int 8))
9074               (match_operand:QI 2 "general_operand" ""))
9075             (const_int 0)))
9076      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9077                            (const_int 8)
9078                            (const_int 8))
9079           (xor:SI
9080             (zero_extract:SI
9081              (match_dup 1)
9082              (const_int 8)
9083              (const_int 8))
9084             (match_dup 2)))])]
9085   ""
9086   "")
9087
9088 (define_insn "*xorqi_cc_ext_1_rex64"
9089   [(set (reg FLAGS_REG)
9090         (compare
9091           (xor:SI
9092             (zero_extract:SI
9093               (match_operand 1 "ext_register_operand" "0")
9094               (const_int 8)
9095               (const_int 8))
9096             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9097           (const_int 0)))
9098    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9099                          (const_int 8)
9100                          (const_int 8))
9101         (xor:SI
9102           (zero_extract:SI
9103            (match_dup 1)
9104            (const_int 8)
9105            (const_int 8))
9106           (match_dup 2)))]
9107   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9108   "xor{b}\t{%2, %h0|%h0, %2}"
9109   [(set_attr "type" "alu")
9110    (set_attr "modrm" "1")
9111    (set_attr "mode" "QI")])
9112
9113 (define_insn "*xorqi_cc_ext_1"
9114   [(set (reg FLAGS_REG)
9115         (compare
9116           (xor:SI
9117             (zero_extract:SI
9118               (match_operand 1 "ext_register_operand" "0")
9119               (const_int 8)
9120               (const_int 8))
9121             (match_operand:QI 2 "general_operand" "qmn"))
9122           (const_int 0)))
9123    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9124                          (const_int 8)
9125                          (const_int 8))
9126         (xor:SI
9127           (zero_extract:SI
9128            (match_dup 1)
9129            (const_int 8)
9130            (const_int 8))
9131           (match_dup 2)))]
9132   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9133   "xor{b}\t{%2, %h0|%h0, %2}"
9134   [(set_attr "type" "alu")
9135    (set_attr "modrm" "1")
9136    (set_attr "mode" "QI")])
9137 \f
9138 ;; Negation instructions
9139
9140 (define_expand "neg<mode>2"
9141   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9142         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9143   ""
9144   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9145
9146 (define_insn_and_split "*neg<dwi>2_doubleword"
9147   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9148         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9149    (clobber (reg:CC FLAGS_REG))]
9150   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9151   "#"
9152   "reload_completed"
9153   [(parallel
9154     [(set (reg:CCZ FLAGS_REG)
9155           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9156      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9157    (parallel
9158     [(set (match_dup 2)
9159           (plus:DWIH (match_dup 3)
9160                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9161                                 (const_int 0))))
9162      (clobber (reg:CC FLAGS_REG))])
9163    (parallel
9164     [(set (match_dup 2)
9165           (neg:DWIH (match_dup 2)))
9166      (clobber (reg:CC FLAGS_REG))])]
9167   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9168
9169 (define_insn "*neg<mode>2_1"
9170   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9171         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9172    (clobber (reg:CC FLAGS_REG))]
9173   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9174   "neg{<imodesuffix>}\t%0"
9175   [(set_attr "type" "negnot")
9176    (set_attr "mode" "<MODE>")])
9177
9178 ;; Combine is quite creative about this pattern.
9179 (define_insn "*negsi2_1_zext"
9180   [(set (match_operand:DI 0 "register_operand" "=r")
9181         (lshiftrt:DI
9182           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9183                              (const_int 32)))
9184         (const_int 32)))
9185    (clobber (reg:CC FLAGS_REG))]
9186   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9187   "neg{l}\t%k0"
9188   [(set_attr "type" "negnot")
9189    (set_attr "mode" "SI")])
9190
9191 ;; The problem with neg is that it does not perform (compare x 0),
9192 ;; it really performs (compare 0 x), which leaves us with the zero
9193 ;; flag being the only useful item.
9194
9195 (define_insn "*neg<mode>2_cmpz"
9196   [(set (reg:CCZ FLAGS_REG)
9197         (compare:CCZ
9198           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9199                    (const_int 0)))
9200    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9201         (neg:SWI (match_dup 1)))]
9202   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9203   "neg{<imodesuffix>}\t%0"
9204   [(set_attr "type" "negnot")
9205    (set_attr "mode" "<MODE>")])
9206
9207 (define_insn "*negsi2_cmpz_zext"
9208   [(set (reg:CCZ FLAGS_REG)
9209         (compare:CCZ
9210           (lshiftrt:DI
9211             (neg:DI (ashift:DI
9212                       (match_operand:DI 1 "register_operand" "0")
9213                       (const_int 32)))
9214             (const_int 32))
9215           (const_int 0)))
9216    (set (match_operand:DI 0 "register_operand" "=r")
9217         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9218                                         (const_int 32)))
9219                      (const_int 32)))]
9220   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9221   "neg{l}\t%k0"
9222   [(set_attr "type" "negnot")
9223    (set_attr "mode" "SI")])
9224
9225 ;; Changing of sign for FP values is doable using integer unit too.
9226
9227 (define_expand "<code><mode>2"
9228   [(set (match_operand:X87MODEF 0 "register_operand" "")
9229         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9230   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9231   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9232
9233 (define_insn "*absneg<mode>2_mixed"
9234   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9235         (match_operator:MODEF 3 "absneg_operator"
9236           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9237    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9238    (clobber (reg:CC FLAGS_REG))]
9239   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9240   "#")
9241
9242 (define_insn "*absneg<mode>2_sse"
9243   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9244         (match_operator:MODEF 3 "absneg_operator"
9245           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9246    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9247    (clobber (reg:CC FLAGS_REG))]
9248   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9249   "#")
9250
9251 (define_insn "*absneg<mode>2_i387"
9252   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9253         (match_operator:X87MODEF 3 "absneg_operator"
9254           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9255    (use (match_operand 2 "" ""))
9256    (clobber (reg:CC FLAGS_REG))]
9257   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9258   "#")
9259
9260 (define_expand "<code>tf2"
9261   [(set (match_operand:TF 0 "register_operand" "")
9262         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9263   "TARGET_SSE2"
9264   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9265
9266 (define_insn "*absnegtf2_sse"
9267   [(set (match_operand:TF 0 "register_operand" "=x,x")
9268         (match_operator:TF 3 "absneg_operator"
9269           [(match_operand:TF 1 "register_operand" "0,x")]))
9270    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9271    (clobber (reg:CC FLAGS_REG))]
9272   "TARGET_SSE2"
9273   "#")
9274
9275 ;; Splitters for fp abs and neg.
9276
9277 (define_split
9278   [(set (match_operand 0 "fp_register_operand" "")
9279         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9280    (use (match_operand 2 "" ""))
9281    (clobber (reg:CC FLAGS_REG))]
9282   "reload_completed"
9283   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9284
9285 (define_split
9286   [(set (match_operand 0 "register_operand" "")
9287         (match_operator 3 "absneg_operator"
9288           [(match_operand 1 "register_operand" "")]))
9289    (use (match_operand 2 "nonimmediate_operand" ""))
9290    (clobber (reg:CC FLAGS_REG))]
9291   "reload_completed && SSE_REG_P (operands[0])"
9292   [(set (match_dup 0) (match_dup 3))]
9293 {
9294   enum machine_mode mode = GET_MODE (operands[0]);
9295   enum machine_mode vmode = GET_MODE (operands[2]);
9296   rtx tmp;
9297
9298   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9299   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9300   if (operands_match_p (operands[0], operands[2]))
9301     {
9302       tmp = operands[1];
9303       operands[1] = operands[2];
9304       operands[2] = tmp;
9305     }
9306   if (GET_CODE (operands[3]) == ABS)
9307     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9308   else
9309     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9310   operands[3] = tmp;
9311 })
9312
9313 (define_split
9314   [(set (match_operand:SF 0 "register_operand" "")
9315         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9316    (use (match_operand:V4SF 2 "" ""))
9317    (clobber (reg:CC FLAGS_REG))]
9318   "reload_completed"
9319   [(parallel [(set (match_dup 0) (match_dup 1))
9320               (clobber (reg:CC FLAGS_REG))])]
9321 {
9322   rtx tmp;
9323   operands[0] = gen_lowpart (SImode, operands[0]);
9324   if (GET_CODE (operands[1]) == ABS)
9325     {
9326       tmp = gen_int_mode (0x7fffffff, SImode);
9327       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9328     }
9329   else
9330     {
9331       tmp = gen_int_mode (0x80000000, SImode);
9332       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9333     }
9334   operands[1] = tmp;
9335 })
9336
9337 (define_split
9338   [(set (match_operand:DF 0 "register_operand" "")
9339         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9340    (use (match_operand 2 "" ""))
9341    (clobber (reg:CC FLAGS_REG))]
9342   "reload_completed"
9343   [(parallel [(set (match_dup 0) (match_dup 1))
9344               (clobber (reg:CC FLAGS_REG))])]
9345 {
9346   rtx tmp;
9347   if (TARGET_64BIT)
9348     {
9349       tmp = gen_lowpart (DImode, operands[0]);
9350       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9351       operands[0] = tmp;
9352
9353       if (GET_CODE (operands[1]) == ABS)
9354         tmp = const0_rtx;
9355       else
9356         tmp = gen_rtx_NOT (DImode, tmp);
9357     }
9358   else
9359     {
9360       operands[0] = gen_highpart (SImode, operands[0]);
9361       if (GET_CODE (operands[1]) == ABS)
9362         {
9363           tmp = gen_int_mode (0x7fffffff, SImode);
9364           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9365         }
9366       else
9367         {
9368           tmp = gen_int_mode (0x80000000, SImode);
9369           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9370         }
9371     }
9372   operands[1] = tmp;
9373 })
9374
9375 (define_split
9376   [(set (match_operand:XF 0 "register_operand" "")
9377         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9378    (use (match_operand 2 "" ""))
9379    (clobber (reg:CC FLAGS_REG))]
9380   "reload_completed"
9381   [(parallel [(set (match_dup 0) (match_dup 1))
9382               (clobber (reg:CC FLAGS_REG))])]
9383 {
9384   rtx tmp;
9385   operands[0] = gen_rtx_REG (SImode,
9386                              true_regnum (operands[0])
9387                              + (TARGET_64BIT ? 1 : 2));
9388   if (GET_CODE (operands[1]) == ABS)
9389     {
9390       tmp = GEN_INT (0x7fff);
9391       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9392     }
9393   else
9394     {
9395       tmp = GEN_INT (0x8000);
9396       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9397     }
9398   operands[1] = tmp;
9399 })
9400
9401 ;; Conditionalize these after reload. If they match before reload, we
9402 ;; lose the clobber and ability to use integer instructions.
9403
9404 (define_insn "*<code><mode>2_1"
9405   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9406         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9407   "TARGET_80387
9408    && (reload_completed
9409        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9410   "f<absneg_mnemonic>"
9411   [(set_attr "type" "fsgn")
9412    (set_attr "mode" "<MODE>")])
9413
9414 (define_insn "*<code>extendsfdf2"
9415   [(set (match_operand:DF 0 "register_operand" "=f")
9416         (absneg:DF (float_extend:DF
9417                      (match_operand:SF 1 "register_operand" "0"))))]
9418   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9419   "f<absneg_mnemonic>"
9420   [(set_attr "type" "fsgn")
9421    (set_attr "mode" "DF")])
9422
9423 (define_insn "*<code>extendsfxf2"
9424   [(set (match_operand:XF 0 "register_operand" "=f")
9425         (absneg:XF (float_extend:XF
9426                      (match_operand:SF 1 "register_operand" "0"))))]
9427   "TARGET_80387"
9428   "f<absneg_mnemonic>"
9429   [(set_attr "type" "fsgn")
9430    (set_attr "mode" "XF")])
9431
9432 (define_insn "*<code>extenddfxf2"
9433   [(set (match_operand:XF 0 "register_operand" "=f")
9434         (absneg:XF (float_extend:XF
9435                      (match_operand:DF 1 "register_operand" "0"))))]
9436   "TARGET_80387"
9437   "f<absneg_mnemonic>"
9438   [(set_attr "type" "fsgn")
9439    (set_attr "mode" "XF")])
9440
9441 ;; Copysign instructions
9442
9443 (define_mode_iterator CSGNMODE [SF DF TF])
9444 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9445
9446 (define_expand "copysign<mode>3"
9447   [(match_operand:CSGNMODE 0 "register_operand" "")
9448    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9449    (match_operand:CSGNMODE 2 "register_operand" "")]
9450   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9451    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9452 {
9453   ix86_expand_copysign (operands);
9454   DONE;
9455 })
9456
9457 (define_insn_and_split "copysign<mode>3_const"
9458   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9459         (unspec:CSGNMODE
9460           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9461            (match_operand:CSGNMODE 2 "register_operand" "0")
9462            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9463           UNSPEC_COPYSIGN))]
9464   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9465    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9466   "#"
9467   "&& reload_completed"
9468   [(const_int 0)]
9469 {
9470   ix86_split_copysign_const (operands);
9471   DONE;
9472 })
9473
9474 (define_insn "copysign<mode>3_var"
9475   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9476         (unspec:CSGNMODE
9477           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9478            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9479            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9480            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9481           UNSPEC_COPYSIGN))
9482    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9483   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9484    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9485   "#")
9486
9487 (define_split
9488   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9489         (unspec:CSGNMODE
9490           [(match_operand:CSGNMODE 2 "register_operand" "")
9491            (match_operand:CSGNMODE 3 "register_operand" "")
9492            (match_operand:<CSGNVMODE> 4 "" "")
9493            (match_operand:<CSGNVMODE> 5 "" "")]
9494           UNSPEC_COPYSIGN))
9495    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9496   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9497     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9498    && reload_completed"
9499   [(const_int 0)]
9500 {
9501   ix86_split_copysign_var (operands);
9502   DONE;
9503 })
9504 \f
9505 ;; One complement instructions
9506
9507 (define_expand "one_cmpl<mode>2"
9508   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9509         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9510   ""
9511   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9512
9513 (define_insn "*one_cmpl<mode>2_1"
9514   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9515         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9516   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9517   "not{<imodesuffix>}\t%0"
9518   [(set_attr "type" "negnot")
9519    (set_attr "mode" "<MODE>")])
9520
9521 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9522 (define_insn "*one_cmplqi2_1"
9523   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9524         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9525   "ix86_unary_operator_ok (NOT, QImode, operands)"
9526   "@
9527    not{b}\t%0
9528    not{l}\t%k0"
9529   [(set_attr "type" "negnot")
9530    (set_attr "mode" "QI,SI")])
9531
9532 ;; ??? Currently never generated - xor is used instead.
9533 (define_insn "*one_cmplsi2_1_zext"
9534   [(set (match_operand:DI 0 "register_operand" "=r")
9535         (zero_extend:DI
9536           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9537   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9538   "not{l}\t%k0"
9539   [(set_attr "type" "negnot")
9540    (set_attr "mode" "SI")])
9541
9542 (define_insn "*one_cmpl<mode>2_2"
9543   [(set (reg FLAGS_REG)
9544         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9545                  (const_int 0)))
9546    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9547         (not:SWI (match_dup 1)))]
9548   "ix86_match_ccmode (insn, CCNOmode)
9549    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9550   "#"
9551   [(set_attr "type" "alu1")
9552    (set_attr "mode" "<MODE>")])
9553
9554 (define_split
9555   [(set (match_operand 0 "flags_reg_operand" "")
9556         (match_operator 2 "compare_operator"
9557           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9558            (const_int 0)]))
9559    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9560         (not:SWI (match_dup 3)))]
9561   "ix86_match_ccmode (insn, CCNOmode)"
9562   [(parallel [(set (match_dup 0)
9563                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9564                                     (const_int 0)]))
9565               (set (match_dup 1)
9566                    (xor:SWI (match_dup 3) (const_int -1)))])]
9567   "")
9568
9569 ;; ??? Currently never generated - xor is used instead.
9570 (define_insn "*one_cmplsi2_2_zext"
9571   [(set (reg FLAGS_REG)
9572         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9573                  (const_int 0)))
9574    (set (match_operand:DI 0 "register_operand" "=r")
9575         (zero_extend:DI (not:SI (match_dup 1))))]
9576   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9577    && ix86_unary_operator_ok (NOT, SImode, operands)"
9578   "#"
9579   [(set_attr "type" "alu1")
9580    (set_attr "mode" "SI")])
9581
9582 (define_split
9583   [(set (match_operand 0 "flags_reg_operand" "")
9584         (match_operator 2 "compare_operator"
9585           [(not:SI (match_operand:SI 3 "register_operand" ""))
9586            (const_int 0)]))
9587    (set (match_operand:DI 1 "register_operand" "")
9588         (zero_extend:DI (not:SI (match_dup 3))))]
9589   "ix86_match_ccmode (insn, CCNOmode)"
9590   [(parallel [(set (match_dup 0)
9591                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9592                                     (const_int 0)]))
9593               (set (match_dup 1)
9594                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9595   "")
9596 \f
9597 ;; Shift instructions
9598
9599 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9600 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9601 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9602 ;; from the assembler input.
9603 ;;
9604 ;; This instruction shifts the target reg/mem as usual, but instead of
9605 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9606 ;; is a left shift double, bits are taken from the high order bits of
9607 ;; reg, else if the insn is a shift right double, bits are taken from the
9608 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9609 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9610 ;;
9611 ;; Since sh[lr]d does not change the `reg' operand, that is done
9612 ;; separately, making all shifts emit pairs of shift double and normal
9613 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9614 ;; support a 63 bit shift, each shift where the count is in a reg expands
9615 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9616 ;;
9617 ;; If the shift count is a constant, we need never emit more than one
9618 ;; shift pair, instead using moves and sign extension for counts greater
9619 ;; than 31.
9620
9621 (define_expand "ashl<mode>3"
9622   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9623         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9624                       (match_operand:QI 2 "nonmemory_operand" "")))]
9625   ""
9626   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9627
9628 (define_insn "*ashl<mode>3_doubleword"
9629   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9630         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9631                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9632    (clobber (reg:CC FLAGS_REG))]
9633   ""
9634   "#"
9635   [(set_attr "type" "multi")])
9636
9637 (define_split
9638   [(set (match_operand:DWI 0 "register_operand" "")
9639         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9640                     (match_operand:QI 2 "nonmemory_operand" "")))
9641    (clobber (reg:CC FLAGS_REG))]
9642   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9643   [(const_int 0)]
9644   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9645
9646 ;; By default we don't ask for a scratch register, because when DWImode
9647 ;; values are manipulated, registers are already at a premium.  But if
9648 ;; we have one handy, we won't turn it away.
9649
9650 (define_peephole2
9651   [(match_scratch:DWIH 3 "r")
9652    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9653                    (ashift:<DWI>
9654                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9655                      (match_operand:QI 2 "nonmemory_operand" "")))
9656               (clobber (reg:CC FLAGS_REG))])
9657    (match_dup 3)]
9658   "TARGET_CMOVE"
9659   [(const_int 0)]
9660   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9661
9662 (define_insn "x86_64_shld"
9663   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9664         (ior:DI (ashift:DI (match_dup 0)
9665                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9666                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9667                   (minus:QI (const_int 64) (match_dup 2)))))
9668    (clobber (reg:CC FLAGS_REG))]
9669   "TARGET_64BIT"
9670   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9671   [(set_attr "type" "ishift")
9672    (set_attr "prefix_0f" "1")
9673    (set_attr "mode" "DI")
9674    (set_attr "athlon_decode" "vector")
9675    (set_attr "amdfam10_decode" "vector")])
9676
9677 (define_insn "x86_shld"
9678   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9679         (ior:SI (ashift:SI (match_dup 0)
9680                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9681                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9682                   (minus:QI (const_int 32) (match_dup 2)))))
9683    (clobber (reg:CC FLAGS_REG))]
9684   ""
9685   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9686   [(set_attr "type" "ishift")
9687    (set_attr "prefix_0f" "1")
9688    (set_attr "mode" "SI")
9689    (set_attr "pent_pair" "np")
9690    (set_attr "athlon_decode" "vector")
9691    (set_attr "amdfam10_decode" "vector")])
9692
9693 (define_expand "x86_shift<mode>_adj_1"
9694   [(set (reg:CCZ FLAGS_REG)
9695         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9696                              (match_dup 4))
9697                      (const_int 0)))
9698    (set (match_operand:SWI48 0 "register_operand" "")
9699         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9700                             (match_operand:SWI48 1 "register_operand" "")
9701                             (match_dup 0)))
9702    (set (match_dup 1)
9703         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9704                             (match_operand:SWI48 3 "register_operand" "r")
9705                             (match_dup 1)))]
9706   "TARGET_CMOVE"
9707   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9708
9709 (define_expand "x86_shift<mode>_adj_2"
9710   [(use (match_operand:SWI48 0 "register_operand" ""))
9711    (use (match_operand:SWI48 1 "register_operand" ""))
9712    (use (match_operand:QI 2 "register_operand" ""))]
9713   ""
9714 {
9715   rtx label = gen_label_rtx ();
9716   rtx tmp;
9717
9718   emit_insn (gen_testqi_ccz_1 (operands[2],
9719                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9720
9721   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9722   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9723   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9724                               gen_rtx_LABEL_REF (VOIDmode, label),
9725                               pc_rtx);
9726   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9727   JUMP_LABEL (tmp) = label;
9728
9729   emit_move_insn (operands[0], operands[1]);
9730   ix86_expand_clear (operands[1]);
9731
9732   emit_label (label);
9733   LABEL_NUSES (label) = 1;
9734
9735   DONE;
9736 })
9737
9738 (define_insn "*ashl<mode>3_1"
9739   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9740         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9741                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9742    (clobber (reg:CC FLAGS_REG))]
9743   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9744 {
9745   switch (get_attr_type (insn))
9746     {
9747     case TYPE_LEA:
9748       return "#";
9749
9750     case TYPE_ALU:
9751       gcc_assert (operands[2] == const1_rtx);
9752       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9753       return "add{<imodesuffix>}\t%0, %0";
9754
9755     default:
9756       if (operands[2] == const1_rtx
9757           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9758         return "sal{<imodesuffix>}\t%0";
9759       else
9760         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9761     }
9762 }
9763   [(set (attr "type")
9764      (cond [(eq_attr "alternative" "1")
9765               (const_string "lea")
9766             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9767                           (const_int 0))
9768                       (match_operand 0 "register_operand" ""))
9769                  (match_operand 2 "const1_operand" ""))
9770               (const_string "alu")
9771            ]
9772            (const_string "ishift")))
9773    (set (attr "length_immediate")
9774      (if_then_else
9775        (ior (eq_attr "type" "alu")
9776             (and (eq_attr "type" "ishift")
9777                  (and (match_operand 2 "const1_operand" "")
9778                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9779                           (const_int 0)))))
9780        (const_string "0")
9781        (const_string "*")))
9782    (set_attr "mode" "<MODE>")])
9783
9784 (define_insn "*ashlsi3_1_zext"
9785   [(set (match_operand:DI 0 "register_operand" "=r,r")
9786         (zero_extend:DI
9787           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9788                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9789    (clobber (reg:CC FLAGS_REG))]
9790   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9791 {
9792   switch (get_attr_type (insn))
9793     {
9794     case TYPE_LEA:
9795       return "#";
9796
9797     case TYPE_ALU:
9798       gcc_assert (operands[2] == const1_rtx);
9799       return "add{l}\t%k0, %k0";
9800
9801     default:
9802       if (operands[2] == const1_rtx
9803           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9804         return "sal{l}\t%k0";
9805       else
9806         return "sal{l}\t{%2, %k0|%k0, %2}";
9807     }
9808 }
9809   [(set (attr "type")
9810      (cond [(eq_attr "alternative" "1")
9811               (const_string "lea")
9812             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9813                      (const_int 0))
9814                  (match_operand 2 "const1_operand" ""))
9815               (const_string "alu")
9816            ]
9817            (const_string "ishift")))
9818    (set (attr "length_immediate")
9819      (if_then_else
9820        (ior (eq_attr "type" "alu")
9821             (and (eq_attr "type" "ishift")
9822                  (and (match_operand 2 "const1_operand" "")
9823                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9824                           (const_int 0)))))
9825        (const_string "0")
9826        (const_string "*")))
9827    (set_attr "mode" "SI")])
9828
9829 (define_insn "*ashlhi3_1"
9830   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9831         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9832                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9833    (clobber (reg:CC FLAGS_REG))]
9834   "TARGET_PARTIAL_REG_STALL
9835    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9836 {
9837   switch (get_attr_type (insn))
9838     {
9839     case TYPE_ALU:
9840       gcc_assert (operands[2] == const1_rtx);
9841       return "add{w}\t%0, %0";
9842
9843     default:
9844       if (operands[2] == const1_rtx
9845           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9846         return "sal{w}\t%0";
9847       else
9848         return "sal{w}\t{%2, %0|%0, %2}";
9849     }
9850 }
9851   [(set (attr "type")
9852      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9853                           (const_int 0))
9854                       (match_operand 0 "register_operand" ""))
9855                  (match_operand 2 "const1_operand" ""))
9856               (const_string "alu")
9857            ]
9858            (const_string "ishift")))
9859    (set (attr "length_immediate")
9860      (if_then_else
9861        (ior (eq_attr "type" "alu")
9862             (and (eq_attr "type" "ishift")
9863                  (and (match_operand 2 "const1_operand" "")
9864                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9865                           (const_int 0)))))
9866        (const_string "0")
9867        (const_string "*")))
9868    (set_attr "mode" "HI")])
9869
9870 (define_insn "*ashlhi3_1_lea"
9871   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9872         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9873                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9874    (clobber (reg:CC FLAGS_REG))]
9875   "!TARGET_PARTIAL_REG_STALL
9876    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9877 {
9878   switch (get_attr_type (insn))
9879     {
9880     case TYPE_LEA:
9881       return "#";
9882
9883     case TYPE_ALU:
9884       gcc_assert (operands[2] == const1_rtx);
9885       return "add{w}\t%0, %0";
9886
9887     default:
9888       if (operands[2] == const1_rtx
9889           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9890         return "sal{w}\t%0";
9891       else
9892         return "sal{w}\t{%2, %0|%0, %2}";
9893     }
9894 }
9895   [(set (attr "type")
9896      (cond [(eq_attr "alternative" "1")
9897               (const_string "lea")
9898             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9899                           (const_int 0))
9900                       (match_operand 0 "register_operand" ""))
9901                  (match_operand 2 "const1_operand" ""))
9902               (const_string "alu")
9903            ]
9904            (const_string "ishift")))
9905    (set (attr "length_immediate")
9906      (if_then_else
9907        (ior (eq_attr "type" "alu")
9908             (and (eq_attr "type" "ishift")
9909                  (and (match_operand 2 "const1_operand" "")
9910                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9911                           (const_int 0)))))
9912        (const_string "0")
9913        (const_string "*")))
9914    (set_attr "mode" "HI,SI")])
9915
9916 (define_insn "*ashlqi3_1"
9917   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9918         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9919                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9920    (clobber (reg:CC FLAGS_REG))]
9921   "TARGET_PARTIAL_REG_STALL
9922    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9923 {
9924   switch (get_attr_type (insn))
9925     {
9926     case TYPE_ALU:
9927       gcc_assert (operands[2] == const1_rtx);
9928       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9929         return "add{l}\t%k0, %k0";
9930       else
9931         return "add{b}\t%0, %0";
9932
9933     default:
9934       if (operands[2] == const1_rtx
9935           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9936         {
9937           if (get_attr_mode (insn) == MODE_SI)
9938             return "sal{l}\t%k0";
9939           else
9940             return "sal{b}\t%0";
9941         }
9942       else
9943         {
9944           if (get_attr_mode (insn) == MODE_SI)
9945             return "sal{l}\t{%2, %k0|%k0, %2}";
9946           else
9947             return "sal{b}\t{%2, %0|%0, %2}";
9948         }
9949     }
9950 }
9951   [(set (attr "type")
9952      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9953                           (const_int 0))
9954                       (match_operand 0 "register_operand" ""))
9955                  (match_operand 2 "const1_operand" ""))
9956               (const_string "alu")
9957            ]
9958            (const_string "ishift")))
9959    (set (attr "length_immediate")
9960      (if_then_else
9961        (ior (eq_attr "type" "alu")
9962             (and (eq_attr "type" "ishift")
9963                  (and (match_operand 2 "const1_operand" "")
9964                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9965                           (const_int 0)))))
9966        (const_string "0")
9967        (const_string "*")))
9968    (set_attr "mode" "QI,SI")])
9969
9970 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9971 (define_insn "*ashlqi3_1_lea"
9972   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9973         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9974                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9975    (clobber (reg:CC FLAGS_REG))]
9976   "!TARGET_PARTIAL_REG_STALL
9977    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9978 {
9979   switch (get_attr_type (insn))
9980     {
9981     case TYPE_LEA:
9982       return "#";
9983
9984     case TYPE_ALU:
9985       gcc_assert (operands[2] == const1_rtx);
9986       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9987         return "add{l}\t%k0, %k0";
9988       else
9989         return "add{b}\t%0, %0";
9990
9991     default:
9992       if (operands[2] == const1_rtx
9993           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9994         {
9995           if (get_attr_mode (insn) == MODE_SI)
9996             return "sal{l}\t%k0";
9997           else
9998             return "sal{b}\t%0";
9999         }
10000       else
10001         {
10002           if (get_attr_mode (insn) == MODE_SI)
10003             return "sal{l}\t{%2, %k0|%k0, %2}";
10004           else
10005             return "sal{b}\t{%2, %0|%0, %2}";
10006         }
10007     }
10008 }
10009   [(set (attr "type")
10010      (cond [(eq_attr "alternative" "2")
10011               (const_string "lea")
10012             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10013                           (const_int 0))
10014                       (match_operand 0 "register_operand" ""))
10015                  (match_operand 2 "const1_operand" ""))
10016               (const_string "alu")
10017            ]
10018            (const_string "ishift")))
10019    (set (attr "length_immediate")
10020      (if_then_else
10021        (ior (eq_attr "type" "alu")
10022             (and (eq_attr "type" "ishift")
10023                  (and (match_operand 2 "const1_operand" "")
10024                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10025                           (const_int 0)))))
10026        (const_string "0")
10027        (const_string "*")))
10028    (set_attr "mode" "QI,SI,SI")])
10029
10030 (define_insn "*ashlqi3_1_slp"
10031   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10032         (ashift:QI (match_dup 0)
10033                    (match_operand:QI 1 "nonmemory_operand" "cI")))
10034    (clobber (reg:CC FLAGS_REG))]
10035   "(optimize_function_for_size_p (cfun)
10036     || !TARGET_PARTIAL_FLAG_REG_STALL
10037     || (operands[1] == const1_rtx
10038         && (TARGET_SHIFT1
10039             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10040 {
10041   switch (get_attr_type (insn))
10042     {
10043     case TYPE_ALU:
10044       gcc_assert (operands[1] == const1_rtx);
10045       return "add{b}\t%0, %0";
10046
10047     default:
10048       if (operands[1] == const1_rtx
10049           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10050         return "sal{b}\t%0";
10051       else
10052         return "sal{b}\t{%1, %0|%0, %1}";
10053     }
10054 }
10055   [(set (attr "type")
10056      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10057                           (const_int 0))
10058                       (match_operand 0 "register_operand" ""))
10059                  (match_operand 1 "const1_operand" ""))
10060               (const_string "alu")
10061            ]
10062            (const_string "ishift1")))
10063    (set (attr "length_immediate")
10064      (if_then_else
10065        (ior (eq_attr "type" "alu")
10066             (and (eq_attr "type" "ishift1")
10067                  (and (match_operand 1 "const1_operand" "")
10068                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10069                           (const_int 0)))))
10070        (const_string "0")
10071        (const_string "*")))
10072    (set_attr "mode" "QI")])
10073
10074 ;; Convert lea to the lea pattern to avoid flags dependency.
10075 (define_split
10076   [(set (match_operand:DI 0 "register_operand" "")
10077         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10078                    (match_operand:QI 2 "const_int_operand" "")))
10079    (clobber (reg:CC FLAGS_REG))]
10080   "TARGET_64BIT && reload_completed
10081    && true_regnum (operands[0]) != true_regnum (operands[1])"
10082   [(set (match_dup 0)
10083         (mult:DI (match_dup 1)
10084                  (match_dup 2)))]
10085   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10086
10087 ;; Convert lea to the lea pattern to avoid flags dependency.
10088 (define_split
10089   [(set (match_operand 0 "register_operand" "")
10090         (ashift (match_operand 1 "index_register_operand" "")
10091                 (match_operand:QI 2 "const_int_operand" "")))
10092    (clobber (reg:CC FLAGS_REG))]
10093   "reload_completed
10094    && true_regnum (operands[0]) != true_regnum (operands[1])
10095    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10096   [(const_int 0)]
10097 {
10098   rtx pat;
10099   enum machine_mode mode = GET_MODE (operands[0]);
10100
10101   if (GET_MODE_SIZE (mode) < 4)
10102     operands[0] = gen_lowpart (SImode, operands[0]);
10103   if (mode != Pmode)
10104     operands[1] = gen_lowpart (Pmode, operands[1]);
10105   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10106
10107   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10108   if (Pmode != SImode)
10109     pat = gen_rtx_SUBREG (SImode, pat, 0);
10110   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10111   DONE;
10112 })
10113
10114 ;; Rare case of shifting RSP is handled by generating move and shift
10115 (define_split
10116   [(set (match_operand 0 "register_operand" "")
10117         (ashift (match_operand 1 "register_operand" "")
10118                 (match_operand:QI 2 "const_int_operand" "")))
10119    (clobber (reg:CC FLAGS_REG))]
10120   "reload_completed
10121    && true_regnum (operands[0]) != true_regnum (operands[1])"
10122   [(const_int 0)]
10123 {
10124   rtx pat, clob;
10125   emit_move_insn (operands[0], operands[1]);
10126   pat = gen_rtx_SET (VOIDmode, operands[0],
10127                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10128                                      operands[0], operands[2]));
10129   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10130   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10131   DONE;
10132 })
10133
10134 ;; Convert lea to the lea pattern to avoid flags dependency.
10135 (define_split
10136   [(set (match_operand:DI 0 "register_operand" "")
10137         (zero_extend:DI
10138           (ashift:SI (match_operand:SI 1 "register_operand" "")
10139                      (match_operand:QI 2 "const_int_operand" ""))))
10140    (clobber (reg:CC FLAGS_REG))]
10141   "TARGET_64BIT && reload_completed
10142    && true_regnum (operands[0]) != true_regnum (operands[1])"
10143   [(set (match_dup 0)
10144         (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10145 {
10146   operands[1] = gen_lowpart (Pmode, operands[1]);
10147   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10148 })
10149
10150 ;; This pattern can't accept a variable shift count, since shifts by
10151 ;; zero don't affect the flags.  We assume that shifts by constant
10152 ;; zero are optimized away.
10153 (define_insn "*ashl<mode>3_cmp"
10154   [(set (reg FLAGS_REG)
10155         (compare
10156           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10157                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10158           (const_int 0)))
10159    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10160         (ashift:SWI (match_dup 1) (match_dup 2)))]
10161   "(optimize_function_for_size_p (cfun)
10162     || !TARGET_PARTIAL_FLAG_REG_STALL
10163     || (operands[2] == const1_rtx
10164         && (TARGET_SHIFT1
10165             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10166    && ix86_match_ccmode (insn, CCGOCmode)
10167    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10168 {
10169   switch (get_attr_type (insn))
10170     {
10171     case TYPE_ALU:
10172       gcc_assert (operands[2] == const1_rtx);
10173       return "add{<imodesuffix>}\t%0, %0";
10174
10175     default:
10176       if (operands[2] == const1_rtx
10177           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10178         return "sal{<imodesuffix>}\t%0";
10179       else
10180         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10181     }
10182 }
10183   [(set (attr "type")
10184      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10185                           (const_int 0))
10186                       (match_operand 0 "register_operand" ""))
10187                  (match_operand 2 "const1_operand" ""))
10188               (const_string "alu")
10189            ]
10190            (const_string "ishift")))
10191    (set (attr "length_immediate")
10192      (if_then_else
10193        (ior (eq_attr "type" "alu")
10194             (and (eq_attr "type" "ishift")
10195                  (and (match_operand 2 "const1_operand" "")
10196                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10197                           (const_int 0)))))
10198        (const_string "0")
10199        (const_string "*")))
10200    (set_attr "mode" "<MODE>")])
10201
10202 (define_insn "*ashlsi3_cmp_zext"
10203   [(set (reg FLAGS_REG)
10204         (compare
10205           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10206                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10207           (const_int 0)))
10208    (set (match_operand:DI 0 "register_operand" "=r")
10209         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10210   "TARGET_64BIT
10211    && (optimize_function_for_size_p (cfun)
10212        || !TARGET_PARTIAL_FLAG_REG_STALL
10213        || (operands[2] == const1_rtx
10214            && (TARGET_SHIFT1
10215                || TARGET_DOUBLE_WITH_ADD)))
10216    && ix86_match_ccmode (insn, CCGOCmode)
10217    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10218 {
10219   switch (get_attr_type (insn))
10220     {
10221     case TYPE_ALU:
10222       gcc_assert (operands[2] == const1_rtx);
10223       return "add{l}\t%k0, %k0";
10224
10225     default:
10226       if (operands[2] == const1_rtx
10227           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10228         return "sal{l}\t%k0";
10229       else
10230         return "sal{l}\t{%2, %k0|%k0, %2}";
10231     }
10232 }
10233   [(set (attr "type")
10234      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10235                      (const_int 0))
10236                  (match_operand 2 "const1_operand" ""))
10237               (const_string "alu")
10238            ]
10239            (const_string "ishift")))
10240    (set (attr "length_immediate")
10241      (if_then_else
10242        (ior (eq_attr "type" "alu")
10243             (and (eq_attr "type" "ishift")
10244                  (and (match_operand 2 "const1_operand" "")
10245                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10246                           (const_int 0)))))
10247        (const_string "0")
10248        (const_string "*")))
10249    (set_attr "mode" "SI")])
10250
10251 (define_insn "*ashl<mode>3_cconly"
10252   [(set (reg FLAGS_REG)
10253         (compare
10254           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10255                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10256           (const_int 0)))
10257    (clobber (match_scratch:SWI 0 "=<r>"))]
10258   "(optimize_function_for_size_p (cfun)
10259     || !TARGET_PARTIAL_FLAG_REG_STALL
10260     || (operands[2] == const1_rtx
10261         && (TARGET_SHIFT1
10262             || TARGET_DOUBLE_WITH_ADD)))
10263    && ix86_match_ccmode (insn, CCGOCmode)
10264    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10265 {
10266   switch (get_attr_type (insn))
10267     {
10268     case TYPE_ALU:
10269       gcc_assert (operands[2] == const1_rtx);
10270       return "add{<imodesuffix>}\t%0, %0";
10271
10272     default:
10273       if (operands[2] == const1_rtx
10274           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10275         return "sal{<imodesuffix>}\t%0";
10276       else
10277         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10278     }
10279 }
10280   [(set (attr "type")
10281      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10282                           (const_int 0))
10283                       (match_operand 0 "register_operand" ""))
10284                  (match_operand 2 "const1_operand" ""))
10285               (const_string "alu")
10286            ]
10287            (const_string "ishift")))
10288    (set (attr "length_immediate")
10289      (if_then_else
10290        (ior (eq_attr "type" "alu")
10291             (and (eq_attr "type" "ishift")
10292                  (and (match_operand 2 "const1_operand" "")
10293                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10294                           (const_int 0)))))
10295        (const_string "0")
10296        (const_string "*")))
10297    (set_attr "mode" "<MODE>")])
10298
10299 ;; See comment above `ashl<mode>3' about how this works.
10300
10301 (define_expand "<shiftrt_insn><mode>3"
10302   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
10303         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
10304                            (match_operand:QI 2 "nonmemory_operand" "")))]
10305   ""
10306   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10307
10308 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
10309   [(set (match_operand:DWI 0 "register_operand" "=r")
10310         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10311                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10312    (clobber (reg:CC FLAGS_REG))]
10313   ""
10314   "#"
10315   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10316   [(const_int 0)]
10317   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10318   [(set_attr "type" "multi")])
10319
10320 ;; By default we don't ask for a scratch register, because when DWImode
10321 ;; values are manipulated, registers are already at a premium.  But if
10322 ;; we have one handy, we won't turn it away.
10323
10324 (define_peephole2
10325   [(match_scratch:DWIH 3 "r")
10326    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
10327                    (any_shiftrt:<DWI>
10328                      (match_operand:<DWI> 1 "register_operand" "")
10329                      (match_operand:QI 2 "nonmemory_operand" "")))
10330               (clobber (reg:CC FLAGS_REG))])
10331    (match_dup 3)]
10332   "TARGET_CMOVE"
10333   [(const_int 0)]
10334   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10335
10336 (define_insn "x86_64_shrd"
10337   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10338         (ior:DI (ashiftrt:DI (match_dup 0)
10339                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10340                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10341                   (minus:QI (const_int 64) (match_dup 2)))))
10342    (clobber (reg:CC FLAGS_REG))]
10343   "TARGET_64BIT"
10344   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10345   [(set_attr "type" "ishift")
10346    (set_attr "prefix_0f" "1")
10347    (set_attr "mode" "DI")
10348    (set_attr "athlon_decode" "vector")
10349    (set_attr "amdfam10_decode" "vector")])
10350
10351 (define_insn "x86_shrd"
10352   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10353         (ior:SI (ashiftrt:SI (match_dup 0)
10354                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10355                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10356                   (minus:QI (const_int 32) (match_dup 2)))))
10357    (clobber (reg:CC FLAGS_REG))]
10358   ""
10359   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10360   [(set_attr "type" "ishift")
10361    (set_attr "prefix_0f" "1")
10362    (set_attr "mode" "SI")
10363    (set_attr "pent_pair" "np")
10364    (set_attr "athlon_decode" "vector")
10365    (set_attr "amdfam10_decode" "vector")])
10366
10367 (define_insn "ashrdi3_cvt"
10368   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10369         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10370                      (match_operand:QI 2 "const_int_operand" "")))
10371    (clobber (reg:CC FLAGS_REG))]
10372   "TARGET_64BIT && INTVAL (operands[2]) == 63
10373    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10374    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10375   "@
10376    {cqto|cqo}
10377    sar{q}\t{%2, %0|%0, %2}"
10378   [(set_attr "type" "imovx,ishift")
10379    (set_attr "prefix_0f" "0,*")
10380    (set_attr "length_immediate" "0,*")
10381    (set_attr "modrm" "0,1")
10382    (set_attr "mode" "DI")])
10383
10384 (define_insn "ashrsi3_cvt"
10385   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10386         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10387                      (match_operand:QI 2 "const_int_operand" "")))
10388    (clobber (reg:CC FLAGS_REG))]
10389   "INTVAL (operands[2]) == 31
10390    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10391    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10392   "@
10393    {cltd|cdq}
10394    sar{l}\t{%2, %0|%0, %2}"
10395   [(set_attr "type" "imovx,ishift")
10396    (set_attr "prefix_0f" "0,*")
10397    (set_attr "length_immediate" "0,*")
10398    (set_attr "modrm" "0,1")
10399    (set_attr "mode" "SI")])
10400
10401 (define_insn "*ashrsi3_cvt_zext"
10402   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10403         (zero_extend:DI
10404           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10405                        (match_operand:QI 2 "const_int_operand" ""))))
10406    (clobber (reg:CC FLAGS_REG))]
10407   "TARGET_64BIT && INTVAL (operands[2]) == 31
10408    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10409    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10410   "@
10411    {cltd|cdq}
10412    sar{l}\t{%2, %k0|%k0, %2}"
10413   [(set_attr "type" "imovx,ishift")
10414    (set_attr "prefix_0f" "0,*")
10415    (set_attr "length_immediate" "0,*")
10416    (set_attr "modrm" "0,1")
10417    (set_attr "mode" "SI")])
10418
10419 (define_expand "x86_shift<mode>_adj_3"
10420   [(use (match_operand:SWI48 0 "register_operand" ""))
10421    (use (match_operand:SWI48 1 "register_operand" ""))
10422    (use (match_operand:QI 2 "register_operand" ""))]
10423   ""
10424 {
10425   rtx label = gen_label_rtx ();
10426   rtx tmp;
10427
10428   emit_insn (gen_testqi_ccz_1 (operands[2],
10429                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10430
10431   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10432   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10433   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10434                               gen_rtx_LABEL_REF (VOIDmode, label),
10435                               pc_rtx);
10436   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10437   JUMP_LABEL (tmp) = label;
10438
10439   emit_move_insn (operands[0], operands[1]);
10440   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10441                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10442   emit_label (label);
10443   LABEL_NUSES (label) = 1;
10444
10445   DONE;
10446 })
10447
10448 (define_insn "*<shiftrt_insn><mode>3_1"
10449   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10450         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10451                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10452    (clobber (reg:CC FLAGS_REG))]
10453   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10454 {
10455   if (operands[2] == const1_rtx
10456       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10457     return "<shiftrt>{<imodesuffix>}\t%0";
10458   else
10459     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10460 }
10461   [(set_attr "type" "ishift")
10462    (set (attr "length_immediate")
10463      (if_then_else
10464        (and (match_operand 2 "const1_operand" "")
10465             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10466                 (const_int 0)))
10467        (const_string "0")
10468        (const_string "*")))
10469    (set_attr "mode" "<MODE>")])
10470
10471 (define_insn "*<shiftrt_insn>si3_1_zext"
10472   [(set (match_operand:DI 0 "register_operand" "=r")
10473         (zero_extend:DI
10474           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10475                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
10476    (clobber (reg:CC FLAGS_REG))]
10477   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10478 {
10479   if (operands[2] == const1_rtx
10480       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10481     return "<shiftrt>{l}\t%k0";
10482   else
10483     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10484 }
10485   [(set_attr "type" "ishift")
10486    (set (attr "length_immediate")
10487      (if_then_else
10488        (and (match_operand 2 "const1_operand" "")
10489             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10490                 (const_int 0)))
10491        (const_string "0")
10492        (const_string "*")))
10493    (set_attr "mode" "SI")])
10494
10495 (define_insn "*<shiftrt_insn>qi3_1_slp"
10496   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10497         (any_shiftrt:QI (match_dup 0)
10498                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10499    (clobber (reg:CC FLAGS_REG))]
10500   "(optimize_function_for_size_p (cfun)
10501     || !TARGET_PARTIAL_REG_STALL
10502     || (operands[1] == const1_rtx
10503         && TARGET_SHIFT1))"
10504 {
10505   if (operands[1] == const1_rtx
10506       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10507     return "<shiftrt>{b}\t%0";
10508   else
10509     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10510 }
10511   [(set_attr "type" "ishift1")
10512    (set (attr "length_immediate")
10513      (if_then_else
10514        (and (match_operand 1 "const1_operand" "")
10515             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10516                 (const_int 0)))
10517        (const_string "0")
10518        (const_string "*")))
10519    (set_attr "mode" "QI")])
10520
10521 ;; This pattern can't accept a variable shift count, since shifts by
10522 ;; zero don't affect the flags.  We assume that shifts by constant
10523 ;; zero are optimized away.
10524 (define_insn "*<shiftrt_insn><mode>3_cmp"
10525   [(set (reg FLAGS_REG)
10526         (compare
10527           (any_shiftrt:SWI
10528             (match_operand:SWI 1 "nonimmediate_operand" "0")
10529             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10530           (const_int 0)))
10531    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10532         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10533   "(optimize_function_for_size_p (cfun)
10534     || !TARGET_PARTIAL_FLAG_REG_STALL
10535     || (operands[2] == const1_rtx
10536         && TARGET_SHIFT1))
10537    && ix86_match_ccmode (insn, CCGOCmode)
10538    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10539 {
10540   if (operands[2] == const1_rtx
10541       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10542     return "<shiftrt>{<imodesuffix>}\t%0";
10543   else
10544     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10545 }
10546   [(set_attr "type" "ishift")
10547    (set (attr "length_immediate")
10548      (if_then_else
10549        (and (match_operand 2 "const1_operand" "")
10550             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10551                 (const_int 0)))
10552        (const_string "0")
10553        (const_string "*")))
10554    (set_attr "mode" "<MODE>")])
10555
10556 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10557   [(set (reg FLAGS_REG)
10558         (compare
10559           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10560                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10561           (const_int 0)))
10562    (set (match_operand:DI 0 "register_operand" "=r")
10563         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10564   "TARGET_64BIT
10565    && (optimize_function_for_size_p (cfun)
10566        || !TARGET_PARTIAL_FLAG_REG_STALL
10567        || (operands[2] == const1_rtx
10568            && TARGET_SHIFT1))
10569    && ix86_match_ccmode (insn, CCGOCmode)
10570    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10571 {
10572   if (operands[2] == const1_rtx
10573       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10574     return "<shiftrt>{l}\t%k0";
10575   else
10576     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10577 }
10578   [(set_attr "type" "ishift")
10579    (set (attr "length_immediate")
10580      (if_then_else
10581        (and (match_operand 2 "const1_operand" "")
10582             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10583                 (const_int 0)))
10584        (const_string "0")
10585        (const_string "*")))
10586    (set_attr "mode" "SI")])
10587
10588 (define_insn "*<shiftrt_insn><mode>3_cconly"
10589   [(set (reg FLAGS_REG)
10590         (compare
10591           (any_shiftrt:SWI
10592             (match_operand:SWI 1 "nonimmediate_operand" "0")
10593             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10594           (const_int 0)))
10595    (clobber (match_scratch:SWI 0 "=<r>"))]
10596   "(optimize_function_for_size_p (cfun)
10597     || !TARGET_PARTIAL_FLAG_REG_STALL
10598     || (operands[2] == const1_rtx
10599         && TARGET_SHIFT1))
10600    && ix86_match_ccmode (insn, CCGOCmode)
10601    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10602 {
10603   if (operands[2] == const1_rtx
10604       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10605     return "<shiftrt>{<imodesuffix>}\t%0";
10606   else
10607     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10608 }
10609   [(set_attr "type" "ishift")
10610    (set (attr "length_immediate")
10611      (if_then_else
10612        (and (match_operand 2 "const1_operand" "")
10613             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10614                 (const_int 0)))
10615        (const_string "0")
10616        (const_string "*")))
10617    (set_attr "mode" "<MODE>")])
10618 \f
10619 ;; Rotate instructions
10620
10621 (define_expand "<rotate_insn>ti3"
10622   [(set (match_operand:TI 0 "register_operand" "")
10623         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10624                        (match_operand:QI 2 "nonmemory_operand" "")))]
10625   "TARGET_64BIT"
10626 {
10627   if (const_1_to_63_operand (operands[2], VOIDmode))
10628     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10629                 (operands[0], operands[1], operands[2]));
10630   else
10631     FAIL;
10632
10633   DONE;
10634 })
10635
10636 (define_expand "<rotate_insn>di3"
10637   [(set (match_operand:DI 0 "shiftdi_operand" "")
10638         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10639                        (match_operand:QI 2 "nonmemory_operand" "")))]
10640  ""
10641 {
10642   if (TARGET_64BIT)
10643     ix86_expand_binary_operator (<CODE>, DImode, operands);
10644   else if (const_1_to_31_operand (operands[2], VOIDmode))
10645     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10646                 (operands[0], operands[1], operands[2]));
10647   else
10648     FAIL;
10649
10650   DONE;
10651 })
10652
10653 (define_expand "<rotate_insn><mode>3"
10654   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10655         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10656                             (match_operand:QI 2 "nonmemory_operand" "")))]
10657   ""
10658   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10659
10660 ;; Implement rotation using two double-precision
10661 ;; shift instructions and a scratch register.
10662
10663 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10664  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10665        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10666                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10667   (clobber (reg:CC FLAGS_REG))
10668   (clobber (match_scratch:DWIH 3 "=&r"))]
10669  ""
10670  "#"
10671  "reload_completed"
10672  [(set (match_dup 3) (match_dup 4))
10673   (parallel
10674    [(set (match_dup 4)
10675          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10676                    (lshiftrt:DWIH (match_dup 5)
10677                                   (minus:QI (match_dup 6) (match_dup 2)))))
10678     (clobber (reg:CC FLAGS_REG))])
10679   (parallel
10680    [(set (match_dup 5)
10681          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10682                    (lshiftrt:DWIH (match_dup 3)
10683                                   (minus:QI (match_dup 6) (match_dup 2)))))
10684     (clobber (reg:CC FLAGS_REG))])]
10685 {
10686   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10687
10688   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10689 })
10690
10691 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10692  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10693        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10694                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10695   (clobber (reg:CC FLAGS_REG))
10696   (clobber (match_scratch:DWIH 3 "=&r"))]
10697  ""
10698  "#"
10699  "reload_completed"
10700  [(set (match_dup 3) (match_dup 4))
10701   (parallel
10702    [(set (match_dup 4)
10703          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10704                    (ashift:DWIH (match_dup 5)
10705                                 (minus:QI (match_dup 6) (match_dup 2)))))
10706     (clobber (reg:CC FLAGS_REG))])
10707   (parallel
10708    [(set (match_dup 5)
10709          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10710                    (ashift:DWIH (match_dup 3)
10711                                 (minus:QI (match_dup 6) (match_dup 2)))))
10712     (clobber (reg:CC FLAGS_REG))])]
10713 {
10714   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10715
10716   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10717 })
10718
10719 (define_insn "*<rotate_insn><mode>3_1"
10720   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10721         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10722                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10723    (clobber (reg:CC FLAGS_REG))]
10724   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10725 {
10726   if (operands[2] == const1_rtx
10727       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10728     return "<rotate>{<imodesuffix>}\t%0";
10729   else
10730     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10731 }
10732   [(set_attr "type" "rotate")
10733    (set (attr "length_immediate")
10734      (if_then_else
10735        (and (match_operand 2 "const1_operand" "")
10736             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10737                 (const_int 0)))
10738        (const_string "0")
10739        (const_string "*")))
10740    (set_attr "mode" "<MODE>")])
10741
10742 (define_insn "*<rotate_insn>si3_1_zext"
10743   [(set (match_operand:DI 0 "register_operand" "=r")
10744         (zero_extend:DI
10745           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10746                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10747    (clobber (reg:CC FLAGS_REG))]
10748   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10749 {
10750     if (operands[2] == const1_rtx
10751         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10752     return "<rotate>{l}\t%k0";
10753   else
10754     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10755 }
10756   [(set_attr "type" "rotate")
10757    (set (attr "length_immediate")
10758      (if_then_else
10759        (and (match_operand 2 "const1_operand" "")
10760             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10761                 (const_int 0)))
10762        (const_string "0")
10763        (const_string "*")))
10764    (set_attr "mode" "SI")])
10765
10766 (define_insn "*<rotate_insn>qi3_1_slp"
10767   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10768         (any_rotate:QI (match_dup 0)
10769                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10770    (clobber (reg:CC FLAGS_REG))]
10771   "(optimize_function_for_size_p (cfun)
10772     || !TARGET_PARTIAL_REG_STALL
10773     || (operands[1] == const1_rtx
10774         && TARGET_SHIFT1))"
10775 {
10776   if (operands[1] == const1_rtx
10777       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10778     return "<rotate>{b}\t%0";
10779   else
10780     return "<rotate>{b}\t{%1, %0|%0, %1}";
10781 }
10782   [(set_attr "type" "rotate1")
10783    (set (attr "length_immediate")
10784      (if_then_else
10785        (and (match_operand 1 "const1_operand" "")
10786             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10787                 (const_int 0)))
10788        (const_string "0")
10789        (const_string "*")))
10790    (set_attr "mode" "QI")])
10791
10792 (define_split
10793  [(set (match_operand:HI 0 "register_operand" "")
10794        (any_rotate:HI (match_dup 0) (const_int 8)))
10795   (clobber (reg:CC FLAGS_REG))]
10796  "reload_completed
10797   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10798  [(parallel [(set (strict_low_part (match_dup 0))
10799                   (bswap:HI (match_dup 0)))
10800              (clobber (reg:CC FLAGS_REG))])]
10801  "")
10802 \f
10803 ;; Bit set / bit test instructions
10804
10805 (define_expand "extv"
10806   [(set (match_operand:SI 0 "register_operand" "")
10807         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10808                          (match_operand:SI 2 "const8_operand" "")
10809                          (match_operand:SI 3 "const8_operand" "")))]
10810   ""
10811 {
10812   /* Handle extractions from %ah et al.  */
10813   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10814     FAIL;
10815
10816   /* From mips.md: extract_bit_field doesn't verify that our source
10817      matches the predicate, so check it again here.  */
10818   if (! ext_register_operand (operands[1], VOIDmode))
10819     FAIL;
10820 })
10821
10822 (define_expand "extzv"
10823   [(set (match_operand:SI 0 "register_operand" "")
10824         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10825                          (match_operand:SI 2 "const8_operand" "")
10826                          (match_operand:SI 3 "const8_operand" "")))]
10827   ""
10828 {
10829   /* Handle extractions from %ah et al.  */
10830   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10831     FAIL;
10832
10833   /* From mips.md: extract_bit_field doesn't verify that our source
10834      matches the predicate, so check it again here.  */
10835   if (! ext_register_operand (operands[1], VOIDmode))
10836     FAIL;
10837 })
10838
10839 (define_expand "insv"
10840   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10841                       (match_operand 1 "const8_operand" "")
10842                       (match_operand 2 "const8_operand" ""))
10843         (match_operand 3 "register_operand" ""))]
10844   ""
10845 {
10846   /* Handle insertions to %ah et al.  */
10847   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10848     FAIL;
10849
10850   /* From mips.md: insert_bit_field doesn't verify that our source
10851      matches the predicate, so check it again here.  */
10852   if (! ext_register_operand (operands[0], VOIDmode))
10853     FAIL;
10854
10855   if (TARGET_64BIT)
10856     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10857   else
10858     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10859
10860   DONE;
10861 })
10862
10863 ;; %%% bts, btr, btc, bt.
10864 ;; In general these instructions are *slow* when applied to memory,
10865 ;; since they enforce atomic operation.  When applied to registers,
10866 ;; it depends on the cpu implementation.  They're never faster than
10867 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10868 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10869 ;; within the instruction itself, so operating on bits in the high
10870 ;; 32-bits of a register becomes easier.
10871 ;;
10872 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10873 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10874 ;; negdf respectively, so they can never be disabled entirely.
10875
10876 (define_insn "*btsq"
10877   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10878                          (const_int 1)
10879                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10880         (const_int 1))
10881    (clobber (reg:CC FLAGS_REG))]
10882   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10883   "bts{q}\t{%1, %0|%0, %1}"
10884   [(set_attr "type" "alu1")
10885    (set_attr "prefix_0f" "1")
10886    (set_attr "mode" "DI")])
10887
10888 (define_insn "*btrq"
10889   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10890                          (const_int 1)
10891                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10892         (const_int 0))
10893    (clobber (reg:CC FLAGS_REG))]
10894   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10895   "btr{q}\t{%1, %0|%0, %1}"
10896   [(set_attr "type" "alu1")
10897    (set_attr "prefix_0f" "1")
10898    (set_attr "mode" "DI")])
10899
10900 (define_insn "*btcq"
10901   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10902                          (const_int 1)
10903                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10904         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10905    (clobber (reg:CC FLAGS_REG))]
10906   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10907   "btc{q}\t{%1, %0|%0, %1}"
10908   [(set_attr "type" "alu1")
10909    (set_attr "prefix_0f" "1")
10910    (set_attr "mode" "DI")])
10911
10912 ;; Allow Nocona to avoid these instructions if a register is available.
10913
10914 (define_peephole2
10915   [(match_scratch:DI 2 "r")
10916    (parallel [(set (zero_extract:DI
10917                      (match_operand:DI 0 "register_operand" "")
10918                      (const_int 1)
10919                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10920                    (const_int 1))
10921               (clobber (reg:CC FLAGS_REG))])]
10922   "TARGET_64BIT && !TARGET_USE_BT"
10923   [(const_int 0)]
10924 {
10925   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10926   rtx op1;
10927
10928   if (HOST_BITS_PER_WIDE_INT >= 64)
10929     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10930   else if (i < HOST_BITS_PER_WIDE_INT)
10931     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10932   else
10933     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10934
10935   op1 = immed_double_const (lo, hi, DImode);
10936   if (i >= 31)
10937     {
10938       emit_move_insn (operands[2], op1);
10939       op1 = operands[2];
10940     }
10941
10942   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10943   DONE;
10944 })
10945
10946 (define_peephole2
10947   [(match_scratch:DI 2 "r")
10948    (parallel [(set (zero_extract:DI
10949                      (match_operand:DI 0 "register_operand" "")
10950                      (const_int 1)
10951                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10952                    (const_int 0))
10953               (clobber (reg:CC FLAGS_REG))])]
10954   "TARGET_64BIT && !TARGET_USE_BT"
10955   [(const_int 0)]
10956 {
10957   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10958   rtx op1;
10959
10960   if (HOST_BITS_PER_WIDE_INT >= 64)
10961     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10962   else if (i < HOST_BITS_PER_WIDE_INT)
10963     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10964   else
10965     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10966
10967   op1 = immed_double_const (~lo, ~hi, DImode);
10968   if (i >= 32)
10969     {
10970       emit_move_insn (operands[2], op1);
10971       op1 = operands[2];
10972     }
10973
10974   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10975   DONE;
10976 })
10977
10978 (define_peephole2
10979   [(match_scratch:DI 2 "r")
10980    (parallel [(set (zero_extract:DI
10981                      (match_operand:DI 0 "register_operand" "")
10982                      (const_int 1)
10983                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10984               (not:DI (zero_extract:DI
10985                         (match_dup 0) (const_int 1) (match_dup 1))))
10986               (clobber (reg:CC FLAGS_REG))])]
10987   "TARGET_64BIT && !TARGET_USE_BT"
10988   [(const_int 0)]
10989 {
10990   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10991   rtx op1;
10992
10993   if (HOST_BITS_PER_WIDE_INT >= 64)
10994     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10995   else if (i < HOST_BITS_PER_WIDE_INT)
10996     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10997   else
10998     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10999
11000   op1 = immed_double_const (lo, hi, DImode);
11001   if (i >= 31)
11002     {
11003       emit_move_insn (operands[2], op1);
11004       op1 = operands[2];
11005     }
11006
11007   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
11008   DONE;
11009 })
11010
11011 (define_insn "*bt<mode>"
11012   [(set (reg:CCC FLAGS_REG)
11013         (compare:CCC
11014           (zero_extract:SWI48
11015             (match_operand:SWI48 0 "register_operand" "r")
11016             (const_int 1)
11017             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
11018           (const_int 0)))]
11019   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11020   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
11021   [(set_attr "type" "alu1")
11022    (set_attr "prefix_0f" "1")
11023    (set_attr "mode" "<MODE>")])
11024 \f
11025 ;; Store-flag instructions.
11026
11027 ;; For all sCOND expanders, also expand the compare or test insn that
11028 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
11029
11030 (define_insn_and_split "*setcc_di_1"
11031   [(set (match_operand:DI 0 "register_operand" "=q")
11032         (match_operator:DI 1 "ix86_comparison_operator"
11033           [(reg FLAGS_REG) (const_int 0)]))]
11034   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11035   "#"
11036   "&& reload_completed"
11037   [(set (match_dup 2) (match_dup 1))
11038    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11039 {
11040   PUT_MODE (operands[1], QImode);
11041   operands[2] = gen_lowpart (QImode, operands[0]);
11042 })
11043
11044 (define_insn_and_split "*setcc_si_1_and"
11045   [(set (match_operand:SI 0 "register_operand" "=q")
11046         (match_operator:SI 1 "ix86_comparison_operator"
11047           [(reg FLAGS_REG) (const_int 0)]))
11048    (clobber (reg:CC FLAGS_REG))]
11049   "!TARGET_PARTIAL_REG_STALL
11050    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11051   "#"
11052   "&& reload_completed"
11053   [(set (match_dup 2) (match_dup 1))
11054    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11055               (clobber (reg:CC FLAGS_REG))])]
11056 {
11057   PUT_MODE (operands[1], QImode);
11058   operands[2] = gen_lowpart (QImode, operands[0]);
11059 })
11060
11061 (define_insn_and_split "*setcc_si_1_movzbl"
11062   [(set (match_operand:SI 0 "register_operand" "=q")
11063         (match_operator:SI 1 "ix86_comparison_operator"
11064           [(reg FLAGS_REG) (const_int 0)]))]
11065   "!TARGET_PARTIAL_REG_STALL
11066    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11067   "#"
11068   "&& reload_completed"
11069   [(set (match_dup 2) (match_dup 1))
11070    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11071 {
11072   PUT_MODE (operands[1], QImode);
11073   operands[2] = gen_lowpart (QImode, operands[0]);
11074 })
11075
11076 (define_insn "*setcc_qi"
11077   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11078         (match_operator:QI 1 "ix86_comparison_operator"
11079           [(reg FLAGS_REG) (const_int 0)]))]
11080   ""
11081   "set%C1\t%0"
11082   [(set_attr "type" "setcc")
11083    (set_attr "mode" "QI")])
11084
11085 (define_insn "*setcc_qi_slp"
11086   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11087         (match_operator:QI 1 "ix86_comparison_operator"
11088           [(reg FLAGS_REG) (const_int 0)]))]
11089   ""
11090   "set%C1\t%0"
11091   [(set_attr "type" "setcc")
11092    (set_attr "mode" "QI")])
11093
11094 ;; In general it is not safe to assume too much about CCmode registers,
11095 ;; so simplify-rtx stops when it sees a second one.  Under certain
11096 ;; conditions this is safe on x86, so help combine not create
11097 ;;
11098 ;;      seta    %al
11099 ;;      testb   %al, %al
11100 ;;      sete    %al
11101
11102 (define_split
11103   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11104         (ne:QI (match_operator 1 "ix86_comparison_operator"
11105                  [(reg FLAGS_REG) (const_int 0)])
11106             (const_int 0)))]
11107   ""
11108   [(set (match_dup 0) (match_dup 1))]
11109 {
11110   PUT_MODE (operands[1], QImode);
11111 })
11112
11113 (define_split
11114   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11115         (ne:QI (match_operator 1 "ix86_comparison_operator"
11116                  [(reg FLAGS_REG) (const_int 0)])
11117             (const_int 0)))]
11118   ""
11119   [(set (match_dup 0) (match_dup 1))]
11120 {
11121   PUT_MODE (operands[1], QImode);
11122 })
11123
11124 (define_split
11125   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11126         (eq:QI (match_operator 1 "ix86_comparison_operator"
11127                  [(reg FLAGS_REG) (const_int 0)])
11128             (const_int 0)))]
11129   ""
11130   [(set (match_dup 0) (match_dup 1))]
11131 {
11132   rtx new_op1 = copy_rtx (operands[1]);
11133   operands[1] = new_op1;
11134   PUT_MODE (new_op1, QImode);
11135   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11136                                              GET_MODE (XEXP (new_op1, 0))));
11137
11138   /* Make sure that (a) the CCmode we have for the flags is strong
11139      enough for the reversed compare or (b) we have a valid FP compare.  */
11140   if (! ix86_comparison_operator (new_op1, VOIDmode))
11141     FAIL;
11142 })
11143
11144 (define_split
11145   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11146         (eq:QI (match_operator 1 "ix86_comparison_operator"
11147                  [(reg FLAGS_REG) (const_int 0)])
11148             (const_int 0)))]
11149   ""
11150   [(set (match_dup 0) (match_dup 1))]
11151 {
11152   rtx new_op1 = copy_rtx (operands[1]);
11153   operands[1] = new_op1;
11154   PUT_MODE (new_op1, QImode);
11155   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11156                                              GET_MODE (XEXP (new_op1, 0))));
11157
11158   /* Make sure that (a) the CCmode we have for the flags is strong
11159      enough for the reversed compare or (b) we have a valid FP compare.  */
11160   if (! ix86_comparison_operator (new_op1, VOIDmode))
11161     FAIL;
11162 })
11163
11164 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11165 ;; subsequent logical operations are used to imitate conditional moves.
11166 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11167 ;; it directly.
11168
11169 (define_insn "*avx_setcc<mode>"
11170   [(set (match_operand:MODEF 0 "register_operand" "=x")
11171         (match_operator:MODEF 1 "avx_comparison_float_operator"
11172           [(match_operand:MODEF 2 "register_operand" "x")
11173            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11174   "TARGET_AVX"
11175   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
11176   [(set_attr "type" "ssecmp")
11177    (set_attr "prefix" "vex")
11178    (set_attr "length_immediate" "1")
11179    (set_attr "mode" "<MODE>")])
11180
11181 (define_insn "*sse_setcc<mode>"
11182   [(set (match_operand:MODEF 0 "register_operand" "=x")
11183         (match_operator:MODEF 1 "sse_comparison_operator"
11184           [(match_operand:MODEF 2 "register_operand" "0")
11185            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11186   "SSE_FLOAT_MODE_P (<MODE>mode)"
11187   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
11188   [(set_attr "type" "ssecmp")
11189    (set_attr "length_immediate" "1")
11190    (set_attr "mode" "<MODE>")])
11191 \f
11192 ;; Basic conditional jump instructions.
11193 ;; We ignore the overflow flag for signed branch instructions.
11194
11195 (define_insn "*jcc_1"
11196   [(set (pc)
11197         (if_then_else (match_operator 1 "ix86_comparison_operator"
11198                                       [(reg FLAGS_REG) (const_int 0)])
11199                       (label_ref (match_operand 0 "" ""))
11200                       (pc)))]
11201   ""
11202   "%+j%C1\t%l0"
11203   [(set_attr "type" "ibr")
11204    (set_attr "modrm" "0")
11205    (set (attr "length")
11206            (if_then_else (and (ge (minus (match_dup 0) (pc))
11207                                   (const_int -126))
11208                               (lt (minus (match_dup 0) (pc))
11209                                   (const_int 128)))
11210              (const_int 2)
11211              (const_int 6)))])
11212
11213 (define_insn "*jcc_2"
11214   [(set (pc)
11215         (if_then_else (match_operator 1 "ix86_comparison_operator"
11216                                       [(reg FLAGS_REG) (const_int 0)])
11217                       (pc)
11218                       (label_ref (match_operand 0 "" ""))))]
11219   ""
11220   "%+j%c1\t%l0"
11221   [(set_attr "type" "ibr")
11222    (set_attr "modrm" "0")
11223    (set (attr "length")
11224            (if_then_else (and (ge (minus (match_dup 0) (pc))
11225                                   (const_int -126))
11226                               (lt (minus (match_dup 0) (pc))
11227                                   (const_int 128)))
11228              (const_int 2)
11229              (const_int 6)))])
11230
11231 ;; In general it is not safe to assume too much about CCmode registers,
11232 ;; so simplify-rtx stops when it sees a second one.  Under certain
11233 ;; conditions this is safe on x86, so help combine not create
11234 ;;
11235 ;;      seta    %al
11236 ;;      testb   %al, %al
11237 ;;      je      Lfoo
11238
11239 (define_split
11240   [(set (pc)
11241         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11242                                       [(reg FLAGS_REG) (const_int 0)])
11243                           (const_int 0))
11244                       (label_ref (match_operand 1 "" ""))
11245                       (pc)))]
11246   ""
11247   [(set (pc)
11248         (if_then_else (match_dup 0)
11249                       (label_ref (match_dup 1))
11250                       (pc)))]
11251 {
11252   PUT_MODE (operands[0], VOIDmode);
11253 })
11254
11255 (define_split
11256   [(set (pc)
11257         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11258                                       [(reg FLAGS_REG) (const_int 0)])
11259                           (const_int 0))
11260                       (label_ref (match_operand 1 "" ""))
11261                       (pc)))]
11262   ""
11263   [(set (pc)
11264         (if_then_else (match_dup 0)
11265                       (label_ref (match_dup 1))
11266                       (pc)))]
11267 {
11268   rtx new_op0 = copy_rtx (operands[0]);
11269   operands[0] = new_op0;
11270   PUT_MODE (new_op0, VOIDmode);
11271   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11272                                              GET_MODE (XEXP (new_op0, 0))));
11273
11274   /* Make sure that (a) the CCmode we have for the flags is strong
11275      enough for the reversed compare or (b) we have a valid FP compare.  */
11276   if (! ix86_comparison_operator (new_op0, VOIDmode))
11277     FAIL;
11278 })
11279
11280 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11281 ;; pass generates from shift insn with QImode operand.  Actually, the mode
11282 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11283 ;; appropriate modulo of the bit offset value.
11284
11285 (define_insn_and_split "*jcc_bt<mode>"
11286   [(set (pc)
11287         (if_then_else (match_operator 0 "bt_comparison_operator"
11288                         [(zero_extract:SWI48
11289                            (match_operand:SWI48 1 "register_operand" "r")
11290                            (const_int 1)
11291                            (zero_extend:SI
11292                              (match_operand:QI 2 "register_operand" "r")))
11293                          (const_int 0)])
11294                       (label_ref (match_operand 3 "" ""))
11295                       (pc)))
11296    (clobber (reg:CC FLAGS_REG))]
11297   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11298   "#"
11299   "&& 1"
11300   [(set (reg:CCC FLAGS_REG)
11301         (compare:CCC
11302           (zero_extract:SWI48
11303             (match_dup 1)
11304             (const_int 1)
11305             (match_dup 2))
11306           (const_int 0)))
11307    (set (pc)
11308         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11309                       (label_ref (match_dup 3))
11310                       (pc)))]
11311 {
11312   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11313
11314   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11315 })
11316
11317 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
11318 ;; also for DImode, this is what combine produces.
11319 (define_insn_and_split "*jcc_bt<mode>_mask"
11320   [(set (pc)
11321         (if_then_else (match_operator 0 "bt_comparison_operator"
11322                         [(zero_extract:SWI48
11323                            (match_operand:SWI48 1 "register_operand" "r")
11324                            (const_int 1)
11325                            (and:SI
11326                              (match_operand:SI 2 "register_operand" "r")
11327                              (match_operand:SI 3 "const_int_operand" "n")))])
11328                       (label_ref (match_operand 4 "" ""))
11329                       (pc)))
11330    (clobber (reg:CC FLAGS_REG))]
11331   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11332    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11333       == GET_MODE_BITSIZE (<MODE>mode)-1"
11334   "#"
11335   "&& 1"
11336   [(set (reg:CCC FLAGS_REG)
11337         (compare:CCC
11338           (zero_extract:SWI48
11339             (match_dup 1)
11340             (const_int 1)
11341             (match_dup 2))
11342           (const_int 0)))
11343    (set (pc)
11344         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11345                       (label_ref (match_dup 4))
11346                       (pc)))]
11347 {
11348   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11349
11350   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11351 })
11352
11353 (define_insn_and_split "*jcc_btsi_1"
11354   [(set (pc)
11355         (if_then_else (match_operator 0 "bt_comparison_operator"
11356                         [(and:SI
11357                            (lshiftrt:SI
11358                              (match_operand:SI 1 "register_operand" "r")
11359                              (match_operand:QI 2 "register_operand" "r"))
11360                            (const_int 1))
11361                          (const_int 0)])
11362                       (label_ref (match_operand 3 "" ""))
11363                       (pc)))
11364    (clobber (reg:CC FLAGS_REG))]
11365   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11366   "#"
11367   "&& 1"
11368   [(set (reg:CCC FLAGS_REG)
11369         (compare:CCC
11370           (zero_extract:SI
11371             (match_dup 1)
11372             (const_int 1)
11373             (match_dup 2))
11374           (const_int 0)))
11375    (set (pc)
11376         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11377                       (label_ref (match_dup 3))
11378                       (pc)))]
11379 {
11380   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11381
11382   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11383 })
11384
11385 ;; avoid useless masking of bit offset operand
11386 (define_insn_and_split "*jcc_btsi_mask_1"
11387   [(set (pc)
11388         (if_then_else
11389           (match_operator 0 "bt_comparison_operator"
11390             [(and:SI
11391                (lshiftrt:SI
11392                  (match_operand:SI 1 "register_operand" "r")
11393                  (subreg:QI
11394                    (and:SI
11395                      (match_operand:SI 2 "register_operand" "r")
11396                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11397                (const_int 1))
11398              (const_int 0)])
11399           (label_ref (match_operand 4 "" ""))
11400           (pc)))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11403    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11404   "#"
11405   "&& 1"
11406   [(set (reg:CCC FLAGS_REG)
11407         (compare:CCC
11408           (zero_extract:SI
11409             (match_dup 1)
11410             (const_int 1)
11411             (match_dup 2))
11412           (const_int 0)))
11413    (set (pc)
11414         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11415                       (label_ref (match_dup 4))
11416                       (pc)))]
11417   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11418
11419 ;; Define combination compare-and-branch fp compare instructions to help
11420 ;; combine.
11421
11422 (define_insn "*fp_jcc_3_387"
11423   [(set (pc)
11424         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11425                         [(match_operand 1 "register_operand" "f")
11426                          (match_operand 2 "nonimmediate_operand" "fm")])
11427           (label_ref (match_operand 3 "" ""))
11428           (pc)))
11429    (clobber (reg:CCFP FPSR_REG))
11430    (clobber (reg:CCFP FLAGS_REG))
11431    (clobber (match_scratch:HI 4 "=a"))]
11432   "TARGET_80387
11433    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11434    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11435    && SELECT_CC_MODE (GET_CODE (operands[0]),
11436                       operands[1], operands[2]) == CCFPmode
11437    && !TARGET_CMOVE"
11438   "#")
11439
11440 (define_insn "*fp_jcc_4_387"
11441   [(set (pc)
11442         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11443                         [(match_operand 1 "register_operand" "f")
11444                          (match_operand 2 "nonimmediate_operand" "fm")])
11445           (pc)
11446           (label_ref (match_operand 3 "" ""))))
11447    (clobber (reg:CCFP FPSR_REG))
11448    (clobber (reg:CCFP FLAGS_REG))
11449    (clobber (match_scratch:HI 4 "=a"))]
11450   "TARGET_80387
11451    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11452    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11453    && SELECT_CC_MODE (GET_CODE (operands[0]),
11454                       operands[1], operands[2]) == CCFPmode
11455    && !TARGET_CMOVE"
11456   "#")
11457
11458 (define_insn "*fp_jcc_5_387"
11459   [(set (pc)
11460         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11461                         [(match_operand 1 "register_operand" "f")
11462                          (match_operand 2 "register_operand" "f")])
11463           (label_ref (match_operand 3 "" ""))
11464           (pc)))
11465    (clobber (reg:CCFP FPSR_REG))
11466    (clobber (reg:CCFP FLAGS_REG))
11467    (clobber (match_scratch:HI 4 "=a"))]
11468   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11469    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11470    && !TARGET_CMOVE"
11471   "#")
11472
11473 (define_insn "*fp_jcc_6_387"
11474   [(set (pc)
11475         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11476                         [(match_operand 1 "register_operand" "f")
11477                          (match_operand 2 "register_operand" "f")])
11478           (pc)
11479           (label_ref (match_operand 3 "" ""))))
11480    (clobber (reg:CCFP FPSR_REG))
11481    (clobber (reg:CCFP FLAGS_REG))
11482    (clobber (match_scratch:HI 4 "=a"))]
11483   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11484    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11485    && !TARGET_CMOVE"
11486   "#")
11487
11488 (define_insn "*fp_jcc_7_387"
11489   [(set (pc)
11490         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11491                         [(match_operand 1 "register_operand" "f")
11492                          (match_operand 2 "const0_operand" "")])
11493           (label_ref (match_operand 3 "" ""))
11494           (pc)))
11495    (clobber (reg:CCFP FPSR_REG))
11496    (clobber (reg:CCFP FLAGS_REG))
11497    (clobber (match_scratch:HI 4 "=a"))]
11498   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11499    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11500    && SELECT_CC_MODE (GET_CODE (operands[0]),
11501                       operands[1], operands[2]) == CCFPmode
11502    && !TARGET_CMOVE"
11503   "#")
11504
11505 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11506 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11507 ;; with a precedence over other operators and is always put in the first
11508 ;; place. Swap condition and operands to match ficom instruction.
11509
11510 (define_insn "*fp_jcc_8<mode>_387"
11511   [(set (pc)
11512         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11513                         [(match_operator 1 "float_operator"
11514                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11515                            (match_operand 3 "register_operand" "f,f")])
11516           (label_ref (match_operand 4 "" ""))
11517           (pc)))
11518    (clobber (reg:CCFP FPSR_REG))
11519    (clobber (reg:CCFP FLAGS_REG))
11520    (clobber (match_scratch:HI 5 "=a,a"))]
11521   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11522    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11523    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11524    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11525    && !TARGET_CMOVE"
11526   "#")
11527
11528 (define_split
11529   [(set (pc)
11530         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11531                         [(match_operand 1 "register_operand" "")
11532                          (match_operand 2 "nonimmediate_operand" "")])
11533           (match_operand 3 "" "")
11534           (match_operand 4 "" "")))
11535    (clobber (reg:CCFP FPSR_REG))
11536    (clobber (reg:CCFP FLAGS_REG))]
11537   "reload_completed"
11538   [(const_int 0)]
11539 {
11540   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11541                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11542   DONE;
11543 })
11544
11545 (define_split
11546   [(set (pc)
11547         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11548                         [(match_operand 1 "register_operand" "")
11549                          (match_operand 2 "general_operand" "")])
11550           (match_operand 3 "" "")
11551           (match_operand 4 "" "")))
11552    (clobber (reg:CCFP FPSR_REG))
11553    (clobber (reg:CCFP FLAGS_REG))
11554    (clobber (match_scratch:HI 5 "=a"))]
11555   "reload_completed"
11556   [(const_int 0)]
11557 {
11558   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11559                         operands[3], operands[4], operands[5], NULL_RTX);
11560   DONE;
11561 })
11562
11563 (define_split
11564   [(set (pc)
11565         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11566                         [(match_operator 1 "float_operator"
11567                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
11568                            (match_operand 3 "register_operand" "")])
11569           (match_operand 4 "" "")
11570           (match_operand 5 "" "")))
11571    (clobber (reg:CCFP FPSR_REG))
11572    (clobber (reg:CCFP FLAGS_REG))
11573    (clobber (match_scratch:HI 6 "=a"))]
11574   "reload_completed"
11575   [(const_int 0)]
11576 {
11577   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11578
11579   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11580                         operands[3], operands[7],
11581                         operands[4], operands[5], operands[6], NULL_RTX);
11582   DONE;
11583 })
11584
11585 ;; %%% Kill this when reload knows how to do it.
11586 (define_split
11587   [(set (pc)
11588         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11589                         [(match_operator 1 "float_operator"
11590                            [(match_operand:X87MODEI12 2 "register_operand" "")])
11591                            (match_operand 3 "register_operand" "")])
11592           (match_operand 4 "" "")
11593           (match_operand 5 "" "")))
11594    (clobber (reg:CCFP FPSR_REG))
11595    (clobber (reg:CCFP FLAGS_REG))
11596    (clobber (match_scratch:HI 6 "=a"))]
11597   "reload_completed"
11598   [(const_int 0)]
11599 {
11600   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11601   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11602
11603   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11604                         operands[3], operands[7],
11605                         operands[4], operands[5], operands[6], operands[2]);
11606   DONE;
11607 })
11608 \f
11609 ;; Unconditional and other jump instructions
11610
11611 (define_insn "jump"
11612   [(set (pc)
11613         (label_ref (match_operand 0 "" "")))]
11614   ""
11615   "jmp\t%l0"
11616   [(set_attr "type" "ibr")
11617    (set (attr "length")
11618            (if_then_else (and (ge (minus (match_dup 0) (pc))
11619                                   (const_int -126))
11620                               (lt (minus (match_dup 0) (pc))
11621                                   (const_int 128)))
11622              (const_int 2)
11623              (const_int 5)))
11624    (set_attr "modrm" "0")])
11625
11626 (define_expand "indirect_jump"
11627   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11628   ""
11629   "")
11630
11631 (define_insn "*indirect_jump"
11632   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11633   ""
11634   "jmp\t%A0"
11635   [(set_attr "type" "ibr")
11636    (set_attr "length_immediate" "0")])
11637
11638 (define_expand "tablejump"
11639   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11640               (use (label_ref (match_operand 1 "" "")))])]
11641   ""
11642 {
11643   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11644      relative.  Convert the relative address to an absolute address.  */
11645   if (flag_pic)
11646     {
11647       rtx op0, op1;
11648       enum rtx_code code;
11649
11650       /* We can't use @GOTOFF for text labels on VxWorks;
11651          see gotoff_operand.  */
11652       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11653         {
11654           code = PLUS;
11655           op0 = operands[0];
11656           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11657         }
11658       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11659         {
11660           code = PLUS;
11661           op0 = operands[0];
11662           op1 = pic_offset_table_rtx;
11663         }
11664       else
11665         {
11666           code = MINUS;
11667           op0 = pic_offset_table_rtx;
11668           op1 = operands[0];
11669         }
11670
11671       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11672                                          OPTAB_DIRECT);
11673     }
11674 })
11675
11676 (define_insn "*tablejump_1"
11677   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11678    (use (label_ref (match_operand 1 "" "")))]
11679   ""
11680   "jmp\t%A0"
11681   [(set_attr "type" "ibr")
11682    (set_attr "length_immediate" "0")])
11683 \f
11684 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11685
11686 (define_peephole2
11687   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11688    (set (match_operand:QI 1 "register_operand" "")
11689         (match_operator:QI 2 "ix86_comparison_operator"
11690           [(reg FLAGS_REG) (const_int 0)]))
11691    (set (match_operand 3 "q_regs_operand" "")
11692         (zero_extend (match_dup 1)))]
11693   "(peep2_reg_dead_p (3, operands[1])
11694     || operands_match_p (operands[1], operands[3]))
11695    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11696   [(set (match_dup 4) (match_dup 0))
11697    (set (strict_low_part (match_dup 5))
11698         (match_dup 2))]
11699 {
11700   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11701   operands[5] = gen_lowpart (QImode, operands[3]);
11702   ix86_expand_clear (operands[3]);
11703 })
11704
11705 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11706
11707 (define_peephole2
11708   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11709    (set (match_operand:QI 1 "register_operand" "")
11710         (match_operator:QI 2 "ix86_comparison_operator"
11711           [(reg FLAGS_REG) (const_int 0)]))
11712    (parallel [(set (match_operand 3 "q_regs_operand" "")
11713                    (zero_extend (match_dup 1)))
11714               (clobber (reg:CC FLAGS_REG))])]
11715   "(peep2_reg_dead_p (3, operands[1])
11716     || operands_match_p (operands[1], operands[3]))
11717    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11718   [(set (match_dup 4) (match_dup 0))
11719    (set (strict_low_part (match_dup 5))
11720         (match_dup 2))]
11721 {
11722   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11723   operands[5] = gen_lowpart (QImode, operands[3]);
11724   ix86_expand_clear (operands[3]);
11725 })
11726 \f
11727 ;; Call instructions.
11728
11729 ;; The predicates normally associated with named expanders are not properly
11730 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11731 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11732
11733 ;; P6 processors will jump to the address after the decrement when %esp
11734 ;; is used as a call operand, so they will execute return address as a code.
11735 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11736  
11737 ;; Call subroutine returning no value.
11738
11739 (define_expand "call_pop"
11740   [(parallel [(call (match_operand:QI 0 "" "")
11741                     (match_operand:SI 1 "" ""))
11742               (set (reg:SI SP_REG)
11743                    (plus:SI (reg:SI SP_REG)
11744                             (match_operand:SI 3 "" "")))])]
11745   "!TARGET_64BIT"
11746 {
11747   ix86_expand_call (NULL, operands[0], operands[1],
11748                     operands[2], operands[3], 0);
11749   DONE;
11750 })
11751
11752 (define_insn "*call_pop_0"
11753   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11754          (match_operand:SI 1 "" ""))
11755    (set (reg:SI SP_REG)
11756         (plus:SI (reg:SI SP_REG)
11757                  (match_operand:SI 2 "immediate_operand" "")))]
11758   "!TARGET_64BIT"
11759 {
11760   if (SIBLING_CALL_P (insn))
11761     return "jmp\t%P0";
11762   else
11763     return "call\t%P0";
11764 }
11765   [(set_attr "type" "call")])
11766
11767 (define_insn "*call_pop_1"
11768   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11769          (match_operand:SI 1 "" ""))
11770    (set (reg:SI SP_REG)
11771         (plus:SI (reg:SI SP_REG)
11772                  (match_operand:SI 2 "immediate_operand" "i")))]
11773   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11774 {
11775   if (constant_call_address_operand (operands[0], Pmode))
11776     return "call\t%P0";
11777   return "call\t%A0";
11778 }
11779   [(set_attr "type" "call")])
11780
11781 (define_insn "*sibcall_pop_1"
11782   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11783          (match_operand:SI 1 "" ""))
11784    (set (reg:SI SP_REG)
11785         (plus:SI (reg:SI SP_REG)
11786                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11787   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11788   "@
11789    jmp\t%P0
11790    jmp\t%A0"
11791   [(set_attr "type" "call")])
11792
11793 (define_expand "call"
11794   [(call (match_operand:QI 0 "" "")
11795          (match_operand 1 "" ""))
11796    (use (match_operand 2 "" ""))]
11797   ""
11798 {
11799   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11800   DONE;
11801 })
11802
11803 (define_expand "sibcall"
11804   [(call (match_operand:QI 0 "" "")
11805          (match_operand 1 "" ""))
11806    (use (match_operand 2 "" ""))]
11807   ""
11808 {
11809   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11810   DONE;
11811 })
11812
11813 (define_insn "*call_0"
11814   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11815          (match_operand 1 "" ""))]
11816   ""
11817 {
11818   if (SIBLING_CALL_P (insn))
11819     return "jmp\t%P0";
11820   else
11821     return "call\t%P0";
11822 }
11823   [(set_attr "type" "call")])
11824
11825 (define_insn "*call_1"
11826   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11827          (match_operand 1 "" ""))]
11828   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11829 {
11830   if (constant_call_address_operand (operands[0], Pmode))
11831     return "call\t%P0";
11832   return "call\t%A0";
11833 }
11834   [(set_attr "type" "call")])
11835
11836 (define_insn "*sibcall_1"
11837   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11838          (match_operand 1 "" ""))]
11839   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11840   "@
11841    jmp\t%P0
11842    jmp\t%A0"
11843   [(set_attr "type" "call")])
11844
11845 (define_insn "*call_1_rex64"
11846   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11847          (match_operand 1 "" ""))]
11848   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11849    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11850 {
11851   if (constant_call_address_operand (operands[0], Pmode))
11852     return "call\t%P0";
11853   return "call\t%A0";
11854 }
11855   [(set_attr "type" "call")])
11856
11857 (define_insn "*call_1_rex64_ms_sysv"
11858   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11859          (match_operand 1 "" ""))
11860    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11861    (clobber (reg:TI XMM6_REG))
11862    (clobber (reg:TI XMM7_REG))
11863    (clobber (reg:TI XMM8_REG))
11864    (clobber (reg:TI XMM9_REG))
11865    (clobber (reg:TI XMM10_REG))
11866    (clobber (reg:TI XMM11_REG))
11867    (clobber (reg:TI XMM12_REG))
11868    (clobber (reg:TI XMM13_REG))
11869    (clobber (reg:TI XMM14_REG))
11870    (clobber (reg:TI XMM15_REG))
11871    (clobber (reg:DI SI_REG))
11872    (clobber (reg:DI DI_REG))]
11873   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11874 {
11875   if (constant_call_address_operand (operands[0], Pmode))
11876     return "call\t%P0";
11877   return "call\t%A0";
11878 }
11879   [(set_attr "type" "call")])
11880
11881 (define_insn "*call_1_rex64_large"
11882   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11883          (match_operand 1 "" ""))]
11884   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11885   "call\t%A0"
11886   [(set_attr "type" "call")])
11887
11888 (define_insn "*sibcall_1_rex64"
11889   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11890          (match_operand 1 "" ""))]
11891   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11892   "@
11893    jmp\t%P0
11894    jmp\t%A0"
11895   [(set_attr "type" "call")])
11896
11897 ;; Call subroutine, returning value in operand 0
11898 (define_expand "call_value_pop"
11899   [(parallel [(set (match_operand 0 "" "")
11900                    (call (match_operand:QI 1 "" "")
11901                          (match_operand:SI 2 "" "")))
11902               (set (reg:SI SP_REG)
11903                    (plus:SI (reg:SI SP_REG)
11904                             (match_operand:SI 4 "" "")))])]
11905   "!TARGET_64BIT"
11906 {
11907   ix86_expand_call (operands[0], operands[1], operands[2],
11908                     operands[3], operands[4], 0);
11909   DONE;
11910 })
11911
11912 (define_expand "call_value"
11913   [(set (match_operand 0 "" "")
11914         (call (match_operand:QI 1 "" "")
11915               (match_operand:SI 2 "" "")))
11916    (use (match_operand:SI 3 "" ""))]
11917   ;; Operand 3 is not used on the i386.
11918   ""
11919 {
11920   ix86_expand_call (operands[0], operands[1], operands[2],
11921                     operands[3], NULL, 0);
11922   DONE;
11923 })
11924
11925 (define_expand "sibcall_value"
11926   [(set (match_operand 0 "" "")
11927         (call (match_operand:QI 1 "" "")
11928               (match_operand:SI 2 "" "")))
11929    (use (match_operand:SI 3 "" ""))]
11930   ;; Operand 3 is not used on the i386.
11931   ""
11932 {
11933   ix86_expand_call (operands[0], operands[1], operands[2],
11934                     operands[3], NULL, 1);
11935   DONE;
11936 })
11937
11938 ;; Call subroutine returning any type.
11939
11940 (define_expand "untyped_call"
11941   [(parallel [(call (match_operand 0 "" "")
11942                     (const_int 0))
11943               (match_operand 1 "" "")
11944               (match_operand 2 "" "")])]
11945   ""
11946 {
11947   int i;
11948
11949   /* In order to give reg-stack an easier job in validating two
11950      coprocessor registers as containing a possible return value,
11951      simply pretend the untyped call returns a complex long double
11952      value. 
11953
11954      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11955      and should have the default ABI.  */
11956
11957   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11958                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11959                     operands[0], const0_rtx,
11960                     GEN_INT ((TARGET_64BIT
11961                               ? (ix86_abi == SYSV_ABI
11962                                  ? X86_64_SSE_REGPARM_MAX
11963                                  : X86_64_MS_SSE_REGPARM_MAX)
11964                               : X86_32_SSE_REGPARM_MAX)
11965                              - 1),
11966                     NULL, 0);
11967
11968   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11969     {
11970       rtx set = XVECEXP (operands[2], 0, i);
11971       emit_move_insn (SET_DEST (set), SET_SRC (set));
11972     }
11973
11974   /* The optimizer does not know that the call sets the function value
11975      registers we stored in the result block.  We avoid problems by
11976      claiming that all hard registers are used and clobbered at this
11977      point.  */
11978   emit_insn (gen_blockage ());
11979
11980   DONE;
11981 })
11982 \f
11983 ;; Prologue and epilogue instructions
11984
11985 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11986 ;; all of memory.  This blocks insns from being moved across this point.
11987
11988 (define_insn "blockage"
11989   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11990   ""
11991   ""
11992   [(set_attr "length" "0")])
11993
11994 ;; Do not schedule instructions accessing memory across this point.
11995
11996 (define_expand "memory_blockage"
11997   [(set (match_dup 0)
11998         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11999   ""
12000 {
12001   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12002   MEM_VOLATILE_P (operands[0]) = 1;
12003 })
12004
12005 (define_insn "*memory_blockage"
12006   [(set (match_operand:BLK 0 "" "")
12007         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12008   ""
12009   ""
12010   [(set_attr "length" "0")])
12011
12012 ;; As USE insns aren't meaningful after reload, this is used instead
12013 ;; to prevent deleting instructions setting registers for PIC code
12014 (define_insn "prologue_use"
12015   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
12016   ""
12017   ""
12018   [(set_attr "length" "0")])
12019
12020 ;; Insn emitted into the body of a function to return from a function.
12021 ;; This is only done if the function's epilogue is known to be simple.
12022 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12023
12024 (define_expand "return"
12025   [(return)]
12026   "ix86_can_use_return_insn_p ()"
12027 {
12028   if (crtl->args.pops_args)
12029     {
12030       rtx popc = GEN_INT (crtl->args.pops_args);
12031       emit_jump_insn (gen_return_pop_internal (popc));
12032       DONE;
12033     }
12034 })
12035
12036 (define_insn "return_internal"
12037   [(return)]
12038   "reload_completed"
12039   "ret"
12040   [(set_attr "length" "1")
12041    (set_attr "atom_unit" "jeu")
12042    (set_attr "length_immediate" "0")
12043    (set_attr "modrm" "0")])
12044
12045 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12046 ;; instruction Athlon and K8 have.
12047
12048 (define_insn "return_internal_long"
12049   [(return)
12050    (unspec [(const_int 0)] UNSPEC_REP)]
12051   "reload_completed"
12052   "rep\;ret"
12053   [(set_attr "length" "2")
12054    (set_attr "atom_unit" "jeu")
12055    (set_attr "length_immediate" "0")
12056    (set_attr "prefix_rep" "1")
12057    (set_attr "modrm" "0")])
12058
12059 (define_insn "return_pop_internal"
12060   [(return)
12061    (use (match_operand:SI 0 "const_int_operand" ""))]
12062   "reload_completed"
12063   "ret\t%0"
12064   [(set_attr "length" "3")
12065    (set_attr "atom_unit" "jeu")
12066    (set_attr "length_immediate" "2")
12067    (set_attr "modrm" "0")])
12068
12069 (define_insn "return_indirect_internal"
12070   [(return)
12071    (use (match_operand:SI 0 "register_operand" "r"))]
12072   "reload_completed"
12073   "jmp\t%A0"
12074   [(set_attr "type" "ibr")
12075    (set_attr "length_immediate" "0")])
12076
12077 (define_insn "nop"
12078   [(const_int 0)]
12079   ""
12080   "nop"
12081   [(set_attr "length" "1")
12082    (set_attr "length_immediate" "0")
12083    (set_attr "modrm" "0")])
12084
12085 (define_insn "vswapmov"
12086   [(set (match_operand:SI 0 "register_operand" "=r")
12087         (match_operand:SI 1 "register_operand" "r"))
12088    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
12089   ""
12090   "movl.s\t{%1, %0|%0, %1}"
12091   [(set_attr "length" "2")
12092    (set_attr "length_immediate" "0")
12093    (set_attr "modrm" "0")])
12094
12095 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12096 ;; branch prediction penalty for the third jump in a 16-byte
12097 ;; block on K8.
12098
12099 (define_insn "pad"
12100   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
12101   ""
12102 {
12103 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12104   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12105 #else
12106   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12107      The align insn is used to avoid 3 jump instructions in the row to improve
12108      branch prediction and the benefits hardly outweigh the cost of extra 8
12109      nops on the average inserted by full alignment pseudo operation.  */
12110 #endif
12111   return "";
12112 }
12113   [(set_attr "length" "16")])
12114
12115 (define_expand "prologue"
12116   [(const_int 0)]
12117   ""
12118   "ix86_expand_prologue (); DONE;")
12119
12120 (define_insn "set_got"
12121   [(set (match_operand:SI 0 "register_operand" "=r")
12122         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12123    (clobber (reg:CC FLAGS_REG))]
12124   "!TARGET_64BIT"
12125   { return output_set_got (operands[0], NULL_RTX); }
12126   [(set_attr "type" "multi")
12127    (set_attr "length" "12")])
12128
12129 (define_insn "set_got_labelled"
12130   [(set (match_operand:SI 0 "register_operand" "=r")
12131         (unspec:SI [(label_ref (match_operand 1 "" ""))]
12132          UNSPEC_SET_GOT))
12133    (clobber (reg:CC FLAGS_REG))]
12134   "!TARGET_64BIT"
12135   { return output_set_got (operands[0], operands[1]); }
12136   [(set_attr "type" "multi")
12137    (set_attr "length" "12")])
12138
12139 (define_insn "set_got_rex64"
12140   [(set (match_operand:DI 0 "register_operand" "=r")
12141         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12142   "TARGET_64BIT"
12143   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12144   [(set_attr "type" "lea")
12145    (set_attr "length_address" "4")
12146    (set_attr "mode" "DI")])
12147
12148 (define_insn "set_rip_rex64"
12149   [(set (match_operand:DI 0 "register_operand" "=r")
12150         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
12151   "TARGET_64BIT"
12152   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12153   [(set_attr "type" "lea")
12154    (set_attr "length_address" "4")
12155    (set_attr "mode" "DI")])
12156
12157 (define_insn "set_got_offset_rex64"
12158   [(set (match_operand:DI 0 "register_operand" "=r")
12159         (unspec:DI
12160           [(label_ref (match_operand 1 "" ""))]
12161           UNSPEC_SET_GOT_OFFSET))]
12162   "TARGET_64BIT"
12163   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12164   [(set_attr "type" "imov")
12165    (set_attr "length_immediate" "0")
12166    (set_attr "length_address" "8")
12167    (set_attr "mode" "DI")])
12168
12169 (define_expand "epilogue"
12170   [(const_int 0)]
12171   ""
12172   "ix86_expand_epilogue (1); DONE;")
12173
12174 (define_expand "sibcall_epilogue"
12175   [(const_int 0)]
12176   ""
12177   "ix86_expand_epilogue (0); DONE;")
12178
12179 (define_expand "eh_return"
12180   [(use (match_operand 0 "register_operand" ""))]
12181   ""
12182 {
12183   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12184
12185   /* Tricky bit: we write the address of the handler to which we will
12186      be returning into someone else's stack frame, one word below the
12187      stack address we wish to restore.  */
12188   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12189   tmp = plus_constant (tmp, -UNITS_PER_WORD);
12190   tmp = gen_rtx_MEM (Pmode, tmp);
12191   emit_move_insn (tmp, ra);
12192
12193   emit_jump_insn (gen_eh_return_internal ());
12194   emit_barrier ();
12195   DONE;
12196 })
12197
12198 (define_insn_and_split "eh_return_internal"
12199   [(eh_return)]
12200   ""
12201   "#"
12202   "epilogue_completed"
12203   [(const_int 0)]
12204   "ix86_expand_epilogue (2); DONE;")
12205
12206 (define_insn "leave"
12207   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12208    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12209    (clobber (mem:BLK (scratch)))]
12210   "!TARGET_64BIT"
12211   "leave"
12212   [(set_attr "type" "leave")])
12213
12214 (define_insn "leave_rex64"
12215   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12216    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12217    (clobber (mem:BLK (scratch)))]
12218   "TARGET_64BIT"
12219   "leave"
12220   [(set_attr "type" "leave")])
12221 \f
12222 ;; Bit manipulation instructions.
12223
12224 (define_expand "ffs<mode>2"
12225   [(set (match_dup 2) (const_int -1))
12226    (parallel [(set (reg:CCZ FLAGS_REG)
12227                    (compare:CCZ
12228                      (match_operand:SWI48 1 "nonimmediate_operand" "")
12229                      (const_int 0)))
12230               (set (match_operand:SWI48 0 "register_operand" "")
12231                    (ctz:SWI48 (match_dup 1)))])
12232    (set (match_dup 0) (if_then_else:SWI48
12233                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12234                         (match_dup 2)
12235                         (match_dup 0)))
12236    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12237               (clobber (reg:CC FLAGS_REG))])]
12238   ""
12239 {
12240   if (<MODE>mode == SImode && !TARGET_CMOVE)
12241     {
12242       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12243       DONE;
12244     }
12245   operands[2] = gen_reg_rtx (<MODE>mode);
12246 })
12247
12248 (define_insn_and_split "ffssi2_no_cmove"
12249   [(set (match_operand:SI 0 "register_operand" "=r")
12250         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12251    (clobber (match_scratch:SI 2 "=&q"))
12252    (clobber (reg:CC FLAGS_REG))]
12253   "!TARGET_CMOVE"
12254   "#"
12255   "&& reload_completed"
12256   [(parallel [(set (reg:CCZ FLAGS_REG)
12257                    (compare:CCZ (match_dup 1) (const_int 0)))
12258               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12259    (set (strict_low_part (match_dup 3))
12260         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12261    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12262               (clobber (reg:CC FLAGS_REG))])
12263    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12264               (clobber (reg:CC FLAGS_REG))])
12265    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12266               (clobber (reg:CC FLAGS_REG))])]
12267 {
12268   operands[3] = gen_lowpart (QImode, operands[2]);
12269   ix86_expand_clear (operands[2]);
12270 })
12271
12272 (define_insn "*ffs<mode>_1"
12273   [(set (reg:CCZ FLAGS_REG)
12274         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12275                      (const_int 0)))
12276    (set (match_operand:SWI48 0 "register_operand" "=r")
12277         (ctz:SWI48 (match_dup 1)))]
12278   ""
12279   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12280   [(set_attr "type" "alu1")
12281    (set_attr "prefix_0f" "1")
12282    (set_attr "mode" "<MODE>")])
12283
12284 (define_insn "ctz<mode>2"
12285   [(set (match_operand:SWI48 0 "register_operand" "=r")
12286         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12287    (clobber (reg:CC FLAGS_REG))]
12288   ""
12289   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12290   [(set_attr "type" "alu1")
12291    (set_attr "prefix_0f" "1")
12292    (set_attr "mode" "<MODE>")])
12293
12294 (define_expand "clz<mode>2"
12295   [(parallel
12296      [(set (match_operand:SWI248 0 "register_operand" "")
12297            (minus:SWI248
12298              (match_dup 2)
12299              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12300       (clobber (reg:CC FLAGS_REG))])
12301    (parallel
12302      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12303       (clobber (reg:CC FLAGS_REG))])]
12304   ""
12305 {
12306   if (TARGET_ABM)
12307     {
12308       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12309       DONE;
12310     }
12311   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12312 })
12313
12314 (define_insn "clz<mode>2_abm"
12315   [(set (match_operand:SWI248 0 "register_operand" "=r")
12316         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12317    (clobber (reg:CC FLAGS_REG))]
12318   "TARGET_ABM"
12319   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12320   [(set_attr "prefix_rep" "1")
12321    (set_attr "type" "bitmanip")
12322    (set_attr "mode" "<MODE>")])
12323
12324 (define_insn "bsr_rex64"
12325   [(set (match_operand:DI 0 "register_operand" "=r")
12326         (minus:DI (const_int 63)
12327                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12328    (clobber (reg:CC FLAGS_REG))]
12329   "TARGET_64BIT"
12330   "bsr{q}\t{%1, %0|%0, %1}"
12331   [(set_attr "type" "alu1")
12332    (set_attr "prefix_0f" "1")
12333    (set_attr "mode" "DI")])
12334
12335 (define_insn "bsr"
12336   [(set (match_operand:SI 0 "register_operand" "=r")
12337         (minus:SI (const_int 31)
12338                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12339    (clobber (reg:CC FLAGS_REG))]
12340   ""
12341   "bsr{l}\t{%1, %0|%0, %1}"
12342   [(set_attr "type" "alu1")
12343    (set_attr "prefix_0f" "1")
12344    (set_attr "mode" "SI")])
12345
12346 (define_insn "*bsrhi"
12347   [(set (match_operand:HI 0 "register_operand" "=r")
12348         (minus:HI (const_int 15)
12349                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12350    (clobber (reg:CC FLAGS_REG))]
12351   ""
12352   "bsr{w}\t{%1, %0|%0, %1}"
12353   [(set_attr "type" "alu1")
12354    (set_attr "prefix_0f" "1")
12355    (set_attr "mode" "HI")])
12356
12357 (define_insn "popcount<mode>2"
12358   [(set (match_operand:SWI248 0 "register_operand" "=r")
12359         (popcount:SWI248
12360           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12361    (clobber (reg:CC FLAGS_REG))]
12362   "TARGET_POPCNT"
12363 {
12364 #if TARGET_MACHO
12365   return "popcnt\t{%1, %0|%0, %1}";
12366 #else
12367   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12368 #endif
12369 }
12370   [(set_attr "prefix_rep" "1")
12371    (set_attr "type" "bitmanip")
12372    (set_attr "mode" "<MODE>")])
12373
12374 (define_insn "*popcount<mode>2_cmp"
12375   [(set (reg FLAGS_REG)
12376         (compare
12377           (popcount:SWI248
12378             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12379           (const_int 0)))
12380    (set (match_operand:SWI248 0 "register_operand" "=r")
12381         (popcount:SWI248 (match_dup 1)))]
12382   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12383 {
12384 #if TARGET_MACHO
12385   return "popcnt\t{%1, %0|%0, %1}";
12386 #else
12387   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12388 #endif
12389 }
12390   [(set_attr "prefix_rep" "1")
12391    (set_attr "type" "bitmanip")
12392    (set_attr "mode" "<MODE>")])
12393
12394 (define_insn "*popcountsi2_cmp_zext"
12395   [(set (reg FLAGS_REG)
12396         (compare
12397           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12398           (const_int 0)))
12399    (set (match_operand:DI 0 "register_operand" "=r")
12400         (zero_extend:DI(popcount:SI (match_dup 1))))]
12401   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12402 {
12403 #if TARGET_MACHO
12404   return "popcnt\t{%1, %0|%0, %1}";
12405 #else
12406   return "popcnt{l}\t{%1, %0|%0, %1}";
12407 #endif
12408 }
12409   [(set_attr "prefix_rep" "1")
12410    (set_attr "type" "bitmanip")
12411    (set_attr "mode" "SI")])
12412
12413 (define_expand "bswap<mode>2"
12414   [(set (match_operand:SWI48 0 "register_operand" "")
12415         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12416   ""
12417 {
12418   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12419     {
12420       rtx x = operands[0];
12421
12422       emit_move_insn (x, operands[1]);
12423       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12424       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12425       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12426       DONE;
12427     }
12428 })
12429
12430 (define_insn "*bswap<mode>2_movbe"
12431   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12432         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12433   "TARGET_MOVBE
12434    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12435   "@
12436     bswap\t%0
12437     movbe\t{%1, %0|%0, %1}
12438     movbe\t{%1, %0|%0, %1}"
12439   [(set_attr "type" "bitmanip,imov,imov")
12440    (set_attr "modrm" "0,1,1")
12441    (set_attr "prefix_0f" "*,1,1")
12442    (set_attr "prefix_extra" "*,1,1")
12443    (set_attr "mode" "<MODE>")])
12444
12445 (define_insn "*bswap<mode>2_1"
12446   [(set (match_operand:SWI48 0 "register_operand" "=r")
12447         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12448   "TARGET_BSWAP"
12449   "bswap\t%0"
12450   [(set_attr "type" "bitmanip")
12451    (set_attr "modrm" "0")
12452    (set_attr "mode" "<MODE>")])
12453
12454 (define_insn "*bswaphi_lowpart_1"
12455   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12456         (bswap:HI (match_dup 0)))
12457    (clobber (reg:CC FLAGS_REG))]
12458   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12459   "@
12460     xchg{b}\t{%h0, %b0|%b0, %h0}
12461     rol{w}\t{$8, %0|%0, 8}"
12462   [(set_attr "length" "2,4")
12463    (set_attr "mode" "QI,HI")])
12464
12465 (define_insn "bswaphi_lowpart"
12466   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12467         (bswap:HI (match_dup 0)))
12468    (clobber (reg:CC FLAGS_REG))]
12469   ""
12470   "rol{w}\t{$8, %0|%0, 8}"
12471   [(set_attr "length" "4")
12472    (set_attr "mode" "HI")])
12473
12474 (define_expand "paritydi2"
12475   [(set (match_operand:DI 0 "register_operand" "")
12476         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12477   "! TARGET_POPCNT"
12478 {
12479   rtx scratch = gen_reg_rtx (QImode);
12480   rtx cond;
12481
12482   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12483                                 NULL_RTX, operands[1]));
12484
12485   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12486                          gen_rtx_REG (CCmode, FLAGS_REG),
12487                          const0_rtx);
12488   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12489
12490   if (TARGET_64BIT)
12491     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12492   else
12493     {
12494       rtx tmp = gen_reg_rtx (SImode);
12495
12496       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12497       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12498     }
12499   DONE;
12500 })
12501
12502 (define_expand "paritysi2"
12503   [(set (match_operand:SI 0 "register_operand" "")
12504         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12505   "! TARGET_POPCNT"
12506 {
12507   rtx scratch = gen_reg_rtx (QImode);
12508   rtx cond;
12509
12510   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12511
12512   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12513                          gen_rtx_REG (CCmode, FLAGS_REG),
12514                          const0_rtx);
12515   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12516
12517   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12518   DONE;
12519 })
12520
12521 (define_insn_and_split "paritydi2_cmp"
12522   [(set (reg:CC FLAGS_REG)
12523         (parity:CC (match_operand:DI 3 "register_operand" "0")))
12524    (clobber (match_scratch:DI 0 "=r"))
12525    (clobber (match_scratch:SI 1 "=&r"))
12526    (clobber (match_scratch:HI 2 "=Q"))]
12527   "! TARGET_POPCNT"
12528   "#"
12529   "&& reload_completed"
12530   [(parallel
12531      [(set (match_dup 1)
12532            (xor:SI (match_dup 1) (match_dup 4)))
12533       (clobber (reg:CC FLAGS_REG))])
12534    (parallel
12535      [(set (reg:CC FLAGS_REG)
12536            (parity:CC (match_dup 1)))
12537       (clobber (match_dup 1))
12538       (clobber (match_dup 2))])]
12539 {
12540   operands[4] = gen_lowpart (SImode, operands[3]);
12541
12542   if (TARGET_64BIT)
12543     {
12544       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12545       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12546     }
12547   else
12548     operands[1] = gen_highpart (SImode, operands[3]);
12549 })
12550
12551 (define_insn_and_split "paritysi2_cmp"
12552   [(set (reg:CC FLAGS_REG)
12553         (parity:CC (match_operand:SI 2 "register_operand" "0")))
12554    (clobber (match_scratch:SI 0 "=r"))
12555    (clobber (match_scratch:HI 1 "=&Q"))]
12556   "! TARGET_POPCNT"
12557   "#"
12558   "&& reload_completed"
12559   [(parallel
12560      [(set (match_dup 1)
12561            (xor:HI (match_dup 1) (match_dup 3)))
12562       (clobber (reg:CC FLAGS_REG))])
12563    (parallel
12564      [(set (reg:CC FLAGS_REG)
12565            (parity:CC (match_dup 1)))
12566       (clobber (match_dup 1))])]
12567 {
12568   operands[3] = gen_lowpart (HImode, operands[2]);
12569
12570   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12571   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12572 })
12573
12574 (define_insn "*parityhi2_cmp"
12575   [(set (reg:CC FLAGS_REG)
12576         (parity:CC (match_operand:HI 1 "register_operand" "0")))
12577    (clobber (match_scratch:HI 0 "=Q"))]
12578   "! TARGET_POPCNT"
12579   "xor{b}\t{%h0, %b0|%b0, %h0}"
12580   [(set_attr "length" "2")
12581    (set_attr "mode" "HI")])
12582
12583 (define_insn "*parityqi2_cmp"
12584   [(set (reg:CC FLAGS_REG)
12585         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12586   "! TARGET_POPCNT"
12587   "test{b}\t%0, %0"
12588   [(set_attr "length" "2")
12589    (set_attr "mode" "QI")])
12590 \f
12591 ;; Thread-local storage patterns for ELF.
12592 ;;
12593 ;; Note that these code sequences must appear exactly as shown
12594 ;; in order to allow linker relaxation.
12595
12596 (define_insn "*tls_global_dynamic_32_gnu"
12597   [(set (match_operand:SI 0 "register_operand" "=a")
12598         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12599                     (match_operand:SI 2 "tls_symbolic_operand" "")
12600                     (match_operand:SI 3 "call_insn_operand" "")]
12601                     UNSPEC_TLS_GD))
12602    (clobber (match_scratch:SI 4 "=d"))
12603    (clobber (match_scratch:SI 5 "=c"))
12604    (clobber (reg:CC FLAGS_REG))]
12605   "!TARGET_64BIT && TARGET_GNU_TLS"
12606   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12607   [(set_attr "type" "multi")
12608    (set_attr "length" "12")])
12609
12610 (define_expand "tls_global_dynamic_32"
12611   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12612                    (unspec:SI
12613                     [(match_dup 2)
12614                      (match_operand:SI 1 "tls_symbolic_operand" "")
12615                      (match_dup 3)]
12616                     UNSPEC_TLS_GD))
12617               (clobber (match_scratch:SI 4 ""))
12618               (clobber (match_scratch:SI 5 ""))
12619               (clobber (reg:CC FLAGS_REG))])]
12620   ""
12621 {
12622   if (flag_pic)
12623     operands[2] = pic_offset_table_rtx;
12624   else
12625     {
12626       operands[2] = gen_reg_rtx (Pmode);
12627       emit_insn (gen_set_got (operands[2]));
12628     }
12629   if (TARGET_GNU2_TLS)
12630     {
12631        emit_insn (gen_tls_dynamic_gnu2_32
12632                   (operands[0], operands[1], operands[2]));
12633        DONE;
12634     }
12635   operands[3] = ix86_tls_get_addr ();
12636 })
12637
12638 (define_insn "*tls_global_dynamic_64"
12639   [(set (match_operand:DI 0 "register_operand" "=a")
12640         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12641                  (match_operand:DI 3 "" "")))
12642    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12643               UNSPEC_TLS_GD)]
12644   "TARGET_64BIT"
12645   { 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"; }
12646   [(set_attr "type" "multi")
12647    (set_attr "length" "16")])
12648
12649 (define_expand "tls_global_dynamic_64"
12650   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12651                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12652               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12653                          UNSPEC_TLS_GD)])]
12654   ""
12655 {
12656   if (TARGET_GNU2_TLS)
12657     {
12658        emit_insn (gen_tls_dynamic_gnu2_64
12659                   (operands[0], operands[1]));
12660        DONE;
12661     }
12662   operands[2] = ix86_tls_get_addr ();
12663 })
12664
12665 (define_insn "*tls_local_dynamic_base_32_gnu"
12666   [(set (match_operand:SI 0 "register_operand" "=a")
12667         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12668                     (match_operand:SI 2 "call_insn_operand" "")]
12669                    UNSPEC_TLS_LD_BASE))
12670    (clobber (match_scratch:SI 3 "=d"))
12671    (clobber (match_scratch:SI 4 "=c"))
12672    (clobber (reg:CC FLAGS_REG))]
12673   "!TARGET_64BIT && TARGET_GNU_TLS"
12674   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12675   [(set_attr "type" "multi")
12676    (set_attr "length" "11")])
12677
12678 (define_expand "tls_local_dynamic_base_32"
12679   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12680                    (unspec:SI [(match_dup 1) (match_dup 2)]
12681                               UNSPEC_TLS_LD_BASE))
12682               (clobber (match_scratch:SI 3 ""))
12683               (clobber (match_scratch:SI 4 ""))
12684               (clobber (reg:CC FLAGS_REG))])]
12685   ""
12686 {
12687   if (flag_pic)
12688     operands[1] = pic_offset_table_rtx;
12689   else
12690     {
12691       operands[1] = gen_reg_rtx (Pmode);
12692       emit_insn (gen_set_got (operands[1]));
12693     }
12694   if (TARGET_GNU2_TLS)
12695     {
12696        emit_insn (gen_tls_dynamic_gnu2_32
12697                   (operands[0], ix86_tls_module_base (), operands[1]));
12698        DONE;
12699     }
12700   operands[2] = ix86_tls_get_addr ();
12701 })
12702
12703 (define_insn "*tls_local_dynamic_base_64"
12704   [(set (match_operand:DI 0 "register_operand" "=a")
12705         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12706                  (match_operand:DI 2 "" "")))
12707    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12708   "TARGET_64BIT"
12709   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12710   [(set_attr "type" "multi")
12711    (set_attr "length" "12")])
12712
12713 (define_expand "tls_local_dynamic_base_64"
12714   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12715                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12716               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12717   ""
12718 {
12719   if (TARGET_GNU2_TLS)
12720     {
12721        emit_insn (gen_tls_dynamic_gnu2_64
12722                   (operands[0], ix86_tls_module_base ()));
12723        DONE;
12724     }
12725   operands[1] = ix86_tls_get_addr ();
12726 })
12727
12728 ;; Local dynamic of a single variable is a lose.  Show combine how
12729 ;; to convert that back to global dynamic.
12730
12731 (define_insn_and_split "*tls_local_dynamic_32_once"
12732   [(set (match_operand:SI 0 "register_operand" "=a")
12733         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12734                              (match_operand:SI 2 "call_insn_operand" "")]
12735                             UNSPEC_TLS_LD_BASE)
12736                  (const:SI (unspec:SI
12737                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12738                             UNSPEC_DTPOFF))))
12739    (clobber (match_scratch:SI 4 "=d"))
12740    (clobber (match_scratch:SI 5 "=c"))
12741    (clobber (reg:CC FLAGS_REG))]
12742   ""
12743   "#"
12744   ""
12745   [(parallel [(set (match_dup 0)
12746                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12747                               UNSPEC_TLS_GD))
12748               (clobber (match_dup 4))
12749               (clobber (match_dup 5))
12750               (clobber (reg:CC FLAGS_REG))])]
12751   "")
12752
12753 ;; Load and add the thread base pointer from %gs:0.
12754
12755 (define_insn "*load_tp_si"
12756   [(set (match_operand:SI 0 "register_operand" "=r")
12757         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12758   "!TARGET_64BIT"
12759   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12760   [(set_attr "type" "imov")
12761    (set_attr "modrm" "0")
12762    (set_attr "length" "7")
12763    (set_attr "memory" "load")
12764    (set_attr "imm_disp" "false")])
12765
12766 (define_insn "*add_tp_si"
12767   [(set (match_operand:SI 0 "register_operand" "=r")
12768         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12769                  (match_operand:SI 1 "register_operand" "0")))
12770    (clobber (reg:CC FLAGS_REG))]
12771   "!TARGET_64BIT"
12772   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12773   [(set_attr "type" "alu")
12774    (set_attr "modrm" "0")
12775    (set_attr "length" "7")
12776    (set_attr "memory" "load")
12777    (set_attr "imm_disp" "false")])
12778
12779 (define_insn "*load_tp_di"
12780   [(set (match_operand:DI 0 "register_operand" "=r")
12781         (unspec:DI [(const_int 0)] UNSPEC_TP))]
12782   "TARGET_64BIT"
12783   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12784   [(set_attr "type" "imov")
12785    (set_attr "modrm" "0")
12786    (set_attr "length" "7")
12787    (set_attr "memory" "load")
12788    (set_attr "imm_disp" "false")])
12789
12790 (define_insn "*add_tp_di"
12791   [(set (match_operand:DI 0 "register_operand" "=r")
12792         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12793                  (match_operand:DI 1 "register_operand" "0")))
12794    (clobber (reg:CC FLAGS_REG))]
12795   "TARGET_64BIT"
12796   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12797   [(set_attr "type" "alu")
12798    (set_attr "modrm" "0")
12799    (set_attr "length" "7")
12800    (set_attr "memory" "load")
12801    (set_attr "imm_disp" "false")])
12802
12803 ;; GNU2 TLS patterns can be split.
12804
12805 (define_expand "tls_dynamic_gnu2_32"
12806   [(set (match_dup 3)
12807         (plus:SI (match_operand:SI 2 "register_operand" "")
12808                  (const:SI
12809                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12810                              UNSPEC_TLSDESC))))
12811    (parallel
12812     [(set (match_operand:SI 0 "register_operand" "")
12813           (unspec:SI [(match_dup 1) (match_dup 3)
12814                       (match_dup 2) (reg:SI SP_REG)]
12815                       UNSPEC_TLSDESC))
12816      (clobber (reg:CC FLAGS_REG))])]
12817   "!TARGET_64BIT && TARGET_GNU2_TLS"
12818 {
12819   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12820   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12821 })
12822
12823 (define_insn "*tls_dynamic_lea_32"
12824   [(set (match_operand:SI 0 "register_operand" "=r")
12825         (plus:SI (match_operand:SI 1 "register_operand" "b")
12826                  (const:SI
12827                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12828                               UNSPEC_TLSDESC))))]
12829   "!TARGET_64BIT && TARGET_GNU2_TLS"
12830   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12831   [(set_attr "type" "lea")
12832    (set_attr "mode" "SI")
12833    (set_attr "length" "6")
12834    (set_attr "length_address" "4")])
12835
12836 (define_insn "*tls_dynamic_call_32"
12837   [(set (match_operand:SI 0 "register_operand" "=a")
12838         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12839                     (match_operand:SI 2 "register_operand" "0")
12840                     ;; we have to make sure %ebx still points to the GOT
12841                     (match_operand:SI 3 "register_operand" "b")
12842                     (reg:SI SP_REG)]
12843                    UNSPEC_TLSDESC))
12844    (clobber (reg:CC FLAGS_REG))]
12845   "!TARGET_64BIT && TARGET_GNU2_TLS"
12846   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12847   [(set_attr "type" "call")
12848    (set_attr "length" "2")
12849    (set_attr "length_address" "0")])
12850
12851 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12852   [(set (match_operand:SI 0 "register_operand" "=&a")
12853         (plus:SI
12854          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12855                      (match_operand:SI 4 "" "")
12856                      (match_operand:SI 2 "register_operand" "b")
12857                      (reg:SI SP_REG)]
12858                     UNSPEC_TLSDESC)
12859          (const:SI (unspec:SI
12860                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12861                     UNSPEC_DTPOFF))))
12862    (clobber (reg:CC FLAGS_REG))]
12863   "!TARGET_64BIT && TARGET_GNU2_TLS"
12864   "#"
12865   ""
12866   [(set (match_dup 0) (match_dup 5))]
12867 {
12868   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12869   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12870 })
12871
12872 (define_expand "tls_dynamic_gnu2_64"
12873   [(set (match_dup 2)
12874         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12875                    UNSPEC_TLSDESC))
12876    (parallel
12877     [(set (match_operand:DI 0 "register_operand" "")
12878           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12879                      UNSPEC_TLSDESC))
12880      (clobber (reg:CC FLAGS_REG))])]
12881   "TARGET_64BIT && TARGET_GNU2_TLS"
12882 {
12883   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12884   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12885 })
12886
12887 (define_insn "*tls_dynamic_lea_64"
12888   [(set (match_operand:DI 0 "register_operand" "=r")
12889         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12890                    UNSPEC_TLSDESC))]
12891   "TARGET_64BIT && TARGET_GNU2_TLS"
12892   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12893   [(set_attr "type" "lea")
12894    (set_attr "mode" "DI")
12895    (set_attr "length" "7")
12896    (set_attr "length_address" "4")])
12897
12898 (define_insn "*tls_dynamic_call_64"
12899   [(set (match_operand:DI 0 "register_operand" "=a")
12900         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12901                     (match_operand:DI 2 "register_operand" "0")
12902                     (reg:DI SP_REG)]
12903                    UNSPEC_TLSDESC))
12904    (clobber (reg:CC FLAGS_REG))]
12905   "TARGET_64BIT && TARGET_GNU2_TLS"
12906   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12907   [(set_attr "type" "call")
12908    (set_attr "length" "2")
12909    (set_attr "length_address" "0")])
12910
12911 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12912   [(set (match_operand:DI 0 "register_operand" "=&a")
12913         (plus:DI
12914          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12915                      (match_operand:DI 3 "" "")
12916                      (reg:DI SP_REG)]
12917                     UNSPEC_TLSDESC)
12918          (const:DI (unspec:DI
12919                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12920                     UNSPEC_DTPOFF))))
12921    (clobber (reg:CC FLAGS_REG))]
12922   "TARGET_64BIT && TARGET_GNU2_TLS"
12923   "#"
12924   ""
12925   [(set (match_dup 0) (match_dup 4))]
12926 {
12927   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12928   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12929 })
12930
12931 ;;
12932 \f
12933 ;; These patterns match the binary 387 instructions for addM3, subM3,
12934 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12935 ;; SFmode.  The first is the normal insn, the second the same insn but
12936 ;; with one operand a conversion, and the third the same insn but with
12937 ;; the other operand a conversion.  The conversion may be SFmode or
12938 ;; SImode if the target mode DFmode, but only SImode if the target mode
12939 ;; is SFmode.
12940
12941 ;; Gcc is slightly more smart about handling normal two address instructions
12942 ;; so use special patterns for add and mull.
12943
12944 (define_insn "*fop_<mode>_comm_mixed_avx"
12945   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12946         (match_operator:MODEF 3 "binary_fp_operator"
12947           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12948            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12949   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12950    && COMMUTATIVE_ARITH_P (operands[3])
12951    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12952   "* return output_387_binary_op (insn, operands);"
12953   [(set (attr "type")
12954         (if_then_else (eq_attr "alternative" "1")
12955            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12956               (const_string "ssemul")
12957               (const_string "sseadd"))
12958            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12959               (const_string "fmul")
12960               (const_string "fop"))))
12961    (set_attr "prefix" "orig,maybe_vex")
12962    (set_attr "mode" "<MODE>")])
12963
12964 (define_insn "*fop_<mode>_comm_mixed"
12965   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12966         (match_operator:MODEF 3 "binary_fp_operator"
12967           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12968            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12969   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12970    && COMMUTATIVE_ARITH_P (operands[3])
12971    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12972   "* return output_387_binary_op (insn, operands);"
12973   [(set (attr "type")
12974         (if_then_else (eq_attr "alternative" "1")
12975            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12976               (const_string "ssemul")
12977               (const_string "sseadd"))
12978            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12979               (const_string "fmul")
12980               (const_string "fop"))))
12981    (set_attr "mode" "<MODE>")])
12982
12983 (define_insn "*fop_<mode>_comm_avx"
12984   [(set (match_operand:MODEF 0 "register_operand" "=x")
12985         (match_operator:MODEF 3 "binary_fp_operator"
12986           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12987            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12988   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12989    && COMMUTATIVE_ARITH_P (operands[3])
12990    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12991   "* return output_387_binary_op (insn, operands);"
12992   [(set (attr "type")
12993         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12994            (const_string "ssemul")
12995            (const_string "sseadd")))
12996    (set_attr "prefix" "vex")
12997    (set_attr "mode" "<MODE>")])
12998
12999 (define_insn "*fop_<mode>_comm_sse"
13000   [(set (match_operand:MODEF 0 "register_operand" "=x")
13001         (match_operator:MODEF 3 "binary_fp_operator"
13002           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13003            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13004   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13005    && COMMUTATIVE_ARITH_P (operands[3])
13006    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13007   "* return output_387_binary_op (insn, operands);"
13008   [(set (attr "type")
13009         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13010            (const_string "ssemul")
13011            (const_string "sseadd")))
13012    (set_attr "mode" "<MODE>")])
13013
13014 (define_insn "*fop_<mode>_comm_i387"
13015   [(set (match_operand:MODEF 0 "register_operand" "=f")
13016         (match_operator:MODEF 3 "binary_fp_operator"
13017           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13018            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13019   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13020    && COMMUTATIVE_ARITH_P (operands[3])
13021    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13022   "* return output_387_binary_op (insn, operands);"
13023   [(set (attr "type")
13024         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13025            (const_string "fmul")
13026            (const_string "fop")))
13027    (set_attr "mode" "<MODE>")])
13028
13029 (define_insn "*fop_<mode>_1_mixed_avx"
13030   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13031         (match_operator:MODEF 3 "binary_fp_operator"
13032           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
13033            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13034   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13035    && !COMMUTATIVE_ARITH_P (operands[3])
13036    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13037   "* return output_387_binary_op (insn, operands);"
13038   [(set (attr "type")
13039         (cond [(and (eq_attr "alternative" "2")
13040                     (match_operand:MODEF 3 "mult_operator" ""))
13041                  (const_string "ssemul")
13042                (and (eq_attr "alternative" "2")
13043                     (match_operand:MODEF 3 "div_operator" ""))
13044                  (const_string "ssediv")
13045                (eq_attr "alternative" "2")
13046                  (const_string "sseadd")
13047                (match_operand:MODEF 3 "mult_operator" "")
13048                  (const_string "fmul")
13049                (match_operand:MODEF 3 "div_operator" "")
13050                  (const_string "fdiv")
13051               ]
13052               (const_string "fop")))
13053    (set_attr "prefix" "orig,orig,maybe_vex")
13054    (set_attr "mode" "<MODE>")])
13055
13056 (define_insn "*fop_<mode>_1_mixed"
13057   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13058         (match_operator:MODEF 3 "binary_fp_operator"
13059           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
13060            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13061   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13062    && !COMMUTATIVE_ARITH_P (operands[3])
13063    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13064   "* return output_387_binary_op (insn, operands);"
13065   [(set (attr "type")
13066         (cond [(and (eq_attr "alternative" "2")
13067                     (match_operand:MODEF 3 "mult_operator" ""))
13068                  (const_string "ssemul")
13069                (and (eq_attr "alternative" "2")
13070                     (match_operand:MODEF 3 "div_operator" ""))
13071                  (const_string "ssediv")
13072                (eq_attr "alternative" "2")
13073                  (const_string "sseadd")
13074                (match_operand:MODEF 3 "mult_operator" "")
13075                  (const_string "fmul")
13076                (match_operand:MODEF 3 "div_operator" "")
13077                  (const_string "fdiv")
13078               ]
13079               (const_string "fop")))
13080    (set_attr "mode" "<MODE>")])
13081
13082 (define_insn "*rcpsf2_sse"
13083   [(set (match_operand:SF 0 "register_operand" "=x")
13084         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13085                    UNSPEC_RCP))]
13086   "TARGET_SSE_MATH"
13087   "%vrcpss\t{%1, %d0|%d0, %1}"
13088   [(set_attr "type" "sse")
13089    (set_attr "atom_sse_attr" "rcp")
13090    (set_attr "prefix" "maybe_vex")
13091    (set_attr "mode" "SF")])
13092
13093 (define_insn "*fop_<mode>_1_avx"
13094   [(set (match_operand:MODEF 0 "register_operand" "=x")
13095         (match_operator:MODEF 3 "binary_fp_operator"
13096           [(match_operand:MODEF 1 "register_operand" "x")
13097            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13098   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13099    && !COMMUTATIVE_ARITH_P (operands[3])"
13100   "* return output_387_binary_op (insn, operands);"
13101   [(set (attr "type")
13102         (cond [(match_operand:MODEF 3 "mult_operator" "")
13103                  (const_string "ssemul")
13104                (match_operand:MODEF 3 "div_operator" "")
13105                  (const_string "ssediv")
13106               ]
13107               (const_string "sseadd")))
13108    (set_attr "prefix" "vex")
13109    (set_attr "mode" "<MODE>")])
13110
13111 (define_insn "*fop_<mode>_1_sse"
13112   [(set (match_operand:MODEF 0 "register_operand" "=x")
13113         (match_operator:MODEF 3 "binary_fp_operator"
13114           [(match_operand:MODEF 1 "register_operand" "0")
13115            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13116   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13117    && !COMMUTATIVE_ARITH_P (operands[3])"
13118   "* return output_387_binary_op (insn, operands);"
13119   [(set (attr "type")
13120         (cond [(match_operand:MODEF 3 "mult_operator" "")
13121                  (const_string "ssemul")
13122                (match_operand:MODEF 3 "div_operator" "")
13123                  (const_string "ssediv")
13124               ]
13125               (const_string "sseadd")))
13126    (set_attr "mode" "<MODE>")])
13127
13128 ;; This pattern is not fully shadowed by the pattern above.
13129 (define_insn "*fop_<mode>_1_i387"
13130   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13131         (match_operator:MODEF 3 "binary_fp_operator"
13132           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13133            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13134   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13135    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13136    && !COMMUTATIVE_ARITH_P (operands[3])
13137    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13138   "* return output_387_binary_op (insn, operands);"
13139   [(set (attr "type")
13140         (cond [(match_operand:MODEF 3 "mult_operator" "")
13141                  (const_string "fmul")
13142                (match_operand:MODEF 3 "div_operator" "")
13143                  (const_string "fdiv")
13144               ]
13145               (const_string "fop")))
13146    (set_attr "mode" "<MODE>")])
13147
13148 ;; ??? Add SSE splitters for these!
13149 (define_insn "*fop_<MODEF:mode>_2_i387"
13150   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13151         (match_operator:MODEF 3 "binary_fp_operator"
13152           [(float:MODEF
13153              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13154            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13155   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13156    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13157    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13158   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13159   [(set (attr "type")
13160         (cond [(match_operand:MODEF 3 "mult_operator" "")
13161                  (const_string "fmul")
13162                (match_operand:MODEF 3 "div_operator" "")
13163                  (const_string "fdiv")
13164               ]
13165               (const_string "fop")))
13166    (set_attr "fp_int_src" "true")
13167    (set_attr "mode" "<X87MODEI12:MODE>")])
13168
13169 (define_insn "*fop_<MODEF:mode>_3_i387"
13170   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13171         (match_operator:MODEF 3 "binary_fp_operator"
13172           [(match_operand:MODEF 1 "register_operand" "0,0")
13173            (float:MODEF
13174              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13175   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13176    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13177    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13178   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13179   [(set (attr "type")
13180         (cond [(match_operand:MODEF 3 "mult_operator" "")
13181                  (const_string "fmul")
13182                (match_operand:MODEF 3 "div_operator" "")
13183                  (const_string "fdiv")
13184               ]
13185               (const_string "fop")))
13186    (set_attr "fp_int_src" "true")
13187    (set_attr "mode" "<MODE>")])
13188
13189 (define_insn "*fop_df_4_i387"
13190   [(set (match_operand:DF 0 "register_operand" "=f,f")
13191         (match_operator:DF 3 "binary_fp_operator"
13192            [(float_extend:DF
13193              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13194             (match_operand:DF 2 "register_operand" "0,f")]))]
13195   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13196    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13197    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13198   "* return output_387_binary_op (insn, operands);"
13199   [(set (attr "type")
13200         (cond [(match_operand:DF 3 "mult_operator" "")
13201                  (const_string "fmul")
13202                (match_operand:DF 3 "div_operator" "")
13203                  (const_string "fdiv")
13204               ]
13205               (const_string "fop")))
13206    (set_attr "mode" "SF")])
13207
13208 (define_insn "*fop_df_5_i387"
13209   [(set (match_operand:DF 0 "register_operand" "=f,f")
13210         (match_operator:DF 3 "binary_fp_operator"
13211           [(match_operand:DF 1 "register_operand" "0,f")
13212            (float_extend:DF
13213             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13214   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13215    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13216   "* return output_387_binary_op (insn, operands);"
13217   [(set (attr "type")
13218         (cond [(match_operand:DF 3 "mult_operator" "")
13219                  (const_string "fmul")
13220                (match_operand:DF 3 "div_operator" "")
13221                  (const_string "fdiv")
13222               ]
13223               (const_string "fop")))
13224    (set_attr "mode" "SF")])
13225
13226 (define_insn "*fop_df_6_i387"
13227   [(set (match_operand:DF 0 "register_operand" "=f,f")
13228         (match_operator:DF 3 "binary_fp_operator"
13229           [(float_extend:DF
13230             (match_operand:SF 1 "register_operand" "0,f"))
13231            (float_extend:DF
13232             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13233   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13234    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13235   "* return output_387_binary_op (insn, operands);"
13236   [(set (attr "type")
13237         (cond [(match_operand:DF 3 "mult_operator" "")
13238                  (const_string "fmul")
13239                (match_operand:DF 3 "div_operator" "")
13240                  (const_string "fdiv")
13241               ]
13242               (const_string "fop")))
13243    (set_attr "mode" "SF")])
13244
13245 (define_insn "*fop_xf_comm_i387"
13246   [(set (match_operand:XF 0 "register_operand" "=f")
13247         (match_operator:XF 3 "binary_fp_operator"
13248                         [(match_operand:XF 1 "register_operand" "%0")
13249                          (match_operand:XF 2 "register_operand" "f")]))]
13250   "TARGET_80387
13251    && COMMUTATIVE_ARITH_P (operands[3])"
13252   "* return output_387_binary_op (insn, operands);"
13253   [(set (attr "type")
13254         (if_then_else (match_operand:XF 3 "mult_operator" "")
13255            (const_string "fmul")
13256            (const_string "fop")))
13257    (set_attr "mode" "XF")])
13258
13259 (define_insn "*fop_xf_1_i387"
13260   [(set (match_operand:XF 0 "register_operand" "=f,f")
13261         (match_operator:XF 3 "binary_fp_operator"
13262                         [(match_operand:XF 1 "register_operand" "0,f")
13263                          (match_operand:XF 2 "register_operand" "f,0")]))]
13264   "TARGET_80387
13265    && !COMMUTATIVE_ARITH_P (operands[3])"
13266   "* return output_387_binary_op (insn, operands);"
13267   [(set (attr "type")
13268         (cond [(match_operand:XF 3 "mult_operator" "")
13269                  (const_string "fmul")
13270                (match_operand:XF 3 "div_operator" "")
13271                  (const_string "fdiv")
13272               ]
13273               (const_string "fop")))
13274    (set_attr "mode" "XF")])
13275
13276 (define_insn "*fop_xf_2_i387"
13277   [(set (match_operand:XF 0 "register_operand" "=f,f")
13278         (match_operator:XF 3 "binary_fp_operator"
13279           [(float:XF
13280              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13281            (match_operand:XF 2 "register_operand" "0,0")]))]
13282   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13283   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13284   [(set (attr "type")
13285         (cond [(match_operand:XF 3 "mult_operator" "")
13286                  (const_string "fmul")
13287                (match_operand:XF 3 "div_operator" "")
13288                  (const_string "fdiv")
13289               ]
13290               (const_string "fop")))
13291    (set_attr "fp_int_src" "true")
13292    (set_attr "mode" "<MODE>")])
13293
13294 (define_insn "*fop_xf_3_i387"
13295   [(set (match_operand:XF 0 "register_operand" "=f,f")
13296         (match_operator:XF 3 "binary_fp_operator"
13297           [(match_operand:XF 1 "register_operand" "0,0")
13298            (float:XF
13299              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13300   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13301   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13302   [(set (attr "type")
13303         (cond [(match_operand:XF 3 "mult_operator" "")
13304                  (const_string "fmul")
13305                (match_operand:XF 3 "div_operator" "")
13306                  (const_string "fdiv")
13307               ]
13308               (const_string "fop")))
13309    (set_attr "fp_int_src" "true")
13310    (set_attr "mode" "<MODE>")])
13311
13312 (define_insn "*fop_xf_4_i387"
13313   [(set (match_operand:XF 0 "register_operand" "=f,f")
13314         (match_operator:XF 3 "binary_fp_operator"
13315            [(float_extend:XF
13316               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13317             (match_operand:XF 2 "register_operand" "0,f")]))]
13318   "TARGET_80387"
13319   "* return output_387_binary_op (insn, operands);"
13320   [(set (attr "type")
13321         (cond [(match_operand:XF 3 "mult_operator" "")
13322                  (const_string "fmul")
13323                (match_operand:XF 3 "div_operator" "")
13324                  (const_string "fdiv")
13325               ]
13326               (const_string "fop")))
13327    (set_attr "mode" "<MODE>")])
13328
13329 (define_insn "*fop_xf_5_i387"
13330   [(set (match_operand:XF 0 "register_operand" "=f,f")
13331         (match_operator:XF 3 "binary_fp_operator"
13332           [(match_operand:XF 1 "register_operand" "0,f")
13333            (float_extend:XF
13334              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13335   "TARGET_80387"
13336   "* return output_387_binary_op (insn, operands);"
13337   [(set (attr "type")
13338         (cond [(match_operand:XF 3 "mult_operator" "")
13339                  (const_string "fmul")
13340                (match_operand:XF 3 "div_operator" "")
13341                  (const_string "fdiv")
13342               ]
13343               (const_string "fop")))
13344    (set_attr "mode" "<MODE>")])
13345
13346 (define_insn "*fop_xf_6_i387"
13347   [(set (match_operand:XF 0 "register_operand" "=f,f")
13348         (match_operator:XF 3 "binary_fp_operator"
13349           [(float_extend:XF
13350              (match_operand:MODEF 1 "register_operand" "0,f"))
13351            (float_extend:XF
13352              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13353   "TARGET_80387"
13354   "* return output_387_binary_op (insn, operands);"
13355   [(set (attr "type")
13356         (cond [(match_operand:XF 3 "mult_operator" "")
13357                  (const_string "fmul")
13358                (match_operand:XF 3 "div_operator" "")
13359                  (const_string "fdiv")
13360               ]
13361               (const_string "fop")))
13362    (set_attr "mode" "<MODE>")])
13363
13364 (define_split
13365   [(set (match_operand 0 "register_operand" "")
13366         (match_operator 3 "binary_fp_operator"
13367            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13368             (match_operand 2 "register_operand" "")]))]
13369   "reload_completed
13370    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13371    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13372   [(const_int 0)]
13373 {
13374   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13375   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13376   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13377                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13378                                           GET_MODE (operands[3]),
13379                                           operands[4],
13380                                           operands[2])));
13381   ix86_free_from_memory (GET_MODE (operands[1]));
13382   DONE;
13383 })
13384
13385 (define_split
13386   [(set (match_operand 0 "register_operand" "")
13387         (match_operator 3 "binary_fp_operator"
13388            [(match_operand 1 "register_operand" "")
13389             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13390   "reload_completed
13391    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13392    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13393   [(const_int 0)]
13394 {
13395   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13396   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13397   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13398                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13399                                           GET_MODE (operands[3]),
13400                                           operands[1],
13401                                           operands[4])));
13402   ix86_free_from_memory (GET_MODE (operands[2]));
13403   DONE;
13404 })
13405 \f
13406 ;; FPU special functions.
13407
13408 ;; This pattern implements a no-op XFmode truncation for
13409 ;; all fancy i386 XFmode math functions.
13410
13411 (define_insn "truncxf<mode>2_i387_noop_unspec"
13412   [(set (match_operand:MODEF 0 "register_operand" "=f")
13413         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13414         UNSPEC_TRUNC_NOOP))]
13415   "TARGET_USE_FANCY_MATH_387"
13416   "* return output_387_reg_move (insn, operands);"
13417   [(set_attr "type" "fmov")
13418    (set_attr "mode" "<MODE>")])
13419
13420 (define_insn "sqrtxf2"
13421   [(set (match_operand:XF 0 "register_operand" "=f")
13422         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13423   "TARGET_USE_FANCY_MATH_387"
13424   "fsqrt"
13425   [(set_attr "type" "fpspc")
13426    (set_attr "mode" "XF")
13427    (set_attr "athlon_decode" "direct")
13428    (set_attr "amdfam10_decode" "direct")])
13429
13430 (define_insn "sqrt_extend<mode>xf2_i387"
13431   [(set (match_operand:XF 0 "register_operand" "=f")
13432         (sqrt:XF
13433           (float_extend:XF
13434             (match_operand:MODEF 1 "register_operand" "0"))))]
13435   "TARGET_USE_FANCY_MATH_387"
13436   "fsqrt"
13437   [(set_attr "type" "fpspc")
13438    (set_attr "mode" "XF")
13439    (set_attr "athlon_decode" "direct")
13440    (set_attr "amdfam10_decode" "direct")])
13441
13442 (define_insn "*rsqrtsf2_sse"
13443   [(set (match_operand:SF 0 "register_operand" "=x")
13444         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13445                    UNSPEC_RSQRT))]
13446   "TARGET_SSE_MATH"
13447   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13448   [(set_attr "type" "sse")
13449    (set_attr "atom_sse_attr" "rcp")
13450    (set_attr "prefix" "maybe_vex")
13451    (set_attr "mode" "SF")])
13452
13453 (define_expand "rsqrtsf2"
13454   [(set (match_operand:SF 0 "register_operand" "")
13455         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13456                    UNSPEC_RSQRT))]
13457   "TARGET_SSE_MATH"
13458 {
13459   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13460   DONE;
13461 })
13462
13463 (define_insn "*sqrt<mode>2_sse"
13464   [(set (match_operand:MODEF 0 "register_operand" "=x")
13465         (sqrt:MODEF
13466           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13467   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13468   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13469   [(set_attr "type" "sse")
13470    (set_attr "atom_sse_attr" "sqrt")
13471    (set_attr "prefix" "maybe_vex")
13472    (set_attr "mode" "<MODE>")
13473    (set_attr "athlon_decode" "*")
13474    (set_attr "amdfam10_decode" "*")])
13475
13476 (define_expand "sqrt<mode>2"
13477   [(set (match_operand:MODEF 0 "register_operand" "")
13478         (sqrt:MODEF
13479           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13480   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13481    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13482 {
13483   if (<MODE>mode == SFmode
13484       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13485       && flag_finite_math_only && !flag_trapping_math
13486       && flag_unsafe_math_optimizations)
13487     {
13488       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13489       DONE;
13490     }
13491
13492   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13493     {
13494       rtx op0 = gen_reg_rtx (XFmode);
13495       rtx op1 = force_reg (<MODE>mode, operands[1]);
13496
13497       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13498       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13499       DONE;
13500    }
13501 })
13502
13503 (define_insn "fpremxf4_i387"
13504   [(set (match_operand:XF 0 "register_operand" "=f")
13505         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13506                     (match_operand:XF 3 "register_operand" "1")]
13507                    UNSPEC_FPREM_F))
13508    (set (match_operand:XF 1 "register_operand" "=u")
13509         (unspec:XF [(match_dup 2) (match_dup 3)]
13510                    UNSPEC_FPREM_U))
13511    (set (reg:CCFP FPSR_REG)
13512         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13513                      UNSPEC_C2_FLAG))]
13514   "TARGET_USE_FANCY_MATH_387"
13515   "fprem"
13516   [(set_attr "type" "fpspc")
13517    (set_attr "mode" "XF")])
13518
13519 (define_expand "fmodxf3"
13520   [(use (match_operand:XF 0 "register_operand" ""))
13521    (use (match_operand:XF 1 "general_operand" ""))
13522    (use (match_operand:XF 2 "general_operand" ""))]
13523   "TARGET_USE_FANCY_MATH_387"
13524 {
13525   rtx label = gen_label_rtx ();
13526
13527   rtx op1 = gen_reg_rtx (XFmode);
13528   rtx op2 = gen_reg_rtx (XFmode);
13529
13530   emit_move_insn (op2, operands[2]);
13531   emit_move_insn (op1, operands[1]);
13532
13533   emit_label (label);
13534   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13535   ix86_emit_fp_unordered_jump (label);
13536   LABEL_NUSES (label) = 1;
13537
13538   emit_move_insn (operands[0], op1);
13539   DONE;
13540 })
13541
13542 (define_expand "fmod<mode>3"
13543   [(use (match_operand:MODEF 0 "register_operand" ""))
13544    (use (match_operand:MODEF 1 "general_operand" ""))
13545    (use (match_operand:MODEF 2 "general_operand" ""))]
13546   "TARGET_USE_FANCY_MATH_387"
13547 {
13548   rtx label = gen_label_rtx ();
13549
13550   rtx op1 = gen_reg_rtx (XFmode);
13551   rtx op2 = gen_reg_rtx (XFmode);
13552
13553   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13554   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13555
13556   emit_label (label);
13557   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13558   ix86_emit_fp_unordered_jump (label);
13559   LABEL_NUSES (label) = 1;
13560
13561   /* Truncate the result properly for strict SSE math.  */
13562   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13563       && !TARGET_MIX_SSE_I387)
13564     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13565   else
13566     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13567
13568   DONE;
13569 })
13570
13571 (define_insn "fprem1xf4_i387"
13572   [(set (match_operand:XF 0 "register_operand" "=f")
13573         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13574                     (match_operand:XF 3 "register_operand" "1")]
13575                    UNSPEC_FPREM1_F))
13576    (set (match_operand:XF 1 "register_operand" "=u")
13577         (unspec:XF [(match_dup 2) (match_dup 3)]
13578                    UNSPEC_FPREM1_U))
13579    (set (reg:CCFP FPSR_REG)
13580         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13581                      UNSPEC_C2_FLAG))]
13582   "TARGET_USE_FANCY_MATH_387"
13583   "fprem1"
13584   [(set_attr "type" "fpspc")
13585    (set_attr "mode" "XF")])
13586
13587 (define_expand "remainderxf3"
13588   [(use (match_operand:XF 0 "register_operand" ""))
13589    (use (match_operand:XF 1 "general_operand" ""))
13590    (use (match_operand:XF 2 "general_operand" ""))]
13591   "TARGET_USE_FANCY_MATH_387"
13592 {
13593   rtx label = gen_label_rtx ();
13594
13595   rtx op1 = gen_reg_rtx (XFmode);
13596   rtx op2 = gen_reg_rtx (XFmode);
13597
13598   emit_move_insn (op2, operands[2]);
13599   emit_move_insn (op1, operands[1]);
13600
13601   emit_label (label);
13602   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13603   ix86_emit_fp_unordered_jump (label);
13604   LABEL_NUSES (label) = 1;
13605
13606   emit_move_insn (operands[0], op1);
13607   DONE;
13608 })
13609
13610 (define_expand "remainder<mode>3"
13611   [(use (match_operand:MODEF 0 "register_operand" ""))
13612    (use (match_operand:MODEF 1 "general_operand" ""))
13613    (use (match_operand:MODEF 2 "general_operand" ""))]
13614   "TARGET_USE_FANCY_MATH_387"
13615 {
13616   rtx label = gen_label_rtx ();
13617
13618   rtx op1 = gen_reg_rtx (XFmode);
13619   rtx op2 = gen_reg_rtx (XFmode);
13620
13621   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13622   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13623
13624   emit_label (label);
13625
13626   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13627   ix86_emit_fp_unordered_jump (label);
13628   LABEL_NUSES (label) = 1;
13629
13630   /* Truncate the result properly for strict SSE math.  */
13631   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13632       && !TARGET_MIX_SSE_I387)
13633     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13634   else
13635     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13636
13637   DONE;
13638 })
13639
13640 (define_insn "*sinxf2_i387"
13641   [(set (match_operand:XF 0 "register_operand" "=f")
13642         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13643   "TARGET_USE_FANCY_MATH_387
13644    && flag_unsafe_math_optimizations"
13645   "fsin"
13646   [(set_attr "type" "fpspc")
13647    (set_attr "mode" "XF")])
13648
13649 (define_insn "*sin_extend<mode>xf2_i387"
13650   [(set (match_operand:XF 0 "register_operand" "=f")
13651         (unspec:XF [(float_extend:XF
13652                       (match_operand:MODEF 1 "register_operand" "0"))]
13653                    UNSPEC_SIN))]
13654   "TARGET_USE_FANCY_MATH_387
13655    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13656        || TARGET_MIX_SSE_I387)
13657    && flag_unsafe_math_optimizations"
13658   "fsin"
13659   [(set_attr "type" "fpspc")
13660    (set_attr "mode" "XF")])
13661
13662 (define_insn "*cosxf2_i387"
13663   [(set (match_operand:XF 0 "register_operand" "=f")
13664         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13665   "TARGET_USE_FANCY_MATH_387
13666    && flag_unsafe_math_optimizations"
13667   "fcos"
13668   [(set_attr "type" "fpspc")
13669    (set_attr "mode" "XF")])
13670
13671 (define_insn "*cos_extend<mode>xf2_i387"
13672   [(set (match_operand:XF 0 "register_operand" "=f")
13673         (unspec:XF [(float_extend:XF
13674                       (match_operand:MODEF 1 "register_operand" "0"))]
13675                    UNSPEC_COS))]
13676   "TARGET_USE_FANCY_MATH_387
13677    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13678        || TARGET_MIX_SSE_I387)
13679    && flag_unsafe_math_optimizations"
13680   "fcos"
13681   [(set_attr "type" "fpspc")
13682    (set_attr "mode" "XF")])
13683
13684 ;; When sincos pattern is defined, sin and cos builtin functions will be
13685 ;; expanded to sincos pattern with one of its outputs left unused.
13686 ;; CSE pass will figure out if two sincos patterns can be combined,
13687 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13688 ;; depending on the unused output.
13689
13690 (define_insn "sincosxf3"
13691   [(set (match_operand:XF 0 "register_operand" "=f")
13692         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13693                    UNSPEC_SINCOS_COS))
13694    (set (match_operand:XF 1 "register_operand" "=u")
13695         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13696   "TARGET_USE_FANCY_MATH_387
13697    && flag_unsafe_math_optimizations"
13698   "fsincos"
13699   [(set_attr "type" "fpspc")
13700    (set_attr "mode" "XF")])
13701
13702 (define_split
13703   [(set (match_operand:XF 0 "register_operand" "")
13704         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13705                    UNSPEC_SINCOS_COS))
13706    (set (match_operand:XF 1 "register_operand" "")
13707         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13708   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13709    && !(reload_completed || reload_in_progress)"
13710   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13711   "")
13712
13713 (define_split
13714   [(set (match_operand:XF 0 "register_operand" "")
13715         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13716                    UNSPEC_SINCOS_COS))
13717    (set (match_operand:XF 1 "register_operand" "")
13718         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13719   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13720    && !(reload_completed || reload_in_progress)"
13721   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13722   "")
13723
13724 (define_insn "sincos_extend<mode>xf3_i387"
13725   [(set (match_operand:XF 0 "register_operand" "=f")
13726         (unspec:XF [(float_extend:XF
13727                       (match_operand:MODEF 2 "register_operand" "0"))]
13728                    UNSPEC_SINCOS_COS))
13729    (set (match_operand:XF 1 "register_operand" "=u")
13730         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13731   "TARGET_USE_FANCY_MATH_387
13732    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13733        || TARGET_MIX_SSE_I387)
13734    && flag_unsafe_math_optimizations"
13735   "fsincos"
13736   [(set_attr "type" "fpspc")
13737    (set_attr "mode" "XF")])
13738
13739 (define_split
13740   [(set (match_operand:XF 0 "register_operand" "")
13741         (unspec:XF [(float_extend:XF
13742                       (match_operand:MODEF 2 "register_operand" ""))]
13743                    UNSPEC_SINCOS_COS))
13744    (set (match_operand:XF 1 "register_operand" "")
13745         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13746   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13747    && !(reload_completed || reload_in_progress)"
13748   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13749   "")
13750
13751 (define_split
13752   [(set (match_operand:XF 0 "register_operand" "")
13753         (unspec:XF [(float_extend:XF
13754                       (match_operand:MODEF 2 "register_operand" ""))]
13755                    UNSPEC_SINCOS_COS))
13756    (set (match_operand:XF 1 "register_operand" "")
13757         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13758   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13759    && !(reload_completed || reload_in_progress)"
13760   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13761   "")
13762
13763 (define_expand "sincos<mode>3"
13764   [(use (match_operand:MODEF 0 "register_operand" ""))
13765    (use (match_operand:MODEF 1 "register_operand" ""))
13766    (use (match_operand:MODEF 2 "register_operand" ""))]
13767   "TARGET_USE_FANCY_MATH_387
13768    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13769        || TARGET_MIX_SSE_I387)
13770    && flag_unsafe_math_optimizations"
13771 {
13772   rtx op0 = gen_reg_rtx (XFmode);
13773   rtx op1 = gen_reg_rtx (XFmode);
13774
13775   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13776   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13777   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13778   DONE;
13779 })
13780
13781 (define_insn "fptanxf4_i387"
13782   [(set (match_operand:XF 0 "register_operand" "=f")
13783         (match_operand:XF 3 "const_double_operand" "F"))
13784    (set (match_operand:XF 1 "register_operand" "=u")
13785         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13786                    UNSPEC_TAN))]
13787   "TARGET_USE_FANCY_MATH_387
13788    && flag_unsafe_math_optimizations
13789    && standard_80387_constant_p (operands[3]) == 2"
13790   "fptan"
13791   [(set_attr "type" "fpspc")
13792    (set_attr "mode" "XF")])
13793
13794 (define_insn "fptan_extend<mode>xf4_i387"
13795   [(set (match_operand:MODEF 0 "register_operand" "=f")
13796         (match_operand:MODEF 3 "const_double_operand" "F"))
13797    (set (match_operand:XF 1 "register_operand" "=u")
13798         (unspec:XF [(float_extend:XF
13799                       (match_operand:MODEF 2 "register_operand" "0"))]
13800                    UNSPEC_TAN))]
13801   "TARGET_USE_FANCY_MATH_387
13802    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13803        || TARGET_MIX_SSE_I387)
13804    && flag_unsafe_math_optimizations
13805    && standard_80387_constant_p (operands[3]) == 2"
13806   "fptan"
13807   [(set_attr "type" "fpspc")
13808    (set_attr "mode" "XF")])
13809
13810 (define_expand "tanxf2"
13811   [(use (match_operand:XF 0 "register_operand" ""))
13812    (use (match_operand:XF 1 "register_operand" ""))]
13813   "TARGET_USE_FANCY_MATH_387
13814    && flag_unsafe_math_optimizations"
13815 {
13816   rtx one = gen_reg_rtx (XFmode);
13817   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13818
13819   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13820   DONE;
13821 })
13822
13823 (define_expand "tan<mode>2"
13824   [(use (match_operand:MODEF 0 "register_operand" ""))
13825    (use (match_operand:MODEF 1 "register_operand" ""))]
13826   "TARGET_USE_FANCY_MATH_387
13827    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13828        || TARGET_MIX_SSE_I387)
13829    && flag_unsafe_math_optimizations"
13830 {
13831   rtx op0 = gen_reg_rtx (XFmode);
13832
13833   rtx one = gen_reg_rtx (<MODE>mode);
13834   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13835
13836   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13837                                              operands[1], op2));
13838   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13839   DONE;
13840 })
13841
13842 (define_insn "*fpatanxf3_i387"
13843   [(set (match_operand:XF 0 "register_operand" "=f")
13844         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13845                     (match_operand:XF 2 "register_operand" "u")]
13846                    UNSPEC_FPATAN))
13847    (clobber (match_scratch:XF 3 "=2"))]
13848   "TARGET_USE_FANCY_MATH_387
13849    && flag_unsafe_math_optimizations"
13850   "fpatan"
13851   [(set_attr "type" "fpspc")
13852    (set_attr "mode" "XF")])
13853
13854 (define_insn "fpatan_extend<mode>xf3_i387"
13855   [(set (match_operand:XF 0 "register_operand" "=f")
13856         (unspec:XF [(float_extend:XF
13857                       (match_operand:MODEF 1 "register_operand" "0"))
13858                     (float_extend:XF
13859                       (match_operand:MODEF 2 "register_operand" "u"))]
13860                    UNSPEC_FPATAN))
13861    (clobber (match_scratch:XF 3 "=2"))]
13862   "TARGET_USE_FANCY_MATH_387
13863    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13864        || TARGET_MIX_SSE_I387)
13865    && flag_unsafe_math_optimizations"
13866   "fpatan"
13867   [(set_attr "type" "fpspc")
13868    (set_attr "mode" "XF")])
13869
13870 (define_expand "atan2xf3"
13871   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13872                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13873                                (match_operand:XF 1 "register_operand" "")]
13874                               UNSPEC_FPATAN))
13875               (clobber (match_scratch:XF 3 ""))])]
13876   "TARGET_USE_FANCY_MATH_387
13877    && flag_unsafe_math_optimizations"
13878   "")
13879
13880 (define_expand "atan2<mode>3"
13881   [(use (match_operand:MODEF 0 "register_operand" ""))
13882    (use (match_operand:MODEF 1 "register_operand" ""))
13883    (use (match_operand:MODEF 2 "register_operand" ""))]
13884   "TARGET_USE_FANCY_MATH_387
13885    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13886        || TARGET_MIX_SSE_I387)
13887    && flag_unsafe_math_optimizations"
13888 {
13889   rtx op0 = gen_reg_rtx (XFmode);
13890
13891   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13892   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13893   DONE;
13894 })
13895
13896 (define_expand "atanxf2"
13897   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13898                    (unspec:XF [(match_dup 2)
13899                                (match_operand:XF 1 "register_operand" "")]
13900                               UNSPEC_FPATAN))
13901               (clobber (match_scratch:XF 3 ""))])]
13902   "TARGET_USE_FANCY_MATH_387
13903    && flag_unsafe_math_optimizations"
13904 {
13905   operands[2] = gen_reg_rtx (XFmode);
13906   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13907 })
13908
13909 (define_expand "atan<mode>2"
13910   [(use (match_operand:MODEF 0 "register_operand" ""))
13911    (use (match_operand:MODEF 1 "register_operand" ""))]
13912   "TARGET_USE_FANCY_MATH_387
13913    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13914        || TARGET_MIX_SSE_I387)
13915    && flag_unsafe_math_optimizations"
13916 {
13917   rtx op0 = gen_reg_rtx (XFmode);
13918
13919   rtx op2 = gen_reg_rtx (<MODE>mode);
13920   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13921
13922   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13923   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13924   DONE;
13925 })
13926
13927 (define_expand "asinxf2"
13928   [(set (match_dup 2)
13929         (mult:XF (match_operand:XF 1 "register_operand" "")
13930                  (match_dup 1)))
13931    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13932    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13933    (parallel [(set (match_operand:XF 0 "register_operand" "")
13934                    (unspec:XF [(match_dup 5) (match_dup 1)]
13935                               UNSPEC_FPATAN))
13936               (clobber (match_scratch:XF 6 ""))])]
13937   "TARGET_USE_FANCY_MATH_387
13938    && flag_unsafe_math_optimizations"
13939 {
13940   int i;
13941
13942   if (optimize_insn_for_size_p ())
13943     FAIL;
13944
13945   for (i = 2; i < 6; i++)
13946     operands[i] = gen_reg_rtx (XFmode);
13947
13948   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13949 })
13950
13951 (define_expand "asin<mode>2"
13952   [(use (match_operand:MODEF 0 "register_operand" ""))
13953    (use (match_operand:MODEF 1 "general_operand" ""))]
13954  "TARGET_USE_FANCY_MATH_387
13955    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13956        || TARGET_MIX_SSE_I387)
13957    && flag_unsafe_math_optimizations"
13958 {
13959   rtx op0 = gen_reg_rtx (XFmode);
13960   rtx op1 = gen_reg_rtx (XFmode);
13961
13962   if (optimize_insn_for_size_p ())
13963     FAIL;
13964
13965   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13966   emit_insn (gen_asinxf2 (op0, op1));
13967   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13968   DONE;
13969 })
13970
13971 (define_expand "acosxf2"
13972   [(set (match_dup 2)
13973         (mult:XF (match_operand:XF 1 "register_operand" "")
13974                  (match_dup 1)))
13975    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13976    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13977    (parallel [(set (match_operand:XF 0 "register_operand" "")
13978                    (unspec:XF [(match_dup 1) (match_dup 5)]
13979                               UNSPEC_FPATAN))
13980               (clobber (match_scratch:XF 6 ""))])]
13981   "TARGET_USE_FANCY_MATH_387
13982    && flag_unsafe_math_optimizations"
13983 {
13984   int i;
13985
13986   if (optimize_insn_for_size_p ())
13987     FAIL;
13988
13989   for (i = 2; i < 6; i++)
13990     operands[i] = gen_reg_rtx (XFmode);
13991
13992   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13993 })
13994
13995 (define_expand "acos<mode>2"
13996   [(use (match_operand:MODEF 0 "register_operand" ""))
13997    (use (match_operand:MODEF 1 "general_operand" ""))]
13998  "TARGET_USE_FANCY_MATH_387
13999    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14000        || TARGET_MIX_SSE_I387)
14001    && flag_unsafe_math_optimizations"
14002 {
14003   rtx op0 = gen_reg_rtx (XFmode);
14004   rtx op1 = gen_reg_rtx (XFmode);
14005
14006   if (optimize_insn_for_size_p ())
14007     FAIL;
14008
14009   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14010   emit_insn (gen_acosxf2 (op0, op1));
14011   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14012   DONE;
14013 })
14014
14015 (define_insn "fyl2xxf3_i387"
14016   [(set (match_operand:XF 0 "register_operand" "=f")
14017         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14018                     (match_operand:XF 2 "register_operand" "u")]
14019                    UNSPEC_FYL2X))
14020    (clobber (match_scratch:XF 3 "=2"))]
14021   "TARGET_USE_FANCY_MATH_387
14022    && flag_unsafe_math_optimizations"
14023   "fyl2x"
14024   [(set_attr "type" "fpspc")
14025    (set_attr "mode" "XF")])
14026
14027 (define_insn "fyl2x_extend<mode>xf3_i387"
14028   [(set (match_operand:XF 0 "register_operand" "=f")
14029         (unspec:XF [(float_extend:XF
14030                       (match_operand:MODEF 1 "register_operand" "0"))
14031                     (match_operand:XF 2 "register_operand" "u")]
14032                    UNSPEC_FYL2X))
14033    (clobber (match_scratch:XF 3 "=2"))]
14034   "TARGET_USE_FANCY_MATH_387
14035    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14036        || TARGET_MIX_SSE_I387)
14037    && flag_unsafe_math_optimizations"
14038   "fyl2x"
14039   [(set_attr "type" "fpspc")
14040    (set_attr "mode" "XF")])
14041
14042 (define_expand "logxf2"
14043   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14044                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14045                                (match_dup 2)] UNSPEC_FYL2X))
14046               (clobber (match_scratch:XF 3 ""))])]
14047   "TARGET_USE_FANCY_MATH_387
14048    && flag_unsafe_math_optimizations"
14049 {
14050   operands[2] = gen_reg_rtx (XFmode);
14051   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14052 })
14053
14054 (define_expand "log<mode>2"
14055   [(use (match_operand:MODEF 0 "register_operand" ""))
14056    (use (match_operand:MODEF 1 "register_operand" ""))]
14057   "TARGET_USE_FANCY_MATH_387
14058    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14059        || TARGET_MIX_SSE_I387)
14060    && flag_unsafe_math_optimizations"
14061 {
14062   rtx op0 = gen_reg_rtx (XFmode);
14063
14064   rtx op2 = gen_reg_rtx (XFmode);
14065   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14066
14067   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14068   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14069   DONE;
14070 })
14071
14072 (define_expand "log10xf2"
14073   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14074                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14075                                (match_dup 2)] UNSPEC_FYL2X))
14076               (clobber (match_scratch:XF 3 ""))])]
14077   "TARGET_USE_FANCY_MATH_387
14078    && flag_unsafe_math_optimizations"
14079 {
14080   operands[2] = gen_reg_rtx (XFmode);
14081   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14082 })
14083
14084 (define_expand "log10<mode>2"
14085   [(use (match_operand:MODEF 0 "register_operand" ""))
14086    (use (match_operand:MODEF 1 "register_operand" ""))]
14087   "TARGET_USE_FANCY_MATH_387
14088    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14089        || TARGET_MIX_SSE_I387)
14090    && flag_unsafe_math_optimizations"
14091 {
14092   rtx op0 = gen_reg_rtx (XFmode);
14093
14094   rtx op2 = gen_reg_rtx (XFmode);
14095   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14096
14097   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14098   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14099   DONE;
14100 })
14101
14102 (define_expand "log2xf2"
14103   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14104                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14105                                (match_dup 2)] UNSPEC_FYL2X))
14106               (clobber (match_scratch:XF 3 ""))])]
14107   "TARGET_USE_FANCY_MATH_387
14108    && flag_unsafe_math_optimizations"
14109 {
14110   operands[2] = gen_reg_rtx (XFmode);
14111   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14112 })
14113
14114 (define_expand "log2<mode>2"
14115   [(use (match_operand:MODEF 0 "register_operand" ""))
14116    (use (match_operand:MODEF 1 "register_operand" ""))]
14117   "TARGET_USE_FANCY_MATH_387
14118    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14119        || TARGET_MIX_SSE_I387)
14120    && flag_unsafe_math_optimizations"
14121 {
14122   rtx op0 = gen_reg_rtx (XFmode);
14123
14124   rtx op2 = gen_reg_rtx (XFmode);
14125   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14126
14127   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14128   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14129   DONE;
14130 })
14131
14132 (define_insn "fyl2xp1xf3_i387"
14133   [(set (match_operand:XF 0 "register_operand" "=f")
14134         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14135                     (match_operand:XF 2 "register_operand" "u")]
14136                    UNSPEC_FYL2XP1))
14137    (clobber (match_scratch:XF 3 "=2"))]
14138   "TARGET_USE_FANCY_MATH_387
14139    && flag_unsafe_math_optimizations"
14140   "fyl2xp1"
14141   [(set_attr "type" "fpspc")
14142    (set_attr "mode" "XF")])
14143
14144 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14145   [(set (match_operand:XF 0 "register_operand" "=f")
14146         (unspec:XF [(float_extend:XF
14147                       (match_operand:MODEF 1 "register_operand" "0"))
14148                     (match_operand:XF 2 "register_operand" "u")]
14149                    UNSPEC_FYL2XP1))
14150    (clobber (match_scratch:XF 3 "=2"))]
14151   "TARGET_USE_FANCY_MATH_387
14152    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14153        || TARGET_MIX_SSE_I387)
14154    && flag_unsafe_math_optimizations"
14155   "fyl2xp1"
14156   [(set_attr "type" "fpspc")
14157    (set_attr "mode" "XF")])
14158
14159 (define_expand "log1pxf2"
14160   [(use (match_operand:XF 0 "register_operand" ""))
14161    (use (match_operand:XF 1 "register_operand" ""))]
14162   "TARGET_USE_FANCY_MATH_387
14163    && flag_unsafe_math_optimizations"
14164 {
14165   if (optimize_insn_for_size_p ())
14166     FAIL;
14167
14168   ix86_emit_i387_log1p (operands[0], operands[1]);
14169   DONE;
14170 })
14171
14172 (define_expand "log1p<mode>2"
14173   [(use (match_operand:MODEF 0 "register_operand" ""))
14174    (use (match_operand:MODEF 1 "register_operand" ""))]
14175   "TARGET_USE_FANCY_MATH_387
14176    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14177        || TARGET_MIX_SSE_I387)
14178    && flag_unsafe_math_optimizations"
14179 {
14180   rtx op0;
14181
14182   if (optimize_insn_for_size_p ())
14183     FAIL;
14184
14185   op0 = gen_reg_rtx (XFmode);
14186
14187   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14188
14189   ix86_emit_i387_log1p (op0, operands[1]);
14190   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14191   DONE;
14192 })
14193
14194 (define_insn "fxtractxf3_i387"
14195   [(set (match_operand:XF 0 "register_operand" "=f")
14196         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14197                    UNSPEC_XTRACT_FRACT))
14198    (set (match_operand:XF 1 "register_operand" "=u")
14199         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14200   "TARGET_USE_FANCY_MATH_387
14201    && flag_unsafe_math_optimizations"
14202   "fxtract"
14203   [(set_attr "type" "fpspc")
14204    (set_attr "mode" "XF")])
14205
14206 (define_insn "fxtract_extend<mode>xf3_i387"
14207   [(set (match_operand:XF 0 "register_operand" "=f")
14208         (unspec:XF [(float_extend:XF
14209                       (match_operand:MODEF 2 "register_operand" "0"))]
14210                    UNSPEC_XTRACT_FRACT))
14211    (set (match_operand:XF 1 "register_operand" "=u")
14212         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14213   "TARGET_USE_FANCY_MATH_387
14214    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14215        || TARGET_MIX_SSE_I387)
14216    && flag_unsafe_math_optimizations"
14217   "fxtract"
14218   [(set_attr "type" "fpspc")
14219    (set_attr "mode" "XF")])
14220
14221 (define_expand "logbxf2"
14222   [(parallel [(set (match_dup 2)
14223                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14224                               UNSPEC_XTRACT_FRACT))
14225               (set (match_operand:XF 0 "register_operand" "")
14226                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14227   "TARGET_USE_FANCY_MATH_387
14228    && flag_unsafe_math_optimizations"
14229 {
14230   operands[2] = gen_reg_rtx (XFmode);
14231 })
14232
14233 (define_expand "logb<mode>2"
14234   [(use (match_operand:MODEF 0 "register_operand" ""))
14235    (use (match_operand:MODEF 1 "register_operand" ""))]
14236   "TARGET_USE_FANCY_MATH_387
14237    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14238        || TARGET_MIX_SSE_I387)
14239    && flag_unsafe_math_optimizations"
14240 {
14241   rtx op0 = gen_reg_rtx (XFmode);
14242   rtx op1 = gen_reg_rtx (XFmode);
14243
14244   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14245   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14246   DONE;
14247 })
14248
14249 (define_expand "ilogbxf2"
14250   [(use (match_operand:SI 0 "register_operand" ""))
14251    (use (match_operand:XF 1 "register_operand" ""))]
14252   "TARGET_USE_FANCY_MATH_387
14253    && flag_unsafe_math_optimizations"
14254 {
14255   rtx op0, op1;
14256
14257   if (optimize_insn_for_size_p ())
14258     FAIL;
14259
14260   op0 = gen_reg_rtx (XFmode);
14261   op1 = gen_reg_rtx (XFmode);
14262
14263   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14264   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14265   DONE;
14266 })
14267
14268 (define_expand "ilogb<mode>2"
14269   [(use (match_operand:SI 0 "register_operand" ""))
14270    (use (match_operand:MODEF 1 "register_operand" ""))]
14271   "TARGET_USE_FANCY_MATH_387
14272    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14273        || TARGET_MIX_SSE_I387)
14274    && flag_unsafe_math_optimizations"
14275 {
14276   rtx op0, op1;
14277
14278   if (optimize_insn_for_size_p ())
14279     FAIL;
14280
14281   op0 = gen_reg_rtx (XFmode);
14282   op1 = gen_reg_rtx (XFmode);
14283
14284   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14285   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14286   DONE;
14287 })
14288
14289 (define_insn "*f2xm1xf2_i387"
14290   [(set (match_operand:XF 0 "register_operand" "=f")
14291         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14292                    UNSPEC_F2XM1))]
14293   "TARGET_USE_FANCY_MATH_387
14294    && flag_unsafe_math_optimizations"
14295   "f2xm1"
14296   [(set_attr "type" "fpspc")
14297    (set_attr "mode" "XF")])
14298
14299 (define_insn "*fscalexf4_i387"
14300   [(set (match_operand:XF 0 "register_operand" "=f")
14301         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14302                     (match_operand:XF 3 "register_operand" "1")]
14303                    UNSPEC_FSCALE_FRACT))
14304    (set (match_operand:XF 1 "register_operand" "=u")
14305         (unspec:XF [(match_dup 2) (match_dup 3)]
14306                    UNSPEC_FSCALE_EXP))]
14307   "TARGET_USE_FANCY_MATH_387
14308    && flag_unsafe_math_optimizations"
14309   "fscale"
14310   [(set_attr "type" "fpspc")
14311    (set_attr "mode" "XF")])
14312
14313 (define_expand "expNcorexf3"
14314   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14315                                (match_operand:XF 2 "register_operand" "")))
14316    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14317    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14318    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14319    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14320    (parallel [(set (match_operand:XF 0 "register_operand" "")
14321                    (unspec:XF [(match_dup 8) (match_dup 4)]
14322                               UNSPEC_FSCALE_FRACT))
14323               (set (match_dup 9)
14324                    (unspec:XF [(match_dup 8) (match_dup 4)]
14325                               UNSPEC_FSCALE_EXP))])]
14326   "TARGET_USE_FANCY_MATH_387
14327    && flag_unsafe_math_optimizations"
14328 {
14329   int i;
14330
14331   if (optimize_insn_for_size_p ())
14332     FAIL;
14333
14334   for (i = 3; i < 10; i++)
14335     operands[i] = gen_reg_rtx (XFmode);
14336
14337   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14338 })
14339
14340 (define_expand "expxf2"
14341   [(use (match_operand:XF 0 "register_operand" ""))
14342    (use (match_operand:XF 1 "register_operand" ""))]
14343   "TARGET_USE_FANCY_MATH_387
14344    && flag_unsafe_math_optimizations"
14345 {
14346   rtx op2;
14347
14348   if (optimize_insn_for_size_p ())
14349     FAIL;
14350
14351   op2 = gen_reg_rtx (XFmode);
14352   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14353
14354   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14355   DONE;
14356 })
14357
14358 (define_expand "exp<mode>2"
14359   [(use (match_operand:MODEF 0 "register_operand" ""))
14360    (use (match_operand:MODEF 1 "general_operand" ""))]
14361  "TARGET_USE_FANCY_MATH_387
14362    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14363        || TARGET_MIX_SSE_I387)
14364    && flag_unsafe_math_optimizations"
14365 {
14366   rtx op0, op1;
14367
14368   if (optimize_insn_for_size_p ())
14369     FAIL;
14370
14371   op0 = gen_reg_rtx (XFmode);
14372   op1 = gen_reg_rtx (XFmode);
14373
14374   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14375   emit_insn (gen_expxf2 (op0, op1));
14376   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14377   DONE;
14378 })
14379
14380 (define_expand "exp10xf2"
14381   [(use (match_operand:XF 0 "register_operand" ""))
14382    (use (match_operand:XF 1 "register_operand" ""))]
14383   "TARGET_USE_FANCY_MATH_387
14384    && flag_unsafe_math_optimizations"
14385 {
14386   rtx op2;
14387
14388   if (optimize_insn_for_size_p ())
14389     FAIL;
14390
14391   op2 = gen_reg_rtx (XFmode);
14392   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14393
14394   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14395   DONE;
14396 })
14397
14398 (define_expand "exp10<mode>2"
14399   [(use (match_operand:MODEF 0 "register_operand" ""))
14400    (use (match_operand:MODEF 1 "general_operand" ""))]
14401  "TARGET_USE_FANCY_MATH_387
14402    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14403        || TARGET_MIX_SSE_I387)
14404    && flag_unsafe_math_optimizations"
14405 {
14406   rtx op0, op1;
14407
14408   if (optimize_insn_for_size_p ())
14409     FAIL;
14410
14411   op0 = gen_reg_rtx (XFmode);
14412   op1 = gen_reg_rtx (XFmode);
14413
14414   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14415   emit_insn (gen_exp10xf2 (op0, op1));
14416   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14417   DONE;
14418 })
14419
14420 (define_expand "exp2xf2"
14421   [(use (match_operand:XF 0 "register_operand" ""))
14422    (use (match_operand:XF 1 "register_operand" ""))]
14423   "TARGET_USE_FANCY_MATH_387
14424    && flag_unsafe_math_optimizations"
14425 {
14426   rtx op2;
14427
14428   if (optimize_insn_for_size_p ())
14429     FAIL;
14430
14431   op2 = gen_reg_rtx (XFmode);
14432   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14433
14434   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14435   DONE;
14436 })
14437
14438 (define_expand "exp2<mode>2"
14439   [(use (match_operand:MODEF 0 "register_operand" ""))
14440    (use (match_operand:MODEF 1 "general_operand" ""))]
14441  "TARGET_USE_FANCY_MATH_387
14442    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14443        || TARGET_MIX_SSE_I387)
14444    && flag_unsafe_math_optimizations"
14445 {
14446   rtx op0, op1;
14447
14448   if (optimize_insn_for_size_p ())
14449     FAIL;
14450
14451   op0 = gen_reg_rtx (XFmode);
14452   op1 = gen_reg_rtx (XFmode);
14453
14454   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14455   emit_insn (gen_exp2xf2 (op0, op1));
14456   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14457   DONE;
14458 })
14459
14460 (define_expand "expm1xf2"
14461   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14462                                (match_dup 2)))
14463    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14464    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14465    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14466    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14467    (parallel [(set (match_dup 7)
14468                    (unspec:XF [(match_dup 6) (match_dup 4)]
14469                               UNSPEC_FSCALE_FRACT))
14470               (set (match_dup 8)
14471                    (unspec:XF [(match_dup 6) (match_dup 4)]
14472                               UNSPEC_FSCALE_EXP))])
14473    (parallel [(set (match_dup 10)
14474                    (unspec:XF [(match_dup 9) (match_dup 8)]
14475                               UNSPEC_FSCALE_FRACT))
14476               (set (match_dup 11)
14477                    (unspec:XF [(match_dup 9) (match_dup 8)]
14478                               UNSPEC_FSCALE_EXP))])
14479    (set (match_dup 12) (minus:XF (match_dup 10)
14480                                  (float_extend:XF (match_dup 13))))
14481    (set (match_operand:XF 0 "register_operand" "")
14482         (plus:XF (match_dup 12) (match_dup 7)))]
14483   "TARGET_USE_FANCY_MATH_387
14484    && flag_unsafe_math_optimizations"
14485 {
14486   int i;
14487
14488   if (optimize_insn_for_size_p ())
14489     FAIL;
14490
14491   for (i = 2; i < 13; i++)
14492     operands[i] = gen_reg_rtx (XFmode);
14493
14494   operands[13]
14495     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14496
14497   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14498 })
14499
14500 (define_expand "expm1<mode>2"
14501   [(use (match_operand:MODEF 0 "register_operand" ""))
14502    (use (match_operand:MODEF 1 "general_operand" ""))]
14503  "TARGET_USE_FANCY_MATH_387
14504    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14505        || TARGET_MIX_SSE_I387)
14506    && flag_unsafe_math_optimizations"
14507 {
14508   rtx op0, op1;
14509
14510   if (optimize_insn_for_size_p ())
14511     FAIL;
14512
14513   op0 = gen_reg_rtx (XFmode);
14514   op1 = gen_reg_rtx (XFmode);
14515
14516   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14517   emit_insn (gen_expm1xf2 (op0, op1));
14518   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14519   DONE;
14520 })
14521
14522 (define_expand "ldexpxf3"
14523   [(set (match_dup 3)
14524         (float:XF (match_operand:SI 2 "register_operand" "")))
14525    (parallel [(set (match_operand:XF 0 " register_operand" "")
14526                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14527                                (match_dup 3)]
14528                               UNSPEC_FSCALE_FRACT))
14529               (set (match_dup 4)
14530                    (unspec:XF [(match_dup 1) (match_dup 3)]
14531                               UNSPEC_FSCALE_EXP))])]
14532   "TARGET_USE_FANCY_MATH_387
14533    && flag_unsafe_math_optimizations"
14534 {
14535   if (optimize_insn_for_size_p ())
14536     FAIL;
14537
14538   operands[3] = gen_reg_rtx (XFmode);
14539   operands[4] = gen_reg_rtx (XFmode);
14540 })
14541
14542 (define_expand "ldexp<mode>3"
14543   [(use (match_operand:MODEF 0 "register_operand" ""))
14544    (use (match_operand:MODEF 1 "general_operand" ""))
14545    (use (match_operand:SI 2 "register_operand" ""))]
14546  "TARGET_USE_FANCY_MATH_387
14547    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14548        || TARGET_MIX_SSE_I387)
14549    && flag_unsafe_math_optimizations"
14550 {
14551   rtx op0, op1;
14552
14553   if (optimize_insn_for_size_p ())
14554     FAIL;
14555
14556   op0 = gen_reg_rtx (XFmode);
14557   op1 = gen_reg_rtx (XFmode);
14558
14559   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14560   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14561   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14562   DONE;
14563 })
14564
14565 (define_expand "scalbxf3"
14566   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14567                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14568                                (match_operand:XF 2 "register_operand" "")]
14569                               UNSPEC_FSCALE_FRACT))
14570               (set (match_dup 3)
14571                    (unspec:XF [(match_dup 1) (match_dup 2)]
14572                               UNSPEC_FSCALE_EXP))])]
14573   "TARGET_USE_FANCY_MATH_387
14574    && flag_unsafe_math_optimizations"
14575 {
14576   if (optimize_insn_for_size_p ())
14577     FAIL;
14578
14579   operands[3] = gen_reg_rtx (XFmode);
14580 })
14581
14582 (define_expand "scalb<mode>3"
14583   [(use (match_operand:MODEF 0 "register_operand" ""))
14584    (use (match_operand:MODEF 1 "general_operand" ""))
14585    (use (match_operand:MODEF 2 "general_operand" ""))]
14586  "TARGET_USE_FANCY_MATH_387
14587    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14588        || TARGET_MIX_SSE_I387)
14589    && flag_unsafe_math_optimizations"
14590 {
14591   rtx op0, op1, op2;
14592
14593   if (optimize_insn_for_size_p ())
14594     FAIL;
14595
14596   op0 = gen_reg_rtx (XFmode);
14597   op1 = gen_reg_rtx (XFmode);
14598   op2 = gen_reg_rtx (XFmode);
14599
14600   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14601   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14602   emit_insn (gen_scalbxf3 (op0, op1, op2));
14603   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14604   DONE;
14605 })
14606
14607 (define_expand "significandxf2"
14608   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14609                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14610                               UNSPEC_XTRACT_FRACT))
14611               (set (match_dup 2)
14612                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14613   "TARGET_USE_FANCY_MATH_387
14614    && flag_unsafe_math_optimizations"
14615 {
14616   operands[2] = gen_reg_rtx (XFmode);
14617 })
14618
14619 (define_expand "significand<mode>2"
14620   [(use (match_operand:MODEF 0 "register_operand" ""))
14621    (use (match_operand:MODEF 1 "register_operand" ""))]
14622   "TARGET_USE_FANCY_MATH_387
14623    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14624        || TARGET_MIX_SSE_I387)
14625    && flag_unsafe_math_optimizations"
14626 {
14627   rtx op0 = gen_reg_rtx (XFmode);
14628   rtx op1 = gen_reg_rtx (XFmode);
14629
14630   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14631   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14632   DONE;
14633 })
14634 \f
14635
14636 (define_insn "sse4_1_round<mode>2"
14637   [(set (match_operand:MODEF 0 "register_operand" "=x")
14638         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14639                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14640                       UNSPEC_ROUND))]
14641   "TARGET_ROUND"
14642   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14643   [(set_attr "type" "ssecvt")
14644    (set_attr "prefix_extra" "1")
14645    (set_attr "prefix" "maybe_vex")
14646    (set_attr "mode" "<MODE>")])
14647
14648 (define_insn "rintxf2"
14649   [(set (match_operand:XF 0 "register_operand" "=f")
14650         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14651                    UNSPEC_FRNDINT))]
14652   "TARGET_USE_FANCY_MATH_387
14653    && flag_unsafe_math_optimizations"
14654   "frndint"
14655   [(set_attr "type" "fpspc")
14656    (set_attr "mode" "XF")])
14657
14658 (define_expand "rint<mode>2"
14659   [(use (match_operand:MODEF 0 "register_operand" ""))
14660    (use (match_operand:MODEF 1 "register_operand" ""))]
14661   "(TARGET_USE_FANCY_MATH_387
14662     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14663         || TARGET_MIX_SSE_I387)
14664     && flag_unsafe_math_optimizations)
14665    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14666        && !flag_trapping_math)"
14667 {
14668   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14669       && !flag_trapping_math)
14670     {
14671       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14672         FAIL;
14673       if (TARGET_ROUND)
14674         emit_insn (gen_sse4_1_round<mode>2
14675                    (operands[0], operands[1], GEN_INT (0x04)));
14676       else
14677         ix86_expand_rint (operand0, operand1);
14678     }
14679   else
14680     {
14681       rtx op0 = gen_reg_rtx (XFmode);
14682       rtx op1 = gen_reg_rtx (XFmode);
14683
14684       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14685       emit_insn (gen_rintxf2 (op0, op1));
14686
14687       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14688     }
14689   DONE;
14690 })
14691
14692 (define_expand "round<mode>2"
14693   [(match_operand:MODEF 0 "register_operand" "")
14694    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14695   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14696    && !flag_trapping_math && !flag_rounding_math"
14697 {
14698   if (optimize_insn_for_size_p ())
14699     FAIL;
14700   if (TARGET_64BIT || (<MODE>mode != DFmode))
14701     ix86_expand_round (operand0, operand1);
14702   else
14703     ix86_expand_rounddf_32 (operand0, operand1);
14704   DONE;
14705 })
14706
14707 (define_insn_and_split "*fistdi2_1"
14708   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14709         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14710                    UNSPEC_FIST))]
14711   "TARGET_USE_FANCY_MATH_387
14712    && can_create_pseudo_p ()"
14713   "#"
14714   "&& 1"
14715   [(const_int 0)]
14716 {
14717   if (memory_operand (operands[0], VOIDmode))
14718     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14719   else
14720     {
14721       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14722       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14723                                          operands[2]));
14724     }
14725   DONE;
14726 }
14727   [(set_attr "type" "fpspc")
14728    (set_attr "mode" "DI")])
14729
14730 (define_insn "fistdi2"
14731   [(set (match_operand:DI 0 "memory_operand" "=m")
14732         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14733                    UNSPEC_FIST))
14734    (clobber (match_scratch:XF 2 "=&1f"))]
14735   "TARGET_USE_FANCY_MATH_387"
14736   "* return output_fix_trunc (insn, operands, 0);"
14737   [(set_attr "type" "fpspc")
14738    (set_attr "mode" "DI")])
14739
14740 (define_insn "fistdi2_with_temp"
14741   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14742         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14743                    UNSPEC_FIST))
14744    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14745    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14746   "TARGET_USE_FANCY_MATH_387"
14747   "#"
14748   [(set_attr "type" "fpspc")
14749    (set_attr "mode" "DI")])
14750
14751 (define_split
14752   [(set (match_operand:DI 0 "register_operand" "")
14753         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14754                    UNSPEC_FIST))
14755    (clobber (match_operand:DI 2 "memory_operand" ""))
14756    (clobber (match_scratch 3 ""))]
14757   "reload_completed"
14758   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14759               (clobber (match_dup 3))])
14760    (set (match_dup 0) (match_dup 2))]
14761   "")
14762
14763 (define_split
14764   [(set (match_operand:DI 0 "memory_operand" "")
14765         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14766                    UNSPEC_FIST))
14767    (clobber (match_operand:DI 2 "memory_operand" ""))
14768    (clobber (match_scratch 3 ""))]
14769   "reload_completed"
14770   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14771               (clobber (match_dup 3))])]
14772   "")
14773
14774 (define_insn_and_split "*fist<mode>2_1"
14775   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14776         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14777                            UNSPEC_FIST))]
14778   "TARGET_USE_FANCY_MATH_387
14779    && can_create_pseudo_p ()"
14780   "#"
14781   "&& 1"
14782   [(const_int 0)]
14783 {
14784   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14785   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14786                                         operands[2]));
14787   DONE;
14788 }
14789   [(set_attr "type" "fpspc")
14790    (set_attr "mode" "<MODE>")])
14791
14792 (define_insn "fist<mode>2"
14793   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14794         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14795                            UNSPEC_FIST))]
14796   "TARGET_USE_FANCY_MATH_387"
14797   "* return output_fix_trunc (insn, operands, 0);"
14798   [(set_attr "type" "fpspc")
14799    (set_attr "mode" "<MODE>")])
14800
14801 (define_insn "fist<mode>2_with_temp"
14802   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14803         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14804                            UNSPEC_FIST))
14805    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14806   "TARGET_USE_FANCY_MATH_387"
14807   "#"
14808   [(set_attr "type" "fpspc")
14809    (set_attr "mode" "<MODE>")])
14810
14811 (define_split
14812   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14813         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14814                            UNSPEC_FIST))
14815    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14816   "reload_completed"
14817   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14818    (set (match_dup 0) (match_dup 2))]
14819   "")
14820
14821 (define_split
14822   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14823         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14824                            UNSPEC_FIST))
14825    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14826   "reload_completed"
14827   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14828   "")
14829
14830 (define_expand "lrintxf<mode>2"
14831   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14832      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14833                       UNSPEC_FIST))]
14834   "TARGET_USE_FANCY_MATH_387"
14835   "")
14836
14837 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14838   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14839      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14840                         UNSPEC_FIX_NOTRUNC))]
14841   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14842    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14843   "")
14844
14845 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14846   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14847    (match_operand:MODEF 1 "register_operand" "")]
14848   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14849    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14850    && !flag_trapping_math && !flag_rounding_math"
14851 {
14852   if (optimize_insn_for_size_p ())
14853     FAIL;
14854   ix86_expand_lround (operand0, operand1);
14855   DONE;
14856 })
14857
14858 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14859 (define_insn_and_split "frndintxf2_floor"
14860   [(set (match_operand:XF 0 "register_operand" "")
14861         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14862          UNSPEC_FRNDINT_FLOOR))
14863    (clobber (reg:CC FLAGS_REG))]
14864   "TARGET_USE_FANCY_MATH_387
14865    && flag_unsafe_math_optimizations
14866    && can_create_pseudo_p ()"
14867   "#"
14868   "&& 1"
14869   [(const_int 0)]
14870 {
14871   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14872
14873   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14874   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14875
14876   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14877                                         operands[2], operands[3]));
14878   DONE;
14879 }
14880   [(set_attr "type" "frndint")
14881    (set_attr "i387_cw" "floor")
14882    (set_attr "mode" "XF")])
14883
14884 (define_insn "frndintxf2_floor_i387"
14885   [(set (match_operand:XF 0 "register_operand" "=f")
14886         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14887          UNSPEC_FRNDINT_FLOOR))
14888    (use (match_operand:HI 2 "memory_operand" "m"))
14889    (use (match_operand:HI 3 "memory_operand" "m"))]
14890   "TARGET_USE_FANCY_MATH_387
14891    && flag_unsafe_math_optimizations"
14892   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14893   [(set_attr "type" "frndint")
14894    (set_attr "i387_cw" "floor")
14895    (set_attr "mode" "XF")])
14896
14897 (define_expand "floorxf2"
14898   [(use (match_operand:XF 0 "register_operand" ""))
14899    (use (match_operand:XF 1 "register_operand" ""))]
14900   "TARGET_USE_FANCY_MATH_387
14901    && flag_unsafe_math_optimizations"
14902 {
14903   if (optimize_insn_for_size_p ())
14904     FAIL;
14905   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14906   DONE;
14907 })
14908
14909 (define_expand "floor<mode>2"
14910   [(use (match_operand:MODEF 0 "register_operand" ""))
14911    (use (match_operand:MODEF 1 "register_operand" ""))]
14912   "(TARGET_USE_FANCY_MATH_387
14913     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14914         || TARGET_MIX_SSE_I387)
14915     && flag_unsafe_math_optimizations)
14916    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14917        && !flag_trapping_math)"
14918 {
14919   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14920       && !flag_trapping_math
14921       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14922     {
14923       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14924         FAIL;
14925       if (TARGET_ROUND)
14926         emit_insn (gen_sse4_1_round<mode>2
14927                    (operands[0], operands[1], GEN_INT (0x01)));
14928       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14929         ix86_expand_floorceil (operand0, operand1, true);
14930       else
14931         ix86_expand_floorceildf_32 (operand0, operand1, true);
14932     }
14933   else
14934     {
14935       rtx op0, op1;
14936
14937       if (optimize_insn_for_size_p ())
14938         FAIL;
14939
14940       op0 = gen_reg_rtx (XFmode);
14941       op1 = gen_reg_rtx (XFmode);
14942       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14943       emit_insn (gen_frndintxf2_floor (op0, op1));
14944
14945       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14946     }
14947   DONE;
14948 })
14949
14950 (define_insn_and_split "*fist<mode>2_floor_1"
14951   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14952         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14953          UNSPEC_FIST_FLOOR))
14954    (clobber (reg:CC FLAGS_REG))]
14955   "TARGET_USE_FANCY_MATH_387
14956    && flag_unsafe_math_optimizations
14957    && can_create_pseudo_p ()"
14958   "#"
14959   "&& 1"
14960   [(const_int 0)]
14961 {
14962   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14963
14964   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14965   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14966   if (memory_operand (operands[0], VOIDmode))
14967     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14968                                       operands[2], operands[3]));
14969   else
14970     {
14971       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14972       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14973                                                   operands[2], operands[3],
14974                                                   operands[4]));
14975     }
14976   DONE;
14977 }
14978   [(set_attr "type" "fistp")
14979    (set_attr "i387_cw" "floor")
14980    (set_attr "mode" "<MODE>")])
14981
14982 (define_insn "fistdi2_floor"
14983   [(set (match_operand:DI 0 "memory_operand" "=m")
14984         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14985          UNSPEC_FIST_FLOOR))
14986    (use (match_operand:HI 2 "memory_operand" "m"))
14987    (use (match_operand:HI 3 "memory_operand" "m"))
14988    (clobber (match_scratch:XF 4 "=&1f"))]
14989   "TARGET_USE_FANCY_MATH_387
14990    && flag_unsafe_math_optimizations"
14991   "* return output_fix_trunc (insn, operands, 0);"
14992   [(set_attr "type" "fistp")
14993    (set_attr "i387_cw" "floor")
14994    (set_attr "mode" "DI")])
14995
14996 (define_insn "fistdi2_floor_with_temp"
14997   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14998         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14999          UNSPEC_FIST_FLOOR))
15000    (use (match_operand:HI 2 "memory_operand" "m,m"))
15001    (use (match_operand:HI 3 "memory_operand" "m,m"))
15002    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15003    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15004   "TARGET_USE_FANCY_MATH_387
15005    && flag_unsafe_math_optimizations"
15006   "#"
15007   [(set_attr "type" "fistp")
15008    (set_attr "i387_cw" "floor")
15009    (set_attr "mode" "DI")])
15010
15011 (define_split
15012   [(set (match_operand:DI 0 "register_operand" "")
15013         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15014          UNSPEC_FIST_FLOOR))
15015    (use (match_operand:HI 2 "memory_operand" ""))
15016    (use (match_operand:HI 3 "memory_operand" ""))
15017    (clobber (match_operand:DI 4 "memory_operand" ""))
15018    (clobber (match_scratch 5 ""))]
15019   "reload_completed"
15020   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15021               (use (match_dup 2))
15022               (use (match_dup 3))
15023               (clobber (match_dup 5))])
15024    (set (match_dup 0) (match_dup 4))]
15025   "")
15026
15027 (define_split
15028   [(set (match_operand:DI 0 "memory_operand" "")
15029         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15030          UNSPEC_FIST_FLOOR))
15031    (use (match_operand:HI 2 "memory_operand" ""))
15032    (use (match_operand:HI 3 "memory_operand" ""))
15033    (clobber (match_operand:DI 4 "memory_operand" ""))
15034    (clobber (match_scratch 5 ""))]
15035   "reload_completed"
15036   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15037               (use (match_dup 2))
15038               (use (match_dup 3))
15039               (clobber (match_dup 5))])]
15040   "")
15041
15042 (define_insn "fist<mode>2_floor"
15043   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15044         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15045          UNSPEC_FIST_FLOOR))
15046    (use (match_operand:HI 2 "memory_operand" "m"))
15047    (use (match_operand:HI 3 "memory_operand" "m"))]
15048   "TARGET_USE_FANCY_MATH_387
15049    && flag_unsafe_math_optimizations"
15050   "* return output_fix_trunc (insn, operands, 0);"
15051   [(set_attr "type" "fistp")
15052    (set_attr "i387_cw" "floor")
15053    (set_attr "mode" "<MODE>")])
15054
15055 (define_insn "fist<mode>2_floor_with_temp"
15056   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15057         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15058          UNSPEC_FIST_FLOOR))
15059    (use (match_operand:HI 2 "memory_operand" "m,m"))
15060    (use (match_operand:HI 3 "memory_operand" "m,m"))
15061    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15062   "TARGET_USE_FANCY_MATH_387
15063    && flag_unsafe_math_optimizations"
15064   "#"
15065   [(set_attr "type" "fistp")
15066    (set_attr "i387_cw" "floor")
15067    (set_attr "mode" "<MODE>")])
15068
15069 (define_split
15070   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15071         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15072          UNSPEC_FIST_FLOOR))
15073    (use (match_operand:HI 2 "memory_operand" ""))
15074    (use (match_operand:HI 3 "memory_operand" ""))
15075    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15076   "reload_completed"
15077   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15078                                   UNSPEC_FIST_FLOOR))
15079               (use (match_dup 2))
15080               (use (match_dup 3))])
15081    (set (match_dup 0) (match_dup 4))]
15082   "")
15083
15084 (define_split
15085   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15086         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15087          UNSPEC_FIST_FLOOR))
15088    (use (match_operand:HI 2 "memory_operand" ""))
15089    (use (match_operand:HI 3 "memory_operand" ""))
15090    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15091   "reload_completed"
15092   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15093                                   UNSPEC_FIST_FLOOR))
15094               (use (match_dup 2))
15095               (use (match_dup 3))])]
15096   "")
15097
15098 (define_expand "lfloorxf<mode>2"
15099   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15100                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15101                     UNSPEC_FIST_FLOOR))
15102               (clobber (reg:CC FLAGS_REG))])]
15103   "TARGET_USE_FANCY_MATH_387
15104    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15105    && flag_unsafe_math_optimizations"
15106   "")
15107
15108 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15109   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15110    (match_operand:MODEF 1 "register_operand" "")]
15111   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15112    && !flag_trapping_math"
15113 {
15114   if (TARGET_64BIT && optimize_insn_for_size_p ())
15115     FAIL;
15116   ix86_expand_lfloorceil (operand0, operand1, true);
15117   DONE;
15118 })
15119
15120 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15121 (define_insn_and_split "frndintxf2_ceil"
15122   [(set (match_operand:XF 0 "register_operand" "")
15123         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15124          UNSPEC_FRNDINT_CEIL))
15125    (clobber (reg:CC FLAGS_REG))]
15126   "TARGET_USE_FANCY_MATH_387
15127    && flag_unsafe_math_optimizations
15128    && can_create_pseudo_p ()"
15129   "#"
15130   "&& 1"
15131   [(const_int 0)]
15132 {
15133   ix86_optimize_mode_switching[I387_CEIL] = 1;
15134
15135   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15136   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15137
15138   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15139                                        operands[2], operands[3]));
15140   DONE;
15141 }
15142   [(set_attr "type" "frndint")
15143    (set_attr "i387_cw" "ceil")
15144    (set_attr "mode" "XF")])
15145
15146 (define_insn "frndintxf2_ceil_i387"
15147   [(set (match_operand:XF 0 "register_operand" "=f")
15148         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15149          UNSPEC_FRNDINT_CEIL))
15150    (use (match_operand:HI 2 "memory_operand" "m"))
15151    (use (match_operand:HI 3 "memory_operand" "m"))]
15152   "TARGET_USE_FANCY_MATH_387
15153    && flag_unsafe_math_optimizations"
15154   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15155   [(set_attr "type" "frndint")
15156    (set_attr "i387_cw" "ceil")
15157    (set_attr "mode" "XF")])
15158
15159 (define_expand "ceilxf2"
15160   [(use (match_operand:XF 0 "register_operand" ""))
15161    (use (match_operand:XF 1 "register_operand" ""))]
15162   "TARGET_USE_FANCY_MATH_387
15163    && flag_unsafe_math_optimizations"
15164 {
15165   if (optimize_insn_for_size_p ())
15166     FAIL;
15167   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15168   DONE;
15169 })
15170
15171 (define_expand "ceil<mode>2"
15172   [(use (match_operand:MODEF 0 "register_operand" ""))
15173    (use (match_operand:MODEF 1 "register_operand" ""))]
15174   "(TARGET_USE_FANCY_MATH_387
15175     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15176         || TARGET_MIX_SSE_I387)
15177     && flag_unsafe_math_optimizations)
15178    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15179        && !flag_trapping_math)"
15180 {
15181   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15182       && !flag_trapping_math
15183       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15184     {
15185       if (TARGET_ROUND)
15186         emit_insn (gen_sse4_1_round<mode>2
15187                    (operands[0], operands[1], GEN_INT (0x02)));
15188       else if (optimize_insn_for_size_p ())
15189         FAIL;
15190       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15191         ix86_expand_floorceil (operand0, operand1, false);
15192       else
15193         ix86_expand_floorceildf_32 (operand0, operand1, false);
15194     }
15195   else
15196     {
15197       rtx op0, op1;
15198
15199       if (optimize_insn_for_size_p ())
15200         FAIL;
15201
15202       op0 = gen_reg_rtx (XFmode);
15203       op1 = gen_reg_rtx (XFmode);
15204       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15205       emit_insn (gen_frndintxf2_ceil (op0, op1));
15206
15207       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15208     }
15209   DONE;
15210 })
15211
15212 (define_insn_and_split "*fist<mode>2_ceil_1"
15213   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15214         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15215          UNSPEC_FIST_CEIL))
15216    (clobber (reg:CC FLAGS_REG))]
15217   "TARGET_USE_FANCY_MATH_387
15218    && flag_unsafe_math_optimizations
15219    && can_create_pseudo_p ()"
15220   "#"
15221   "&& 1"
15222   [(const_int 0)]
15223 {
15224   ix86_optimize_mode_switching[I387_CEIL] = 1;
15225
15226   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15227   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15228   if (memory_operand (operands[0], VOIDmode))
15229     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15230                                      operands[2], operands[3]));
15231   else
15232     {
15233       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15234       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15235                                                  operands[2], operands[3],
15236                                                  operands[4]));
15237     }
15238   DONE;
15239 }
15240   [(set_attr "type" "fistp")
15241    (set_attr "i387_cw" "ceil")
15242    (set_attr "mode" "<MODE>")])
15243
15244 (define_insn "fistdi2_ceil"
15245   [(set (match_operand:DI 0 "memory_operand" "=m")
15246         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15247          UNSPEC_FIST_CEIL))
15248    (use (match_operand:HI 2 "memory_operand" "m"))
15249    (use (match_operand:HI 3 "memory_operand" "m"))
15250    (clobber (match_scratch:XF 4 "=&1f"))]
15251   "TARGET_USE_FANCY_MATH_387
15252    && flag_unsafe_math_optimizations"
15253   "* return output_fix_trunc (insn, operands, 0);"
15254   [(set_attr "type" "fistp")
15255    (set_attr "i387_cw" "ceil")
15256    (set_attr "mode" "DI")])
15257
15258 (define_insn "fistdi2_ceil_with_temp"
15259   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15260         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15261          UNSPEC_FIST_CEIL))
15262    (use (match_operand:HI 2 "memory_operand" "m,m"))
15263    (use (match_operand:HI 3 "memory_operand" "m,m"))
15264    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15265    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15266   "TARGET_USE_FANCY_MATH_387
15267    && flag_unsafe_math_optimizations"
15268   "#"
15269   [(set_attr "type" "fistp")
15270    (set_attr "i387_cw" "ceil")
15271    (set_attr "mode" "DI")])
15272
15273 (define_split
15274   [(set (match_operand:DI 0 "register_operand" "")
15275         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15276          UNSPEC_FIST_CEIL))
15277    (use (match_operand:HI 2 "memory_operand" ""))
15278    (use (match_operand:HI 3 "memory_operand" ""))
15279    (clobber (match_operand:DI 4 "memory_operand" ""))
15280    (clobber (match_scratch 5 ""))]
15281   "reload_completed"
15282   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15283               (use (match_dup 2))
15284               (use (match_dup 3))
15285               (clobber (match_dup 5))])
15286    (set (match_dup 0) (match_dup 4))]
15287   "")
15288
15289 (define_split
15290   [(set (match_operand:DI 0 "memory_operand" "")
15291         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15292          UNSPEC_FIST_CEIL))
15293    (use (match_operand:HI 2 "memory_operand" ""))
15294    (use (match_operand:HI 3 "memory_operand" ""))
15295    (clobber (match_operand:DI 4 "memory_operand" ""))
15296    (clobber (match_scratch 5 ""))]
15297   "reload_completed"
15298   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15299               (use (match_dup 2))
15300               (use (match_dup 3))
15301               (clobber (match_dup 5))])]
15302   "")
15303
15304 (define_insn "fist<mode>2_ceil"
15305   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15306         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15307          UNSPEC_FIST_CEIL))
15308    (use (match_operand:HI 2 "memory_operand" "m"))
15309    (use (match_operand:HI 3 "memory_operand" "m"))]
15310   "TARGET_USE_FANCY_MATH_387
15311    && flag_unsafe_math_optimizations"
15312   "* return output_fix_trunc (insn, operands, 0);"
15313   [(set_attr "type" "fistp")
15314    (set_attr "i387_cw" "ceil")
15315    (set_attr "mode" "<MODE>")])
15316
15317 (define_insn "fist<mode>2_ceil_with_temp"
15318   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15319         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15320          UNSPEC_FIST_CEIL))
15321    (use (match_operand:HI 2 "memory_operand" "m,m"))
15322    (use (match_operand:HI 3 "memory_operand" "m,m"))
15323    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15324   "TARGET_USE_FANCY_MATH_387
15325    && flag_unsafe_math_optimizations"
15326   "#"
15327   [(set_attr "type" "fistp")
15328    (set_attr "i387_cw" "ceil")
15329    (set_attr "mode" "<MODE>")])
15330
15331 (define_split
15332   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15333         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15334          UNSPEC_FIST_CEIL))
15335    (use (match_operand:HI 2 "memory_operand" ""))
15336    (use (match_operand:HI 3 "memory_operand" ""))
15337    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15338   "reload_completed"
15339   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15340                                   UNSPEC_FIST_CEIL))
15341               (use (match_dup 2))
15342               (use (match_dup 3))])
15343    (set (match_dup 0) (match_dup 4))]
15344   "")
15345
15346 (define_split
15347   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15348         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15349          UNSPEC_FIST_CEIL))
15350    (use (match_operand:HI 2 "memory_operand" ""))
15351    (use (match_operand:HI 3 "memory_operand" ""))
15352    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15353   "reload_completed"
15354   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15355                                   UNSPEC_FIST_CEIL))
15356               (use (match_dup 2))
15357               (use (match_dup 3))])]
15358   "")
15359
15360 (define_expand "lceilxf<mode>2"
15361   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15362                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15363                     UNSPEC_FIST_CEIL))
15364               (clobber (reg:CC FLAGS_REG))])]
15365   "TARGET_USE_FANCY_MATH_387
15366    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15367    && flag_unsafe_math_optimizations"
15368   "")
15369
15370 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15371   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15372    (match_operand:MODEF 1 "register_operand" "")]
15373   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15374    && !flag_trapping_math"
15375 {
15376   ix86_expand_lfloorceil (operand0, operand1, false);
15377   DONE;
15378 })
15379
15380 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15381 (define_insn_and_split "frndintxf2_trunc"
15382   [(set (match_operand:XF 0 "register_operand" "")
15383         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15384          UNSPEC_FRNDINT_TRUNC))
15385    (clobber (reg:CC FLAGS_REG))]
15386   "TARGET_USE_FANCY_MATH_387
15387    && flag_unsafe_math_optimizations
15388    && can_create_pseudo_p ()"
15389   "#"
15390   "&& 1"
15391   [(const_int 0)]
15392 {
15393   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15394
15395   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15396   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15397
15398   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15399                                         operands[2], operands[3]));
15400   DONE;
15401 }
15402   [(set_attr "type" "frndint")
15403    (set_attr "i387_cw" "trunc")
15404    (set_attr "mode" "XF")])
15405
15406 (define_insn "frndintxf2_trunc_i387"
15407   [(set (match_operand:XF 0 "register_operand" "=f")
15408         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15409          UNSPEC_FRNDINT_TRUNC))
15410    (use (match_operand:HI 2 "memory_operand" "m"))
15411    (use (match_operand:HI 3 "memory_operand" "m"))]
15412   "TARGET_USE_FANCY_MATH_387
15413    && flag_unsafe_math_optimizations"
15414   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15415   [(set_attr "type" "frndint")
15416    (set_attr "i387_cw" "trunc")
15417    (set_attr "mode" "XF")])
15418
15419 (define_expand "btruncxf2"
15420   [(use (match_operand:XF 0 "register_operand" ""))
15421    (use (match_operand:XF 1 "register_operand" ""))]
15422   "TARGET_USE_FANCY_MATH_387
15423    && flag_unsafe_math_optimizations"
15424 {
15425   if (optimize_insn_for_size_p ())
15426     FAIL;
15427   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15428   DONE;
15429 })
15430
15431 (define_expand "btrunc<mode>2"
15432   [(use (match_operand:MODEF 0 "register_operand" ""))
15433    (use (match_operand:MODEF 1 "register_operand" ""))]
15434   "(TARGET_USE_FANCY_MATH_387
15435     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15436         || TARGET_MIX_SSE_I387)
15437     && flag_unsafe_math_optimizations)
15438    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15439        && !flag_trapping_math)"
15440 {
15441   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15442       && !flag_trapping_math
15443       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15444     {
15445       if (TARGET_ROUND)
15446         emit_insn (gen_sse4_1_round<mode>2
15447                    (operands[0], operands[1], GEN_INT (0x03)));
15448       else if (optimize_insn_for_size_p ())
15449         FAIL;
15450       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15451         ix86_expand_trunc (operand0, operand1);
15452       else
15453         ix86_expand_truncdf_32 (operand0, operand1);
15454     }
15455   else
15456     {
15457       rtx op0, op1;
15458
15459       if (optimize_insn_for_size_p ())
15460         FAIL;
15461
15462       op0 = gen_reg_rtx (XFmode);
15463       op1 = gen_reg_rtx (XFmode);
15464       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15465       emit_insn (gen_frndintxf2_trunc (op0, op1));
15466
15467       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15468     }
15469   DONE;
15470 })
15471
15472 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15473 (define_insn_and_split "frndintxf2_mask_pm"
15474   [(set (match_operand:XF 0 "register_operand" "")
15475         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15476          UNSPEC_FRNDINT_MASK_PM))
15477    (clobber (reg:CC FLAGS_REG))]
15478   "TARGET_USE_FANCY_MATH_387
15479    && flag_unsafe_math_optimizations
15480    && can_create_pseudo_p ()"
15481   "#"
15482   "&& 1"
15483   [(const_int 0)]
15484 {
15485   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15486
15487   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15488   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15489
15490   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15491                                           operands[2], operands[3]));
15492   DONE;
15493 }
15494   [(set_attr "type" "frndint")
15495    (set_attr "i387_cw" "mask_pm")
15496    (set_attr "mode" "XF")])
15497
15498 (define_insn "frndintxf2_mask_pm_i387"
15499   [(set (match_operand:XF 0 "register_operand" "=f")
15500         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15501          UNSPEC_FRNDINT_MASK_PM))
15502    (use (match_operand:HI 2 "memory_operand" "m"))
15503    (use (match_operand:HI 3 "memory_operand" "m"))]
15504   "TARGET_USE_FANCY_MATH_387
15505    && flag_unsafe_math_optimizations"
15506   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15507   [(set_attr "type" "frndint")
15508    (set_attr "i387_cw" "mask_pm")
15509    (set_attr "mode" "XF")])
15510
15511 (define_expand "nearbyintxf2"
15512   [(use (match_operand:XF 0 "register_operand" ""))
15513    (use (match_operand:XF 1 "register_operand" ""))]
15514   "TARGET_USE_FANCY_MATH_387
15515    && flag_unsafe_math_optimizations"
15516 {
15517   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15518
15519   DONE;
15520 })
15521
15522 (define_expand "nearbyint<mode>2"
15523   [(use (match_operand:MODEF 0 "register_operand" ""))
15524    (use (match_operand:MODEF 1 "register_operand" ""))]
15525   "TARGET_USE_FANCY_MATH_387
15526    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15527        || TARGET_MIX_SSE_I387)
15528    && flag_unsafe_math_optimizations"
15529 {
15530   rtx op0 = gen_reg_rtx (XFmode);
15531   rtx op1 = gen_reg_rtx (XFmode);
15532
15533   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15534   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15535
15536   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15537   DONE;
15538 })
15539
15540 (define_insn "fxam<mode>2_i387"
15541   [(set (match_operand:HI 0 "register_operand" "=a")
15542         (unspec:HI
15543           [(match_operand:X87MODEF 1 "register_operand" "f")]
15544           UNSPEC_FXAM))]
15545   "TARGET_USE_FANCY_MATH_387"
15546   "fxam\n\tfnstsw\t%0"
15547   [(set_attr "type" "multi")
15548    (set_attr "length" "4")
15549    (set_attr "unit" "i387")
15550    (set_attr "mode" "<MODE>")])
15551
15552 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15553   [(set (match_operand:HI 0 "register_operand" "")
15554         (unspec:HI
15555           [(match_operand:MODEF 1 "memory_operand" "")]
15556           UNSPEC_FXAM_MEM))]
15557   "TARGET_USE_FANCY_MATH_387
15558    && can_create_pseudo_p ()"
15559   "#"
15560   "&& 1"
15561   [(set (match_dup 2)(match_dup 1))
15562    (set (match_dup 0)
15563         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15564 {
15565   operands[2] = gen_reg_rtx (<MODE>mode);
15566
15567   MEM_VOLATILE_P (operands[1]) = 1;
15568 }
15569   [(set_attr "type" "multi")
15570    (set_attr "unit" "i387")
15571    (set_attr "mode" "<MODE>")])
15572
15573 (define_expand "isinfxf2"
15574   [(use (match_operand:SI 0 "register_operand" ""))
15575    (use (match_operand:XF 1 "register_operand" ""))]
15576   "TARGET_USE_FANCY_MATH_387
15577    && TARGET_C99_FUNCTIONS"
15578 {
15579   rtx mask = GEN_INT (0x45);
15580   rtx val = GEN_INT (0x05);
15581
15582   rtx cond;
15583
15584   rtx scratch = gen_reg_rtx (HImode);
15585   rtx res = gen_reg_rtx (QImode);
15586
15587   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15588
15589   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15590   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15591   cond = gen_rtx_fmt_ee (EQ, QImode,
15592                          gen_rtx_REG (CCmode, FLAGS_REG),
15593                          const0_rtx);
15594   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15595   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15596   DONE;
15597 })
15598
15599 (define_expand "isinf<mode>2"
15600   [(use (match_operand:SI 0 "register_operand" ""))
15601    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15602   "TARGET_USE_FANCY_MATH_387
15603    && TARGET_C99_FUNCTIONS
15604    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15605 {
15606   rtx mask = GEN_INT (0x45);
15607   rtx val = GEN_INT (0x05);
15608
15609   rtx cond;
15610
15611   rtx scratch = gen_reg_rtx (HImode);
15612   rtx res = gen_reg_rtx (QImode);
15613
15614   /* Remove excess precision by forcing value through memory. */
15615   if (memory_operand (operands[1], VOIDmode))
15616     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15617   else
15618     {
15619       enum ix86_stack_slot slot = (virtuals_instantiated
15620                                    ? SLOT_TEMP
15621                                    : SLOT_VIRTUAL);
15622       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15623
15624       emit_move_insn (temp, operands[1]);
15625       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15626     }
15627
15628   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15629   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15630   cond = gen_rtx_fmt_ee (EQ, QImode,
15631                          gen_rtx_REG (CCmode, FLAGS_REG),
15632                          const0_rtx);
15633   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15634   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15635   DONE;
15636 })
15637
15638 (define_expand "signbit<mode>2"
15639   [(use (match_operand:SI 0 "register_operand" ""))
15640    (use (match_operand:X87MODEF 1 "register_operand" ""))]
15641   "TARGET_USE_FANCY_MATH_387
15642    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15643 {
15644   rtx mask = GEN_INT (0x0200);
15645
15646   rtx scratch = gen_reg_rtx (HImode);
15647
15648   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15649   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15650   DONE;
15651 })
15652 \f
15653 ;; Block operation instructions
15654
15655 (define_insn "cld"
15656   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15657   ""
15658   "cld"
15659   [(set_attr "length" "1")
15660    (set_attr "length_immediate" "0")
15661    (set_attr "modrm" "0")])
15662
15663 (define_expand "movmemsi"
15664   [(use (match_operand:BLK 0 "memory_operand" ""))
15665    (use (match_operand:BLK 1 "memory_operand" ""))
15666    (use (match_operand:SI 2 "nonmemory_operand" ""))
15667    (use (match_operand:SI 3 "const_int_operand" ""))
15668    (use (match_operand:SI 4 "const_int_operand" ""))
15669    (use (match_operand:SI 5 "const_int_operand" ""))]
15670   ""
15671 {
15672  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15673                          operands[4], operands[5]))
15674    DONE;
15675  else
15676    FAIL;
15677 })
15678
15679 (define_expand "movmemdi"
15680   [(use (match_operand:BLK 0 "memory_operand" ""))
15681    (use (match_operand:BLK 1 "memory_operand" ""))
15682    (use (match_operand:DI 2 "nonmemory_operand" ""))
15683    (use (match_operand:DI 3 "const_int_operand" ""))
15684    (use (match_operand:SI 4 "const_int_operand" ""))
15685    (use (match_operand:SI 5 "const_int_operand" ""))]
15686   "TARGET_64BIT"
15687 {
15688  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15689                          operands[4], operands[5]))
15690    DONE;
15691  else
15692    FAIL;
15693 })
15694
15695 ;; Most CPUs don't like single string operations
15696 ;; Handle this case here to simplify previous expander.
15697
15698 (define_expand "strmov"
15699   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15700    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15701    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15702               (clobber (reg:CC FLAGS_REG))])
15703    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15704               (clobber (reg:CC FLAGS_REG))])]
15705   ""
15706 {
15707   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15708
15709   /* If .md ever supports :P for Pmode, these can be directly
15710      in the pattern above.  */
15711   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15712   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15713
15714   /* Can't use this if the user has appropriated esi or edi.  */
15715   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15716       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15717     {
15718       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15719                                       operands[2], operands[3],
15720                                       operands[5], operands[6]));
15721       DONE;
15722     }
15723
15724   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15725 })
15726
15727 (define_expand "strmov_singleop"
15728   [(parallel [(set (match_operand 1 "memory_operand" "")
15729                    (match_operand 3 "memory_operand" ""))
15730               (set (match_operand 0 "register_operand" "")
15731                    (match_operand 4 "" ""))
15732               (set (match_operand 2 "register_operand" "")
15733                    (match_operand 5 "" ""))])]
15734   ""
15735   "ix86_current_function_needs_cld = 1;")
15736
15737 (define_insn "*strmovdi_rex_1"
15738   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15739         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15740    (set (match_operand:DI 0 "register_operand" "=D")
15741         (plus:DI (match_dup 2)
15742                  (const_int 8)))
15743    (set (match_operand:DI 1 "register_operand" "=S")
15744         (plus:DI (match_dup 3)
15745                  (const_int 8)))]
15746   "TARGET_64BIT"
15747   "movsq"
15748   [(set_attr "type" "str")
15749    (set_attr "mode" "DI")
15750    (set_attr "memory" "both")])
15751
15752 (define_insn "*strmovsi_1"
15753   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15754         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15755    (set (match_operand:SI 0 "register_operand" "=D")
15756         (plus:SI (match_dup 2)
15757                  (const_int 4)))
15758    (set (match_operand:SI 1 "register_operand" "=S")
15759         (plus:SI (match_dup 3)
15760                  (const_int 4)))]
15761   "!TARGET_64BIT"
15762   "movs{l|d}"
15763   [(set_attr "type" "str")
15764    (set_attr "mode" "SI")
15765    (set_attr "memory" "both")])
15766
15767 (define_insn "*strmovsi_rex_1"
15768   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15769         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15770    (set (match_operand:DI 0 "register_operand" "=D")
15771         (plus:DI (match_dup 2)
15772                  (const_int 4)))
15773    (set (match_operand:DI 1 "register_operand" "=S")
15774         (plus:DI (match_dup 3)
15775                  (const_int 4)))]
15776   "TARGET_64BIT"
15777   "movs{l|d}"
15778   [(set_attr "type" "str")
15779    (set_attr "mode" "SI")
15780    (set_attr "memory" "both")])
15781
15782 (define_insn "*strmovhi_1"
15783   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15784         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15785    (set (match_operand:SI 0 "register_operand" "=D")
15786         (plus:SI (match_dup 2)
15787                  (const_int 2)))
15788    (set (match_operand:SI 1 "register_operand" "=S")
15789         (plus:SI (match_dup 3)
15790                  (const_int 2)))]
15791   "!TARGET_64BIT"
15792   "movsw"
15793   [(set_attr "type" "str")
15794    (set_attr "memory" "both")
15795    (set_attr "mode" "HI")])
15796
15797 (define_insn "*strmovhi_rex_1"
15798   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15799         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15800    (set (match_operand:DI 0 "register_operand" "=D")
15801         (plus:DI (match_dup 2)
15802                  (const_int 2)))
15803    (set (match_operand:DI 1 "register_operand" "=S")
15804         (plus:DI (match_dup 3)
15805                  (const_int 2)))]
15806   "TARGET_64BIT"
15807   "movsw"
15808   [(set_attr "type" "str")
15809    (set_attr "memory" "both")
15810    (set_attr "mode" "HI")])
15811
15812 (define_insn "*strmovqi_1"
15813   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15814         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15815    (set (match_operand:SI 0 "register_operand" "=D")
15816         (plus:SI (match_dup 2)
15817                  (const_int 1)))
15818    (set (match_operand:SI 1 "register_operand" "=S")
15819         (plus:SI (match_dup 3)
15820                  (const_int 1)))]
15821   "!TARGET_64BIT"
15822   "movsb"
15823   [(set_attr "type" "str")
15824    (set_attr "memory" "both")
15825    (set_attr "mode" "QI")])
15826
15827 (define_insn "*strmovqi_rex_1"
15828   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15829         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15830    (set (match_operand:DI 0 "register_operand" "=D")
15831         (plus:DI (match_dup 2)
15832                  (const_int 1)))
15833    (set (match_operand:DI 1 "register_operand" "=S")
15834         (plus:DI (match_dup 3)
15835                  (const_int 1)))]
15836   "TARGET_64BIT"
15837   "movsb"
15838   [(set_attr "type" "str")
15839    (set_attr "memory" "both")
15840    (set_attr "prefix_rex" "0")
15841    (set_attr "mode" "QI")])
15842
15843 (define_expand "rep_mov"
15844   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15845               (set (match_operand 0 "register_operand" "")
15846                    (match_operand 5 "" ""))
15847               (set (match_operand 2 "register_operand" "")
15848                    (match_operand 6 "" ""))
15849               (set (match_operand 1 "memory_operand" "")
15850                    (match_operand 3 "memory_operand" ""))
15851               (use (match_dup 4))])]
15852   ""
15853   "ix86_current_function_needs_cld = 1;")
15854
15855 (define_insn "*rep_movdi_rex64"
15856   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15857    (set (match_operand:DI 0 "register_operand" "=D")
15858         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15859                             (const_int 3))
15860                  (match_operand:DI 3 "register_operand" "0")))
15861    (set (match_operand:DI 1 "register_operand" "=S")
15862         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15863                  (match_operand:DI 4 "register_operand" "1")))
15864    (set (mem:BLK (match_dup 3))
15865         (mem:BLK (match_dup 4)))
15866    (use (match_dup 5))]
15867   "TARGET_64BIT"
15868   "rep movsq"
15869   [(set_attr "type" "str")
15870    (set_attr "prefix_rep" "1")
15871    (set_attr "memory" "both")
15872    (set_attr "mode" "DI")])
15873
15874 (define_insn "*rep_movsi"
15875   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15876    (set (match_operand:SI 0 "register_operand" "=D")
15877         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15878                             (const_int 2))
15879                  (match_operand:SI 3 "register_operand" "0")))
15880    (set (match_operand:SI 1 "register_operand" "=S")
15881         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15882                  (match_operand:SI 4 "register_operand" "1")))
15883    (set (mem:BLK (match_dup 3))
15884         (mem:BLK (match_dup 4)))
15885    (use (match_dup 5))]
15886   "!TARGET_64BIT"
15887   "rep movs{l|d}"
15888   [(set_attr "type" "str")
15889    (set_attr "prefix_rep" "1")
15890    (set_attr "memory" "both")
15891    (set_attr "mode" "SI")])
15892
15893 (define_insn "*rep_movsi_rex64"
15894   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15895    (set (match_operand:DI 0 "register_operand" "=D")
15896         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15897                             (const_int 2))
15898                  (match_operand:DI 3 "register_operand" "0")))
15899    (set (match_operand:DI 1 "register_operand" "=S")
15900         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15901                  (match_operand:DI 4 "register_operand" "1")))
15902    (set (mem:BLK (match_dup 3))
15903         (mem:BLK (match_dup 4)))
15904    (use (match_dup 5))]
15905   "TARGET_64BIT"
15906   "rep movs{l|d}"
15907   [(set_attr "type" "str")
15908    (set_attr "prefix_rep" "1")
15909    (set_attr "memory" "both")
15910    (set_attr "mode" "SI")])
15911
15912 (define_insn "*rep_movqi"
15913   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15914    (set (match_operand:SI 0 "register_operand" "=D")
15915         (plus:SI (match_operand:SI 3 "register_operand" "0")
15916                  (match_operand:SI 5 "register_operand" "2")))
15917    (set (match_operand:SI 1 "register_operand" "=S")
15918         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15919    (set (mem:BLK (match_dup 3))
15920         (mem:BLK (match_dup 4)))
15921    (use (match_dup 5))]
15922   "!TARGET_64BIT"
15923   "rep movsb"
15924   [(set_attr "type" "str")
15925    (set_attr "prefix_rep" "1")
15926    (set_attr "memory" "both")
15927    (set_attr "mode" "SI")])
15928
15929 (define_insn "*rep_movqi_rex64"
15930   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15931    (set (match_operand:DI 0 "register_operand" "=D")
15932         (plus:DI (match_operand:DI 3 "register_operand" "0")
15933                  (match_operand:DI 5 "register_operand" "2")))
15934    (set (match_operand:DI 1 "register_operand" "=S")
15935         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15936    (set (mem:BLK (match_dup 3))
15937         (mem:BLK (match_dup 4)))
15938    (use (match_dup 5))]
15939   "TARGET_64BIT"
15940   "rep movsb"
15941   [(set_attr "type" "str")
15942    (set_attr "prefix_rep" "1")
15943    (set_attr "memory" "both")
15944    (set_attr "mode" "SI")])
15945
15946 (define_expand "setmemsi"
15947    [(use (match_operand:BLK 0 "memory_operand" ""))
15948     (use (match_operand:SI 1 "nonmemory_operand" ""))
15949     (use (match_operand 2 "const_int_operand" ""))
15950     (use (match_operand 3 "const_int_operand" ""))
15951     (use (match_operand:SI 4 "const_int_operand" ""))
15952     (use (match_operand:SI 5 "const_int_operand" ""))]
15953   ""
15954 {
15955  if (ix86_expand_setmem (operands[0], operands[1],
15956                          operands[2], operands[3],
15957                          operands[4], operands[5]))
15958    DONE;
15959  else
15960    FAIL;
15961 })
15962
15963 (define_expand "setmemdi"
15964    [(use (match_operand:BLK 0 "memory_operand" ""))
15965     (use (match_operand:DI 1 "nonmemory_operand" ""))
15966     (use (match_operand 2 "const_int_operand" ""))
15967     (use (match_operand 3 "const_int_operand" ""))
15968     (use (match_operand 4 "const_int_operand" ""))
15969     (use (match_operand 5 "const_int_operand" ""))]
15970   "TARGET_64BIT"
15971 {
15972  if (ix86_expand_setmem (operands[0], operands[1],
15973                          operands[2], operands[3],
15974                          operands[4], operands[5]))
15975    DONE;
15976  else
15977    FAIL;
15978 })
15979
15980 ;; Most CPUs don't like single string operations
15981 ;; Handle this case here to simplify previous expander.
15982
15983 (define_expand "strset"
15984   [(set (match_operand 1 "memory_operand" "")
15985         (match_operand 2 "register_operand" ""))
15986    (parallel [(set (match_operand 0 "register_operand" "")
15987                    (match_dup 3))
15988               (clobber (reg:CC FLAGS_REG))])]
15989   ""
15990 {
15991   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15992     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15993
15994   /* If .md ever supports :P for Pmode, this can be directly
15995      in the pattern above.  */
15996   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15997                               GEN_INT (GET_MODE_SIZE (GET_MODE
15998                                                       (operands[2]))));
15999   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16000     {
16001       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16002                                       operands[3]));
16003       DONE;
16004     }
16005 })
16006
16007 (define_expand "strset_singleop"
16008   [(parallel [(set (match_operand 1 "memory_operand" "")
16009                    (match_operand 2 "register_operand" ""))
16010               (set (match_operand 0 "register_operand" "")
16011                    (match_operand 3 "" ""))])]
16012   ""
16013   "ix86_current_function_needs_cld = 1;")
16014
16015 (define_insn "*strsetdi_rex_1"
16016   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16017         (match_operand:DI 2 "register_operand" "a"))
16018    (set (match_operand:DI 0 "register_operand" "=D")
16019         (plus:DI (match_dup 1)
16020                  (const_int 8)))]
16021   "TARGET_64BIT"
16022   "stosq"
16023   [(set_attr "type" "str")
16024    (set_attr "memory" "store")
16025    (set_attr "mode" "DI")])
16026
16027 (define_insn "*strsetsi_1"
16028   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16029         (match_operand:SI 2 "register_operand" "a"))
16030    (set (match_operand:SI 0 "register_operand" "=D")
16031         (plus:SI (match_dup 1)
16032                  (const_int 4)))]
16033   "!TARGET_64BIT"
16034   "stos{l|d}"
16035   [(set_attr "type" "str")
16036    (set_attr "memory" "store")
16037    (set_attr "mode" "SI")])
16038
16039 (define_insn "*strsetsi_rex_1"
16040   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16041         (match_operand:SI 2 "register_operand" "a"))
16042    (set (match_operand:DI 0 "register_operand" "=D")
16043         (plus:DI (match_dup 1)
16044                  (const_int 4)))]
16045   "TARGET_64BIT"
16046   "stos{l|d}"
16047   [(set_attr "type" "str")
16048    (set_attr "memory" "store")
16049    (set_attr "mode" "SI")])
16050
16051 (define_insn "*strsethi_1"
16052   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16053         (match_operand:HI 2 "register_operand" "a"))
16054    (set (match_operand:SI 0 "register_operand" "=D")
16055         (plus:SI (match_dup 1)
16056                  (const_int 2)))]
16057   "!TARGET_64BIT"
16058   "stosw"
16059   [(set_attr "type" "str")
16060    (set_attr "memory" "store")
16061    (set_attr "mode" "HI")])
16062
16063 (define_insn "*strsethi_rex_1"
16064   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16065         (match_operand:HI 2 "register_operand" "a"))
16066    (set (match_operand:DI 0 "register_operand" "=D")
16067         (plus:DI (match_dup 1)
16068                  (const_int 2)))]
16069   "TARGET_64BIT"
16070   "stosw"
16071   [(set_attr "type" "str")
16072    (set_attr "memory" "store")
16073    (set_attr "mode" "HI")])
16074
16075 (define_insn "*strsetqi_1"
16076   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16077         (match_operand:QI 2 "register_operand" "a"))
16078    (set (match_operand:SI 0 "register_operand" "=D")
16079         (plus:SI (match_dup 1)
16080                  (const_int 1)))]
16081   "!TARGET_64BIT"
16082   "stosb"
16083   [(set_attr "type" "str")
16084    (set_attr "memory" "store")
16085    (set_attr "mode" "QI")])
16086
16087 (define_insn "*strsetqi_rex_1"
16088   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16089         (match_operand:QI 2 "register_operand" "a"))
16090    (set (match_operand:DI 0 "register_operand" "=D")
16091         (plus:DI (match_dup 1)
16092                  (const_int 1)))]
16093   "TARGET_64BIT"
16094   "stosb"
16095   [(set_attr "type" "str")
16096    (set_attr "memory" "store")
16097    (set_attr "prefix_rex" "0")
16098    (set_attr "mode" "QI")])
16099
16100 (define_expand "rep_stos"
16101   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16102               (set (match_operand 0 "register_operand" "")
16103                    (match_operand 4 "" ""))
16104               (set (match_operand 2 "memory_operand" "") (const_int 0))
16105               (use (match_operand 3 "register_operand" ""))
16106               (use (match_dup 1))])]
16107   ""
16108   "ix86_current_function_needs_cld = 1;")
16109
16110 (define_insn "*rep_stosdi_rex64"
16111   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16112    (set (match_operand:DI 0 "register_operand" "=D")
16113         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16114                             (const_int 3))
16115                  (match_operand:DI 3 "register_operand" "0")))
16116    (set (mem:BLK (match_dup 3))
16117         (const_int 0))
16118    (use (match_operand:DI 2 "register_operand" "a"))
16119    (use (match_dup 4))]
16120   "TARGET_64BIT"
16121   "rep stosq"
16122   [(set_attr "type" "str")
16123    (set_attr "prefix_rep" "1")
16124    (set_attr "memory" "store")
16125    (set_attr "mode" "DI")])
16126
16127 (define_insn "*rep_stossi"
16128   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16129    (set (match_operand:SI 0 "register_operand" "=D")
16130         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16131                             (const_int 2))
16132                  (match_operand:SI 3 "register_operand" "0")))
16133    (set (mem:BLK (match_dup 3))
16134         (const_int 0))
16135    (use (match_operand:SI 2 "register_operand" "a"))
16136    (use (match_dup 4))]
16137   "!TARGET_64BIT"
16138   "rep stos{l|d}"
16139   [(set_attr "type" "str")
16140    (set_attr "prefix_rep" "1")
16141    (set_attr "memory" "store")
16142    (set_attr "mode" "SI")])
16143
16144 (define_insn "*rep_stossi_rex64"
16145   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16146    (set (match_operand:DI 0 "register_operand" "=D")
16147         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16148                             (const_int 2))
16149                  (match_operand:DI 3 "register_operand" "0")))
16150    (set (mem:BLK (match_dup 3))
16151         (const_int 0))
16152    (use (match_operand:SI 2 "register_operand" "a"))
16153    (use (match_dup 4))]
16154   "TARGET_64BIT"
16155   "rep stos{l|d}"
16156   [(set_attr "type" "str")
16157    (set_attr "prefix_rep" "1")
16158    (set_attr "memory" "store")
16159    (set_attr "mode" "SI")])
16160
16161 (define_insn "*rep_stosqi"
16162   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16163    (set (match_operand:SI 0 "register_operand" "=D")
16164         (plus:SI (match_operand:SI 3 "register_operand" "0")
16165                  (match_operand:SI 4 "register_operand" "1")))
16166    (set (mem:BLK (match_dup 3))
16167         (const_int 0))
16168    (use (match_operand:QI 2 "register_operand" "a"))
16169    (use (match_dup 4))]
16170   "!TARGET_64BIT"
16171   "rep stosb"
16172   [(set_attr "type" "str")
16173    (set_attr "prefix_rep" "1")
16174    (set_attr "memory" "store")
16175    (set_attr "mode" "QI")])
16176
16177 (define_insn "*rep_stosqi_rex64"
16178   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16179    (set (match_operand:DI 0 "register_operand" "=D")
16180         (plus:DI (match_operand:DI 3 "register_operand" "0")
16181                  (match_operand:DI 4 "register_operand" "1")))
16182    (set (mem:BLK (match_dup 3))
16183         (const_int 0))
16184    (use (match_operand:QI 2 "register_operand" "a"))
16185    (use (match_dup 4))]
16186   "TARGET_64BIT"
16187   "rep stosb"
16188   [(set_attr "type" "str")
16189    (set_attr "prefix_rep" "1")
16190    (set_attr "memory" "store")
16191    (set_attr "prefix_rex" "0")
16192    (set_attr "mode" "QI")])
16193
16194 (define_expand "cmpstrnsi"
16195   [(set (match_operand:SI 0 "register_operand" "")
16196         (compare:SI (match_operand:BLK 1 "general_operand" "")
16197                     (match_operand:BLK 2 "general_operand" "")))
16198    (use (match_operand 3 "general_operand" ""))
16199    (use (match_operand 4 "immediate_operand" ""))]
16200   ""
16201 {
16202   rtx addr1, addr2, out, outlow, count, countreg, align;
16203
16204   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16205     FAIL;
16206
16207   /* Can't use this if the user has appropriated esi or edi.  */
16208   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
16209     FAIL;
16210
16211   out = operands[0];
16212   if (!REG_P (out))
16213     out = gen_reg_rtx (SImode);
16214
16215   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16216   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16217   if (addr1 != XEXP (operands[1], 0))
16218     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16219   if (addr2 != XEXP (operands[2], 0))
16220     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16221
16222   count = operands[3];
16223   countreg = ix86_zero_extend_to_Pmode (count);
16224
16225   /* %%% Iff we are testing strict equality, we can use known alignment
16226      to good advantage.  This may be possible with combine, particularly
16227      once cc0 is dead.  */
16228   align = operands[4];
16229
16230   if (CONST_INT_P (count))
16231     {
16232       if (INTVAL (count) == 0)
16233         {
16234           emit_move_insn (operands[0], const0_rtx);
16235           DONE;
16236         }
16237       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16238                                      operands[1], operands[2]));
16239     }
16240   else
16241     {
16242       rtx (*cmp_insn)(rtx, rtx);
16243
16244       if (TARGET_64BIT)
16245         cmp_insn = gen_cmpdi_1;
16246       else
16247         cmp_insn = gen_cmpsi_1;
16248       emit_insn (cmp_insn (countreg, countreg));
16249       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16250                                   operands[1], operands[2]));
16251     }
16252
16253   outlow = gen_lowpart (QImode, out);
16254   emit_insn (gen_cmpintqi (outlow));
16255   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16256
16257   if (operands[0] != out)
16258     emit_move_insn (operands[0], out);
16259
16260   DONE;
16261 })
16262
16263 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16264
16265 (define_expand "cmpintqi"
16266   [(set (match_dup 1)
16267         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16268    (set (match_dup 2)
16269         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16270    (parallel [(set (match_operand:QI 0 "register_operand" "")
16271                    (minus:QI (match_dup 1)
16272                              (match_dup 2)))
16273               (clobber (reg:CC FLAGS_REG))])]
16274   ""
16275   "operands[1] = gen_reg_rtx (QImode);
16276    operands[2] = gen_reg_rtx (QImode);")
16277
16278 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16279 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16280
16281 (define_expand "cmpstrnqi_nz_1"
16282   [(parallel [(set (reg:CC FLAGS_REG)
16283                    (compare:CC (match_operand 4 "memory_operand" "")
16284                                (match_operand 5 "memory_operand" "")))
16285               (use (match_operand 2 "register_operand" ""))
16286               (use (match_operand:SI 3 "immediate_operand" ""))
16287               (clobber (match_operand 0 "register_operand" ""))
16288               (clobber (match_operand 1 "register_operand" ""))
16289               (clobber (match_dup 2))])]
16290   ""
16291   "ix86_current_function_needs_cld = 1;")
16292
16293 (define_insn "*cmpstrnqi_nz_1"
16294   [(set (reg:CC FLAGS_REG)
16295         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16296                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16297    (use (match_operand:SI 6 "register_operand" "2"))
16298    (use (match_operand:SI 3 "immediate_operand" "i"))
16299    (clobber (match_operand:SI 0 "register_operand" "=S"))
16300    (clobber (match_operand:SI 1 "register_operand" "=D"))
16301    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16302   "!TARGET_64BIT"
16303   "repz cmpsb"
16304   [(set_attr "type" "str")
16305    (set_attr "mode" "QI")
16306    (set_attr "prefix_rep" "1")])
16307
16308 (define_insn "*cmpstrnqi_nz_rex_1"
16309   [(set (reg:CC FLAGS_REG)
16310         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16311                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16312    (use (match_operand:DI 6 "register_operand" "2"))
16313    (use (match_operand:SI 3 "immediate_operand" "i"))
16314    (clobber (match_operand:DI 0 "register_operand" "=S"))
16315    (clobber (match_operand:DI 1 "register_operand" "=D"))
16316    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16317   "TARGET_64BIT"
16318   "repz cmpsb"
16319   [(set_attr "type" "str")
16320    (set_attr "mode" "QI")
16321    (set_attr "prefix_rex" "0")
16322    (set_attr "prefix_rep" "1")])
16323
16324 ;; The same, but the count is not known to not be zero.
16325
16326 (define_expand "cmpstrnqi_1"
16327   [(parallel [(set (reg:CC FLAGS_REG)
16328                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16329                                      (const_int 0))
16330                   (compare:CC (match_operand 4 "memory_operand" "")
16331                               (match_operand 5 "memory_operand" ""))
16332                   (const_int 0)))
16333               (use (match_operand:SI 3 "immediate_operand" ""))
16334               (use (reg:CC FLAGS_REG))
16335               (clobber (match_operand 0 "register_operand" ""))
16336               (clobber (match_operand 1 "register_operand" ""))
16337               (clobber (match_dup 2))])]
16338   ""
16339   "ix86_current_function_needs_cld = 1;")
16340
16341 (define_insn "*cmpstrnqi_1"
16342   [(set (reg:CC FLAGS_REG)
16343         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16344                              (const_int 0))
16345           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16346                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16347           (const_int 0)))
16348    (use (match_operand:SI 3 "immediate_operand" "i"))
16349    (use (reg:CC FLAGS_REG))
16350    (clobber (match_operand:SI 0 "register_operand" "=S"))
16351    (clobber (match_operand:SI 1 "register_operand" "=D"))
16352    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16353   "!TARGET_64BIT"
16354   "repz cmpsb"
16355   [(set_attr "type" "str")
16356    (set_attr "mode" "QI")
16357    (set_attr "prefix_rep" "1")])
16358
16359 (define_insn "*cmpstrnqi_rex_1"
16360   [(set (reg:CC FLAGS_REG)
16361         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16362                              (const_int 0))
16363           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16364                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16365           (const_int 0)))
16366    (use (match_operand:SI 3 "immediate_operand" "i"))
16367    (use (reg:CC FLAGS_REG))
16368    (clobber (match_operand:DI 0 "register_operand" "=S"))
16369    (clobber (match_operand:DI 1 "register_operand" "=D"))
16370    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16371   "TARGET_64BIT"
16372   "repz cmpsb"
16373   [(set_attr "type" "str")
16374    (set_attr "mode" "QI")
16375    (set_attr "prefix_rex" "0")
16376    (set_attr "prefix_rep" "1")])
16377
16378 (define_expand "strlensi"
16379   [(set (match_operand:SI 0 "register_operand" "")
16380         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16381                     (match_operand:QI 2 "immediate_operand" "")
16382                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16383   ""
16384 {
16385  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16386    DONE;
16387  else
16388    FAIL;
16389 })
16390
16391 (define_expand "strlendi"
16392   [(set (match_operand:DI 0 "register_operand" "")
16393         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16394                     (match_operand:QI 2 "immediate_operand" "")
16395                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16396   ""
16397 {
16398  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16399    DONE;
16400  else
16401    FAIL;
16402 })
16403
16404 (define_expand "strlenqi_1"
16405   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16406               (clobber (match_operand 1 "register_operand" ""))
16407               (clobber (reg:CC FLAGS_REG))])]
16408   ""
16409   "ix86_current_function_needs_cld = 1;")
16410
16411 (define_insn "*strlenqi_1"
16412   [(set (match_operand:SI 0 "register_operand" "=&c")
16413         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16414                     (match_operand:QI 2 "register_operand" "a")
16415                     (match_operand:SI 3 "immediate_operand" "i")
16416                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16417    (clobber (match_operand:SI 1 "register_operand" "=D"))
16418    (clobber (reg:CC FLAGS_REG))]
16419   "!TARGET_64BIT"
16420   "repnz scasb"
16421   [(set_attr "type" "str")
16422    (set_attr "mode" "QI")
16423    (set_attr "prefix_rep" "1")])
16424
16425 (define_insn "*strlenqi_rex_1"
16426   [(set (match_operand:DI 0 "register_operand" "=&c")
16427         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16428                     (match_operand:QI 2 "register_operand" "a")
16429                     (match_operand:DI 3 "immediate_operand" "i")
16430                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16431    (clobber (match_operand:DI 1 "register_operand" "=D"))
16432    (clobber (reg:CC FLAGS_REG))]
16433   "TARGET_64BIT"
16434   "repnz scasb"
16435   [(set_attr "type" "str")
16436    (set_attr "mode" "QI")
16437    (set_attr "prefix_rex" "0")
16438    (set_attr "prefix_rep" "1")])
16439
16440 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16441 ;; handled in combine, but it is not currently up to the task.
16442 ;; When used for their truth value, the cmpstrn* expanders generate
16443 ;; code like this:
16444 ;;
16445 ;;   repz cmpsb
16446 ;;   seta       %al
16447 ;;   setb       %dl
16448 ;;   cmpb       %al, %dl
16449 ;;   jcc        label
16450 ;;
16451 ;; The intermediate three instructions are unnecessary.
16452
16453 ;; This one handles cmpstrn*_nz_1...
16454 (define_peephole2
16455   [(parallel[
16456      (set (reg:CC FLAGS_REG)
16457           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16458                       (mem:BLK (match_operand 5 "register_operand" ""))))
16459      (use (match_operand 6 "register_operand" ""))
16460      (use (match_operand:SI 3 "immediate_operand" ""))
16461      (clobber (match_operand 0 "register_operand" ""))
16462      (clobber (match_operand 1 "register_operand" ""))
16463      (clobber (match_operand 2 "register_operand" ""))])
16464    (set (match_operand:QI 7 "register_operand" "")
16465         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16466    (set (match_operand:QI 8 "register_operand" "")
16467         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16468    (set (reg FLAGS_REG)
16469         (compare (match_dup 7) (match_dup 8)))
16470   ]
16471   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16472   [(parallel[
16473      (set (reg:CC FLAGS_REG)
16474           (compare:CC (mem:BLK (match_dup 4))
16475                       (mem:BLK (match_dup 5))))
16476      (use (match_dup 6))
16477      (use (match_dup 3))
16478      (clobber (match_dup 0))
16479      (clobber (match_dup 1))
16480      (clobber (match_dup 2))])]
16481   "")
16482
16483 ;; ...and this one handles cmpstrn*_1.
16484 (define_peephole2
16485   [(parallel[
16486      (set (reg:CC FLAGS_REG)
16487           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16488                                (const_int 0))
16489             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16490                         (mem:BLK (match_operand 5 "register_operand" "")))
16491             (const_int 0)))
16492      (use (match_operand:SI 3 "immediate_operand" ""))
16493      (use (reg:CC FLAGS_REG))
16494      (clobber (match_operand 0 "register_operand" ""))
16495      (clobber (match_operand 1 "register_operand" ""))
16496      (clobber (match_operand 2 "register_operand" ""))])
16497    (set (match_operand:QI 7 "register_operand" "")
16498         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16499    (set (match_operand:QI 8 "register_operand" "")
16500         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16501    (set (reg FLAGS_REG)
16502         (compare (match_dup 7) (match_dup 8)))
16503   ]
16504   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16505   [(parallel[
16506      (set (reg:CC FLAGS_REG)
16507           (if_then_else:CC (ne (match_dup 6)
16508                                (const_int 0))
16509             (compare:CC (mem:BLK (match_dup 4))
16510                         (mem:BLK (match_dup 5)))
16511             (const_int 0)))
16512      (use (match_dup 3))
16513      (use (reg:CC FLAGS_REG))
16514      (clobber (match_dup 0))
16515      (clobber (match_dup 1))
16516      (clobber (match_dup 2))])]
16517   "")
16518
16519
16520 \f
16521 ;; Conditional move instructions.
16522
16523 (define_expand "mov<mode>cc"
16524   [(set (match_operand:SWIM 0 "register_operand" "")
16525         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16526                            (match_operand:SWIM 2 "general_operand" "")
16527                            (match_operand:SWIM 3 "general_operand" "")))]
16528   ""
16529   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16530
16531 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16532 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16533 ;; So just document what we're doing explicitly.
16534
16535 (define_expand "x86_mov<mode>cc_0_m1"
16536   [(parallel
16537     [(set (match_operand:SWI48 0 "register_operand" "")
16538           (if_then_else:SWI48
16539             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16540              [(match_operand 1 "flags_reg_operand" "")
16541               (const_int 0)])
16542             (const_int -1)
16543             (const_int 0)))
16544      (clobber (reg:CC FLAGS_REG))])]
16545   ""
16546   "")
16547
16548 (define_insn "*x86_mov<mode>cc_0_m1"
16549   [(set (match_operand:SWI48 0 "register_operand" "=r")
16550         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16551                              [(reg FLAGS_REG) (const_int 0)])
16552           (const_int -1)
16553           (const_int 0)))
16554    (clobber (reg:CC FLAGS_REG))]
16555   ""
16556   "sbb{<imodesuffix>}\t%0, %0"
16557   ; Since we don't have the proper number of operands for an alu insn,
16558   ; fill in all the blanks.
16559   [(set_attr "type" "alu")
16560    (set_attr "use_carry" "1")
16561    (set_attr "pent_pair" "pu")
16562    (set_attr "memory" "none")
16563    (set_attr "imm_disp" "false")
16564    (set_attr "mode" "<MODE>")
16565    (set_attr "length_immediate" "0")])
16566
16567 (define_insn "*x86_mov<mode>cc_0_m1_se"
16568   [(set (match_operand:SWI48 0 "register_operand" "=r")
16569         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16570                              [(reg FLAGS_REG) (const_int 0)])
16571                             (const_int 1)
16572                             (const_int 0)))
16573    (clobber (reg:CC FLAGS_REG))]
16574   ""
16575   "sbb{<imodesuffix>}\t%0, %0"
16576   [(set_attr "type" "alu")
16577    (set_attr "use_carry" "1")
16578    (set_attr "pent_pair" "pu")
16579    (set_attr "memory" "none")
16580    (set_attr "imm_disp" "false")
16581    (set_attr "mode" "<MODE>")
16582    (set_attr "length_immediate" "0")])
16583
16584 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16585   [(set (match_operand:SWI48 0 "register_operand" "=r")
16586         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16587                     [(reg FLAGS_REG) (const_int 0)])))]
16588   ""
16589   "sbb{<imodesuffix>}\t%0, %0"
16590   [(set_attr "type" "alu")
16591    (set_attr "use_carry" "1")
16592    (set_attr "pent_pair" "pu")
16593    (set_attr "memory" "none")
16594    (set_attr "imm_disp" "false")
16595    (set_attr "mode" "<MODE>")
16596    (set_attr "length_immediate" "0")])
16597
16598 (define_insn "*mov<mode>cc_noc"
16599   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16600         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16601                                [(reg FLAGS_REG) (const_int 0)])
16602           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16603           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16604   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16605   "@
16606    cmov%O2%C1\t{%2, %0|%0, %2}
16607    cmov%O2%c1\t{%3, %0|%0, %3}"
16608   [(set_attr "type" "icmov")
16609    (set_attr "mode" "<MODE>")])
16610
16611 (define_insn_and_split "*movqicc_noc"
16612   [(set (match_operand:QI 0 "register_operand" "=r,r")
16613         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16614                            [(match_operand 4 "flags_reg_operand" "")
16615                             (const_int 0)])
16616                       (match_operand:QI 2 "register_operand" "r,0")
16617                       (match_operand:QI 3 "register_operand" "0,r")))]
16618   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16619   "#"
16620   "&& reload_completed"
16621   [(set (match_dup 0)
16622         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16623                       (match_dup 2)
16624                       (match_dup 3)))]
16625   "operands[0] = gen_lowpart (SImode, operands[0]);
16626    operands[2] = gen_lowpart (SImode, operands[2]);
16627    operands[3] = gen_lowpart (SImode, operands[3]);"
16628   [(set_attr "type" "icmov")
16629    (set_attr "mode" "SI")])
16630
16631 (define_expand "mov<mode>cc"
16632   [(set (match_operand:X87MODEF 0 "register_operand" "")
16633         (if_then_else:X87MODEF
16634           (match_operand 1 "ix86_fp_comparison_operator" "")
16635           (match_operand:X87MODEF 2 "register_operand" "")
16636           (match_operand:X87MODEF 3 "register_operand" "")))]
16637   "(TARGET_80387 && TARGET_CMOVE)
16638    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16639   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16640
16641 (define_insn "*movsfcc_1_387"
16642   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16643         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16644                                 [(reg FLAGS_REG) (const_int 0)])
16645                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16646                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16647   "TARGET_80387 && TARGET_CMOVE
16648    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16649   "@
16650    fcmov%F1\t{%2, %0|%0, %2}
16651    fcmov%f1\t{%3, %0|%0, %3}
16652    cmov%O2%C1\t{%2, %0|%0, %2}
16653    cmov%O2%c1\t{%3, %0|%0, %3}"
16654   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16655    (set_attr "mode" "SF,SF,SI,SI")])
16656
16657 (define_insn "*movdfcc_1"
16658   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16659         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16660                                 [(reg FLAGS_REG) (const_int 0)])
16661                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16662                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16663   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16664    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16665   "@
16666    fcmov%F1\t{%2, %0|%0, %2}
16667    fcmov%f1\t{%3, %0|%0, %3}
16668    #
16669    #"
16670   [(set_attr "type" "fcmov,fcmov,multi,multi")
16671    (set_attr "mode" "DF")])
16672
16673 (define_insn "*movdfcc_1_rex64"
16674   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16675         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16676                                 [(reg FLAGS_REG) (const_int 0)])
16677                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16678                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16679   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16680    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16681   "@
16682    fcmov%F1\t{%2, %0|%0, %2}
16683    fcmov%f1\t{%3, %0|%0, %3}
16684    cmov%O2%C1\t{%2, %0|%0, %2}
16685    cmov%O2%c1\t{%3, %0|%0, %3}"
16686   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16687    (set_attr "mode" "DF")])
16688
16689 (define_split
16690   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16691         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16692                                 [(match_operand 4 "flags_reg_operand" "")
16693                                  (const_int 0)])
16694                       (match_operand:DF 2 "nonimmediate_operand" "")
16695                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16696   "!TARGET_64BIT && reload_completed"
16697   [(set (match_dup 2)
16698         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16699                       (match_dup 5)
16700                       (match_dup 6)))
16701    (set (match_dup 3)
16702         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16703                       (match_dup 7)
16704                       (match_dup 8)))]
16705 {
16706   split_di (&operands[2], 2, &operands[5], &operands[7]);
16707   split_di (&operands[0], 1, &operands[2], &operands[3]);
16708 })
16709
16710 (define_insn "*movxfcc_1"
16711   [(set (match_operand:XF 0 "register_operand" "=f,f")
16712         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16713                                 [(reg FLAGS_REG) (const_int 0)])
16714                       (match_operand:XF 2 "register_operand" "f,0")
16715                       (match_operand:XF 3 "register_operand" "0,f")))]
16716   "TARGET_80387 && TARGET_CMOVE"
16717   "@
16718    fcmov%F1\t{%2, %0|%0, %2}
16719    fcmov%f1\t{%3, %0|%0, %3}"
16720   [(set_attr "type" "fcmov")
16721    (set_attr "mode" "XF")])
16722
16723 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16724 ;; the scalar versions to have only XMM registers as operands.
16725
16726 ;; XOP conditional move
16727 (define_insn "*xop_pcmov_<mode>"
16728   [(set (match_operand:MODEF 0 "register_operand" "=x")
16729         (if_then_else:MODEF
16730           (match_operand:MODEF 1 "register_operand" "x")
16731           (match_operand:MODEF 2 "register_operand" "x")
16732           (match_operand:MODEF 3 "register_operand" "x")))]
16733   "TARGET_XOP"
16734   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16735   [(set_attr "type" "sse4arg")])
16736
16737 ;; These versions of the min/max patterns are intentionally ignorant of
16738 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16739 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16740 ;; are undefined in this condition, we're certain this is correct.
16741
16742 (define_insn "*avx_<code><mode>3"
16743   [(set (match_operand:MODEF 0 "register_operand" "=x")
16744         (smaxmin:MODEF
16745           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16746           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16747   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16748   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16749   [(set_attr "type" "sseadd")
16750    (set_attr "prefix" "vex")
16751    (set_attr "mode" "<MODE>")])
16752
16753 (define_insn "<code><mode>3"
16754   [(set (match_operand:MODEF 0 "register_operand" "=x")
16755         (smaxmin:MODEF
16756           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16757           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16758   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16759   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16760   [(set_attr "type" "sseadd")
16761    (set_attr "mode" "<MODE>")])
16762
16763 ;; These versions of the min/max patterns implement exactly the operations
16764 ;;   min = (op1 < op2 ? op1 : op2)
16765 ;;   max = (!(op1 < op2) ? op1 : op2)
16766 ;; Their operands are not commutative, and thus they may be used in the
16767 ;; presence of -0.0 and NaN.
16768
16769 (define_insn "*avx_ieee_smin<mode>3"
16770   [(set (match_operand:MODEF 0 "register_operand" "=x")
16771         (unspec:MODEF
16772           [(match_operand:MODEF 1 "register_operand" "x")
16773            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16774          UNSPEC_IEEE_MIN))]
16775   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16776   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16777   [(set_attr "type" "sseadd")
16778    (set_attr "prefix" "vex")
16779    (set_attr "mode" "<MODE>")])
16780
16781 (define_insn "*ieee_smin<mode>3"
16782   [(set (match_operand:MODEF 0 "register_operand" "=x")
16783         (unspec:MODEF
16784           [(match_operand:MODEF 1 "register_operand" "0")
16785            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16786          UNSPEC_IEEE_MIN))]
16787   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16788   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16789   [(set_attr "type" "sseadd")
16790    (set_attr "mode" "<MODE>")])
16791
16792 (define_insn "*avx_ieee_smax<mode>3"
16793   [(set (match_operand:MODEF 0 "register_operand" "=x")
16794         (unspec:MODEF
16795           [(match_operand:MODEF 1 "register_operand" "0")
16796            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16797          UNSPEC_IEEE_MAX))]
16798   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16799   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16800   [(set_attr "type" "sseadd")
16801    (set_attr "prefix" "vex")
16802    (set_attr "mode" "<MODE>")])
16803
16804 (define_insn "*ieee_smax<mode>3"
16805   [(set (match_operand:MODEF 0 "register_operand" "=x")
16806         (unspec:MODEF
16807           [(match_operand:MODEF 1 "register_operand" "0")
16808            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16809          UNSPEC_IEEE_MAX))]
16810   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16811   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16812   [(set_attr "type" "sseadd")
16813    (set_attr "mode" "<MODE>")])
16814
16815 ;; Make two stack loads independent:
16816 ;;   fld aa              fld aa
16817 ;;   fld %st(0)     ->   fld bb
16818 ;;   fmul bb             fmul %st(1), %st
16819 ;;
16820 ;; Actually we only match the last two instructions for simplicity.
16821 (define_peephole2
16822   [(set (match_operand 0 "fp_register_operand" "")
16823         (match_operand 1 "fp_register_operand" ""))
16824    (set (match_dup 0)
16825         (match_operator 2 "binary_fp_operator"
16826            [(match_dup 0)
16827             (match_operand 3 "memory_operand" "")]))]
16828   "REGNO (operands[0]) != REGNO (operands[1])"
16829   [(set (match_dup 0) (match_dup 3))
16830    (set (match_dup 0) (match_dup 4))]
16831
16832   ;; The % modifier is not operational anymore in peephole2's, so we have to
16833   ;; swap the operands manually in the case of addition and multiplication.
16834   "if (COMMUTATIVE_ARITH_P (operands[2]))
16835      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16836                                  operands[0], operands[1]);
16837    else
16838      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16839                                  operands[1], operands[0]);")
16840
16841 ;; Conditional addition patterns
16842 (define_expand "add<mode>cc"
16843   [(match_operand:SWI 0 "register_operand" "")
16844    (match_operand 1 "comparison_operator" "")
16845    (match_operand:SWI 2 "register_operand" "")
16846    (match_operand:SWI 3 "const_int_operand" "")]
16847   ""
16848   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16849
16850 \f
16851 ;; Misc patterns (?)
16852
16853 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16854 ;; Otherwise there will be nothing to keep
16855 ;;
16856 ;; [(set (reg ebp) (reg esp))]
16857 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16858 ;;  (clobber (eflags)]
16859 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16860 ;;
16861 ;; in proper program order.
16862 (define_insn "pro_epilogue_adjust_stack_1"
16863   [(set (match_operand:SI 0 "register_operand" "=r,r")
16864         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16865                  (match_operand:SI 2 "immediate_operand" "i,i")))
16866    (clobber (reg:CC FLAGS_REG))
16867    (clobber (mem:BLK (scratch)))]
16868   "!TARGET_64BIT"
16869 {
16870   switch (get_attr_type (insn))
16871     {
16872     case TYPE_IMOV:
16873       return "mov{l}\t{%1, %0|%0, %1}";
16874
16875     case TYPE_ALU:
16876       if (CONST_INT_P (operands[2])
16877           && (INTVAL (operands[2]) == 128
16878               || (INTVAL (operands[2]) < 0
16879                   && INTVAL (operands[2]) != -128)))
16880         {
16881           operands[2] = GEN_INT (-INTVAL (operands[2]));
16882           return "sub{l}\t{%2, %0|%0, %2}";
16883         }
16884       return "add{l}\t{%2, %0|%0, %2}";
16885
16886     case TYPE_LEA:
16887       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16888       return "lea{l}\t{%a2, %0|%0, %a2}";
16889
16890     default:
16891       gcc_unreachable ();
16892     }
16893 }
16894   [(set (attr "type")
16895         (cond [(and (eq_attr "alternative" "0") 
16896                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16897                  (const_string "alu")
16898                (match_operand:SI 2 "const0_operand" "")
16899                  (const_string "imov")
16900               ]
16901               (const_string "lea")))
16902    (set (attr "length_immediate")
16903         (cond [(eq_attr "type" "imov")
16904                  (const_string "0")
16905                (and (eq_attr "type" "alu")
16906                     (match_operand 2 "const128_operand" ""))
16907                  (const_string "1")
16908               ]
16909               (const_string "*")))
16910    (set_attr "mode" "SI")])
16911
16912 (define_insn "pro_epilogue_adjust_stack_rex64"
16913   [(set (match_operand:DI 0 "register_operand" "=r,r")
16914         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16915                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16916    (clobber (reg:CC FLAGS_REG))
16917    (clobber (mem:BLK (scratch)))]
16918   "TARGET_64BIT"
16919 {
16920   switch (get_attr_type (insn))
16921     {
16922     case TYPE_IMOV:
16923       return "mov{q}\t{%1, %0|%0, %1}";
16924
16925     case TYPE_ALU:
16926       if (CONST_INT_P (operands[2])
16927           /* Avoid overflows.  */
16928           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16929           && (INTVAL (operands[2]) == 128
16930               || (INTVAL (operands[2]) < 0
16931                   && INTVAL (operands[2]) != -128)))
16932         {
16933           operands[2] = GEN_INT (-INTVAL (operands[2]));
16934           return "sub{q}\t{%2, %0|%0, %2}";
16935         }
16936       return "add{q}\t{%2, %0|%0, %2}";
16937
16938     case TYPE_LEA:
16939       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16940       return "lea{q}\t{%a2, %0|%0, %a2}";
16941
16942     default:
16943       gcc_unreachable ();
16944     }
16945 }
16946   [(set (attr "type")
16947         (cond [(and (eq_attr "alternative" "0")
16948                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16949                  (const_string "alu")
16950                (match_operand:DI 2 "const0_operand" "")
16951                  (const_string "imov")
16952               ]
16953               (const_string "lea")))
16954    (set (attr "length_immediate")
16955         (cond [(eq_attr "type" "imov")
16956                  (const_string "0")
16957                (and (eq_attr "type" "alu")
16958                     (match_operand 2 "const128_operand" ""))
16959                  (const_string "1")
16960               ]
16961               (const_string "*")))
16962    (set_attr "mode" "DI")])
16963
16964 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16965   [(set (match_operand:DI 0 "register_operand" "=r,r")
16966         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16967                  (match_operand:DI 3 "immediate_operand" "i,i")))
16968    (use (match_operand:DI 2 "register_operand" "r,r"))
16969    (clobber (reg:CC FLAGS_REG))
16970    (clobber (mem:BLK (scratch)))]
16971   "TARGET_64BIT"
16972 {
16973   switch (get_attr_type (insn))
16974     {
16975     case TYPE_ALU:
16976       return "add{q}\t{%2, %0|%0, %2}";
16977
16978     case TYPE_LEA:
16979       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16980       return "lea{q}\t{%a2, %0|%0, %a2}";
16981
16982     default:
16983       gcc_unreachable ();
16984     }
16985 }
16986   [(set_attr "type" "alu,lea")
16987    (set_attr "mode" "DI")])
16988
16989 (define_insn "allocate_stack_worker_32"
16990   [(set (match_operand:SI 0 "register_operand" "=a")
16991         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16992                             UNSPECV_STACK_PROBE))
16993    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16994    (clobber (reg:CC FLAGS_REG))]
16995   "!TARGET_64BIT && TARGET_STACK_PROBE"
16996   "call\t___chkstk"
16997   [(set_attr "type" "multi")
16998    (set_attr "length" "5")])
16999
17000 (define_insn "allocate_stack_worker_64"
17001   [(set (match_operand:DI 0 "register_operand" "=a")
17002         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
17003                             UNSPECV_STACK_PROBE))
17004    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
17005    (clobber (reg:DI R10_REG))
17006    (clobber (reg:DI R11_REG))
17007    (clobber (reg:CC FLAGS_REG))]
17008   "TARGET_64BIT && TARGET_STACK_PROBE"
17009   "call\t___chkstk"
17010   [(set_attr "type" "multi")
17011    (set_attr "length" "5")])
17012
17013 (define_expand "allocate_stack"
17014   [(match_operand 0 "register_operand" "")
17015    (match_operand 1 "general_operand" "")]
17016   "TARGET_STACK_PROBE"
17017 {
17018   rtx x;
17019
17020 #ifndef CHECK_STACK_LIMIT
17021 #define CHECK_STACK_LIMIT 0
17022 #endif
17023
17024   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17025       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17026     {
17027       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
17028                                stack_pointer_rtx, 0, OPTAB_DIRECT);
17029       if (x != stack_pointer_rtx)
17030         emit_move_insn (stack_pointer_rtx, x);
17031     }
17032   else
17033     {
17034       x = copy_to_mode_reg (Pmode, operands[1]);
17035       if (TARGET_64BIT)
17036         x = gen_allocate_stack_worker_64 (x, x);
17037       else
17038         x = gen_allocate_stack_worker_32 (x, x);
17039       emit_insn (x);
17040     }
17041
17042   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17043   DONE;
17044 })
17045
17046 ;; Use IOR for stack probes, this is shorter.
17047 (define_expand "probe_stack"
17048   [(match_operand 0 "memory_operand" "")]
17049   ""
17050 {
17051   if (GET_MODE (operands[0]) == DImode)
17052     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
17053   else
17054     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
17055   DONE;
17056 })
17057
17058 (define_expand "builtin_setjmp_receiver"
17059   [(label_ref (match_operand 0 "" ""))]
17060   "!TARGET_64BIT && flag_pic"
17061 {
17062 #if TARGET_MACHO
17063   if (TARGET_MACHO)
17064     {
17065       rtx xops[3];
17066       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17067       rtx label_rtx = gen_label_rtx ();
17068       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17069       xops[0] = xops[1] = picreg;
17070       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17071       ix86_expand_binary_operator (MINUS, SImode, xops);
17072     }
17073   else
17074 #endif
17075     emit_insn (gen_set_got (pic_offset_table_rtx));
17076   DONE;
17077 })
17078 \f
17079 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17080
17081 (define_split
17082   [(set (match_operand 0 "register_operand" "")
17083         (match_operator 3 "promotable_binary_operator"
17084            [(match_operand 1 "register_operand" "")
17085             (match_operand 2 "aligned_operand" "")]))
17086    (clobber (reg:CC FLAGS_REG))]
17087   "! TARGET_PARTIAL_REG_STALL && reload_completed
17088    && ((GET_MODE (operands[0]) == HImode
17089         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17090             /* ??? next two lines just !satisfies_constraint_K (...) */
17091             || !CONST_INT_P (operands[2])
17092             || satisfies_constraint_K (operands[2])))
17093        || (GET_MODE (operands[0]) == QImode
17094            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17095   [(parallel [(set (match_dup 0)
17096                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17097               (clobber (reg:CC FLAGS_REG))])]
17098   "operands[0] = gen_lowpart (SImode, operands[0]);
17099    operands[1] = gen_lowpart (SImode, operands[1]);
17100    if (GET_CODE (operands[3]) != ASHIFT)
17101      operands[2] = gen_lowpart (SImode, operands[2]);
17102    PUT_MODE (operands[3], SImode);")
17103
17104 ; Promote the QImode tests, as i386 has encoding of the AND
17105 ; instruction with 32-bit sign-extended immediate and thus the
17106 ; instruction size is unchanged, except in the %eax case for
17107 ; which it is increased by one byte, hence the ! optimize_size.
17108 (define_split
17109   [(set (match_operand 0 "flags_reg_operand" "")
17110         (match_operator 2 "compare_operator"
17111           [(and (match_operand 3 "aligned_operand" "")
17112                 (match_operand 4 "const_int_operand" ""))
17113            (const_int 0)]))
17114    (set (match_operand 1 "register_operand" "")
17115         (and (match_dup 3) (match_dup 4)))]
17116   "! TARGET_PARTIAL_REG_STALL && reload_completed
17117    && optimize_insn_for_speed_p ()
17118    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17119        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17120    /* Ensure that the operand will remain sign-extended immediate.  */
17121    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17122   [(parallel [(set (match_dup 0)
17123                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17124                                     (const_int 0)]))
17125               (set (match_dup 1)
17126                    (and:SI (match_dup 3) (match_dup 4)))])]
17127 {
17128   operands[4]
17129     = gen_int_mode (INTVAL (operands[4])
17130                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17131   operands[1] = gen_lowpart (SImode, operands[1]);
17132   operands[3] = gen_lowpart (SImode, operands[3]);
17133 })
17134
17135 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17136 ; the TEST instruction with 32-bit sign-extended immediate and thus
17137 ; the instruction size would at least double, which is not what we
17138 ; want even with ! optimize_size.
17139 (define_split
17140   [(set (match_operand 0 "flags_reg_operand" "")
17141         (match_operator 1 "compare_operator"
17142           [(and (match_operand:HI 2 "aligned_operand" "")
17143                 (match_operand:HI 3 "const_int_operand" ""))
17144            (const_int 0)]))]
17145   "! TARGET_PARTIAL_REG_STALL && reload_completed
17146    && ! TARGET_FAST_PREFIX
17147    && optimize_insn_for_speed_p ()
17148    /* Ensure that the operand will remain sign-extended immediate.  */
17149    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17150   [(set (match_dup 0)
17151         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17152                          (const_int 0)]))]
17153 {
17154   operands[3]
17155     = gen_int_mode (INTVAL (operands[3])
17156                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17157   operands[2] = gen_lowpart (SImode, operands[2]);
17158 })
17159
17160 (define_split
17161   [(set (match_operand 0 "register_operand" "")
17162         (neg (match_operand 1 "register_operand" "")))
17163    (clobber (reg:CC FLAGS_REG))]
17164   "! TARGET_PARTIAL_REG_STALL && reload_completed
17165    && (GET_MODE (operands[0]) == HImode
17166        || (GET_MODE (operands[0]) == QImode
17167            && (TARGET_PROMOTE_QImode
17168                || optimize_insn_for_size_p ())))"
17169   [(parallel [(set (match_dup 0)
17170                    (neg:SI (match_dup 1)))
17171               (clobber (reg:CC FLAGS_REG))])]
17172   "operands[0] = gen_lowpart (SImode, operands[0]);
17173    operands[1] = gen_lowpart (SImode, operands[1]);")
17174
17175 (define_split
17176   [(set (match_operand 0 "register_operand" "")
17177         (not (match_operand 1 "register_operand" "")))]
17178   "! TARGET_PARTIAL_REG_STALL && reload_completed
17179    && (GET_MODE (operands[0]) == HImode
17180        || (GET_MODE (operands[0]) == QImode
17181            && (TARGET_PROMOTE_QImode
17182                || optimize_insn_for_size_p ())))"
17183   [(set (match_dup 0)
17184         (not:SI (match_dup 1)))]
17185   "operands[0] = gen_lowpart (SImode, operands[0]);
17186    operands[1] = gen_lowpart (SImode, operands[1]);")
17187
17188 (define_split
17189   [(set (match_operand 0 "register_operand" "")
17190         (if_then_else (match_operator 1 "comparison_operator"
17191                                 [(reg FLAGS_REG) (const_int 0)])
17192                       (match_operand 2 "register_operand" "")
17193                       (match_operand 3 "register_operand" "")))]
17194   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17195    && (GET_MODE (operands[0]) == HImode
17196        || (GET_MODE (operands[0]) == QImode
17197            && (TARGET_PROMOTE_QImode
17198                || optimize_insn_for_size_p ())))"
17199   [(set (match_dup 0)
17200         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17201   "operands[0] = gen_lowpart (SImode, operands[0]);
17202    operands[2] = gen_lowpart (SImode, operands[2]);
17203    operands[3] = gen_lowpart (SImode, operands[3]);")
17204
17205 \f
17206 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17207 ;; transform a complex memory operation into two memory to register operations.
17208
17209 ;; Don't push memory operands
17210 (define_peephole2
17211   [(set (match_operand:SI 0 "push_operand" "")
17212         (match_operand:SI 1 "memory_operand" ""))
17213    (match_scratch:SI 2 "r")]
17214   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17215    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17216   [(set (match_dup 2) (match_dup 1))
17217    (set (match_dup 0) (match_dup 2))]
17218   "")
17219
17220 (define_peephole2
17221   [(set (match_operand:DI 0 "push_operand" "")
17222         (match_operand:DI 1 "memory_operand" ""))
17223    (match_scratch:DI 2 "r")]
17224   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17225    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17226   [(set (match_dup 2) (match_dup 1))
17227    (set (match_dup 0) (match_dup 2))]
17228   "")
17229
17230 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17231 ;; SImode pushes.
17232 (define_peephole2
17233   [(set (match_operand:SF 0 "push_operand" "")
17234         (match_operand:SF 1 "memory_operand" ""))
17235    (match_scratch:SF 2 "r")]
17236   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17237    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17238   [(set (match_dup 2) (match_dup 1))
17239    (set (match_dup 0) (match_dup 2))]
17240   "")
17241
17242 (define_peephole2
17243   [(set (match_operand:HI 0 "push_operand" "")
17244         (match_operand:HI 1 "memory_operand" ""))
17245    (match_scratch:HI 2 "r")]
17246   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17247    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17248   [(set (match_dup 2) (match_dup 1))
17249    (set (match_dup 0) (match_dup 2))]
17250   "")
17251
17252 (define_peephole2
17253   [(set (match_operand:QI 0 "push_operand" "")
17254         (match_operand:QI 1 "memory_operand" ""))
17255    (match_scratch:QI 2 "q")]
17256   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17257    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17258   [(set (match_dup 2) (match_dup 1))
17259    (set (match_dup 0) (match_dup 2))]
17260   "")
17261
17262 ;; Don't move an immediate directly to memory when the instruction
17263 ;; gets too big.
17264 (define_peephole2
17265   [(match_scratch:SI 1 "r")
17266    (set (match_operand:SI 0 "memory_operand" "")
17267         (const_int 0))]
17268   "optimize_insn_for_speed_p ()
17269    && ! TARGET_USE_MOV0
17270    && TARGET_SPLIT_LONG_MOVES
17271    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17272    && peep2_regno_dead_p (0, FLAGS_REG)"
17273   [(parallel [(set (match_dup 1) (const_int 0))
17274               (clobber (reg:CC FLAGS_REG))])
17275    (set (match_dup 0) (match_dup 1))]
17276   "")
17277
17278 (define_peephole2
17279   [(match_scratch:HI 1 "r")
17280    (set (match_operand:HI 0 "memory_operand" "")
17281         (const_int 0))]
17282   "optimize_insn_for_speed_p ()
17283    && ! TARGET_USE_MOV0
17284    && TARGET_SPLIT_LONG_MOVES
17285    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17286    && peep2_regno_dead_p (0, FLAGS_REG)"
17287   [(parallel [(set (match_dup 2) (const_int 0))
17288               (clobber (reg:CC FLAGS_REG))])
17289    (set (match_dup 0) (match_dup 1))]
17290   "operands[2] = gen_lowpart (SImode, operands[1]);")
17291
17292 (define_peephole2
17293   [(match_scratch:QI 1 "q")
17294    (set (match_operand:QI 0 "memory_operand" "")
17295         (const_int 0))]
17296   "optimize_insn_for_speed_p ()
17297    && ! TARGET_USE_MOV0
17298    && TARGET_SPLIT_LONG_MOVES
17299    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17300    && peep2_regno_dead_p (0, FLAGS_REG)"
17301   [(parallel [(set (match_dup 2) (const_int 0))
17302               (clobber (reg:CC FLAGS_REG))])
17303    (set (match_dup 0) (match_dup 1))]
17304   "operands[2] = gen_lowpart (SImode, operands[1]);")
17305
17306 (define_peephole2
17307   [(match_scratch:SI 2 "r")
17308    (set (match_operand:SI 0 "memory_operand" "")
17309         (match_operand:SI 1 "immediate_operand" ""))]
17310   "optimize_insn_for_speed_p ()
17311    && TARGET_SPLIT_LONG_MOVES
17312    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17313   [(set (match_dup 2) (match_dup 1))
17314    (set (match_dup 0) (match_dup 2))]
17315   "")
17316
17317 (define_peephole2
17318   [(match_scratch:HI 2 "r")
17319    (set (match_operand:HI 0 "memory_operand" "")
17320         (match_operand:HI 1 "immediate_operand" ""))]
17321   "optimize_insn_for_speed_p ()
17322    && TARGET_SPLIT_LONG_MOVES
17323    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17324   [(set (match_dup 2) (match_dup 1))
17325    (set (match_dup 0) (match_dup 2))]
17326   "")
17327
17328 (define_peephole2
17329   [(match_scratch:QI 2 "q")
17330    (set (match_operand:QI 0 "memory_operand" "")
17331         (match_operand:QI 1 "immediate_operand" ""))]
17332   "optimize_insn_for_speed_p ()
17333    && TARGET_SPLIT_LONG_MOVES
17334    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17335   [(set (match_dup 2) (match_dup 1))
17336    (set (match_dup 0) (match_dup 2))]
17337   "")
17338
17339 ;; Don't compare memory with zero, load and use a test instead.
17340 (define_peephole2
17341   [(set (match_operand 0 "flags_reg_operand" "")
17342         (match_operator 1 "compare_operator"
17343           [(match_operand:SI 2 "memory_operand" "")
17344            (const_int 0)]))
17345    (match_scratch:SI 3 "r")]
17346   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17347   [(set (match_dup 3) (match_dup 2))
17348    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17349   "")
17350
17351 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17352 ;; Don't split NOTs with a displacement operand, because resulting XOR
17353 ;; will not be pairable anyway.
17354 ;;
17355 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17356 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17357 ;; so this split helps here as well.
17358 ;;
17359 ;; Note: Can't do this as a regular split because we can't get proper
17360 ;; lifetime information then.
17361
17362 (define_peephole2
17363   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17364         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17365   "optimize_insn_for_speed_p ()
17366    && ((TARGET_NOT_UNPAIRABLE
17367         && (!MEM_P (operands[0])
17368             || !memory_displacement_operand (operands[0], SImode)))
17369        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17370    && peep2_regno_dead_p (0, FLAGS_REG)"
17371   [(parallel [(set (match_dup 0)
17372                    (xor:SI (match_dup 1) (const_int -1)))
17373               (clobber (reg:CC FLAGS_REG))])]
17374   "")
17375
17376 (define_peephole2
17377   [(set (match_operand:HI 0 "nonimmediate_operand" "")
17378         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17379   "optimize_insn_for_speed_p ()
17380    && ((TARGET_NOT_UNPAIRABLE
17381         && (!MEM_P (operands[0])
17382             || !memory_displacement_operand (operands[0], HImode)))
17383        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17384    && peep2_regno_dead_p (0, FLAGS_REG)"
17385   [(parallel [(set (match_dup 0)
17386                    (xor:HI (match_dup 1) (const_int -1)))
17387               (clobber (reg:CC FLAGS_REG))])]
17388   "")
17389
17390 (define_peephole2
17391   [(set (match_operand:QI 0 "nonimmediate_operand" "")
17392         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17393   "optimize_insn_for_speed_p ()
17394    && ((TARGET_NOT_UNPAIRABLE
17395         && (!MEM_P (operands[0])
17396             || !memory_displacement_operand (operands[0], QImode)))
17397        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17398    && peep2_regno_dead_p (0, FLAGS_REG)"
17399   [(parallel [(set (match_dup 0)
17400                    (xor:QI (match_dup 1) (const_int -1)))
17401               (clobber (reg:CC FLAGS_REG))])]
17402   "")
17403
17404 ;; Non pairable "test imm, reg" instructions can be translated to
17405 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17406 ;; byte opcode instead of two, have a short form for byte operands),
17407 ;; so do it for other CPUs as well.  Given that the value was dead,
17408 ;; this should not create any new dependencies.  Pass on the sub-word
17409 ;; versions if we're concerned about partial register stalls.
17410
17411 (define_peephole2
17412   [(set (match_operand 0 "flags_reg_operand" "")
17413         (match_operator 1 "compare_operator"
17414           [(and:SI (match_operand:SI 2 "register_operand" "")
17415                    (match_operand:SI 3 "immediate_operand" ""))
17416            (const_int 0)]))]
17417   "ix86_match_ccmode (insn, CCNOmode)
17418    && (true_regnum (operands[2]) != AX_REG
17419        || satisfies_constraint_K (operands[3]))
17420    && peep2_reg_dead_p (1, operands[2])"
17421   [(parallel
17422      [(set (match_dup 0)
17423            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17424                             (const_int 0)]))
17425       (set (match_dup 2)
17426            (and:SI (match_dup 2) (match_dup 3)))])]
17427   "")
17428
17429 ;; We don't need to handle HImode case, because it will be promoted to SImode
17430 ;; on ! TARGET_PARTIAL_REG_STALL
17431
17432 (define_peephole2
17433   [(set (match_operand 0 "flags_reg_operand" "")
17434         (match_operator 1 "compare_operator"
17435           [(and:QI (match_operand:QI 2 "register_operand" "")
17436                    (match_operand:QI 3 "immediate_operand" ""))
17437            (const_int 0)]))]
17438   "! TARGET_PARTIAL_REG_STALL
17439    && ix86_match_ccmode (insn, CCNOmode)
17440    && true_regnum (operands[2]) != AX_REG
17441    && peep2_reg_dead_p (1, operands[2])"
17442   [(parallel
17443      [(set (match_dup 0)
17444            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17445                             (const_int 0)]))
17446       (set (match_dup 2)
17447            (and:QI (match_dup 2) (match_dup 3)))])]
17448   "")
17449
17450 (define_peephole2
17451   [(set (match_operand 0 "flags_reg_operand" "")
17452         (match_operator 1 "compare_operator"
17453           [(and:SI
17454              (zero_extract:SI
17455                (match_operand 2 "ext_register_operand" "")
17456                (const_int 8)
17457                (const_int 8))
17458              (match_operand 3 "const_int_operand" ""))
17459            (const_int 0)]))]
17460   "! TARGET_PARTIAL_REG_STALL
17461    && ix86_match_ccmode (insn, CCNOmode)
17462    && true_regnum (operands[2]) != AX_REG
17463    && peep2_reg_dead_p (1, operands[2])"
17464   [(parallel [(set (match_dup 0)
17465                    (match_op_dup 1
17466                      [(and:SI
17467                         (zero_extract:SI
17468                           (match_dup 2)
17469                           (const_int 8)
17470                           (const_int 8))
17471                         (match_dup 3))
17472                       (const_int 0)]))
17473               (set (zero_extract:SI (match_dup 2)
17474                                     (const_int 8)
17475                                     (const_int 8))
17476                    (and:SI
17477                      (zero_extract:SI
17478                        (match_dup 2)
17479                        (const_int 8)
17480                        (const_int 8))
17481                      (match_dup 3)))])]
17482   "")
17483
17484 ;; Don't do logical operations with memory inputs.
17485 (define_peephole2
17486   [(match_scratch:SI 2 "r")
17487    (parallel [(set (match_operand:SI 0 "register_operand" "")
17488                    (match_operator:SI 3 "arith_or_logical_operator"
17489                      [(match_dup 0)
17490                       (match_operand:SI 1 "memory_operand" "")]))
17491               (clobber (reg:CC FLAGS_REG))])]
17492   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17493   [(set (match_dup 2) (match_dup 1))
17494    (parallel [(set (match_dup 0)
17495                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17496               (clobber (reg:CC FLAGS_REG))])]
17497   "")
17498
17499 (define_peephole2
17500   [(match_scratch:SI 2 "r")
17501    (parallel [(set (match_operand:SI 0 "register_operand" "")
17502                    (match_operator:SI 3 "arith_or_logical_operator"
17503                      [(match_operand:SI 1 "memory_operand" "")
17504                       (match_dup 0)]))
17505               (clobber (reg:CC FLAGS_REG))])]
17506   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17507   [(set (match_dup 2) (match_dup 1))
17508    (parallel [(set (match_dup 0)
17509                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17510               (clobber (reg:CC FLAGS_REG))])]
17511   "")
17512
17513 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17514 ;; refers to the destination of the load!
17515
17516 (define_peephole2
17517   [(set (match_operand:SI 0 "register_operand" "")
17518         (match_operand:SI 1 "register_operand" ""))
17519    (parallel [(set (match_dup 0)
17520                    (match_operator:SI 3 "commutative_operator"
17521                      [(match_dup 0)
17522                       (match_operand:SI 2 "memory_operand" "")]))
17523               (clobber (reg:CC FLAGS_REG))])]
17524   "REGNO (operands[0]) != REGNO (operands[1])
17525    && GENERAL_REGNO_P (REGNO (operands[0]))
17526    && GENERAL_REGNO_P (REGNO (operands[1]))"
17527   [(set (match_dup 0) (match_dup 4))
17528    (parallel [(set (match_dup 0)
17529                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17530               (clobber (reg:CC FLAGS_REG))])]
17531   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17532
17533 (define_peephole2
17534   [(set (match_operand 0 "register_operand" "")
17535         (match_operand 1 "register_operand" ""))
17536    (set (match_dup 0)
17537                    (match_operator 3 "commutative_operator"
17538                      [(match_dup 0)
17539                       (match_operand 2 "memory_operand" "")]))]
17540   "REGNO (operands[0]) != REGNO (operands[1])
17541    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17542        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17543   [(set (match_dup 0) (match_dup 2))
17544    (set (match_dup 0)
17545         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17546   "")
17547
17548 ; Don't do logical operations with memory outputs
17549 ;
17550 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17551 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17552 ; the same decoder scheduling characteristics as the original.
17553
17554 (define_peephole2
17555   [(match_scratch:SI 2 "r")
17556    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17557                    (match_operator:SI 3 "arith_or_logical_operator"
17558                      [(match_dup 0)
17559                       (match_operand:SI 1 "nonmemory_operand" "")]))
17560               (clobber (reg:CC FLAGS_REG))])]
17561   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17562    /* Do not split stack checking probes.  */
17563    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17564   [(set (match_dup 2) (match_dup 0))
17565    (parallel [(set (match_dup 2)
17566                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17567               (clobber (reg:CC FLAGS_REG))])
17568    (set (match_dup 0) (match_dup 2))]
17569   "")
17570
17571 (define_peephole2
17572   [(match_scratch:SI 2 "r")
17573    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17574                    (match_operator:SI 3 "arith_or_logical_operator"
17575                      [(match_operand:SI 1 "nonmemory_operand" "")
17576                       (match_dup 0)]))
17577               (clobber (reg:CC FLAGS_REG))])]
17578   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17579    /* Do not split stack checking probes.  */
17580    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17581   [(set (match_dup 2) (match_dup 0))
17582    (parallel [(set (match_dup 2)
17583                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17584               (clobber (reg:CC FLAGS_REG))])
17585    (set (match_dup 0) (match_dup 2))]
17586   "")
17587
17588 ;; Attempt to always use XOR for zeroing registers.
17589 (define_peephole2
17590   [(set (match_operand 0 "register_operand" "")
17591         (match_operand 1 "const0_operand" ""))]
17592   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17593    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17594    && GENERAL_REG_P (operands[0])
17595    && peep2_regno_dead_p (0, FLAGS_REG)"
17596   [(parallel [(set (match_dup 0) (const_int 0))
17597               (clobber (reg:CC FLAGS_REG))])]
17598 {
17599   operands[0] = gen_lowpart (word_mode, operands[0]);
17600 })
17601
17602 (define_peephole2
17603   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17604         (const_int 0))]
17605   "(GET_MODE (operands[0]) == QImode
17606     || GET_MODE (operands[0]) == HImode)
17607    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17608    && peep2_regno_dead_p (0, FLAGS_REG)"
17609   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17610               (clobber (reg:CC FLAGS_REG))])])
17611
17612 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17613 (define_peephole2
17614   [(set (match_operand 0 "register_operand" "")
17615         (const_int -1))]
17616   "(GET_MODE (operands[0]) == HImode
17617     || GET_MODE (operands[0]) == SImode
17618     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17619    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17620    && peep2_regno_dead_p (0, FLAGS_REG)"
17621   [(parallel [(set (match_dup 0) (const_int -1))
17622               (clobber (reg:CC FLAGS_REG))])]
17623   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17624                               operands[0]);")
17625
17626 ;; Attempt to convert simple leas to adds. These can be created by
17627 ;; move expanders.
17628 (define_peephole2
17629   [(set (match_operand:SI 0 "register_operand" "")
17630         (plus:SI (match_dup 0)
17631                  (match_operand:SI 1 "nonmemory_operand" "")))]
17632   "peep2_regno_dead_p (0, FLAGS_REG)"
17633   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17634               (clobber (reg:CC FLAGS_REG))])]
17635   "")
17636
17637 (define_peephole2
17638   [(set (match_operand:SI 0 "register_operand" "")
17639         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17640                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17641   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17642   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17643               (clobber (reg:CC FLAGS_REG))])]
17644   "operands[2] = gen_lowpart (SImode, operands[2]);")
17645
17646 (define_peephole2
17647   [(set (match_operand:DI 0 "register_operand" "")
17648         (plus:DI (match_dup 0)
17649                  (match_operand:DI 1 "x86_64_general_operand" "")))]
17650   "peep2_regno_dead_p (0, FLAGS_REG)"
17651   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17652               (clobber (reg:CC FLAGS_REG))])]
17653   "")
17654
17655 (define_peephole2
17656   [(set (match_operand:SI 0 "register_operand" "")
17657         (mult:SI (match_dup 0)
17658                  (match_operand:SI 1 "const_int_operand" "")))]
17659   "exact_log2 (INTVAL (operands[1])) >= 0
17660    && peep2_regno_dead_p (0, FLAGS_REG)"
17661   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17662               (clobber (reg:CC FLAGS_REG))])]
17663   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17664
17665 (define_peephole2
17666   [(set (match_operand:DI 0 "register_operand" "")
17667         (mult:DI (match_dup 0)
17668                  (match_operand:DI 1 "const_int_operand" "")))]
17669   "exact_log2 (INTVAL (operands[1])) >= 0
17670    && peep2_regno_dead_p (0, FLAGS_REG)"
17671   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17672               (clobber (reg:CC FLAGS_REG))])]
17673   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17674
17675 (define_peephole2
17676   [(set (match_operand:SI 0 "register_operand" "")
17677         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17678                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17679   "exact_log2 (INTVAL (operands[2])) >= 0
17680    && REGNO (operands[0]) == REGNO (operands[1])
17681    && peep2_regno_dead_p (0, FLAGS_REG)"
17682   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17683               (clobber (reg:CC FLAGS_REG))])]
17684   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17685
17686 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17687 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17688 ;; many CPUs it is also faster, since special hardware to avoid esp
17689 ;; dependencies is present.
17690
17691 ;; While some of these conversions may be done using splitters, we use peepholes
17692 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17693
17694 ;; Convert prologue esp subtractions to push.
17695 ;; We need register to push.  In order to keep verify_flow_info happy we have
17696 ;; two choices
17697 ;; - use scratch and clobber it in order to avoid dependencies
17698 ;; - use already live register
17699 ;; We can't use the second way right now, since there is no reliable way how to
17700 ;; verify that given register is live.  First choice will also most likely in
17701 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17702 ;; call clobbered registers are dead.  We may want to use base pointer as an
17703 ;; alternative when no register is available later.
17704
17705 (define_peephole2
17706   [(match_scratch:SI 0 "r")
17707    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17708               (clobber (reg:CC FLAGS_REG))
17709               (clobber (mem:BLK (scratch)))])]
17710   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17711   [(clobber (match_dup 0))
17712    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17713               (clobber (mem:BLK (scratch)))])])
17714
17715 (define_peephole2
17716   [(match_scratch:SI 0 "r")
17717    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17718               (clobber (reg:CC FLAGS_REG))
17719               (clobber (mem:BLK (scratch)))])]
17720   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17721   [(clobber (match_dup 0))
17722    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17723    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17724               (clobber (mem:BLK (scratch)))])])
17725
17726 ;; Convert esp subtractions to push.
17727 (define_peephole2
17728   [(match_scratch:SI 0 "r")
17729    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17730               (clobber (reg:CC FLAGS_REG))])]
17731   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17732   [(clobber (match_dup 0))
17733    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17734
17735 (define_peephole2
17736   [(match_scratch:SI 0 "r")
17737    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17738               (clobber (reg:CC FLAGS_REG))])]
17739   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17740   [(clobber (match_dup 0))
17741    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17742    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17743
17744 ;; Convert epilogue deallocator to pop.
17745 (define_peephole2
17746   [(match_scratch:SI 0 "r")
17747    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17748               (clobber (reg:CC FLAGS_REG))
17749               (clobber (mem:BLK (scratch)))])]
17750   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17751   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17752               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17753               (clobber (mem:BLK (scratch)))])]
17754   "")
17755
17756 ;; Two pops case is tricky, since pop causes dependency on destination register.
17757 ;; We use two registers if available.
17758 (define_peephole2
17759   [(match_scratch:SI 0 "r")
17760    (match_scratch:SI 1 "r")
17761    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17762               (clobber (reg:CC FLAGS_REG))
17763               (clobber (mem:BLK (scratch)))])]
17764   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17765   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17766               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17767               (clobber (mem:BLK (scratch)))])
17768    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17769               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17770   "")
17771
17772 (define_peephole2
17773   [(match_scratch:SI 0 "r")
17774    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17775               (clobber (reg:CC FLAGS_REG))
17776               (clobber (mem:BLK (scratch)))])]
17777   "optimize_insn_for_size_p ()"
17778   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17779               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17780               (clobber (mem:BLK (scratch)))])
17781    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17782               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17783   "")
17784
17785 ;; Convert esp additions to pop.
17786 (define_peephole2
17787   [(match_scratch:SI 0 "r")
17788    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17789               (clobber (reg:CC FLAGS_REG))])]
17790   ""
17791   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17792               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17793   "")
17794
17795 ;; Two pops case is tricky, since pop causes dependency on destination register.
17796 ;; We use two registers if available.
17797 (define_peephole2
17798   [(match_scratch:SI 0 "r")
17799    (match_scratch:SI 1 "r")
17800    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17801               (clobber (reg:CC FLAGS_REG))])]
17802   ""
17803   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17804               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17805    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17806               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17807   "")
17808
17809 (define_peephole2
17810   [(match_scratch:SI 0 "r")
17811    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17812               (clobber (reg:CC FLAGS_REG))])]
17813   "optimize_insn_for_size_p ()"
17814   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17815               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17816    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17817               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17818   "")
17819 \f
17820 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17821 ;; required and register dies.  Similarly for 128 to -128.
17822 (define_peephole2
17823   [(set (match_operand 0 "flags_reg_operand" "")
17824         (match_operator 1 "compare_operator"
17825           [(match_operand 2 "register_operand" "")
17826            (match_operand 3 "const_int_operand" "")]))]
17827   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17828      && incdec_operand (operands[3], GET_MODE (operands[3])))
17829     || (!TARGET_FUSE_CMP_AND_BRANCH
17830         && INTVAL (operands[3]) == 128))
17831    && ix86_match_ccmode (insn, CCGCmode)
17832    && peep2_reg_dead_p (1, operands[2])"
17833   [(parallel [(set (match_dup 0)
17834                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17835               (clobber (match_dup 2))])]
17836   "")
17837 \f
17838 (define_peephole2
17839   [(match_scratch:DI 0 "r")
17840    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17841               (clobber (reg:CC FLAGS_REG))
17842               (clobber (mem:BLK (scratch)))])]
17843   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17844   [(clobber (match_dup 0))
17845    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17846               (clobber (mem:BLK (scratch)))])])
17847
17848 (define_peephole2
17849   [(match_scratch:DI 0 "r")
17850    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17851               (clobber (reg:CC FLAGS_REG))
17852               (clobber (mem:BLK (scratch)))])]
17853   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17854   [(clobber (match_dup 0))
17855    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17856    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17857               (clobber (mem:BLK (scratch)))])])
17858
17859 ;; Convert esp subtractions to push.
17860 (define_peephole2
17861   [(match_scratch:DI 0 "r")
17862    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17863               (clobber (reg:CC FLAGS_REG))])]
17864   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17865   [(clobber (match_dup 0))
17866    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17867
17868 (define_peephole2
17869   [(match_scratch:DI 0 "r")
17870    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17871               (clobber (reg:CC FLAGS_REG))])]
17872   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17873   [(clobber (match_dup 0))
17874    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17875    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17876
17877 ;; Convert epilogue deallocator to pop.
17878 (define_peephole2
17879   [(match_scratch:DI 0 "r")
17880    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17881               (clobber (reg:CC FLAGS_REG))
17882               (clobber (mem:BLK (scratch)))])]
17883   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17884   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17885               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17886               (clobber (mem:BLK (scratch)))])]
17887   "")
17888
17889 ;; Two pops case is tricky, since pop causes dependency on destination register.
17890 ;; We use two registers if available.
17891 (define_peephole2
17892   [(match_scratch:DI 0 "r")
17893    (match_scratch:DI 1 "r")
17894    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17895               (clobber (reg:CC FLAGS_REG))
17896               (clobber (mem:BLK (scratch)))])]
17897   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17898   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17899               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17900               (clobber (mem:BLK (scratch)))])
17901    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17902               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17903   "")
17904
17905 (define_peephole2
17906   [(match_scratch:DI 0 "r")
17907    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17908               (clobber (reg:CC FLAGS_REG))
17909               (clobber (mem:BLK (scratch)))])]
17910   "optimize_insn_for_size_p ()"
17911   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17912               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17913               (clobber (mem:BLK (scratch)))])
17914    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17915               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17916   "")
17917
17918 ;; Convert esp additions to pop.
17919 (define_peephole2
17920   [(match_scratch:DI 0 "r")
17921    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17922               (clobber (reg:CC FLAGS_REG))])]
17923   ""
17924   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17925               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17926   "")
17927
17928 ;; Two pops case is tricky, since pop causes dependency on destination register.
17929 ;; We use two registers if available.
17930 (define_peephole2
17931   [(match_scratch:DI 0 "r")
17932    (match_scratch:DI 1 "r")
17933    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17934               (clobber (reg:CC FLAGS_REG))])]
17935   ""
17936   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17937               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17938    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17939               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17940   "")
17941
17942 (define_peephole2
17943   [(match_scratch:DI 0 "r")
17944    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17945               (clobber (reg:CC FLAGS_REG))])]
17946   "optimize_insn_for_size_p ()"
17947   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17948               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17949    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17950               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17951   "")
17952 \f
17953 ;; Convert imul by three, five and nine into lea
17954 (define_peephole2
17955   [(parallel
17956     [(set (match_operand:SI 0 "register_operand" "")
17957           (mult:SI (match_operand:SI 1 "register_operand" "")
17958                    (match_operand:SI 2 "const_int_operand" "")))
17959      (clobber (reg:CC FLAGS_REG))])]
17960   "INTVAL (operands[2]) == 3
17961    || INTVAL (operands[2]) == 5
17962    || INTVAL (operands[2]) == 9"
17963   [(set (match_dup 0)
17964         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17965                  (match_dup 1)))]
17966   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17967
17968 (define_peephole2
17969   [(parallel
17970     [(set (match_operand:SI 0 "register_operand" "")
17971           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17972                    (match_operand:SI 2 "const_int_operand" "")))
17973      (clobber (reg:CC FLAGS_REG))])]
17974   "optimize_insn_for_speed_p ()
17975    && (INTVAL (operands[2]) == 3
17976        || INTVAL (operands[2]) == 5
17977        || INTVAL (operands[2]) == 9)"
17978   [(set (match_dup 0) (match_dup 1))
17979    (set (match_dup 0)
17980         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17981                  (match_dup 0)))]
17982   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17983
17984 (define_peephole2
17985   [(parallel
17986     [(set (match_operand:DI 0 "register_operand" "")
17987           (mult:DI (match_operand:DI 1 "register_operand" "")
17988                    (match_operand:DI 2 "const_int_operand" "")))
17989      (clobber (reg:CC FLAGS_REG))])]
17990   "TARGET_64BIT
17991    && (INTVAL (operands[2]) == 3
17992        || INTVAL (operands[2]) == 5
17993        || INTVAL (operands[2]) == 9)"
17994   [(set (match_dup 0)
17995         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17996                  (match_dup 1)))]
17997   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17998
17999 (define_peephole2
18000   [(parallel
18001     [(set (match_operand:DI 0 "register_operand" "")
18002           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18003                    (match_operand:DI 2 "const_int_operand" "")))
18004      (clobber (reg:CC FLAGS_REG))])]
18005   "TARGET_64BIT
18006    && optimize_insn_for_speed_p ()
18007    && (INTVAL (operands[2]) == 3
18008        || INTVAL (operands[2]) == 5
18009        || INTVAL (operands[2]) == 9)"
18010   [(set (match_dup 0) (match_dup 1))
18011    (set (match_dup 0)
18012         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18013                  (match_dup 0)))]
18014   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18015
18016 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18017 ;; imul $32bit_imm, reg, reg is direct decoded.
18018 (define_peephole2
18019   [(match_scratch:DI 3 "r")
18020    (parallel [(set (match_operand:DI 0 "register_operand" "")
18021                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18022                             (match_operand:DI 2 "immediate_operand" "")))
18023               (clobber (reg:CC FLAGS_REG))])]
18024   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18025    && !satisfies_constraint_K (operands[2])"
18026   [(set (match_dup 3) (match_dup 1))
18027    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18028               (clobber (reg:CC FLAGS_REG))])]
18029 "")
18030
18031 (define_peephole2
18032   [(match_scratch:SI 3 "r")
18033    (parallel [(set (match_operand:SI 0 "register_operand" "")
18034                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18035                             (match_operand:SI 2 "immediate_operand" "")))
18036               (clobber (reg:CC FLAGS_REG))])]
18037   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18038    && !satisfies_constraint_K (operands[2])"
18039   [(set (match_dup 3) (match_dup 1))
18040    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18041               (clobber (reg:CC FLAGS_REG))])]
18042 "")
18043
18044 (define_peephole2
18045   [(match_scratch:SI 3 "r")
18046    (parallel [(set (match_operand:DI 0 "register_operand" "")
18047                    (zero_extend:DI
18048                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18049                               (match_operand:SI 2 "immediate_operand" ""))))
18050               (clobber (reg:CC FLAGS_REG))])]
18051   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18052    && !satisfies_constraint_K (operands[2])"
18053   [(set (match_dup 3) (match_dup 1))
18054    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18055               (clobber (reg:CC FLAGS_REG))])]
18056 "")
18057
18058 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18059 ;; Convert it into imul reg, reg
18060 ;; It would be better to force assembler to encode instruction using long
18061 ;; immediate, but there is apparently no way to do so.
18062 (define_peephole2
18063   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18064                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18065                             (match_operand:DI 2 "const_int_operand" "")))
18066               (clobber (reg:CC FLAGS_REG))])
18067    (match_scratch:DI 3 "r")]
18068   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18069    && satisfies_constraint_K (operands[2])"
18070   [(set (match_dup 3) (match_dup 2))
18071    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18072               (clobber (reg:CC FLAGS_REG))])]
18073 {
18074   if (!rtx_equal_p (operands[0], operands[1]))
18075     emit_move_insn (operands[0], operands[1]);
18076 })
18077
18078 (define_peephole2
18079   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18080                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18081                             (match_operand:SI 2 "const_int_operand" "")))
18082               (clobber (reg:CC FLAGS_REG))])
18083    (match_scratch:SI 3 "r")]
18084   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18085    && satisfies_constraint_K (operands[2])"
18086   [(set (match_dup 3) (match_dup 2))
18087    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18088               (clobber (reg:CC FLAGS_REG))])]
18089 {
18090   if (!rtx_equal_p (operands[0], operands[1]))
18091     emit_move_insn (operands[0], operands[1]);
18092 })
18093
18094 (define_peephole2
18095   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18096                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18097                             (match_operand:HI 2 "immediate_operand" "")))
18098               (clobber (reg:CC FLAGS_REG))])
18099    (match_scratch:HI 3 "r")]
18100   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
18101   [(set (match_dup 3) (match_dup 2))
18102    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18103               (clobber (reg:CC FLAGS_REG))])]
18104 {
18105   if (!rtx_equal_p (operands[0], operands[1]))
18106     emit_move_insn (operands[0], operands[1]);
18107 })
18108
18109 ;; After splitting up read-modify operations, array accesses with memory
18110 ;; operands might end up in form:
18111 ;;  sall    $2, %eax
18112 ;;  movl    4(%esp), %edx
18113 ;;  addl    %edx, %eax
18114 ;; instead of pre-splitting:
18115 ;;  sall    $2, %eax
18116 ;;  addl    4(%esp), %eax
18117 ;; Turn it into:
18118 ;;  movl    4(%esp), %edx
18119 ;;  leal    (%edx,%eax,4), %eax
18120
18121 (define_peephole2
18122   [(parallel [(set (match_operand 0 "register_operand" "")
18123                    (ashift (match_operand 1 "register_operand" "")
18124                            (match_operand 2 "const_int_operand" "")))
18125                (clobber (reg:CC FLAGS_REG))])
18126    (set (match_operand 3 "register_operand")
18127         (match_operand 4 "x86_64_general_operand" ""))
18128    (parallel [(set (match_operand 5 "register_operand" "")
18129                    (plus (match_operand 6 "register_operand" "")
18130                          (match_operand 7 "register_operand" "")))
18131                    (clobber (reg:CC FLAGS_REG))])]
18132   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
18133    /* Validate MODE for lea.  */
18134    && ((!TARGET_PARTIAL_REG_STALL
18135         && (GET_MODE (operands[0]) == QImode
18136             || GET_MODE (operands[0]) == HImode))
18137        || GET_MODE (operands[0]) == SImode
18138        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18139    /* We reorder load and the shift.  */
18140    && !rtx_equal_p (operands[1], operands[3])
18141    && !reg_overlap_mentioned_p (operands[0], operands[4])
18142    /* Last PLUS must consist of operand 0 and 3.  */
18143    && !rtx_equal_p (operands[0], operands[3])
18144    && (rtx_equal_p (operands[3], operands[6])
18145        || rtx_equal_p (operands[3], operands[7]))
18146    && (rtx_equal_p (operands[0], operands[6])
18147        || rtx_equal_p (operands[0], operands[7]))
18148    /* The intermediate operand 0 must die or be same as output.  */
18149    && (rtx_equal_p (operands[0], operands[5])
18150        || peep2_reg_dead_p (3, operands[0]))"
18151   [(set (match_dup 3) (match_dup 4))
18152    (set (match_dup 0) (match_dup 1))]
18153 {
18154   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
18155   int scale = 1 << INTVAL (operands[2]);
18156   rtx index = gen_lowpart (Pmode, operands[1]);
18157   rtx base = gen_lowpart (Pmode, operands[3]);
18158   rtx dest = gen_lowpart (mode, operands[5]);
18159
18160   operands[1] = gen_rtx_PLUS (Pmode, base,
18161                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
18162   if (mode != Pmode)
18163     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18164   operands[0] = dest;
18165 })
18166 \f
18167 ;; Call-value patterns last so that the wildcard operand does not
18168 ;; disrupt insn-recog's switch tables.
18169
18170 (define_insn "*call_value_pop_0"
18171   [(set (match_operand 0 "" "")
18172         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18173               (match_operand:SI 2 "" "")))
18174    (set (reg:SI SP_REG)
18175         (plus:SI (reg:SI SP_REG)
18176                  (match_operand:SI 3 "immediate_operand" "")))]
18177   "!TARGET_64BIT"
18178 {
18179   if (SIBLING_CALL_P (insn))
18180     return "jmp\t%P1";
18181   else
18182     return "call\t%P1";
18183 }
18184   [(set_attr "type" "callv")])
18185
18186 (define_insn "*call_value_pop_1"
18187   [(set (match_operand 0 "" "")
18188         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18189               (match_operand:SI 2 "" "")))
18190    (set (reg:SI SP_REG)
18191         (plus:SI (reg:SI SP_REG)
18192                  (match_operand:SI 3 "immediate_operand" "i")))]
18193   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18194 {
18195   if (constant_call_address_operand (operands[1], Pmode))
18196     return "call\t%P1";
18197   return "call\t%A1";
18198 }
18199   [(set_attr "type" "callv")])
18200
18201 (define_insn "*sibcall_value_pop_1"
18202   [(set (match_operand 0 "" "")
18203         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18204               (match_operand:SI 2 "" "")))
18205    (set (reg:SI SP_REG)
18206         (plus:SI (reg:SI SP_REG)
18207                  (match_operand:SI 3 "immediate_operand" "i,i")))]
18208   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18209   "@
18210    jmp\t%P1
18211    jmp\t%A1"
18212   [(set_attr "type" "callv")])
18213
18214 (define_insn "*call_value_0"
18215   [(set (match_operand 0 "" "")
18216         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18217               (match_operand:SI 2 "" "")))]
18218   "!TARGET_64BIT"
18219 {
18220   if (SIBLING_CALL_P (insn))
18221     return "jmp\t%P1";
18222   else
18223     return "call\t%P1";
18224 }
18225   [(set_attr "type" "callv")])
18226
18227 (define_insn "*call_value_0_rex64"
18228   [(set (match_operand 0 "" "")
18229         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18230               (match_operand:DI 2 "const_int_operand" "")))]
18231   "TARGET_64BIT"
18232 {
18233   if (SIBLING_CALL_P (insn))
18234     return "jmp\t%P1";
18235   else
18236     return "call\t%P1";
18237 }
18238   [(set_attr "type" "callv")])
18239
18240 (define_insn "*call_value_0_rex64_ms_sysv"
18241   [(set (match_operand 0 "" "")
18242         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18243               (match_operand:DI 2 "const_int_operand" "")))
18244    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18245    (clobber (reg:TI XMM6_REG))
18246    (clobber (reg:TI XMM7_REG))
18247    (clobber (reg:TI XMM8_REG))
18248    (clobber (reg:TI XMM9_REG))
18249    (clobber (reg:TI XMM10_REG))
18250    (clobber (reg:TI XMM11_REG))
18251    (clobber (reg:TI XMM12_REG))
18252    (clobber (reg:TI XMM13_REG))
18253    (clobber (reg:TI XMM14_REG))
18254    (clobber (reg:TI XMM15_REG))
18255    (clobber (reg:DI SI_REG))
18256    (clobber (reg:DI DI_REG))]
18257   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18258 {
18259   if (SIBLING_CALL_P (insn))
18260     return "jmp\t%P1";
18261   else
18262     return "call\t%P1";
18263 }
18264   [(set_attr "type" "callv")])
18265
18266 (define_insn "*call_value_1"
18267   [(set (match_operand 0 "" "")
18268         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18269               (match_operand:SI 2 "" "")))]
18270   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18271 {
18272   if (constant_call_address_operand (operands[1], Pmode))
18273     return "call\t%P1";
18274   return "call\t%A1";
18275 }
18276   [(set_attr "type" "callv")])
18277
18278 (define_insn "*sibcall_value_1"
18279   [(set (match_operand 0 "" "")
18280         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18281               (match_operand:SI 2 "" "")))]
18282   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18283   "@
18284    jmp\t%P1
18285    jmp\t%A1"
18286   [(set_attr "type" "callv")])
18287
18288 (define_insn "*call_value_1_rex64"
18289   [(set (match_operand 0 "" "")
18290         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18291               (match_operand:DI 2 "" "")))]
18292   "TARGET_64BIT && !SIBLING_CALL_P (insn)
18293    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
18294 {
18295   if (constant_call_address_operand (operands[1], Pmode))
18296     return "call\t%P1";
18297   return "call\t%A1";
18298 }
18299   [(set_attr "type" "callv")])
18300
18301 (define_insn "*call_value_1_rex64_ms_sysv"
18302   [(set (match_operand 0 "" "")
18303         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18304               (match_operand:DI 2 "" "")))
18305    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18306    (clobber (reg:TI XMM6_REG))
18307    (clobber (reg:TI XMM7_REG))
18308    (clobber (reg:TI XMM8_REG))
18309    (clobber (reg:TI XMM9_REG))
18310    (clobber (reg:TI XMM10_REG))
18311    (clobber (reg:TI XMM11_REG))
18312    (clobber (reg:TI XMM12_REG))
18313    (clobber (reg:TI XMM13_REG))
18314    (clobber (reg:TI XMM14_REG))
18315    (clobber (reg:TI XMM15_REG))
18316    (clobber (reg:DI SI_REG))
18317    (clobber (reg:DI DI_REG))]
18318   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18319 {
18320   if (constant_call_address_operand (operands[1], Pmode))
18321     return "call\t%P1";
18322   return "call\t%A1";
18323 }
18324   [(set_attr "type" "callv")])
18325
18326 (define_insn "*call_value_1_rex64_large"
18327   [(set (match_operand 0 "" "")
18328         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18329               (match_operand:DI 2 "" "")))]
18330   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18331   "call\t%A1"
18332   [(set_attr "type" "callv")])
18333
18334 (define_insn "*sibcall_value_1_rex64"
18335   [(set (match_operand 0 "" "")
18336         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18337               (match_operand:DI 2 "" "")))]
18338   "TARGET_64BIT && SIBLING_CALL_P (insn)"
18339   "@
18340    jmp\t%P1
18341    jmp\t%A1"
18342   [(set_attr "type" "callv")])
18343 \f
18344 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18345 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18346 ;; caught for use by garbage collectors and the like.  Using an insn that
18347 ;; maps to SIGILL makes it more likely the program will rightfully die.
18348 ;; Keeping with tradition, "6" is in honor of #UD.
18349 (define_insn "trap"
18350   [(trap_if (const_int 1) (const_int 6))]
18351   ""
18352   { return ASM_SHORT "0x0b0f"; }
18353   [(set_attr "length" "2")])
18354
18355 (define_expand "sse_prologue_save"
18356   [(parallel [(set (match_operand:BLK 0 "" "")
18357                    (unspec:BLK [(reg:DI XMM0_REG)
18358                                 (reg:DI XMM1_REG)
18359                                 (reg:DI XMM2_REG)
18360                                 (reg:DI XMM3_REG)
18361                                 (reg:DI XMM4_REG)
18362                                 (reg:DI XMM5_REG)
18363                                 (reg:DI XMM6_REG)
18364                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18365               (clobber (reg:CC FLAGS_REG))
18366               (clobber (match_operand:DI 1 "register_operand" ""))
18367               (use (match_operand:DI 2 "immediate_operand" ""))
18368               (use (label_ref:DI (match_operand 3 "" "")))
18369               (clobber (match_operand:DI 4 "register_operand" ""))
18370               (use (match_dup 1))])]
18371   "TARGET_64BIT"
18372   "")
18373
18374 ;; Pre-reload version of prologue save.  Until after prologue generation we don't know
18375 ;; what the size of save instruction will be.
18376 ;; Operand 0+operand 6 is the memory save area
18377 ;; Operand 1 is number of registers to save (will get overwritten to operand 5)
18378 ;; Operand 2 is number of non-vaargs SSE arguments
18379 ;; Operand 3 is label starting the save block
18380 ;; Operand 4 is used for temporary computation of jump address
18381 (define_insn "*sse_prologue_save_insn1"
18382   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18383                           (match_operand:DI 6 "const_int_operand" "n")))
18384         (unspec:BLK [(reg:DI XMM0_REG)
18385                      (reg:DI XMM1_REG)
18386                      (reg:DI XMM2_REG)
18387                      (reg:DI XMM3_REG)
18388                      (reg:DI XMM4_REG)
18389                      (reg:DI XMM5_REG)
18390                      (reg:DI XMM6_REG)
18391                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18392    (clobber (reg:CC FLAGS_REG))
18393    (clobber (match_operand:DI 1 "register_operand" "=r"))
18394    (use (match_operand:DI 2 "const_int_operand" "i"))
18395    (use (label_ref:DI (match_operand 3 "" "X")))
18396    (clobber (match_operand:DI 4 "register_operand" "=&r"))
18397    (use (match_operand:DI 5 "register_operand" "1"))]
18398   "TARGET_64BIT
18399    && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18400    && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
18401   "#"
18402   [(set_attr "type" "other")
18403    (set_attr "memory" "store")
18404    (set_attr "mode" "DI")])
18405
18406 ;; We know size of save instruction; expand the computation of jump address
18407 ;; in the jumptable.
18408 (define_split
18409   [(parallel [(set (match_operand:BLK 0 "" "")
18410                     (unspec:BLK [(reg:DI XMM0_REG)
18411                                  (reg:DI XMM1_REG)
18412                                  (reg:DI XMM2_REG)
18413                                  (reg:DI XMM3_REG)
18414                                  (reg:DI XMM4_REG)
18415                                  (reg:DI XMM5_REG)
18416                                  (reg:DI XMM6_REG)
18417                                  (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18418                (clobber (reg:CC FLAGS_REG))
18419                (clobber (match_operand:DI 1 "register_operand" ""))
18420                (use (match_operand:DI 2 "const_int_operand" ""))
18421                (use (match_operand 3 "" ""))
18422                (clobber (match_operand:DI 4 "register_operand" ""))
18423                (use (match_operand:DI 5 "register_operand" ""))])]
18424   "reload_completed"
18425   [(parallel [(set (match_dup 0)
18426                    (unspec:BLK [(reg:DI XMM0_REG)
18427                                 (reg:DI XMM1_REG)
18428                                 (reg:DI XMM2_REG)
18429                                 (reg:DI XMM3_REG)
18430                                 (reg:DI XMM4_REG)
18431                                 (reg:DI XMM5_REG)
18432                                 (reg:DI XMM6_REG)
18433                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18434               (use (match_dup 1))
18435               (use (match_dup 2))
18436               (use (match_dup 3))
18437               (use (match_dup 5))])]
18438 {
18439   /* Movaps is 4 bytes, AVX and movsd is 5 bytes.  */
18440   int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
18441
18442   /* Compute address to jump to:
18443      label - eax*size + nnamed_sse_arguments*size. */
18444   if (size == 5)
18445     emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18446                             gen_rtx_PLUS
18447                               (Pmode,
18448                                gen_rtx_MULT (Pmode, operands[1],
18449                                              GEN_INT (4)),
18450                                operands[1])));
18451   else  if (size == 4)
18452     emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18453                             gen_rtx_MULT (Pmode, operands[1],
18454                                           GEN_INT (4))));
18455   else
18456     gcc_unreachable ();
18457   if (INTVAL (operands[2]))
18458     emit_move_insn
18459       (operands[1],
18460        gen_rtx_CONST (DImode,
18461                       gen_rtx_PLUS (DImode,
18462                                     operands[3],
18463                                     GEN_INT (INTVAL (operands[2])
18464                                              * size))));
18465   else
18466     emit_move_insn (operands[1], operands[3]);
18467   emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
18468   operands[5] = GEN_INT (size);
18469 })
18470
18471 (define_insn "sse_prologue_save_insn"
18472   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18473                           (match_operand:DI 4 "const_int_operand" "n")))
18474         (unspec:BLK [(reg:DI XMM0_REG)
18475                      (reg:DI XMM1_REG)
18476                      (reg:DI XMM2_REG)
18477                      (reg:DI XMM3_REG)
18478                      (reg:DI XMM4_REG)
18479                      (reg:DI XMM5_REG)
18480                      (reg:DI XMM6_REG)
18481                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18482    (use (match_operand:DI 1 "register_operand" "r"))
18483    (use (match_operand:DI 2 "const_int_operand" "i"))
18484    (use (label_ref:DI (match_operand 3 "" "X")))
18485    (use (match_operand:DI 5 "const_int_operand" "i"))]
18486   "TARGET_64BIT
18487    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18488    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18489 {
18490   int i;
18491   operands[0] = gen_rtx_MEM (Pmode,
18492                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18493   /* VEX instruction with a REX prefix will #UD.  */
18494   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18495     gcc_unreachable ();
18496
18497   output_asm_insn ("jmp\t%A1", operands);
18498   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18499     {
18500       operands[4] = adjust_address (operands[0], DImode, i*16);
18501       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18502       PUT_MODE (operands[4], TImode);
18503       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18504         output_asm_insn ("rex", operands);
18505       if (crtl->stack_alignment_needed < 128)
18506         output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
18507       else
18508         output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18509     }
18510   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18511                                      CODE_LABEL_NUMBER (operands[3]));
18512   return "";
18513 }
18514   [(set_attr "type" "other")
18515    (set_attr "length_immediate" "0")
18516    (set_attr "length_address" "0")
18517    ;; 2 bytes for jump and opernds[4] bytes for each save.
18518    (set (attr "length")
18519      (plus (const_int 2)
18520            (mult (symbol_ref ("INTVAL (operands[5])"))
18521                  (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
18522    (set_attr "memory" "store")
18523    (set_attr "modrm" "0")
18524    (set_attr "prefix" "maybe_vex")
18525    (set_attr "mode" "DI")])
18526
18527 (define_expand "prefetch"
18528   [(prefetch (match_operand 0 "address_operand" "")
18529              (match_operand:SI 1 "const_int_operand" "")
18530              (match_operand:SI 2 "const_int_operand" ""))]
18531   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18532 {
18533   int rw = INTVAL (operands[1]);
18534   int locality = INTVAL (operands[2]);
18535
18536   gcc_assert (rw == 0 || rw == 1);
18537   gcc_assert (locality >= 0 && locality <= 3);
18538   gcc_assert (GET_MODE (operands[0]) == Pmode
18539               || GET_MODE (operands[0]) == VOIDmode);
18540
18541   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18542      supported by SSE counterpart or the SSE prefetch is not available
18543      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18544      of locality.  */
18545   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18546     operands[2] = GEN_INT (3);
18547   else
18548     operands[1] = const0_rtx;
18549 })
18550
18551 (define_insn "*prefetch_sse"
18552   [(prefetch (match_operand:SI 0 "address_operand" "p")
18553              (const_int 0)
18554              (match_operand:SI 1 "const_int_operand" ""))]
18555   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18556 {
18557   static const char * const patterns[4] = {
18558    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18559   };
18560
18561   int locality = INTVAL (operands[1]);
18562   gcc_assert (locality >= 0 && locality <= 3);
18563
18564   return patterns[locality];
18565 }
18566   [(set_attr "type" "sse")
18567    (set_attr "atom_sse_attr" "prefetch")
18568    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18569    (set_attr "memory" "none")])
18570
18571 (define_insn "*prefetch_sse_rex"
18572   [(prefetch (match_operand:DI 0 "address_operand" "p")
18573              (const_int 0)
18574              (match_operand:SI 1 "const_int_operand" ""))]
18575   "TARGET_PREFETCH_SSE && TARGET_64BIT"
18576 {
18577   static const char * const patterns[4] = {
18578    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18579   };
18580
18581   int locality = INTVAL (operands[1]);
18582   gcc_assert (locality >= 0 && locality <= 3);
18583
18584   return patterns[locality];
18585 }
18586   [(set_attr "type" "sse")
18587    (set_attr "atom_sse_attr" "prefetch")
18588    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18589    (set_attr "memory" "none")])
18590
18591 (define_insn "*prefetch_3dnow"
18592   [(prefetch (match_operand:SI 0 "address_operand" "p")
18593              (match_operand:SI 1 "const_int_operand" "n")
18594              (const_int 3))]
18595   "TARGET_3DNOW && !TARGET_64BIT"
18596 {
18597   if (INTVAL (operands[1]) == 0)
18598     return "prefetch\t%a0";
18599   else
18600     return "prefetchw\t%a0";
18601 }
18602   [(set_attr "type" "mmx")
18603    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18604    (set_attr "memory" "none")])
18605
18606 (define_insn "*prefetch_3dnow_rex"
18607   [(prefetch (match_operand:DI 0 "address_operand" "p")
18608              (match_operand:SI 1 "const_int_operand" "n")
18609              (const_int 3))]
18610   "TARGET_3DNOW && TARGET_64BIT"
18611 {
18612   if (INTVAL (operands[1]) == 0)
18613     return "prefetch\t%a0";
18614   else
18615     return "prefetchw\t%a0";
18616 }
18617   [(set_attr "type" "mmx")
18618    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18619    (set_attr "memory" "none")])
18620
18621 (define_expand "stack_protect_set"
18622   [(match_operand 0 "memory_operand" "")
18623    (match_operand 1 "memory_operand" "")]
18624   ""
18625 {
18626 #ifdef TARGET_THREAD_SSP_OFFSET
18627   if (TARGET_64BIT)
18628     emit_insn (gen_stack_tls_protect_set_di (operands[0],
18629                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18630   else
18631     emit_insn (gen_stack_tls_protect_set_si (operands[0],
18632                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18633 #else
18634   if (TARGET_64BIT)
18635     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18636   else
18637     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18638 #endif
18639   DONE;
18640 })
18641
18642 (define_insn "stack_protect_set_si"
18643   [(set (match_operand:SI 0 "memory_operand" "=m")
18644         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18645    (set (match_scratch:SI 2 "=&r") (const_int 0))
18646    (clobber (reg:CC FLAGS_REG))]
18647   ""
18648   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18649   [(set_attr "type" "multi")])
18650
18651 (define_insn "stack_protect_set_di"
18652   [(set (match_operand:DI 0 "memory_operand" "=m")
18653         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18654    (set (match_scratch:DI 2 "=&r") (const_int 0))
18655    (clobber (reg:CC FLAGS_REG))]
18656   "TARGET_64BIT"
18657   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18658   [(set_attr "type" "multi")])
18659
18660 (define_insn "stack_tls_protect_set_si"
18661   [(set (match_operand:SI 0 "memory_operand" "=m")
18662         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18663    (set (match_scratch:SI 2 "=&r") (const_int 0))
18664    (clobber (reg:CC FLAGS_REG))]
18665   ""
18666   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18667   [(set_attr "type" "multi")])
18668
18669 (define_insn "stack_tls_protect_set_di"
18670   [(set (match_operand:DI 0 "memory_operand" "=m")
18671         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18672    (set (match_scratch:DI 2 "=&r") (const_int 0))
18673    (clobber (reg:CC FLAGS_REG))]
18674   "TARGET_64BIT"
18675   {
18676      /* The kernel uses a different segment register for performance reasons; a
18677         system call would not have to trash the userspace segment register,
18678         which would be expensive */
18679      if (ix86_cmodel != CM_KERNEL)
18680         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18681      else
18682         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18683   }
18684   [(set_attr "type" "multi")])
18685
18686 (define_expand "stack_protect_test"
18687   [(match_operand 0 "memory_operand" "")
18688    (match_operand 1 "memory_operand" "")
18689    (match_operand 2 "" "")]
18690   ""
18691 {
18692   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18693
18694 #ifdef TARGET_THREAD_SSP_OFFSET
18695   if (TARGET_64BIT)
18696     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18697                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18698   else
18699     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18700                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18701 #else
18702   if (TARGET_64BIT)
18703     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18704   else
18705     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18706 #endif
18707
18708   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18709                                   flags, const0_rtx, operands[2]));
18710   DONE;
18711 })
18712
18713 (define_insn "stack_protect_test_si"
18714   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18715         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18716                      (match_operand:SI 2 "memory_operand" "m")]
18717                     UNSPEC_SP_TEST))
18718    (clobber (match_scratch:SI 3 "=&r"))]
18719   ""
18720   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18721   [(set_attr "type" "multi")])
18722
18723 (define_insn "stack_protect_test_di"
18724   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18725         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18726                      (match_operand:DI 2 "memory_operand" "m")]
18727                     UNSPEC_SP_TEST))
18728    (clobber (match_scratch:DI 3 "=&r"))]
18729   "TARGET_64BIT"
18730   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18731   [(set_attr "type" "multi")])
18732
18733 (define_insn "stack_tls_protect_test_si"
18734   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18735         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18736                      (match_operand:SI 2 "const_int_operand" "i")]
18737                     UNSPEC_SP_TLS_TEST))
18738    (clobber (match_scratch:SI 3 "=r"))]
18739   ""
18740   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18741   [(set_attr "type" "multi")])
18742
18743 (define_insn "stack_tls_protect_test_di"
18744   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18745         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18746                      (match_operand:DI 2 "const_int_operand" "i")]
18747                     UNSPEC_SP_TLS_TEST))
18748    (clobber (match_scratch:DI 3 "=r"))]
18749   "TARGET_64BIT"
18750   {
18751      /* The kernel uses a different segment register for performance reasons; a
18752         system call would not have to trash the userspace segment register,
18753         which would be expensive */
18754      if (ix86_cmodel != CM_KERNEL)
18755         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18756      else
18757         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18758   }
18759   [(set_attr "type" "multi")])
18760
18761 (define_insn "sse4_2_crc32<mode>"
18762   [(set (match_operand:SI 0 "register_operand" "=r")
18763         (unspec:SI
18764           [(match_operand:SI 1 "register_operand" "0")
18765            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18766           UNSPEC_CRC32))]
18767   "TARGET_SSE4_2 || TARGET_CRC32"
18768   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18769   [(set_attr "type" "sselog1")
18770    (set_attr "prefix_rep" "1")
18771    (set_attr "prefix_extra" "1")
18772    (set (attr "prefix_data16")
18773      (if_then_else (match_operand:HI 2 "" "")
18774        (const_string "1")
18775        (const_string "*")))
18776    (set (attr "prefix_rex")
18777      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18778        (const_string "1")
18779        (const_string "*")))
18780    (set_attr "mode" "SI")])
18781
18782 (define_insn "sse4_2_crc32di"
18783   [(set (match_operand:DI 0 "register_operand" "=r")
18784         (unspec:DI
18785           [(match_operand:DI 1 "register_operand" "0")
18786            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18787           UNSPEC_CRC32))]
18788   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18789   "crc32{q}\t{%2, %0|%0, %2}"
18790   [(set_attr "type" "sselog1")
18791    (set_attr "prefix_rep" "1")
18792    (set_attr "prefix_extra" "1")
18793    (set_attr "mode" "DI")])
18794
18795 (define_expand "rdpmc"
18796   [(match_operand:DI 0 "register_operand" "")
18797    (match_operand:SI 1 "register_operand" "")]
18798   ""
18799 {
18800   rtx reg = gen_reg_rtx (DImode);
18801   rtx si;
18802
18803   /* Force operand 1 into ECX.  */
18804   rtx ecx = gen_rtx_REG (SImode, CX_REG);
18805   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18806   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18807                                 UNSPECV_RDPMC);
18808
18809   if (TARGET_64BIT)
18810     {
18811       rtvec vec = rtvec_alloc (2);
18812       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18813       rtx upper = gen_reg_rtx (DImode);
18814       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18815                                         gen_rtvec (1, const0_rtx),
18816                                         UNSPECV_RDPMC);
18817       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18818       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18819       emit_insn (load);
18820       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18821                                    NULL, 1, OPTAB_DIRECT);
18822       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18823                                  OPTAB_DIRECT);
18824     }
18825   else
18826     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18827   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18828   DONE;
18829 })
18830
18831 (define_insn "*rdpmc"
18832   [(set (match_operand:DI 0 "register_operand" "=A")
18833         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18834                             UNSPECV_RDPMC))]
18835   "!TARGET_64BIT"
18836   "rdpmc"
18837   [(set_attr "type" "other")
18838    (set_attr "length" "2")])
18839
18840 (define_insn "*rdpmc_rex64"
18841   [(set (match_operand:DI 0 "register_operand" "=a")
18842         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18843                             UNSPECV_RDPMC))
18844   (set (match_operand:DI 1 "register_operand" "=d")
18845        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18846   "TARGET_64BIT"
18847   "rdpmc"
18848   [(set_attr "type" "other")
18849    (set_attr "length" "2")])
18850
18851 (define_expand "rdtsc"
18852   [(set (match_operand:DI 0 "register_operand" "")
18853         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18854   ""
18855 {
18856   if (TARGET_64BIT)
18857     {
18858       rtvec vec = rtvec_alloc (2);
18859       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18860       rtx upper = gen_reg_rtx (DImode);
18861       rtx lower = gen_reg_rtx (DImode);
18862       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18863                                          gen_rtvec (1, const0_rtx),
18864                                          UNSPECV_RDTSC);
18865       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18866       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18867       emit_insn (load);
18868       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18869                                    NULL, 1, OPTAB_DIRECT);
18870       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18871                                    OPTAB_DIRECT);
18872       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18873       DONE;
18874     }
18875 })
18876
18877 (define_insn "*rdtsc"
18878   [(set (match_operand:DI 0 "register_operand" "=A")
18879         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18880   "!TARGET_64BIT"
18881   "rdtsc"
18882   [(set_attr "type" "other")
18883    (set_attr "length" "2")])
18884
18885 (define_insn "*rdtsc_rex64"
18886   [(set (match_operand:DI 0 "register_operand" "=a")
18887         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18888    (set (match_operand:DI 1 "register_operand" "=d")
18889         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18890   "TARGET_64BIT"
18891   "rdtsc"
18892   [(set_attr "type" "other")
18893    (set_attr "length" "2")])
18894
18895 (define_expand "rdtscp"
18896   [(match_operand:DI 0 "register_operand" "")
18897    (match_operand:SI 1 "memory_operand" "")]
18898   ""
18899 {
18900   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18901                                     gen_rtvec (1, const0_rtx),
18902                                     UNSPECV_RDTSCP);
18903   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18904                                     gen_rtvec (1, const0_rtx),
18905                                     UNSPECV_RDTSCP);
18906   rtx reg = gen_reg_rtx (DImode);
18907   rtx tmp = gen_reg_rtx (SImode);
18908
18909   if (TARGET_64BIT)
18910     {
18911       rtvec vec = rtvec_alloc (3);
18912       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18913       rtx upper = gen_reg_rtx (DImode);
18914       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18915       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18916       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18917       emit_insn (load);
18918       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18919                                    NULL, 1, OPTAB_DIRECT);
18920       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18921                                  OPTAB_DIRECT);
18922     }
18923   else
18924     {
18925       rtvec vec = rtvec_alloc (2);
18926       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18927       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18928       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18929       emit_insn (load);
18930     }
18931   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18932   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18933   DONE;
18934 })
18935
18936 (define_insn "*rdtscp"
18937   [(set (match_operand:DI 0 "register_operand" "=A")
18938         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18939    (set (match_operand:SI 1 "register_operand" "=c")
18940         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18941   "!TARGET_64BIT"
18942   "rdtscp"
18943   [(set_attr "type" "other")
18944    (set_attr "length" "3")])
18945
18946 (define_insn "*rdtscp_rex64"
18947   [(set (match_operand:DI 0 "register_operand" "=a")
18948         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18949    (set (match_operand:DI 1 "register_operand" "=d")
18950         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18951    (set (match_operand:SI 2 "register_operand" "=c")
18952         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18953   "TARGET_64BIT"
18954   "rdtscp"
18955   [(set_attr "type" "other")
18956    (set_attr "length" "3")])
18957
18958 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18959 ;;
18960 ;; LWP instructions
18961 ;;
18962 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18963
18964 (define_expand "lwp_llwpcb"
18965   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18966                     UNSPECV_LLWP_INTRINSIC)]
18967   "TARGET_LWP"
18968   "")
18969
18970 (define_insn "*lwp_llwpcb<mode>1"
18971   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18972                     UNSPECV_LLWP_INTRINSIC)]
18973   "TARGET_LWP"
18974   "llwpcb\t%0"
18975   [(set_attr "type" "lwp")
18976    (set_attr "mode" "<MODE>")
18977    (set_attr "length" "5")])
18978
18979 (define_expand "lwp_slwpcb"
18980   [(set (match_operand 0 "register_operand" "=r")
18981         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18982   "TARGET_LWP"
18983   {
18984     if (TARGET_64BIT)
18985       emit_insn (gen_lwp_slwpcbdi (operands[0]));
18986     else
18987       emit_insn (gen_lwp_slwpcbsi (operands[0]));
18988     DONE;
18989   })
18990
18991 (define_insn "lwp_slwpcb<mode>"
18992   [(set (match_operand:P 0 "register_operand" "=r")
18993         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18994   "TARGET_LWP"
18995   "slwpcb\t%0"
18996   [(set_attr "type" "lwp")
18997    (set_attr "mode" "<MODE>")
18998    (set_attr "length" "5")])
18999
19000 (define_expand "lwp_lwpval<mode>3"
19001   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
19002                      (match_operand:SI 2 "nonimmediate_operand" "rm")
19003                      (match_operand:SI 3 "const_int_operand" "i")]
19004                     UNSPECV_LWPVAL_INTRINSIC)]
19005   "TARGET_LWP"
19006   "/* Avoid unused variable warning.  */
19007    (void) operand0;")
19008
19009 (define_insn "*lwp_lwpval<mode>3_1"
19010   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19011                      (match_operand:SI 1 "nonimmediate_operand" "rm")
19012                      (match_operand:SI 2 "const_int_operand" "i")]
19013                     UNSPECV_LWPVAL_INTRINSIC)]
19014   "TARGET_LWP"
19015   "lwpval\t{%2, %1, %0|%0, %1, %2}"
19016   [(set_attr "type" "lwp")
19017    (set_attr "mode" "<MODE>")
19018    (set (attr "length")
19019         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19020
19021 (define_expand "lwp_lwpins<mode>3"
19022   [(set (reg:CCC FLAGS_REG)
19023         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
19024                               (match_operand:SI 2 "nonimmediate_operand" "rm")
19025                               (match_operand:SI 3 "const_int_operand" "i")]
19026                              UNSPECV_LWPINS_INTRINSIC))
19027    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19028         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19029   "TARGET_LWP"
19030   "")
19031
19032 (define_insn "*lwp_lwpins<mode>3_1"
19033   [(set (reg:CCC FLAGS_REG)
19034         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19035                               (match_operand:SI 1 "nonimmediate_operand" "rm")
19036                               (match_operand:SI 2 "const_int_operand" "i")]
19037                              UNSPECV_LWPINS_INTRINSIC))]
19038   "TARGET_LWP"
19039   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19040   [(set_attr "type" "lwp")
19041    (set_attr "mode" "<MODE>")
19042    (set (attr "length")
19043         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19044
19045 (include "mmx.md")
19046 (include "sse.md")
19047 (include "sync.md")