OSDN Git Service

* config/i386/i386.md: Use {} around multi-line preparation statements.
[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"
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           return "%vxorpd\t%0, %d0";
3117         case MODE_TI:
3118           return "%vpxor\t%0, %d0";
3119         default:
3120           gcc_unreachable ();
3121         }
3122     case 6:
3123     case 7:
3124     case 8:
3125       switch (get_attr_mode (insn))
3126         {
3127         case MODE_V4SF:
3128           return "%vmovaps\t{%1, %0|%0, %1}";
3129         case MODE_V2DF:
3130           return "%vmovapd\t{%1, %0|%0, %1}";
3131         case MODE_TI:
3132           return "%vmovdqa\t{%1, %0|%0, %1}";
3133         case MODE_DI:
3134           return "%vmovq\t{%1, %0|%0, %1}";
3135         case MODE_DF:
3136           if (TARGET_AVX)
3137             {
3138               if (REG_P (operands[0]) && REG_P (operands[1]))
3139                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3140               else
3141                 return "vmovsd\t{%1, %0|%0, %1}";
3142             }
3143           else
3144             return "movsd\t{%1, %0|%0, %1}";
3145         case MODE_V1DF:
3146           if (TARGET_AVX)
3147             {
3148               if (REG_P (operands[0]))
3149                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3150               else
3151                 return "vmovlpd\t{%1, %0|%0, %1}";
3152             }
3153           else
3154             return "movlpd\t{%1, %0|%0, %1}";
3155         case MODE_V2SF:
3156           if (TARGET_AVX)
3157             {
3158               if (REG_P (operands[0]))
3159                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3160               else
3161                 return "vmovlps\t{%1, %0|%0, %1}";
3162             }
3163           else
3164             return "movlps\t{%1, %0|%0, %1}";
3165         default:
3166           gcc_unreachable ();
3167         }
3168
3169     default:
3170       gcc_unreachable ();
3171     }
3172 }
3173   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3174    (set (attr "prefix")
3175      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3176        (const_string "orig")
3177        (const_string "maybe_vex")))
3178    (set (attr "prefix_data16")
3179      (if_then_else (eq_attr "mode" "V1DF")
3180        (const_string "1")
3181        (const_string "*")))
3182    (set (attr "mode")
3183         (cond [(eq_attr "alternative" "0,1,2")
3184                  (const_string "DF")
3185                (eq_attr "alternative" "3,4")
3186                  (const_string "SI")
3187
3188                /* For SSE1, we have many fewer alternatives.  */
3189                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3190                  (cond [(eq_attr "alternative" "5,6")
3191                           (const_string "V4SF")
3192                        ]
3193                    (const_string "V2SF"))
3194
3195                /* xorps is one byte shorter.  */
3196                (eq_attr "alternative" "5")
3197                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3198                             (const_int 0))
3199                           (const_string "V4SF")
3200                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3201                             (const_int 0))
3202                           (const_string "TI")
3203                        ]
3204                        (const_string "V2DF"))
3205
3206                /* For architectures resolving dependencies on
3207                   whole SSE registers use APD move to break dependency
3208                   chains, otherwise use short move to avoid extra work.
3209
3210                   movaps encodes one byte shorter.  */
3211                (eq_attr "alternative" "6")
3212                  (cond
3213                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3214                         (const_int 0))
3215                       (const_string "V4SF")
3216                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3217                         (const_int 0))
3218                       (const_string "V2DF")
3219                    ]
3220                    (const_string "DF"))
3221                /* For architectures resolving dependencies on register
3222                   parts we may avoid extra work to zero out upper part
3223                   of register.  */
3224                (eq_attr "alternative" "7")
3225                  (if_then_else
3226                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3227                        (const_int 0))
3228                    (const_string "V1DF")
3229                    (const_string "DF"))
3230               ]
3231               (const_string "DF")))])
3232
3233 (define_insn "*movdf_integer_rex64"
3234   [(set (match_operand:DF 0 "nonimmediate_operand"
3235                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3236         (match_operand:DF 1 "general_operand"
3237                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3238   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3239    && (reload_in_progress || reload_completed
3240        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3241        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3242            && optimize_function_for_size_p (cfun)
3243            && standard_80387_constant_p (operands[1]))
3244        || GET_CODE (operands[1]) != CONST_DOUBLE
3245        || memory_operand (operands[0], DFmode))"
3246 {
3247   switch (which_alternative)
3248     {
3249     case 0:
3250     case 1:
3251       return output_387_reg_move (insn, operands);
3252
3253     case 2:
3254       return standard_80387_constant_opcode (operands[1]);
3255
3256     case 3:
3257     case 4:
3258       return "#";
3259
3260     case 5:
3261       switch (get_attr_mode (insn))
3262         {
3263         case MODE_V4SF:
3264           return "%vxorps\t%0, %d0";
3265         case MODE_V2DF:
3266           return "%vxorpd\t%0, %d0";
3267         case MODE_TI:
3268           return "%vpxor\t%0, %d0";
3269         default:
3270           gcc_unreachable ();
3271         }
3272     case 6:
3273     case 7:
3274     case 8:
3275       switch (get_attr_mode (insn))
3276         {
3277         case MODE_V4SF:
3278           return "%vmovaps\t{%1, %0|%0, %1}";
3279         case MODE_V2DF:
3280           return "%vmovapd\t{%1, %0|%0, %1}";
3281         case MODE_TI:
3282           return "%vmovdqa\t{%1, %0|%0, %1}";
3283         case MODE_DI:
3284           return "%vmovq\t{%1, %0|%0, %1}";
3285         case MODE_DF:
3286           if (TARGET_AVX)
3287             {
3288               if (REG_P (operands[0]) && REG_P (operands[1]))
3289                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3290               else
3291                 return "vmovsd\t{%1, %0|%0, %1}";
3292             }
3293           else
3294             return "movsd\t{%1, %0|%0, %1}";
3295         case MODE_V1DF:
3296           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3297         case MODE_V2SF:
3298           return "%vmovlps\t{%1, %d0|%d0, %1}";
3299         default:
3300           gcc_unreachable ();
3301         }
3302
3303     case 9:
3304     case 10:
3305     return "%vmovd\t{%1, %0|%0, %1}";
3306
3307     default:
3308       gcc_unreachable();
3309     }
3310 }
3311   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3312    (set (attr "prefix")
3313      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3314        (const_string "orig")
3315        (const_string "maybe_vex")))
3316    (set (attr "prefix_data16")
3317      (if_then_else (eq_attr "mode" "V1DF")
3318        (const_string "1")
3319        (const_string "*")))
3320    (set (attr "mode")
3321         (cond [(eq_attr "alternative" "0,1,2")
3322                  (const_string "DF")
3323                (eq_attr "alternative" "3,4,9,10")
3324                  (const_string "DI")
3325
3326                /* For SSE1, we have many fewer alternatives.  */
3327                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3328                  (cond [(eq_attr "alternative" "5,6")
3329                           (const_string "V4SF")
3330                        ]
3331                    (const_string "V2SF"))
3332
3333                /* xorps is one byte shorter.  */
3334                (eq_attr "alternative" "5")
3335                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3336                             (const_int 0))
3337                           (const_string "V4SF")
3338                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3339                             (const_int 0))
3340                           (const_string "TI")
3341                        ]
3342                        (const_string "V2DF"))
3343
3344                /* For architectures resolving dependencies on
3345                   whole SSE registers use APD move to break dependency
3346                   chains, otherwise use short move to avoid extra work.
3347
3348                   movaps encodes one byte shorter.  */
3349                (eq_attr "alternative" "6")
3350                  (cond
3351                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3352                         (const_int 0))
3353                       (const_string "V4SF")
3354                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3355                         (const_int 0))
3356                       (const_string "V2DF")
3357                    ]
3358                    (const_string "DF"))
3359                /* For architectures resolving dependencies on register
3360                   parts we may avoid extra work to zero out upper part
3361                   of register.  */
3362                (eq_attr "alternative" "7")
3363                  (if_then_else
3364                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3365                        (const_int 0))
3366                    (const_string "V1DF")
3367                    (const_string "DF"))
3368               ]
3369               (const_string "DF")))])
3370
3371 (define_insn "*movdf_integer"
3372   [(set (match_operand:DF 0 "nonimmediate_operand"
3373                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3374         (match_operand:DF 1 "general_operand"
3375                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3376   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3377    && optimize_function_for_speed_p (cfun)
3378    && TARGET_INTEGER_DFMODE_MOVES
3379    && (reload_in_progress || reload_completed
3380        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3381        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3382            && optimize_function_for_size_p (cfun)
3383            && standard_80387_constant_p (operands[1]))
3384        || GET_CODE (operands[1]) != CONST_DOUBLE
3385        || memory_operand (operands[0], DFmode))"
3386 {
3387   switch (which_alternative)
3388     {
3389     case 0:
3390     case 1:
3391       return output_387_reg_move (insn, operands);
3392
3393     case 2:
3394       return standard_80387_constant_opcode (operands[1]);
3395
3396     case 3:
3397     case 4:
3398       return "#";
3399
3400     case 5:
3401       switch (get_attr_mode (insn))
3402         {
3403         case MODE_V4SF:
3404           return "xorps\t%0, %0";
3405         case MODE_V2DF:
3406           return "xorpd\t%0, %0";
3407         case MODE_TI:
3408           return "pxor\t%0, %0";
3409         default:
3410           gcc_unreachable ();
3411         }
3412     case 6:
3413     case 7:
3414     case 8:
3415       switch (get_attr_mode (insn))
3416         {
3417         case MODE_V4SF:
3418           return "movaps\t{%1, %0|%0, %1}";
3419         case MODE_V2DF:
3420           return "movapd\t{%1, %0|%0, %1}";
3421         case MODE_TI:
3422           return "movdqa\t{%1, %0|%0, %1}";
3423         case MODE_DI:
3424           return "movq\t{%1, %0|%0, %1}";
3425         case MODE_DF:
3426           return "movsd\t{%1, %0|%0, %1}";
3427         case MODE_V1DF:
3428           return "movlpd\t{%1, %0|%0, %1}";
3429         case MODE_V2SF:
3430           return "movlps\t{%1, %0|%0, %1}";
3431         default:
3432           gcc_unreachable ();
3433         }
3434
3435     default:
3436       gcc_unreachable();
3437     }
3438 }
3439   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3440    (set (attr "prefix_data16")
3441      (if_then_else (eq_attr "mode" "V1DF")
3442        (const_string "1")
3443        (const_string "*")))
3444    (set (attr "mode")
3445         (cond [(eq_attr "alternative" "0,1,2")
3446                  (const_string "DF")
3447                (eq_attr "alternative" "3,4")
3448                  (const_string "SI")
3449
3450                /* For SSE1, we have many fewer alternatives.  */
3451                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3452                  (cond [(eq_attr "alternative" "5,6")
3453                           (const_string "V4SF")
3454                        ]
3455                    (const_string "V2SF"))
3456
3457                /* xorps is one byte shorter.  */
3458                (eq_attr "alternative" "5")
3459                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3460                             (const_int 0))
3461                           (const_string "V4SF")
3462                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3463                             (const_int 0))
3464                           (const_string "TI")
3465                        ]
3466                        (const_string "V2DF"))
3467
3468                /* For architectures resolving dependencies on
3469                   whole SSE registers use APD move to break dependency
3470                   chains, otherwise use short move to avoid extra work.
3471
3472                   movaps encodes one byte shorter.  */
3473                (eq_attr "alternative" "6")
3474                  (cond
3475                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3476                         (const_int 0))
3477                       (const_string "V4SF")
3478                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3479                         (const_int 0))
3480                       (const_string "V2DF")
3481                    ]
3482                    (const_string "DF"))
3483                /* For architectures resolving dependencies on register
3484                   parts we may avoid extra work to zero out upper part
3485                   of register.  */
3486                (eq_attr "alternative" "7")
3487                  (if_then_else
3488                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3489                        (const_int 0))
3490                    (const_string "V1DF")
3491                    (const_string "DF"))
3492               ]
3493               (const_string "DF")))])
3494
3495 (define_split
3496   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3497         (match_operand:DF 1 "general_operand" ""))]
3498   "reload_completed
3499    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3500    && ! (ANY_FP_REG_P (operands[0]) ||
3501          (GET_CODE (operands[0]) == SUBREG
3502           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3503    && ! (ANY_FP_REG_P (operands[1]) ||
3504          (GET_CODE (operands[1]) == SUBREG
3505           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3506   [(const_int 0)]
3507   "ix86_split_long_move (operands); DONE;")
3508
3509 (define_insn "*swapdf"
3510   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3511         (match_operand:DF 1 "fp_register_operand" "+f"))
3512    (set (match_dup 1)
3513         (match_dup 0))]
3514   "reload_completed || TARGET_80387"
3515 {
3516   if (STACK_TOP_P (operands[0]))
3517     return "fxch\t%1";
3518   else
3519     return "fxch\t%0";
3520 }
3521   [(set_attr "type" "fxch")
3522    (set_attr "mode" "DF")])
3523
3524 (define_expand "movxf"
3525   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3526         (match_operand:XF 1 "general_operand" ""))]
3527   ""
3528   "ix86_expand_move (XFmode, operands); DONE;")
3529
3530 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3531 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3532 ;; Pushing using integer instructions is longer except for constants
3533 ;; and direct memory references.
3534 ;; (assuming that any given constant is pushed only once, but this ought to be
3535 ;;  handled elsewhere).
3536
3537 (define_insn "*pushxf_nointeger"
3538   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3539         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3540   "optimize_function_for_size_p (cfun)"
3541 {
3542   /* This insn should be already split before reg-stack.  */
3543   gcc_unreachable ();
3544 }
3545   [(set_attr "type" "multi")
3546    (set_attr "unit" "i387,*,*")
3547    (set_attr "mode" "XF,SI,SI")])
3548
3549 (define_insn "*pushxf_integer"
3550   [(set (match_operand:XF 0 "push_operand" "=<,<")
3551         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3552   "optimize_function_for_speed_p (cfun)"
3553 {
3554   /* This insn should be already split before reg-stack.  */
3555   gcc_unreachable ();
3556 }
3557   [(set_attr "type" "multi")
3558    (set_attr "unit" "i387,*")
3559    (set_attr "mode" "XF,SI")])
3560
3561 (define_split
3562   [(set (match_operand 0 "push_operand" "")
3563         (match_operand 1 "general_operand" ""))]
3564   "reload_completed
3565    && (GET_MODE (operands[0]) == XFmode
3566        || GET_MODE (operands[0]) == DFmode)
3567    && !ANY_FP_REG_P (operands[1])"
3568   [(const_int 0)]
3569   "ix86_split_long_move (operands); DONE;")
3570
3571 (define_split
3572   [(set (match_operand:XF 0 "push_operand" "")
3573         (match_operand:XF 1 "any_fp_register_operand" ""))]
3574   ""
3575   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3576    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3577   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3578
3579 ;; Do not use integer registers when optimizing for size
3580 (define_insn "*movxf_nointeger"
3581   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3582         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3583   "optimize_function_for_size_p (cfun)
3584    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3585    && (reload_in_progress || reload_completed
3586        || standard_80387_constant_p (operands[1])
3587        || GET_CODE (operands[1]) != CONST_DOUBLE
3588        || memory_operand (operands[0], XFmode))"
3589 {
3590   switch (which_alternative)
3591     {
3592     case 0:
3593     case 1:
3594       return output_387_reg_move (insn, operands);
3595
3596     case 2:
3597       return standard_80387_constant_opcode (operands[1]);
3598
3599     case 3: case 4:
3600       return "#";
3601     default:
3602       gcc_unreachable ();
3603     }
3604 }
3605   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3606    (set_attr "mode" "XF,XF,XF,SI,SI")])
3607
3608 (define_insn "*movxf_integer"
3609   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3610         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3611   "optimize_function_for_speed_p (cfun)
3612    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3613    && (reload_in_progress || reload_completed
3614        || GET_CODE (operands[1]) != CONST_DOUBLE
3615        || memory_operand (operands[0], XFmode))"
3616 {
3617   switch (which_alternative)
3618     {
3619     case 0:
3620     case 1:
3621       return output_387_reg_move (insn, operands);
3622
3623     case 2:
3624       return standard_80387_constant_opcode (operands[1]);
3625
3626     case 3: case 4:
3627       return "#";
3628
3629     default:
3630       gcc_unreachable ();
3631     }
3632 }
3633   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3634    (set_attr "mode" "XF,XF,XF,SI,SI")])
3635
3636 (define_expand "movtf"
3637   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3638         (match_operand:TF 1 "nonimmediate_operand" ""))]
3639   "TARGET_SSE2"
3640 {
3641   ix86_expand_move (TFmode, operands);
3642   DONE;
3643 })
3644
3645 (define_insn "*movtf_internal"
3646   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3647         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3648   "TARGET_SSE2
3649    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3650 {
3651   switch (which_alternative)
3652     {
3653     case 0:
3654     case 1:
3655       if (get_attr_mode (insn) == MODE_V4SF)
3656         return "%vmovaps\t{%1, %0|%0, %1}";
3657       else
3658         return "%vmovdqa\t{%1, %0|%0, %1}";
3659     case 2:
3660       if (get_attr_mode (insn) == MODE_V4SF)
3661         return "%vxorps\t%0, %d0";
3662       else
3663         return "%vpxor\t%0, %d0";
3664     case 3:
3665     case 4:
3666         return "#";
3667     default:
3668       gcc_unreachable ();
3669     }
3670 }
3671   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3672    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3673    (set (attr "mode")
3674         (cond [(eq_attr "alternative" "0,2")
3675                  (if_then_else
3676                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3677                        (const_int 0))
3678                    (const_string "V4SF")
3679                    (const_string "TI"))
3680                (eq_attr "alternative" "1")
3681                  (if_then_else
3682                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3683                             (const_int 0))
3684                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3685                             (const_int 0)))
3686                    (const_string "V4SF")
3687                    (const_string "TI"))]
3688                (const_string "DI")))])
3689
3690 (define_insn "*pushtf_sse"
3691   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3692         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3693   "TARGET_SSE2"
3694 {
3695   /* This insn should be already split before reg-stack.  */
3696   gcc_unreachable ();
3697 }
3698   [(set_attr "type" "multi")
3699    (set_attr "unit" "sse,*,*")
3700    (set_attr "mode" "TF,SI,SI")])
3701
3702 (define_split
3703   [(set (match_operand:TF 0 "push_operand" "")
3704         (match_operand:TF 1 "general_operand" ""))]
3705   "TARGET_SSE2 && reload_completed
3706    && !SSE_REG_P (operands[1])"
3707   [(const_int 0)]
3708   "ix86_split_long_move (operands); DONE;")
3709
3710 (define_split
3711   [(set (match_operand:TF 0 "push_operand" "")
3712         (match_operand:TF 1 "any_fp_register_operand" ""))]
3713   "TARGET_SSE2"
3714   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3715    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3716   "")
3717
3718 (define_split
3719   [(set (match_operand 0 "nonimmediate_operand" "")
3720         (match_operand 1 "general_operand" ""))]
3721   "reload_completed
3722    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3723    && GET_MODE (operands[0]) == XFmode
3724    && ! (ANY_FP_REG_P (operands[0]) ||
3725          (GET_CODE (operands[0]) == SUBREG
3726           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3727    && ! (ANY_FP_REG_P (operands[1]) ||
3728          (GET_CODE (operands[1]) == SUBREG
3729           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3730   [(const_int 0)]
3731   "ix86_split_long_move (operands); DONE;")
3732
3733 (define_split
3734   [(set (match_operand 0 "register_operand" "")
3735         (match_operand 1 "memory_operand" ""))]
3736   "reload_completed
3737    && MEM_P (operands[1])
3738    && (GET_MODE (operands[0]) == TFmode
3739        || GET_MODE (operands[0]) == XFmode
3740        || GET_MODE (operands[0]) == SFmode
3741        || GET_MODE (operands[0]) == DFmode)
3742    && (operands[2] = find_constant_src (insn))"
3743   [(set (match_dup 0) (match_dup 2))]
3744 {
3745   rtx c = operands[2];
3746   rtx r = operands[0];
3747
3748   if (GET_CODE (r) == SUBREG)
3749     r = SUBREG_REG (r);
3750
3751   if (SSE_REG_P (r))
3752     {
3753       if (!standard_sse_constant_p (c))
3754         FAIL;
3755     }
3756   else if (FP_REG_P (r))
3757     {
3758       if (!standard_80387_constant_p (c))
3759         FAIL;
3760     }
3761   else if (MMX_REG_P (r))
3762     FAIL;
3763 })
3764
3765 (define_split
3766   [(set (match_operand 0 "register_operand" "")
3767         (float_extend (match_operand 1 "memory_operand" "")))]
3768   "reload_completed
3769    && MEM_P (operands[1])
3770    && (GET_MODE (operands[0]) == TFmode
3771        || GET_MODE (operands[0]) == XFmode
3772        || GET_MODE (operands[0]) == SFmode
3773        || GET_MODE (operands[0]) == DFmode)
3774    && (operands[2] = find_constant_src (insn))"
3775   [(set (match_dup 0) (match_dup 2))]
3776 {
3777   rtx c = operands[2];
3778   rtx r = operands[0];
3779
3780   if (GET_CODE (r) == SUBREG)
3781     r = SUBREG_REG (r);
3782
3783   if (SSE_REG_P (r))
3784     {
3785       if (!standard_sse_constant_p (c))
3786         FAIL;
3787     }
3788   else if (FP_REG_P (r))
3789     {
3790       if (!standard_80387_constant_p (c))
3791         FAIL;
3792     }
3793   else if (MMX_REG_P (r))
3794     FAIL;
3795 })
3796
3797 (define_insn "swapxf"
3798   [(set (match_operand:XF 0 "register_operand" "+f")
3799         (match_operand:XF 1 "register_operand" "+f"))
3800    (set (match_dup 1)
3801         (match_dup 0))]
3802   "TARGET_80387"
3803 {
3804   if (STACK_TOP_P (operands[0]))
3805     return "fxch\t%1";
3806   else
3807     return "fxch\t%0";
3808 }
3809   [(set_attr "type" "fxch")
3810    (set_attr "mode" "XF")])
3811
3812 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3813 (define_split
3814   [(set (match_operand:X87MODEF 0 "register_operand" "")
3815         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3816   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3817    && (standard_80387_constant_p (operands[1]) == 8
3818        || standard_80387_constant_p (operands[1]) == 9)"
3819   [(set (match_dup 0)(match_dup 1))
3820    (set (match_dup 0)
3821         (neg:X87MODEF (match_dup 0)))]
3822 {
3823   REAL_VALUE_TYPE r;
3824
3825   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3826   if (real_isnegzero (&r))
3827     operands[1] = CONST0_RTX (<MODE>mode);
3828   else
3829     operands[1] = CONST1_RTX (<MODE>mode);
3830 })
3831
3832 (define_split
3833   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3834         (match_operand:TF 1 "general_operand" ""))]
3835   "reload_completed
3836    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3837   [(const_int 0)]
3838   "ix86_split_long_move (operands); DONE;")
3839 \f
3840 ;; Zero extension instructions
3841
3842 (define_expand "zero_extendhisi2"
3843   [(set (match_operand:SI 0 "register_operand" "")
3844      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3845   ""
3846 {
3847   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3848     {
3849       operands[1] = force_reg (HImode, operands[1]);
3850       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3851       DONE;
3852     }
3853 })
3854
3855 (define_insn "zero_extendhisi2_and"
3856   [(set (match_operand:SI 0 "register_operand" "=r")
3857      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3858    (clobber (reg:CC FLAGS_REG))]
3859   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3860   "#"
3861   [(set_attr "type" "alu1")
3862    (set_attr "mode" "SI")])
3863
3864 (define_split
3865   [(set (match_operand:SI 0 "register_operand" "")
3866         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3867    (clobber (reg:CC FLAGS_REG))]
3868   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3869    && optimize_function_for_speed_p (cfun)"
3870   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3871               (clobber (reg:CC FLAGS_REG))])]
3872   "")
3873
3874 (define_insn "*zero_extendhisi2_movzwl"
3875   [(set (match_operand:SI 0 "register_operand" "=r")
3876      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3877   "!TARGET_ZERO_EXTEND_WITH_AND
3878    || optimize_function_for_size_p (cfun)"
3879   "movz{wl|x}\t{%1, %0|%0, %1}"
3880   [(set_attr "type" "imovx")
3881    (set_attr "mode" "SI")])
3882
3883 (define_expand "zero_extendqihi2"
3884   [(parallel
3885     [(set (match_operand:HI 0 "register_operand" "")
3886        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3887      (clobber (reg:CC FLAGS_REG))])]
3888   ""
3889   "")
3890
3891 (define_insn "*zero_extendqihi2_and"
3892   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3893      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
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" "HI")])
3899
3900 (define_insn "*zero_extendqihi2_movzbw_and"
3901   [(set (match_operand:HI 0 "register_operand" "=r,r")
3902      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3903    (clobber (reg:CC FLAGS_REG))]
3904   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3905   "#"
3906   [(set_attr "type" "imovx,alu1")
3907    (set_attr "mode" "HI")])
3908
3909 ; zero extend to SImode here to avoid partial register stalls
3910 (define_insn "*zero_extendqihi2_movzbl"
3911   [(set (match_operand:HI 0 "register_operand" "=r")
3912      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3913   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3914    && reload_completed"
3915   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3916   [(set_attr "type" "imovx")
3917    (set_attr "mode" "SI")])
3918
3919 ;; For the movzbw case strip only the clobber
3920 (define_split
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   "reload_completed
3925    && (!TARGET_ZERO_EXTEND_WITH_AND
3926        || optimize_function_for_size_p (cfun))
3927    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3928   [(set (match_operand:HI 0 "register_operand" "")
3929         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3930
3931 ;; When source and destination does not overlap, clear destination
3932 ;; first and then do the movb
3933 (define_split
3934   [(set (match_operand:HI 0 "register_operand" "")
3935         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3936    (clobber (reg:CC FLAGS_REG))]
3937   "reload_completed
3938    && ANY_QI_REG_P (operands[0])
3939    && (TARGET_ZERO_EXTEND_WITH_AND
3940        && optimize_function_for_speed_p (cfun))
3941    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3942   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3943 {
3944   operands[2] = gen_lowpart (QImode, operands[0]);
3945   ix86_expand_clear (operands[0]);
3946 })
3947
3948 ;; Rest is handled by single and.
3949 (define_split
3950   [(set (match_operand:HI 0 "register_operand" "")
3951         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3952    (clobber (reg:CC FLAGS_REG))]
3953   "reload_completed
3954    && true_regnum (operands[0]) == true_regnum (operands[1])"
3955   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3956               (clobber (reg:CC FLAGS_REG))])]
3957   "")
3958
3959 (define_expand "zero_extendqisi2"
3960   [(parallel
3961     [(set (match_operand:SI 0 "register_operand" "")
3962        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3963      (clobber (reg:CC FLAGS_REG))])]
3964   ""
3965   "")
3966
3967 (define_insn "*zero_extendqisi2_and"
3968   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3969      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3970    (clobber (reg:CC FLAGS_REG))]
3971   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3972   "#"
3973   [(set_attr "type" "alu1")
3974    (set_attr "mode" "SI")])
3975
3976 (define_insn "*zero_extendqisi2_movzbl_and"
3977   [(set (match_operand:SI 0 "register_operand" "=r,r")
3978      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3979    (clobber (reg:CC FLAGS_REG))]
3980   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3981   "#"
3982   [(set_attr "type" "imovx,alu1")
3983    (set_attr "mode" "SI")])
3984
3985 (define_insn "*zero_extendqisi2_movzbl"
3986   [(set (match_operand:SI 0 "register_operand" "=r")
3987      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3988   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3989    && reload_completed"
3990   "movz{bl|x}\t{%1, %0|%0, %1}"
3991   [(set_attr "type" "imovx")
3992    (set_attr "mode" "SI")])
3993
3994 ;; For the movzbl case strip only the clobber
3995 (define_split
3996   [(set (match_operand:SI 0 "register_operand" "")
3997         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3998    (clobber (reg:CC FLAGS_REG))]
3999   "reload_completed
4000    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4001    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4002   [(set (match_dup 0)
4003         (zero_extend:SI (match_dup 1)))])
4004
4005 ;; When source and destination does not overlap, clear destination
4006 ;; first and then do the movb
4007 (define_split
4008   [(set (match_operand:SI 0 "register_operand" "")
4009         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4010    (clobber (reg:CC FLAGS_REG))]
4011   "reload_completed
4012    && ANY_QI_REG_P (operands[0])
4013    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4014    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4015    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4016   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4017 {
4018   operands[2] = gen_lowpart (QImode, operands[0]);
4019   ix86_expand_clear (operands[0]);
4020 })
4021
4022 ;; Rest is handled by single and.
4023 (define_split
4024   [(set (match_operand:SI 0 "register_operand" "")
4025         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4026    (clobber (reg:CC FLAGS_REG))]
4027   "reload_completed
4028    && true_regnum (operands[0]) == true_regnum (operands[1])"
4029   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4030               (clobber (reg:CC FLAGS_REG))])]
4031   "")
4032
4033 ;; %%% Kill me once multi-word ops are sane.
4034 (define_expand "zero_extendsidi2"
4035   [(set (match_operand:DI 0 "register_operand" "")
4036      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4037   ""
4038 {
4039   if (!TARGET_64BIT)
4040     {
4041       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4042       DONE;
4043     }
4044 })
4045
4046 (define_insn "zero_extendsidi2_32"
4047   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4048         (zero_extend:DI
4049          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4050    (clobber (reg:CC FLAGS_REG))]
4051   "!TARGET_64BIT"
4052   "@
4053    #
4054    #
4055    #
4056    movd\t{%1, %0|%0, %1}
4057    movd\t{%1, %0|%0, %1}
4058    %vmovd\t{%1, %0|%0, %1}
4059    %vmovd\t{%1, %0|%0, %1}"
4060   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4061    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4062    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4063
4064 (define_insn "zero_extendsidi2_rex64"
4065   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4066      (zero_extend:DI
4067        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4068   "TARGET_64BIT"
4069   "@
4070    mov\t{%k1, %k0|%k0, %k1}
4071    #
4072    movd\t{%1, %0|%0, %1}
4073    movd\t{%1, %0|%0, %1}
4074    %vmovd\t{%1, %0|%0, %1}
4075    %vmovd\t{%1, %0|%0, %1}"
4076   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4077    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4078    (set_attr "prefix_0f" "0,*,*,*,*,*")
4079    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4080
4081 (define_split
4082   [(set (match_operand:DI 0 "memory_operand" "")
4083      (zero_extend:DI (match_dup 0)))]
4084   "TARGET_64BIT"
4085   [(set (match_dup 4) (const_int 0))]
4086   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4087
4088 (define_split
4089   [(set (match_operand:DI 0 "register_operand" "")
4090         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4091    (clobber (reg:CC FLAGS_REG))]
4092   "!TARGET_64BIT && reload_completed
4093    && true_regnum (operands[0]) == true_regnum (operands[1])"
4094   [(set (match_dup 4) (const_int 0))]
4095   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4096
4097 (define_split
4098   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4099         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4100    (clobber (reg:CC FLAGS_REG))]
4101   "!TARGET_64BIT && reload_completed
4102    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4103   [(set (match_dup 3) (match_dup 1))
4104    (set (match_dup 4) (const_int 0))]
4105   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4106
4107 (define_insn "zero_extendhidi2"
4108   [(set (match_operand:DI 0 "register_operand" "=r")
4109      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4110   "TARGET_64BIT"
4111   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4112   [(set_attr "type" "imovx")
4113    (set_attr "mode" "SI")])
4114
4115 (define_insn "zero_extendqidi2"
4116   [(set (match_operand:DI 0 "register_operand" "=r")
4117      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4118   "TARGET_64BIT"
4119   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4120   [(set_attr "type" "imovx")
4121    (set_attr "mode" "SI")])
4122 \f
4123 ;; Sign extension instructions
4124
4125 (define_expand "extendsidi2"
4126   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4127                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4128               (clobber (reg:CC FLAGS_REG))
4129               (clobber (match_scratch:SI 2 ""))])]
4130   ""
4131 {
4132   if (TARGET_64BIT)
4133     {
4134       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4135       DONE;
4136     }
4137 })
4138
4139 (define_insn "*extendsidi2_1"
4140   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4141         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4142    (clobber (reg:CC FLAGS_REG))
4143    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4144   "!TARGET_64BIT"
4145   "#")
4146
4147 (define_insn "extendsidi2_rex64"
4148   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4149         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4150   "TARGET_64BIT"
4151   "@
4152    {cltq|cdqe}
4153    movs{lq|x}\t{%1, %0|%0, %1}"
4154   [(set_attr "type" "imovx")
4155    (set_attr "mode" "DI")
4156    (set_attr "prefix_0f" "0")
4157    (set_attr "modrm" "0,1")])
4158
4159 (define_insn "extendhidi2"
4160   [(set (match_operand:DI 0 "register_operand" "=r")
4161         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4162   "TARGET_64BIT"
4163   "movs{wq|x}\t{%1, %0|%0, %1}"
4164   [(set_attr "type" "imovx")
4165    (set_attr "mode" "DI")])
4166
4167 (define_insn "extendqidi2"
4168   [(set (match_operand:DI 0 "register_operand" "=r")
4169         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4170   "TARGET_64BIT"
4171   "movs{bq|x}\t{%1, %0|%0, %1}"
4172    [(set_attr "type" "imovx")
4173     (set_attr "mode" "DI")])
4174
4175 ;; Extend to memory case when source register does die.
4176 (define_split
4177   [(set (match_operand:DI 0 "memory_operand" "")
4178         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4179    (clobber (reg:CC FLAGS_REG))
4180    (clobber (match_operand:SI 2 "register_operand" ""))]
4181   "(reload_completed
4182     && dead_or_set_p (insn, operands[1])
4183     && !reg_mentioned_p (operands[1], operands[0]))"
4184   [(set (match_dup 3) (match_dup 1))
4185    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4186               (clobber (reg:CC FLAGS_REG))])
4187    (set (match_dup 4) (match_dup 1))]
4188   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4189
4190 ;; Extend to memory case when source register does not die.
4191 (define_split
4192   [(set (match_operand:DI 0 "memory_operand" "")
4193         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4194    (clobber (reg:CC FLAGS_REG))
4195    (clobber (match_operand:SI 2 "register_operand" ""))]
4196   "reload_completed"
4197   [(const_int 0)]
4198 {
4199   split_di (&operands[0], 1, &operands[3], &operands[4]);
4200
4201   emit_move_insn (operands[3], operands[1]);
4202
4203   /* Generate a cltd if possible and doing so it profitable.  */
4204   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4205       && true_regnum (operands[1]) == AX_REG
4206       && true_regnum (operands[2]) == DX_REG)
4207     {
4208       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4209     }
4210   else
4211     {
4212       emit_move_insn (operands[2], operands[1]);
4213       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4214     }
4215   emit_move_insn (operands[4], operands[2]);
4216   DONE;
4217 })
4218
4219 ;; Extend to register case.  Optimize case where source and destination
4220 ;; registers match and cases where we can use cltd.
4221 (define_split
4222   [(set (match_operand:DI 0 "register_operand" "")
4223         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4224    (clobber (reg:CC FLAGS_REG))
4225    (clobber (match_scratch:SI 2 ""))]
4226   "reload_completed"
4227   [(const_int 0)]
4228 {
4229   split_di (&operands[0], 1, &operands[3], &operands[4]);
4230
4231   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4232     emit_move_insn (operands[3], operands[1]);
4233
4234   /* Generate a cltd if possible and doing so it profitable.  */
4235   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4236       && true_regnum (operands[3]) == AX_REG
4237       && true_regnum (operands[4]) == DX_REG)
4238     {
4239       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4240       DONE;
4241     }
4242
4243   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4244     emit_move_insn (operands[4], operands[1]);
4245
4246   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4247   DONE;
4248 })
4249
4250 (define_insn "extendhisi2"
4251   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4252         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4253   ""
4254 {
4255   switch (get_attr_prefix_0f (insn))
4256     {
4257     case 0:
4258       return "{cwtl|cwde}";
4259     default:
4260       return "movs{wl|x}\t{%1, %0|%0, %1}";
4261     }
4262 }
4263   [(set_attr "type" "imovx")
4264    (set_attr "mode" "SI")
4265    (set (attr "prefix_0f")
4266      ;; movsx is short decodable while cwtl is vector decoded.
4267      (if_then_else (and (eq_attr "cpu" "!k6")
4268                         (eq_attr "alternative" "0"))
4269         (const_string "0")
4270         (const_string "1")))
4271    (set (attr "modrm")
4272      (if_then_else (eq_attr "prefix_0f" "0")
4273         (const_string "0")
4274         (const_string "1")))])
4275
4276 (define_insn "*extendhisi2_zext"
4277   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4278         (zero_extend:DI
4279           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4280   "TARGET_64BIT"
4281 {
4282   switch (get_attr_prefix_0f (insn))
4283     {
4284     case 0:
4285       return "{cwtl|cwde}";
4286     default:
4287       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4288     }
4289 }
4290   [(set_attr "type" "imovx")
4291    (set_attr "mode" "SI")
4292    (set (attr "prefix_0f")
4293      ;; movsx is short decodable while cwtl is vector decoded.
4294      (if_then_else (and (eq_attr "cpu" "!k6")
4295                         (eq_attr "alternative" "0"))
4296         (const_string "0")
4297         (const_string "1")))
4298    (set (attr "modrm")
4299      (if_then_else (eq_attr "prefix_0f" "0")
4300         (const_string "0")
4301         (const_string "1")))])
4302
4303 (define_insn "extendqihi2"
4304   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4305         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4306   ""
4307 {
4308   switch (get_attr_prefix_0f (insn))
4309     {
4310     case 0:
4311       return "{cbtw|cbw}";
4312     default:
4313       return "movs{bw|x}\t{%1, %0|%0, %1}";
4314     }
4315 }
4316   [(set_attr "type" "imovx")
4317    (set_attr "mode" "HI")
4318    (set (attr "prefix_0f")
4319      ;; movsx is short decodable while cwtl is vector decoded.
4320      (if_then_else (and (eq_attr "cpu" "!k6")
4321                         (eq_attr "alternative" "0"))
4322         (const_string "0")
4323         (const_string "1")))
4324    (set (attr "modrm")
4325      (if_then_else (eq_attr "prefix_0f" "0")
4326         (const_string "0")
4327         (const_string "1")))])
4328
4329 (define_insn "extendqisi2"
4330   [(set (match_operand:SI 0 "register_operand" "=r")
4331         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4332   ""
4333   "movs{bl|x}\t{%1, %0|%0, %1}"
4334    [(set_attr "type" "imovx")
4335     (set_attr "mode" "SI")])
4336
4337 (define_insn "*extendqisi2_zext"
4338   [(set (match_operand:DI 0 "register_operand" "=r")
4339         (zero_extend:DI
4340           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4341   "TARGET_64BIT"
4342   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4343    [(set_attr "type" "imovx")
4344     (set_attr "mode" "SI")])
4345 \f
4346 ;; Conversions between float and double.
4347
4348 ;; These are all no-ops in the model used for the 80387.  So just
4349 ;; emit moves.
4350
4351 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4352 (define_insn "*dummy_extendsfdf2"
4353   [(set (match_operand:DF 0 "push_operand" "=<")
4354         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4355   "0"
4356   "#")
4357
4358 (define_split
4359   [(set (match_operand:DF 0 "push_operand" "")
4360         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4361   ""
4362   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4363    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4364
4365 (define_insn "*dummy_extendsfxf2"
4366   [(set (match_operand:XF 0 "push_operand" "=<")
4367         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4368   "0"
4369   "#")
4370
4371 (define_split
4372   [(set (match_operand:XF 0 "push_operand" "")
4373         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4374   ""
4375   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4376    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4377   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4378
4379 (define_split
4380   [(set (match_operand:XF 0 "push_operand" "")
4381         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4382   ""
4383   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4384    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4385   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4386
4387 (define_expand "extendsfdf2"
4388   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4389         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4390   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4391 {
4392   /* ??? Needed for compress_float_constant since all fp constants
4393      are LEGITIMATE_CONSTANT_P.  */
4394   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4395     {
4396       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4397           && standard_80387_constant_p (operands[1]) > 0)
4398         {
4399           operands[1] = simplify_const_unary_operation
4400             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4401           emit_move_insn_1 (operands[0], operands[1]);
4402           DONE;
4403         }
4404       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4405     }
4406 })
4407
4408 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4409    cvtss2sd:
4410       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4411       cvtps2pd xmm2,xmm1
4412    We do the conversion post reload to avoid producing of 128bit spills
4413    that might lead to ICE on 32bit target.  The sequence unlikely combine
4414    anyway.  */
4415 (define_split
4416   [(set (match_operand:DF 0 "register_operand" "")
4417         (float_extend:DF
4418           (match_operand:SF 1 "nonimmediate_operand" "")))]
4419   "TARGET_USE_VECTOR_FP_CONVERTS
4420    && optimize_insn_for_speed_p ()
4421    && reload_completed && SSE_REG_P (operands[0])"
4422    [(set (match_dup 2)
4423          (float_extend:V2DF
4424            (vec_select:V2SF
4425              (match_dup 3)
4426              (parallel [(const_int 0) (const_int 1)]))))]
4427 {
4428   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4429   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4430   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4431      Try to avoid move when unpacking can be done in source.  */
4432   if (REG_P (operands[1]))
4433     {
4434       /* If it is unsafe to overwrite upper half of source, we need
4435          to move to destination and unpack there.  */
4436       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4437            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4438           && true_regnum (operands[0]) != true_regnum (operands[1]))
4439         {
4440           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4441           emit_move_insn (tmp, operands[1]);
4442         }
4443       else
4444         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4445       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4446                                              operands[3]));
4447     }
4448   else
4449     emit_insn (gen_vec_setv4sf_0 (operands[3],
4450                                   CONST0_RTX (V4SFmode), operands[1]));
4451 })
4452
4453 (define_insn "*extendsfdf2_mixed"
4454   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4455         (float_extend:DF
4456           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4457   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4458 {
4459   switch (which_alternative)
4460     {
4461     case 0:
4462     case 1:
4463       return output_387_reg_move (insn, operands);
4464
4465     case 2:
4466       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4467
4468     default:
4469       gcc_unreachable ();
4470     }
4471 }
4472   [(set_attr "type" "fmov,fmov,ssecvt")
4473    (set_attr "prefix" "orig,orig,maybe_vex")
4474    (set_attr "mode" "SF,XF,DF")])
4475
4476 (define_insn "*extendsfdf2_sse"
4477   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4478         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4479   "TARGET_SSE2 && TARGET_SSE_MATH"
4480   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4481   [(set_attr "type" "ssecvt")
4482    (set_attr "prefix" "maybe_vex")
4483    (set_attr "mode" "DF")])
4484
4485 (define_insn "*extendsfdf2_i387"
4486   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4487         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4488   "TARGET_80387"
4489   "* return output_387_reg_move (insn, operands);"
4490   [(set_attr "type" "fmov")
4491    (set_attr "mode" "SF,XF")])
4492
4493 (define_expand "extend<mode>xf2"
4494   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4495         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4496   "TARGET_80387"
4497 {
4498   /* ??? Needed for compress_float_constant since all fp constants
4499      are LEGITIMATE_CONSTANT_P.  */
4500   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4501     {
4502       if (standard_80387_constant_p (operands[1]) > 0)
4503         {
4504           operands[1] = simplify_const_unary_operation
4505             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4506           emit_move_insn_1 (operands[0], operands[1]);
4507           DONE;
4508         }
4509       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4510     }
4511 })
4512
4513 (define_insn "*extend<mode>xf2_i387"
4514   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4515         (float_extend:XF
4516           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4517   "TARGET_80387"
4518   "* return output_387_reg_move (insn, operands);"
4519   [(set_attr "type" "fmov")
4520    (set_attr "mode" "<MODE>,XF")])
4521
4522 ;; %%% This seems bad bad news.
4523 ;; This cannot output into an f-reg because there is no way to be sure
4524 ;; of truncating in that case.  Otherwise this is just like a simple move
4525 ;; insn.  So we pretend we can output to a reg in order to get better
4526 ;; register preferencing, but we really use a stack slot.
4527
4528 ;; Conversion from DFmode to SFmode.
4529
4530 (define_expand "truncdfsf2"
4531   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4532         (float_truncate:SF
4533           (match_operand:DF 1 "nonimmediate_operand" "")))]
4534   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4535 {
4536   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4537     ;
4538   else if (flag_unsafe_math_optimizations)
4539     ;
4540   else
4541     {
4542       enum ix86_stack_slot slot = (virtuals_instantiated
4543                                    ? SLOT_TEMP
4544                                    : SLOT_VIRTUAL);
4545       rtx temp = assign_386_stack_local (SFmode, slot);
4546       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4547       DONE;
4548     }
4549 })
4550
4551 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4552    cvtsd2ss:
4553       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4554       cvtpd2ps xmm2,xmm1
4555    We do the conversion post reload to avoid producing of 128bit spills
4556    that might lead to ICE on 32bit target.  The sequence unlikely combine
4557    anyway.  */
4558 (define_split
4559   [(set (match_operand:SF 0 "register_operand" "")
4560         (float_truncate:SF
4561           (match_operand:DF 1 "nonimmediate_operand" "")))]
4562   "TARGET_USE_VECTOR_FP_CONVERTS
4563    && optimize_insn_for_speed_p ()
4564    && reload_completed && SSE_REG_P (operands[0])"
4565    [(set (match_dup 2)
4566          (vec_concat:V4SF
4567            (float_truncate:V2SF
4568              (match_dup 4))
4569            (match_dup 3)))]
4570 {
4571   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4572   operands[3] = CONST0_RTX (V2SFmode);
4573   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4574   /* Use movsd for loading from memory, unpcklpd for registers.
4575      Try to avoid move when unpacking can be done in source, or SSE3
4576      movddup is available.  */
4577   if (REG_P (operands[1]))
4578     {
4579       if (!TARGET_SSE3
4580           && true_regnum (operands[0]) != true_regnum (operands[1])
4581           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4582               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4583         {
4584           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4585           emit_move_insn (tmp, operands[1]);
4586           operands[1] = tmp;
4587         }
4588       else if (!TARGET_SSE3)
4589         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4590       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4591     }
4592   else
4593     emit_insn (gen_sse2_loadlpd (operands[4],
4594                                  CONST0_RTX (V2DFmode), operands[1]));
4595 })
4596
4597 (define_expand "truncdfsf2_with_temp"
4598   [(parallel [(set (match_operand:SF 0 "" "")
4599                    (float_truncate:SF (match_operand:DF 1 "" "")))
4600               (clobber (match_operand:SF 2 "" ""))])]
4601   "")
4602
4603 (define_insn "*truncdfsf_fast_mixed"
4604   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4605         (float_truncate:SF
4606           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4607   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4608 {
4609   switch (which_alternative)
4610     {
4611     case 0:
4612       return output_387_reg_move (insn, operands);
4613     case 1:
4614       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4615     default:
4616       gcc_unreachable ();
4617     }
4618 }
4619   [(set_attr "type" "fmov,ssecvt")
4620    (set_attr "prefix" "orig,maybe_vex")
4621    (set_attr "mode" "SF")])
4622
4623 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4624 ;; because nothing we do here is unsafe.
4625 (define_insn "*truncdfsf_fast_sse"
4626   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4627         (float_truncate:SF
4628           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4629   "TARGET_SSE2 && TARGET_SSE_MATH"
4630   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4631   [(set_attr "type" "ssecvt")
4632    (set_attr "prefix" "maybe_vex")
4633    (set_attr "mode" "SF")])
4634
4635 (define_insn "*truncdfsf_fast_i387"
4636   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4637         (float_truncate:SF
4638           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4639   "TARGET_80387 && flag_unsafe_math_optimizations"
4640   "* return output_387_reg_move (insn, operands);"
4641   [(set_attr "type" "fmov")
4642    (set_attr "mode" "SF")])
4643
4644 (define_insn "*truncdfsf_mixed"
4645   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4646         (float_truncate:SF
4647           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4648    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4649   "TARGET_MIX_SSE_I387"
4650 {
4651   switch (which_alternative)
4652     {
4653     case 0:
4654       return output_387_reg_move (insn, operands);
4655     case 1:
4656       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4657
4658     default:
4659       return "#";
4660     }
4661 }
4662   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4663    (set_attr "unit" "*,*,i387,i387,i387")
4664    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4665    (set_attr "mode" "SF")])
4666
4667 (define_insn "*truncdfsf_i387"
4668   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4669         (float_truncate:SF
4670           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4671    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4672   "TARGET_80387"
4673 {
4674   switch (which_alternative)
4675     {
4676     case 0:
4677       return output_387_reg_move (insn, operands);
4678
4679     default:
4680       return "#";
4681     }
4682 }
4683   [(set_attr "type" "fmov,multi,multi,multi")
4684    (set_attr "unit" "*,i387,i387,i387")
4685    (set_attr "mode" "SF")])
4686
4687 (define_insn "*truncdfsf2_i387_1"
4688   [(set (match_operand:SF 0 "memory_operand" "=m")
4689         (float_truncate:SF
4690           (match_operand:DF 1 "register_operand" "f")))]
4691   "TARGET_80387
4692    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4693    && !TARGET_MIX_SSE_I387"
4694   "* return output_387_reg_move (insn, operands);"
4695   [(set_attr "type" "fmov")
4696    (set_attr "mode" "SF")])
4697
4698 (define_split
4699   [(set (match_operand:SF 0 "register_operand" "")
4700         (float_truncate:SF
4701          (match_operand:DF 1 "fp_register_operand" "")))
4702    (clobber (match_operand 2 "" ""))]
4703   "reload_completed"
4704   [(set (match_dup 2) (match_dup 1))
4705    (set (match_dup 0) (match_dup 2))]
4706 {
4707   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4708 })
4709
4710 ;; Conversion from XFmode to {SF,DF}mode
4711
4712 (define_expand "truncxf<mode>2"
4713   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4714                    (float_truncate:MODEF
4715                      (match_operand:XF 1 "register_operand" "")))
4716               (clobber (match_dup 2))])]
4717   "TARGET_80387"
4718 {
4719   if (flag_unsafe_math_optimizations)
4720     {
4721       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4722       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4723       if (reg != operands[0])
4724         emit_move_insn (operands[0], reg);
4725       DONE;
4726     }
4727   else
4728     {
4729      enum ix86_stack_slot slot = (virtuals_instantiated
4730                                   ? SLOT_TEMP
4731                                   : SLOT_VIRTUAL);
4732       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4733     }
4734 })
4735
4736 (define_insn "*truncxfsf2_mixed"
4737   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4738         (float_truncate:SF
4739           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4740    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4741   "TARGET_80387"
4742 {
4743   gcc_assert (!which_alternative);
4744   return output_387_reg_move (insn, operands);
4745 }
4746   [(set_attr "type" "fmov,multi,multi,multi")
4747    (set_attr "unit" "*,i387,i387,i387")
4748    (set_attr "mode" "SF")])
4749
4750 (define_insn "*truncxfdf2_mixed"
4751   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4752         (float_truncate:DF
4753           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4754    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4755   "TARGET_80387"
4756 {
4757   gcc_assert (!which_alternative);
4758   return output_387_reg_move (insn, operands);
4759 }
4760   [(set_attr "type" "fmov,multi,multi,multi")
4761    (set_attr "unit" "*,i387,i387,i387")
4762    (set_attr "mode" "DF")])
4763
4764 (define_insn "truncxf<mode>2_i387_noop"
4765   [(set (match_operand:MODEF 0 "register_operand" "=f")
4766         (float_truncate:MODEF
4767           (match_operand:XF 1 "register_operand" "f")))]
4768   "TARGET_80387 && flag_unsafe_math_optimizations"
4769   "* return output_387_reg_move (insn, operands);"
4770   [(set_attr "type" "fmov")
4771    (set_attr "mode" "<MODE>")])
4772
4773 (define_insn "*truncxf<mode>2_i387"
4774   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4775         (float_truncate:MODEF
4776           (match_operand:XF 1 "register_operand" "f")))]
4777   "TARGET_80387"
4778   "* return output_387_reg_move (insn, operands);"
4779   [(set_attr "type" "fmov")
4780    (set_attr "mode" "<MODE>")])
4781
4782 (define_split
4783   [(set (match_operand:MODEF 0 "register_operand" "")
4784         (float_truncate:MODEF
4785           (match_operand:XF 1 "register_operand" "")))
4786    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4787   "TARGET_80387 && reload_completed"
4788   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4789    (set (match_dup 0) (match_dup 2))]
4790   "")
4791
4792 (define_split
4793   [(set (match_operand:MODEF 0 "memory_operand" "")
4794         (float_truncate:MODEF
4795           (match_operand:XF 1 "register_operand" "")))
4796    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4797   "TARGET_80387"
4798   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4799   "")
4800 \f
4801 ;; Signed conversion to DImode.
4802
4803 (define_expand "fix_truncxfdi2"
4804   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4805                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4806               (clobber (reg:CC FLAGS_REG))])]
4807   "TARGET_80387"
4808 {
4809   if (TARGET_FISTTP)
4810    {
4811      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4812      DONE;
4813    }
4814 })
4815
4816 (define_expand "fix_trunc<mode>di2"
4817   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4818                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4819               (clobber (reg:CC FLAGS_REG))])]
4820   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4821 {
4822   if (TARGET_FISTTP
4823       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4824    {
4825      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4826      DONE;
4827    }
4828   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4829    {
4830      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4831      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4832      if (out != operands[0])
4833         emit_move_insn (operands[0], out);
4834      DONE;
4835    }
4836 })
4837
4838 ;; Signed conversion to SImode.
4839
4840 (define_expand "fix_truncxfsi2"
4841   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4842                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4843               (clobber (reg:CC FLAGS_REG))])]
4844   "TARGET_80387"
4845 {
4846   if (TARGET_FISTTP)
4847    {
4848      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4849      DONE;
4850    }
4851 })
4852
4853 (define_expand "fix_trunc<mode>si2"
4854   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4855                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4856               (clobber (reg:CC FLAGS_REG))])]
4857   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4858 {
4859   if (TARGET_FISTTP
4860       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4861    {
4862      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4863      DONE;
4864    }
4865   if (SSE_FLOAT_MODE_P (<MODE>mode))
4866    {
4867      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4868      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4869      if (out != operands[0])
4870         emit_move_insn (operands[0], out);
4871      DONE;
4872    }
4873 })
4874
4875 ;; Signed conversion to HImode.
4876
4877 (define_expand "fix_trunc<mode>hi2"
4878   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4879                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4880               (clobber (reg:CC FLAGS_REG))])]
4881   "TARGET_80387
4882    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4883 {
4884   if (TARGET_FISTTP)
4885    {
4886      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4887      DONE;
4888    }
4889 })
4890
4891 ;; Unsigned conversion to SImode.
4892
4893 (define_expand "fixuns_trunc<mode>si2"
4894   [(parallel
4895     [(set (match_operand:SI 0 "register_operand" "")
4896           (unsigned_fix:SI
4897             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4898      (use (match_dup 2))
4899      (clobber (match_scratch:<ssevecmode> 3 ""))
4900      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4901   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4902 {
4903   enum machine_mode mode = <MODE>mode;
4904   enum machine_mode vecmode = <ssevecmode>mode;
4905   REAL_VALUE_TYPE TWO31r;
4906   rtx two31;
4907
4908   if (optimize_insn_for_size_p ())
4909     FAIL;
4910
4911   real_ldexp (&TWO31r, &dconst1, 31);
4912   two31 = const_double_from_real_value (TWO31r, mode);
4913   two31 = ix86_build_const_vector (mode, true, two31);
4914   operands[2] = force_reg (vecmode, two31);
4915 })
4916
4917 (define_insn_and_split "*fixuns_trunc<mode>_1"
4918   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4919         (unsigned_fix:SI
4920           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4921    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4922    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4923    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4924   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4925    && optimize_function_for_speed_p (cfun)"
4926   "#"
4927   "&& reload_completed"
4928   [(const_int 0)]
4929 {
4930   ix86_split_convert_uns_si_sse (operands);
4931   DONE;
4932 })
4933
4934 ;; Unsigned conversion to HImode.
4935 ;; Without these patterns, we'll try the unsigned SI conversion which
4936 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4937
4938 (define_expand "fixuns_trunc<mode>hi2"
4939   [(set (match_dup 2)
4940         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4941    (set (match_operand:HI 0 "nonimmediate_operand" "")
4942         (subreg:HI (match_dup 2) 0))]
4943   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4944   "operands[2] = gen_reg_rtx (SImode);")
4945
4946 ;; When SSE is available, it is always faster to use it!
4947 (define_insn "fix_trunc<mode>di_sse"
4948   [(set (match_operand:DI 0 "register_operand" "=r,r")
4949         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4950   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4951    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4952   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4953   [(set_attr "type" "sseicvt")
4954    (set_attr "prefix" "maybe_vex")
4955    (set_attr "prefix_rex" "1")
4956    (set_attr "mode" "<MODE>")
4957    (set_attr "athlon_decode" "double,vector")
4958    (set_attr "amdfam10_decode" "double,double")])
4959
4960 (define_insn "fix_trunc<mode>si_sse"
4961   [(set (match_operand:SI 0 "register_operand" "=r,r")
4962         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4963   "SSE_FLOAT_MODE_P (<MODE>mode)
4964    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4965   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4966   [(set_attr "type" "sseicvt")
4967    (set_attr "prefix" "maybe_vex")
4968    (set_attr "mode" "<MODE>")
4969    (set_attr "athlon_decode" "double,vector")
4970    (set_attr "amdfam10_decode" "double,double")])
4971
4972 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4973 (define_peephole2
4974   [(set (match_operand:MODEF 0 "register_operand" "")
4975         (match_operand:MODEF 1 "memory_operand" ""))
4976    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4977         (fix:SSEMODEI24 (match_dup 0)))]
4978   "TARGET_SHORTEN_X87_SSE
4979    && peep2_reg_dead_p (2, operands[0])"
4980   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4981   "")
4982
4983 ;; Avoid vector decoded forms of the instruction.
4984 (define_peephole2
4985   [(match_scratch:DF 2 "Y2")
4986    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4987         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4988   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4989   [(set (match_dup 2) (match_dup 1))
4990    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4991   "")
4992
4993 (define_peephole2
4994   [(match_scratch:SF 2 "x")
4995    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4996         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4997   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4998   [(set (match_dup 2) (match_dup 1))
4999    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5000   "")
5001
5002 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5003   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5004         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5005   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5006    && TARGET_FISTTP
5007    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5008          && (TARGET_64BIT || <MODE>mode != DImode))
5009         && TARGET_SSE_MATH)
5010    && can_create_pseudo_p ()"
5011   "#"
5012   "&& 1"
5013   [(const_int 0)]
5014 {
5015   if (memory_operand (operands[0], VOIDmode))
5016     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5017   else
5018     {
5019       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5020       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5021                                                             operands[1],
5022                                                             operands[2]));
5023     }
5024   DONE;
5025 }
5026   [(set_attr "type" "fisttp")
5027    (set_attr "mode" "<MODE>")])
5028
5029 (define_insn "fix_trunc<mode>_i387_fisttp"
5030   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5031         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5032    (clobber (match_scratch:XF 2 "=&1f"))]
5033   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5034    && TARGET_FISTTP
5035    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5036          && (TARGET_64BIT || <MODE>mode != DImode))
5037         && TARGET_SSE_MATH)"
5038   "* return output_fix_trunc (insn, operands, 1);"
5039   [(set_attr "type" "fisttp")
5040    (set_attr "mode" "<MODE>")])
5041
5042 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5043   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5044         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5045    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5046    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5047   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5048    && TARGET_FISTTP
5049    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5050         && (TARGET_64BIT || <MODE>mode != DImode))
5051         && TARGET_SSE_MATH)"
5052   "#"
5053   [(set_attr "type" "fisttp")
5054    (set_attr "mode" "<MODE>")])
5055
5056 (define_split
5057   [(set (match_operand:X87MODEI 0 "register_operand" "")
5058         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5059    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5060    (clobber (match_scratch 3 ""))]
5061   "reload_completed"
5062   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5063               (clobber (match_dup 3))])
5064    (set (match_dup 0) (match_dup 2))]
5065   "")
5066
5067 (define_split
5068   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5069         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5070    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5071    (clobber (match_scratch 3 ""))]
5072   "reload_completed"
5073   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5074               (clobber (match_dup 3))])]
5075   "")
5076
5077 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5078 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5079 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5080 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5081 ;; function in i386.c.
5082 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5083   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5084         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5085    (clobber (reg:CC FLAGS_REG))]
5086   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5087    && !TARGET_FISTTP
5088    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5089          && (TARGET_64BIT || <MODE>mode != DImode))
5090    && can_create_pseudo_p ()"
5091   "#"
5092   "&& 1"
5093   [(const_int 0)]
5094 {
5095   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5096
5097   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5098   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5099   if (memory_operand (operands[0], VOIDmode))
5100     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5101                                          operands[2], operands[3]));
5102   else
5103     {
5104       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5105       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5106                                                      operands[2], operands[3],
5107                                                      operands[4]));
5108     }
5109   DONE;
5110 }
5111   [(set_attr "type" "fistp")
5112    (set_attr "i387_cw" "trunc")
5113    (set_attr "mode" "<MODE>")])
5114
5115 (define_insn "fix_truncdi_i387"
5116   [(set (match_operand:DI 0 "memory_operand" "=m")
5117         (fix:DI (match_operand 1 "register_operand" "f")))
5118    (use (match_operand:HI 2 "memory_operand" "m"))
5119    (use (match_operand:HI 3 "memory_operand" "m"))
5120    (clobber (match_scratch:XF 4 "=&1f"))]
5121   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5122    && !TARGET_FISTTP
5123    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5124   "* return output_fix_trunc (insn, operands, 0);"
5125   [(set_attr "type" "fistp")
5126    (set_attr "i387_cw" "trunc")
5127    (set_attr "mode" "DI")])
5128
5129 (define_insn "fix_truncdi_i387_with_temp"
5130   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5131         (fix:DI (match_operand 1 "register_operand" "f,f")))
5132    (use (match_operand:HI 2 "memory_operand" "m,m"))
5133    (use (match_operand:HI 3 "memory_operand" "m,m"))
5134    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5135    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5136   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5137    && !TARGET_FISTTP
5138    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5139   "#"
5140   [(set_attr "type" "fistp")
5141    (set_attr "i387_cw" "trunc")
5142    (set_attr "mode" "DI")])
5143
5144 (define_split
5145   [(set (match_operand:DI 0 "register_operand" "")
5146         (fix:DI (match_operand 1 "register_operand" "")))
5147    (use (match_operand:HI 2 "memory_operand" ""))
5148    (use (match_operand:HI 3 "memory_operand" ""))
5149    (clobber (match_operand:DI 4 "memory_operand" ""))
5150    (clobber (match_scratch 5 ""))]
5151   "reload_completed"
5152   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5153               (use (match_dup 2))
5154               (use (match_dup 3))
5155               (clobber (match_dup 5))])
5156    (set (match_dup 0) (match_dup 4))]
5157   "")
5158
5159 (define_split
5160   [(set (match_operand:DI 0 "memory_operand" "")
5161         (fix:DI (match_operand 1 "register_operand" "")))
5162    (use (match_operand:HI 2 "memory_operand" ""))
5163    (use (match_operand:HI 3 "memory_operand" ""))
5164    (clobber (match_operand:DI 4 "memory_operand" ""))
5165    (clobber (match_scratch 5 ""))]
5166   "reload_completed"
5167   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5168               (use (match_dup 2))
5169               (use (match_dup 3))
5170               (clobber (match_dup 5))])]
5171   "")
5172
5173 (define_insn "fix_trunc<mode>_i387"
5174   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5175         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5176    (use (match_operand:HI 2 "memory_operand" "m"))
5177    (use (match_operand:HI 3 "memory_operand" "m"))]
5178   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5179    && !TARGET_FISTTP
5180    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5181   "* return output_fix_trunc (insn, operands, 0);"
5182   [(set_attr "type" "fistp")
5183    (set_attr "i387_cw" "trunc")
5184    (set_attr "mode" "<MODE>")])
5185
5186 (define_insn "fix_trunc<mode>_i387_with_temp"
5187   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5188         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5189    (use (match_operand:HI 2 "memory_operand" "m,m"))
5190    (use (match_operand:HI 3 "memory_operand" "m,m"))
5191    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5192   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5193    && !TARGET_FISTTP
5194    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5195   "#"
5196   [(set_attr "type" "fistp")
5197    (set_attr "i387_cw" "trunc")
5198    (set_attr "mode" "<MODE>")])
5199
5200 (define_split
5201   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5202         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5203    (use (match_operand:HI 2 "memory_operand" ""))
5204    (use (match_operand:HI 3 "memory_operand" ""))
5205    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5206   "reload_completed"
5207   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5208               (use (match_dup 2))
5209               (use (match_dup 3))])
5210    (set (match_dup 0) (match_dup 4))]
5211   "")
5212
5213 (define_split
5214   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5215         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5216    (use (match_operand:HI 2 "memory_operand" ""))
5217    (use (match_operand:HI 3 "memory_operand" ""))
5218    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5219   "reload_completed"
5220   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5221               (use (match_dup 2))
5222               (use (match_dup 3))])]
5223   "")
5224
5225 (define_insn "x86_fnstcw_1"
5226   [(set (match_operand:HI 0 "memory_operand" "=m")
5227         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5228   "TARGET_80387"
5229   "fnstcw\t%0"
5230   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5231    (set_attr "mode" "HI")
5232    (set_attr "unit" "i387")])
5233
5234 (define_insn "x86_fldcw_1"
5235   [(set (reg:HI FPCR_REG)
5236         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5237   "TARGET_80387"
5238   "fldcw\t%0"
5239   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5240    (set_attr "mode" "HI")
5241    (set_attr "unit" "i387")
5242    (set_attr "athlon_decode" "vector")
5243    (set_attr "amdfam10_decode" "vector")])
5244 \f
5245 ;; Conversion between fixed point and floating point.
5246
5247 ;; Even though we only accept memory inputs, the backend _really_
5248 ;; wants to be able to do this between registers.
5249
5250 (define_expand "floathi<mode>2"
5251   [(set (match_operand:X87MODEF 0 "register_operand" "")
5252         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5253   "TARGET_80387
5254    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5255        || TARGET_MIX_SSE_I387)"
5256   "")
5257
5258 ;; Pre-reload splitter to add memory clobber to the pattern.
5259 (define_insn_and_split "*floathi<mode>2_1"
5260   [(set (match_operand:X87MODEF 0 "register_operand" "")
5261         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5262   "TARGET_80387
5263    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5264        || TARGET_MIX_SSE_I387)
5265    && can_create_pseudo_p ()"
5266   "#"
5267   "&& 1"
5268   [(parallel [(set (match_dup 0)
5269               (float:X87MODEF (match_dup 1)))
5270    (clobber (match_dup 2))])]
5271   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5272
5273 (define_insn "*floathi<mode>2_i387_with_temp"
5274   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5275         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5276   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5277   "TARGET_80387
5278    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5279        || TARGET_MIX_SSE_I387)"
5280   "#"
5281   [(set_attr "type" "fmov,multi")
5282    (set_attr "mode" "<MODE>")
5283    (set_attr "unit" "*,i387")
5284    (set_attr "fp_int_src" "true")])
5285
5286 (define_insn "*floathi<mode>2_i387"
5287   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5288         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5289   "TARGET_80387
5290    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5291        || TARGET_MIX_SSE_I387)"
5292   "fild%Z1\t%1"
5293   [(set_attr "type" "fmov")
5294    (set_attr "mode" "<MODE>")
5295    (set_attr "fp_int_src" "true")])
5296
5297 (define_split
5298   [(set (match_operand:X87MODEF 0 "register_operand" "")
5299         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5300    (clobber (match_operand:HI 2 "memory_operand" ""))]
5301   "TARGET_80387
5302    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5303        || TARGET_MIX_SSE_I387)
5304    && reload_completed"
5305   [(set (match_dup 2) (match_dup 1))
5306    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5307   "")
5308
5309 (define_split
5310   [(set (match_operand:X87MODEF 0 "register_operand" "")
5311         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5312    (clobber (match_operand:HI 2 "memory_operand" ""))]
5313    "TARGET_80387
5314     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5315         || TARGET_MIX_SSE_I387)
5316     && reload_completed"
5317   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5318   "")
5319
5320 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5321   [(set (match_operand:X87MODEF 0 "register_operand" "")
5322         (float:X87MODEF
5323           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5324   "TARGET_80387
5325    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5326        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5327 {
5328   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5329         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5330       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5331     {
5332       rtx reg = gen_reg_rtx (XFmode);
5333       rtx insn;
5334
5335       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5336
5337       if (<X87MODEF:MODE>mode == SFmode)
5338         insn = gen_truncxfsf2 (operands[0], reg);
5339       else if (<X87MODEF:MODE>mode == DFmode)
5340         insn = gen_truncxfdf2 (operands[0], reg);
5341       else
5342         gcc_unreachable ();
5343
5344       emit_insn (insn);
5345       DONE;
5346     }
5347 })
5348
5349 ;; Pre-reload splitter to add memory clobber to the pattern.
5350 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5351   [(set (match_operand:X87MODEF 0 "register_operand" "")
5352         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5353   "((TARGET_80387
5354      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5355      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5356            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5357          || TARGET_MIX_SSE_I387))
5358     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5359         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5360         && ((<SSEMODEI24:MODE>mode == SImode
5361              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5362              && optimize_function_for_speed_p (cfun)
5363              && flag_trapping_math)
5364             || !(TARGET_INTER_UNIT_CONVERSIONS
5365                  || optimize_function_for_size_p (cfun)))))
5366    && can_create_pseudo_p ()"
5367   "#"
5368   "&& 1"
5369   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5370               (clobber (match_dup 2))])]
5371 {
5372   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5373
5374   /* Avoid store forwarding (partial memory) stall penalty
5375      by passing DImode value through XMM registers.  */
5376   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5377       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5378       && optimize_function_for_speed_p (cfun))
5379     {
5380       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5381                                                             operands[1],
5382                                                             operands[2]));
5383       DONE;
5384     }
5385 })
5386
5387 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5388   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5389         (float:MODEF
5390           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5391    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5392   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5393    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5394   "#"
5395   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5396    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5397    (set_attr "unit" "*,i387,*,*,*")
5398    (set_attr "athlon_decode" "*,*,double,direct,double")
5399    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5400    (set_attr "fp_int_src" "true")])
5401
5402 (define_insn "*floatsi<mode>2_vector_mixed"
5403   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5404         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5405   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5406    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5407   "@
5408    fild%Z1\t%1
5409    #"
5410   [(set_attr "type" "fmov,sseicvt")
5411    (set_attr "mode" "<MODE>,<ssevecmode>")
5412    (set_attr "unit" "i387,*")
5413    (set_attr "athlon_decode" "*,direct")
5414    (set_attr "amdfam10_decode" "*,double")
5415    (set_attr "fp_int_src" "true")])
5416
5417 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5418   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5419         (float:MODEF
5420           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5421   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5422   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5423    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5424   "#"
5425   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5426    (set_attr "mode" "<MODEF:MODE>")
5427    (set_attr "unit" "*,i387,*,*")
5428    (set_attr "athlon_decode" "*,*,double,direct")
5429    (set_attr "amdfam10_decode" "*,*,vector,double")
5430    (set_attr "fp_int_src" "true")])
5431
5432 (define_split
5433   [(set (match_operand:MODEF 0 "register_operand" "")
5434         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5435    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5436   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5437    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5438    && TARGET_INTER_UNIT_CONVERSIONS
5439    && reload_completed
5440    && (SSE_REG_P (operands[0])
5441        || (GET_CODE (operands[0]) == SUBREG
5442            && SSE_REG_P (operands[0])))"
5443   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5444   "")
5445
5446 (define_split
5447   [(set (match_operand:MODEF 0 "register_operand" "")
5448         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5449    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5450   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5451    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5452    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5453    && reload_completed
5454    && (SSE_REG_P (operands[0])
5455        || (GET_CODE (operands[0]) == SUBREG
5456            && SSE_REG_P (operands[0])))"
5457   [(set (match_dup 2) (match_dup 1))
5458    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5459   "")
5460
5461 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5462   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5463         (float:MODEF
5464           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5465   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5466    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5467    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5468   "@
5469    fild%Z1\t%1
5470    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5471    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5472   [(set_attr "type" "fmov,sseicvt,sseicvt")
5473    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5474    (set_attr "mode" "<MODEF:MODE>")
5475    (set (attr "prefix_rex")
5476      (if_then_else
5477        (and (eq_attr "prefix" "maybe_vex")
5478             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5479        (const_string "1")
5480        (const_string "*")))
5481    (set_attr "unit" "i387,*,*")
5482    (set_attr "athlon_decode" "*,double,direct")
5483    (set_attr "amdfam10_decode" "*,vector,double")
5484    (set_attr "fp_int_src" "true")])
5485
5486 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5487   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5488         (float:MODEF
5489           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5490   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5491    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5492    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5493   "@
5494    fild%Z1\t%1
5495    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5496   [(set_attr "type" "fmov,sseicvt")
5497    (set_attr "prefix" "orig,maybe_vex")
5498    (set_attr "mode" "<MODEF:MODE>")
5499    (set (attr "prefix_rex")
5500      (if_then_else
5501        (and (eq_attr "prefix" "maybe_vex")
5502             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5503        (const_string "1")
5504        (const_string "*")))
5505    (set_attr "athlon_decode" "*,direct")
5506    (set_attr "amdfam10_decode" "*,double")
5507    (set_attr "fp_int_src" "true")])
5508
5509 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5510   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5511         (float:MODEF
5512           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5513    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5514   "TARGET_SSE2 && TARGET_SSE_MATH
5515    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5516   "#"
5517   [(set_attr "type" "sseicvt")
5518    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5519    (set_attr "athlon_decode" "double,direct,double")
5520    (set_attr "amdfam10_decode" "vector,double,double")
5521    (set_attr "fp_int_src" "true")])
5522
5523 (define_insn "*floatsi<mode>2_vector_sse"
5524   [(set (match_operand:MODEF 0 "register_operand" "=x")
5525         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5526   "TARGET_SSE2 && TARGET_SSE_MATH
5527    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5528   "#"
5529   [(set_attr "type" "sseicvt")
5530    (set_attr "mode" "<MODE>")
5531    (set_attr "athlon_decode" "direct")
5532    (set_attr "amdfam10_decode" "double")
5533    (set_attr "fp_int_src" "true")])
5534
5535 (define_split
5536   [(set (match_operand:MODEF 0 "register_operand" "")
5537         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5538    (clobber (match_operand:SI 2 "memory_operand" ""))]
5539   "TARGET_SSE2 && TARGET_SSE_MATH
5540    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5541    && reload_completed
5542    && (SSE_REG_P (operands[0])
5543        || (GET_CODE (operands[0]) == SUBREG
5544            && SSE_REG_P (operands[0])))"
5545   [(const_int 0)]
5546 {
5547   rtx op1 = operands[1];
5548
5549   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5550                                      <MODE>mode, 0);
5551   if (GET_CODE (op1) == SUBREG)
5552     op1 = SUBREG_REG (op1);
5553
5554   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5555     {
5556       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5557       emit_insn (gen_sse2_loadld (operands[4],
5558                                   CONST0_RTX (V4SImode), operands[1]));
5559     }
5560   /* We can ignore possible trapping value in the
5561      high part of SSE register for non-trapping math. */
5562   else if (SSE_REG_P (op1) && !flag_trapping_math)
5563     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5564   else
5565     {
5566       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5567       emit_move_insn (operands[2], operands[1]);
5568       emit_insn (gen_sse2_loadld (operands[4],
5569                                   CONST0_RTX (V4SImode), operands[2]));
5570     }
5571   emit_insn
5572     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5573   DONE;
5574 })
5575
5576 (define_split
5577   [(set (match_operand:MODEF 0 "register_operand" "")
5578         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5579    (clobber (match_operand:SI 2 "memory_operand" ""))]
5580   "TARGET_SSE2 && TARGET_SSE_MATH
5581    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5582    && reload_completed
5583    && (SSE_REG_P (operands[0])
5584        || (GET_CODE (operands[0]) == SUBREG
5585            && SSE_REG_P (operands[0])))"
5586   [(const_int 0)]
5587 {
5588   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5589                                      <MODE>mode, 0);
5590   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5591
5592   emit_insn (gen_sse2_loadld (operands[4],
5593                               CONST0_RTX (V4SImode), operands[1]));
5594   emit_insn
5595     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5596   DONE;
5597 })
5598
5599 (define_split
5600   [(set (match_operand:MODEF 0 "register_operand" "")
5601         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5602   "TARGET_SSE2 && TARGET_SSE_MATH
5603    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5604    && reload_completed
5605    && (SSE_REG_P (operands[0])
5606        || (GET_CODE (operands[0]) == SUBREG
5607            && SSE_REG_P (operands[0])))"
5608   [(const_int 0)]
5609 {
5610   rtx op1 = operands[1];
5611
5612   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5613                                      <MODE>mode, 0);
5614   if (GET_CODE (op1) == SUBREG)
5615     op1 = SUBREG_REG (op1);
5616
5617   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5618     {
5619       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5620       emit_insn (gen_sse2_loadld (operands[4],
5621                                   CONST0_RTX (V4SImode), operands[1]));
5622     }
5623   /* We can ignore possible trapping value in the
5624      high part of SSE register for non-trapping math. */
5625   else if (SSE_REG_P (op1) && !flag_trapping_math)
5626     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5627   else
5628     gcc_unreachable ();
5629   emit_insn
5630     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5631   DONE;
5632 })
5633
5634 (define_split
5635   [(set (match_operand:MODEF 0 "register_operand" "")
5636         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5637   "TARGET_SSE2 && TARGET_SSE_MATH
5638    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5639    && reload_completed
5640    && (SSE_REG_P (operands[0])
5641        || (GET_CODE (operands[0]) == SUBREG
5642            && SSE_REG_P (operands[0])))"
5643   [(const_int 0)]
5644 {
5645   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5646                                      <MODE>mode, 0);
5647   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5648
5649   emit_insn (gen_sse2_loadld (operands[4],
5650                               CONST0_RTX (V4SImode), operands[1]));
5651   emit_insn
5652     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5653   DONE;
5654 })
5655
5656 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5657   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5658         (float:MODEF
5659           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5660   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5661   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5662    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5663   "#"
5664   [(set_attr "type" "sseicvt")
5665    (set_attr "mode" "<MODEF:MODE>")
5666    (set_attr "athlon_decode" "double,direct")
5667    (set_attr "amdfam10_decode" "vector,double")
5668    (set_attr "fp_int_src" "true")])
5669
5670 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5671   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5672         (float:MODEF
5673           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5674   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5675    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5676    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5677   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5678   [(set_attr "type" "sseicvt")
5679    (set_attr "prefix" "maybe_vex")
5680    (set_attr "mode" "<MODEF:MODE>")
5681    (set (attr "prefix_rex")
5682      (if_then_else
5683        (and (eq_attr "prefix" "maybe_vex")
5684             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5685        (const_string "1")
5686        (const_string "*")))
5687    (set_attr "athlon_decode" "double,direct")
5688    (set_attr "amdfam10_decode" "vector,double")
5689    (set_attr "fp_int_src" "true")])
5690
5691 (define_split
5692   [(set (match_operand:MODEF 0 "register_operand" "")
5693         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5694    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5695   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5696    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5697    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5698    && reload_completed
5699    && (SSE_REG_P (operands[0])
5700        || (GET_CODE (operands[0]) == SUBREG
5701            && SSE_REG_P (operands[0])))"
5702   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5703   "")
5704
5705 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5706   [(set (match_operand:MODEF 0 "register_operand" "=x")
5707         (float:MODEF
5708           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5709   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5710    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5711    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5712   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5713   [(set_attr "type" "sseicvt")
5714    (set_attr "prefix" "maybe_vex")
5715    (set_attr "mode" "<MODEF:MODE>")
5716    (set (attr "prefix_rex")
5717      (if_then_else
5718        (and (eq_attr "prefix" "maybe_vex")
5719             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5720        (const_string "1")
5721        (const_string "*")))
5722    (set_attr "athlon_decode" "direct")
5723    (set_attr "amdfam10_decode" "double")
5724    (set_attr "fp_int_src" "true")])
5725
5726 (define_split
5727   [(set (match_operand:MODEF 0 "register_operand" "")
5728         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5729    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5730   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5731    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5732    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5733    && reload_completed
5734    && (SSE_REG_P (operands[0])
5735        || (GET_CODE (operands[0]) == SUBREG
5736            && SSE_REG_P (operands[0])))"
5737   [(set (match_dup 2) (match_dup 1))
5738    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5739   "")
5740
5741 (define_split
5742   [(set (match_operand:MODEF 0 "register_operand" "")
5743         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5744    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5745   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5746    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5747    && reload_completed
5748    && (SSE_REG_P (operands[0])
5749        || (GET_CODE (operands[0]) == SUBREG
5750            && SSE_REG_P (operands[0])))"
5751   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5752   "")
5753
5754 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5755   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5756         (float:X87MODEF
5757           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5758   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5759   "TARGET_80387
5760    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5761   "@
5762    fild%Z1\t%1
5763    #"
5764   [(set_attr "type" "fmov,multi")
5765    (set_attr "mode" "<X87MODEF:MODE>")
5766    (set_attr "unit" "*,i387")
5767    (set_attr "fp_int_src" "true")])
5768
5769 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5770   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5771         (float:X87MODEF
5772           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5773   "TARGET_80387
5774    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5775   "fild%Z1\t%1"
5776   [(set_attr "type" "fmov")
5777    (set_attr "mode" "<X87MODEF:MODE>")
5778    (set_attr "fp_int_src" "true")])
5779
5780 (define_split
5781   [(set (match_operand:X87MODEF 0 "register_operand" "")
5782         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5783    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5784   "TARGET_80387
5785    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5786    && reload_completed
5787    && FP_REG_P (operands[0])"
5788   [(set (match_dup 2) (match_dup 1))
5789    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5790   "")
5791
5792 (define_split
5793   [(set (match_operand:X87MODEF 0 "register_operand" "")
5794         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5795    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5796   "TARGET_80387
5797    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5798    && reload_completed
5799    && FP_REG_P (operands[0])"
5800   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5801   "")
5802
5803 ;; Avoid store forwarding (partial memory) stall penalty
5804 ;; by passing DImode value through XMM registers.  */
5805
5806 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5807   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5808         (float:X87MODEF
5809           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5810    (clobber (match_scratch:V4SI 3 "=X,x"))
5811    (clobber (match_scratch:V4SI 4 "=X,x"))
5812    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5813   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5814    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5815    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5816   "#"
5817   [(set_attr "type" "multi")
5818    (set_attr "mode" "<X87MODEF:MODE>")
5819    (set_attr "unit" "i387")
5820    (set_attr "fp_int_src" "true")])
5821
5822 (define_split
5823   [(set (match_operand:X87MODEF 0 "register_operand" "")
5824         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5825    (clobber (match_scratch:V4SI 3 ""))
5826    (clobber (match_scratch:V4SI 4 ""))
5827    (clobber (match_operand:DI 2 "memory_operand" ""))]
5828   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5829    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5830    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5831    && reload_completed
5832    && FP_REG_P (operands[0])"
5833   [(set (match_dup 2) (match_dup 3))
5834    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5835 {
5836   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5837      Assemble the 64-bit DImode value in an xmm register.  */
5838   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5839                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5840   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5841                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5842   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5843                                          operands[4]));
5844
5845   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5846 })
5847
5848 (define_split
5849   [(set (match_operand:X87MODEF 0 "register_operand" "")
5850         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5851    (clobber (match_scratch:V4SI 3 ""))
5852    (clobber (match_scratch:V4SI 4 ""))
5853    (clobber (match_operand:DI 2 "memory_operand" ""))]
5854   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5855    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5856    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5857    && reload_completed
5858    && FP_REG_P (operands[0])"
5859   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5860   "")
5861
5862 ;; Avoid store forwarding (partial memory) stall penalty by extending
5863 ;; SImode value to DImode through XMM register instead of pushing two
5864 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5865 ;; targets benefit from this optimization. Also note that fild
5866 ;; loads from memory only.
5867
5868 (define_insn "*floatunssi<mode>2_1"
5869   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5870         (unsigned_float:X87MODEF
5871           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5872    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5873    (clobber (match_scratch:SI 3 "=X,x"))]
5874   "!TARGET_64BIT
5875    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5876    && TARGET_SSE"
5877   "#"
5878   [(set_attr "type" "multi")
5879    (set_attr "mode" "<MODE>")])
5880
5881 (define_split
5882   [(set (match_operand:X87MODEF 0 "register_operand" "")
5883         (unsigned_float:X87MODEF
5884           (match_operand:SI 1 "register_operand" "")))
5885    (clobber (match_operand:DI 2 "memory_operand" ""))
5886    (clobber (match_scratch:SI 3 ""))]
5887   "!TARGET_64BIT
5888    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5889    && TARGET_SSE
5890    && reload_completed"
5891   [(set (match_dup 2) (match_dup 1))
5892    (set (match_dup 0)
5893         (float:X87MODEF (match_dup 2)))]
5894   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5895
5896 (define_split
5897   [(set (match_operand:X87MODEF 0 "register_operand" "")
5898         (unsigned_float:X87MODEF
5899           (match_operand:SI 1 "memory_operand" "")))
5900    (clobber (match_operand:DI 2 "memory_operand" ""))
5901    (clobber (match_scratch:SI 3 ""))]
5902   "!TARGET_64BIT
5903    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5904    && TARGET_SSE
5905    && reload_completed"
5906   [(set (match_dup 2) (match_dup 3))
5907    (set (match_dup 0)
5908         (float:X87MODEF (match_dup 2)))]
5909 {
5910   emit_move_insn (operands[3], operands[1]);
5911   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5912 })
5913
5914 (define_expand "floatunssi<mode>2"
5915   [(parallel
5916      [(set (match_operand:X87MODEF 0 "register_operand" "")
5917            (unsigned_float:X87MODEF
5918              (match_operand:SI 1 "nonimmediate_operand" "")))
5919       (clobber (match_dup 2))
5920       (clobber (match_scratch:SI 3 ""))])]
5921   "!TARGET_64BIT
5922    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5923         && TARGET_SSE)
5924        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5925 {
5926   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5927     {
5928       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5929       DONE;
5930     }
5931   else
5932     {
5933       enum ix86_stack_slot slot = (virtuals_instantiated
5934                                    ? SLOT_TEMP
5935                                    : SLOT_VIRTUAL);
5936       operands[2] = assign_386_stack_local (DImode, slot);
5937     }
5938 })
5939
5940 (define_expand "floatunsdisf2"
5941   [(use (match_operand:SF 0 "register_operand" ""))
5942    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5943   "TARGET_64BIT && TARGET_SSE_MATH"
5944   "x86_emit_floatuns (operands); DONE;")
5945
5946 (define_expand "floatunsdidf2"
5947   [(use (match_operand:DF 0 "register_operand" ""))
5948    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5949   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5950    && TARGET_SSE2 && TARGET_SSE_MATH"
5951 {
5952   if (TARGET_64BIT)
5953     x86_emit_floatuns (operands);
5954   else
5955     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5956   DONE;
5957 })
5958 \f
5959 ;; Add instructions
5960
5961 (define_expand "add<mode>3"
5962   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5963         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5964                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5965   ""
5966   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5967
5968 (define_insn_and_split "*add<dwi>3_doubleword"
5969   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5970         (plus:<DWI>
5971           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5972           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5973    (clobber (reg:CC FLAGS_REG))]
5974   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5975   "#"
5976   "reload_completed"
5977   [(parallel [(set (reg:CC FLAGS_REG)
5978                    (unspec:CC [(match_dup 1) (match_dup 2)]
5979                               UNSPEC_ADD_CARRY))
5980               (set (match_dup 0)
5981                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5982    (parallel [(set (match_dup 3)
5983                    (plus:DWIH
5984                      (match_dup 4)
5985                      (plus:DWIH
5986                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5987                        (match_dup 5))))
5988               (clobber (reg:CC FLAGS_REG))])]
5989   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5990
5991 (define_insn "*add<mode>3_cc"
5992   [(set (reg:CC FLAGS_REG)
5993         (unspec:CC
5994           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5995            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5996           UNSPEC_ADD_CARRY))
5997    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5998         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5999   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6000   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6001   [(set_attr "type" "alu")
6002    (set_attr "mode" "<MODE>")])
6003
6004 (define_insn "addqi3_cc"
6005   [(set (reg:CC FLAGS_REG)
6006         (unspec:CC
6007           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6008            (match_operand:QI 2 "general_operand" "qn,qm")]
6009           UNSPEC_ADD_CARRY))
6010    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6011         (plus:QI (match_dup 1) (match_dup 2)))]
6012   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6013   "add{b}\t{%2, %0|%0, %2}"
6014   [(set_attr "type" "alu")
6015    (set_attr "mode" "QI")])
6016
6017 (define_insn "*lea_1"
6018   [(set (match_operand:DWIH 0 "register_operand" "=r")
6019         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6020   ""
6021   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6022   [(set_attr "type" "lea")
6023    (set_attr "mode" "<MODE>")])
6024
6025 (define_insn "*lea_2"
6026   [(set (match_operand:SI 0 "register_operand" "=r")
6027         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6028   "TARGET_64BIT"
6029   "lea{l}\t{%a1, %0|%0, %a1}"
6030   [(set_attr "type" "lea")
6031    (set_attr "mode" "SI")])
6032
6033 (define_insn "*lea_2_zext"
6034   [(set (match_operand:DI 0 "register_operand" "=r")
6035         (zero_extend:DI
6036           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6037   "TARGET_64BIT"
6038   "lea{l}\t{%a1, %k0|%k0, %a1}"
6039   [(set_attr "type" "lea")
6040    (set_attr "mode" "SI")])
6041
6042 (define_insn "*add<mode>_1"
6043   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6044         (plus:SWI48
6045           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6046           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6047    (clobber (reg:CC FLAGS_REG))]
6048   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6049 {
6050   switch (get_attr_type (insn))
6051     {
6052     case TYPE_LEA:
6053       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6054       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6055
6056     case TYPE_INCDEC:
6057       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6058       if (operands[2] == const1_rtx)
6059         return "inc{<imodesuffix>}\t%0";
6060       else
6061         {
6062           gcc_assert (operands[2] == constm1_rtx);
6063           return "dec{<imodesuffix>}\t%0";
6064         }
6065
6066     default:
6067       /* Use add as much as possible to replace lea for AGU optimization. */
6068       if (which_alternative == 2 && TARGET_OPT_AGU)
6069         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6070         
6071       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6072       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6073         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6074
6075       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6076     }
6077 }
6078   [(set (attr "type")
6079      (cond [(and (eq_attr "alternative" "2") 
6080                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6081               (const_string "lea")
6082             (eq_attr "alternative" "3")
6083               (const_string "lea")
6084             ; Current assemblers are broken and do not allow @GOTOFF in
6085             ; ought but a memory context.
6086             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6087               (const_string "lea")
6088             (match_operand:SWI48 2 "incdec_operand" "")
6089               (const_string "incdec")
6090            ]
6091            (const_string "alu")))
6092    (set (attr "length_immediate")
6093       (if_then_else
6094         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6095         (const_string "1")
6096         (const_string "*")))
6097    (set_attr "mode" "<MODE>")])
6098
6099 ;; It may seem that nonimmediate operand is proper one for operand 1.
6100 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6101 ;; we take care in ix86_binary_operator_ok to not allow two memory
6102 ;; operands so proper swapping will be done in reload.  This allow
6103 ;; patterns constructed from addsi_1 to match.
6104
6105 (define_insn "*addsi_1_zext"
6106   [(set (match_operand:DI 0 "register_operand" "=r,r")
6107         (zero_extend:DI
6108           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6109                    (match_operand:SI 2 "general_operand" "g,li"))))
6110    (clobber (reg:CC FLAGS_REG))]
6111   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6112 {
6113   switch (get_attr_type (insn))
6114     {
6115     case TYPE_LEA:
6116       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6117       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6118
6119     case TYPE_INCDEC:
6120       if (operands[2] == const1_rtx)
6121         return "inc{l}\t%k0";
6122       else
6123         {
6124           gcc_assert (operands[2] == constm1_rtx);
6125           return "dec{l}\t%k0";
6126         }
6127
6128     default:
6129       if (x86_maybe_negate_const_int (&operands[2], SImode))
6130         return "sub{l}\t{%2, %k0|%k0, %2}";
6131
6132       return "add{l}\t{%2, %k0|%k0, %2}";
6133     }
6134 }
6135   [(set (attr "type")
6136      (cond [(eq_attr "alternative" "1")
6137               (const_string "lea")
6138             ; Current assemblers are broken and do not allow @GOTOFF in
6139             ; ought but a memory context.
6140             (match_operand:SI 2 "pic_symbolic_operand" "")
6141               (const_string "lea")
6142             (match_operand:SI 2 "incdec_operand" "")
6143               (const_string "incdec")
6144            ]
6145            (const_string "alu")))
6146    (set (attr "length_immediate")
6147       (if_then_else
6148         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6149         (const_string "1")
6150         (const_string "*")))
6151    (set_attr "mode" "SI")])
6152
6153 (define_insn "*addhi_1"
6154   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6155         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6156                  (match_operand:HI 2 "general_operand" "rn,rm")))
6157    (clobber (reg:CC FLAGS_REG))]
6158   "TARGET_PARTIAL_REG_STALL
6159    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6160 {
6161   switch (get_attr_type (insn))
6162     {
6163     case TYPE_INCDEC:
6164       if (operands[2] == const1_rtx)
6165         return "inc{w}\t%0";
6166       else
6167         {
6168           gcc_assert (operands[2] == constm1_rtx);
6169           return "dec{w}\t%0";
6170         }
6171
6172     default:
6173       if (x86_maybe_negate_const_int (&operands[2], HImode))
6174         return "sub{w}\t{%2, %0|%0, %2}";
6175
6176       return "add{w}\t{%2, %0|%0, %2}";
6177     }
6178 }
6179   [(set (attr "type")
6180      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6181         (const_string "incdec")
6182         (const_string "alu")))
6183    (set (attr "length_immediate")
6184       (if_then_else
6185         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6186         (const_string "1")
6187         (const_string "*")))
6188    (set_attr "mode" "HI")])
6189
6190 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6191 ;; type optimizations enabled by define-splits.  This is not important
6192 ;; for PII, and in fact harmful because of partial register stalls.
6193
6194 (define_insn "*addhi_1_lea"
6195   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6196         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6197                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6198    (clobber (reg:CC FLAGS_REG))]
6199   "!TARGET_PARTIAL_REG_STALL
6200    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6201 {
6202   switch (get_attr_type (insn))
6203     {
6204     case TYPE_LEA:
6205       return "#";
6206     case TYPE_INCDEC:
6207       if (operands[2] == const1_rtx)
6208         return "inc{w}\t%0";
6209       else
6210         {
6211           gcc_assert (operands[2] == constm1_rtx);
6212           return "dec{w}\t%0";
6213         }
6214
6215     default:
6216       if (x86_maybe_negate_const_int (&operands[2], HImode))
6217         return "sub{w}\t{%2, %0|%0, %2}";
6218
6219       return "add{w}\t{%2, %0|%0, %2}";
6220     }
6221 }
6222   [(set (attr "type")
6223      (if_then_else (eq_attr "alternative" "2")
6224         (const_string "lea")
6225         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6226            (const_string "incdec")
6227            (const_string "alu"))))
6228    (set (attr "length_immediate")
6229       (if_then_else
6230         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6231         (const_string "1")
6232         (const_string "*")))
6233    (set_attr "mode" "HI,HI,SI")])
6234
6235 (define_insn "*addqi_1"
6236   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6237         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6238                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6239    (clobber (reg:CC FLAGS_REG))]
6240   "TARGET_PARTIAL_REG_STALL
6241    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6242 {
6243   int widen = (which_alternative == 2);
6244   switch (get_attr_type (insn))
6245     {
6246     case TYPE_INCDEC:
6247       if (operands[2] == const1_rtx)
6248         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6249       else
6250         {
6251           gcc_assert (operands[2] == constm1_rtx);
6252           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6253         }
6254
6255     default:
6256       if (x86_maybe_negate_const_int (&operands[2], QImode))
6257         {
6258           if (widen)
6259             return "sub{l}\t{%2, %k0|%k0, %2}";
6260           else
6261             return "sub{b}\t{%2, %0|%0, %2}";
6262         }
6263       if (widen)
6264         return "add{l}\t{%k2, %k0|%k0, %k2}";
6265       else
6266         return "add{b}\t{%2, %0|%0, %2}";
6267     }
6268 }
6269   [(set (attr "type")
6270      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6271         (const_string "incdec")
6272         (const_string "alu")))
6273    (set (attr "length_immediate")
6274       (if_then_else
6275         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6276         (const_string "1")
6277         (const_string "*")))
6278    (set_attr "mode" "QI,QI,SI")])
6279
6280 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6281 (define_insn "*addqi_1_lea"
6282   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6283         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6284                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6285    (clobber (reg:CC FLAGS_REG))]
6286   "!TARGET_PARTIAL_REG_STALL
6287    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6288 {
6289   int widen = (which_alternative == 2);
6290   switch (get_attr_type (insn))
6291     {
6292     case TYPE_LEA:
6293       return "#";
6294     case TYPE_INCDEC:
6295       if (operands[2] == const1_rtx)
6296         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6297       else
6298         {
6299           gcc_assert (operands[2] == constm1_rtx);
6300           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6301         }
6302
6303     default:
6304       if (x86_maybe_negate_const_int (&operands[2], QImode))
6305         {
6306           if (widen)
6307             return "sub{l}\t{%2, %k0|%k0, %2}";
6308           else
6309             return "sub{b}\t{%2, %0|%0, %2}";
6310         }
6311       if (widen)
6312         return "add{l}\t{%k2, %k0|%k0, %k2}";
6313       else
6314         return "add{b}\t{%2, %0|%0, %2}";
6315     }
6316 }
6317   [(set (attr "type")
6318      (if_then_else (eq_attr "alternative" "3")
6319         (const_string "lea")
6320         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6321            (const_string "incdec")
6322            (const_string "alu"))))
6323    (set (attr "length_immediate")
6324       (if_then_else
6325         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6326         (const_string "1")
6327         (const_string "*")))
6328    (set_attr "mode" "QI,QI,SI,SI")])
6329
6330 (define_insn "*addqi_1_slp"
6331   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6332         (plus:QI (match_dup 0)
6333                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6334    (clobber (reg:CC FLAGS_REG))]
6335   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6336    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6337 {
6338   switch (get_attr_type (insn))
6339     {
6340     case TYPE_INCDEC:
6341       if (operands[1] == const1_rtx)
6342         return "inc{b}\t%0";
6343       else
6344         {
6345           gcc_assert (operands[1] == constm1_rtx);
6346           return "dec{b}\t%0";
6347         }
6348
6349     default:
6350       if (x86_maybe_negate_const_int (&operands[1], QImode))
6351         return "sub{b}\t{%1, %0|%0, %1}";
6352
6353       return "add{b}\t{%1, %0|%0, %1}";
6354     }
6355 }
6356   [(set (attr "type")
6357      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6358         (const_string "incdec")
6359         (const_string "alu1")))
6360    (set (attr "memory")
6361      (if_then_else (match_operand 1 "memory_operand" "")
6362         (const_string "load")
6363         (const_string "none")))
6364    (set_attr "mode" "QI")])
6365
6366 (define_insn "*add<mode>_2"
6367   [(set (reg FLAGS_REG)
6368         (compare
6369           (plus:SWI48
6370             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6371             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6372           (const_int 0)))
6373    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6374         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6375   "ix86_match_ccmode (insn, CCGOCmode)
6376    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6377    /* Current assemblers are broken and do not allow @GOTOFF in
6378       ought but a memory context.  */
6379    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6380 {
6381   switch (get_attr_type (insn))
6382     {
6383     case TYPE_INCDEC:
6384       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6385       if (operands[2] == const1_rtx)
6386         return "inc{<imodesuffix>}\t%0";
6387       else
6388         {
6389           gcc_assert (operands[2] == constm1_rtx);
6390           return "dec{<imodesuffix>}\t%0";
6391         }
6392
6393     default:
6394       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6395       /* ???? In DImode, we ought to handle there the 32bit case too
6396          - do we need new constraint?  */
6397       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6398         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6399
6400       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6401     }
6402 }
6403   [(set (attr "type")
6404      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6405         (const_string "incdec")
6406         (const_string "alu")))
6407    (set (attr "length_immediate")
6408       (if_then_else
6409         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6410         (const_string "1")
6411         (const_string "*")))
6412    (set_attr "mode" "<MODE>")])
6413
6414 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6415 (define_insn "*addsi_2_zext"
6416   [(set (reg FLAGS_REG)
6417         (compare
6418           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6419                    (match_operand:SI 2 "general_operand" "g"))
6420           (const_int 0)))
6421    (set (match_operand:DI 0 "register_operand" "=r")
6422         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6423   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6424    && ix86_binary_operator_ok (PLUS, SImode, operands)
6425    /* Current assemblers are broken and do not allow @GOTOFF in
6426       ought but a memory context.  */
6427    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6428 {
6429   switch (get_attr_type (insn))
6430     {
6431     case TYPE_INCDEC:
6432       if (operands[2] == const1_rtx)
6433         return "inc{l}\t%k0";
6434       else
6435         {
6436           gcc_assert (operands[2] == constm1_rtx);
6437           return "dec{l}\t%k0";
6438         }
6439
6440     default:
6441       if (x86_maybe_negate_const_int (&operands[2], SImode))
6442         return "sub{l}\t{%2, %k0|%k0, %2}";
6443
6444       return "add{l}\t{%2, %k0|%k0, %2}";
6445     }
6446 }
6447   [(set (attr "type")
6448      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6449         (const_string "incdec")
6450         (const_string "alu")))
6451    (set (attr "length_immediate")
6452       (if_then_else
6453         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6454         (const_string "1")
6455         (const_string "*")))
6456    (set_attr "mode" "SI")])
6457
6458 (define_insn "*addhi_2"
6459   [(set (reg FLAGS_REG)
6460         (compare
6461           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6462                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6463           (const_int 0)))
6464    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6465         (plus:HI (match_dup 1) (match_dup 2)))]
6466   "ix86_match_ccmode (insn, CCGOCmode)
6467    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6468 {
6469   switch (get_attr_type (insn))
6470     {
6471     case TYPE_INCDEC:
6472       if (operands[2] == const1_rtx)
6473         return "inc{w}\t%0";
6474       else
6475         {
6476           gcc_assert (operands[2] == constm1_rtx);
6477           return "dec{w}\t%0";
6478         }
6479
6480     default:
6481       if (x86_maybe_negate_const_int (&operands[2], HImode))
6482         return "sub{w}\t{%2, %0|%0, %2}";
6483
6484       return "add{w}\t{%2, %0|%0, %2}";
6485     }
6486 }
6487   [(set (attr "type")
6488      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6489         (const_string "incdec")
6490         (const_string "alu")))
6491    (set (attr "length_immediate")
6492       (if_then_else
6493         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6494         (const_string "1")
6495         (const_string "*")))
6496    (set_attr "mode" "HI")])
6497
6498 (define_insn "*addqi_2"
6499   [(set (reg FLAGS_REG)
6500         (compare
6501           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6502                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6503           (const_int 0)))
6504    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6505         (plus:QI (match_dup 1) (match_dup 2)))]
6506   "ix86_match_ccmode (insn, CCGOCmode)
6507    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6508 {
6509   switch (get_attr_type (insn))
6510     {
6511     case TYPE_INCDEC:
6512       if (operands[2] == const1_rtx)
6513         return "inc{b}\t%0";
6514       else
6515         {
6516           gcc_assert (operands[2] == constm1_rtx
6517                       || (CONST_INT_P (operands[2])
6518                           && INTVAL (operands[2]) == 255));
6519           return "dec{b}\t%0";
6520         }
6521
6522     default:
6523       if (x86_maybe_negate_const_int (&operands[2], QImode))
6524         return "sub{b}\t{%2, %0|%0, %2}";
6525
6526       return "add{b}\t{%2, %0|%0, %2}";
6527     }
6528 }
6529   [(set (attr "type")
6530      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6531         (const_string "incdec")
6532         (const_string "alu")))
6533    (set_attr "mode" "QI")])
6534
6535 (define_insn "*add<mode>_3"
6536   [(set (reg FLAGS_REG)
6537         (compare
6538           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6539           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6540    (clobber (match_scratch:SWI48 0 "=r"))]
6541   "ix86_match_ccmode (insn, CCZmode)
6542    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6543    /* Current assemblers are broken and do not allow @GOTOFF in
6544       ought but a memory context.  */
6545    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6546 {
6547   switch (get_attr_type (insn))
6548     {
6549     case TYPE_INCDEC:
6550       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6551       if (operands[2] == const1_rtx)
6552         return "inc{<imodesuffix>}\t%0";
6553       else
6554         {
6555           gcc_assert (operands[2] == constm1_rtx);
6556           return "dec{<imodesuffix>}\t%0";
6557         }
6558
6559     default:
6560       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6561       /* ???? In DImode, we ought to handle there the 32bit case too
6562          - do we need new constraint?  */
6563       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6564         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6565
6566       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6567     }
6568 }
6569   [(set (attr "type")
6570      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6571         (const_string "incdec")
6572         (const_string "alu")))
6573    (set (attr "length_immediate")
6574       (if_then_else
6575         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6576         (const_string "1")
6577         (const_string "*")))
6578    (set_attr "mode" "<MODE>")])
6579
6580 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6581 (define_insn "*addsi_3_zext"
6582   [(set (reg FLAGS_REG)
6583         (compare
6584           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6585           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6586    (set (match_operand:DI 0 "register_operand" "=r")
6587         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6588   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6589    && ix86_binary_operator_ok (PLUS, SImode, operands)
6590    /* Current assemblers are broken and do not allow @GOTOFF in
6591       ought but a memory context.  */
6592    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6593 {
6594   switch (get_attr_type (insn))
6595     {
6596     case TYPE_INCDEC:
6597       if (operands[2] == const1_rtx)
6598         return "inc{l}\t%k0";
6599       else
6600         {
6601           gcc_assert (operands[2] == constm1_rtx);
6602           return "dec{l}\t%k0";
6603         }
6604
6605     default:
6606       if (x86_maybe_negate_const_int (&operands[2], SImode))
6607         return "sub{l}\t{%2, %k0|%k0, %2}";
6608
6609       return "add{l}\t{%2, %k0|%k0, %2}";
6610     }
6611 }
6612   [(set (attr "type")
6613      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6614         (const_string "incdec")
6615         (const_string "alu")))
6616    (set (attr "length_immediate")
6617       (if_then_else
6618         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6619         (const_string "1")
6620         (const_string "*")))
6621    (set_attr "mode" "SI")])
6622
6623 (define_insn "*addhi_3"
6624   [(set (reg FLAGS_REG)
6625         (compare
6626           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6627           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6628    (clobber (match_scratch:HI 0 "=r"))]
6629   "ix86_match_ccmode (insn, CCZmode)
6630    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6631 {
6632   switch (get_attr_type (insn))
6633     {
6634     case TYPE_INCDEC:
6635       if (operands[2] == const1_rtx)
6636         return "inc{w}\t%0";
6637       else
6638         {
6639           gcc_assert (operands[2] == constm1_rtx);
6640           return "dec{w}\t%0";
6641         }
6642
6643     default:
6644       if (x86_maybe_negate_const_int (&operands[2], HImode))
6645         return "sub{w}\t{%2, %0|%0, %2}";
6646
6647       return "add{w}\t{%2, %0|%0, %2}";
6648     }
6649 }
6650   [(set (attr "type")
6651      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6652         (const_string "incdec")
6653         (const_string "alu")))
6654    (set (attr "length_immediate")
6655       (if_then_else
6656         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6657         (const_string "1")
6658         (const_string "*")))
6659    (set_attr "mode" "HI")])
6660
6661 (define_insn "*addqi_3"
6662   [(set (reg FLAGS_REG)
6663         (compare
6664           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6665           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6666    (clobber (match_scratch:QI 0 "=q"))]
6667   "ix86_match_ccmode (insn, CCZmode)
6668    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6669 {
6670   switch (get_attr_type (insn))
6671     {
6672     case TYPE_INCDEC:
6673       if (operands[2] == const1_rtx)
6674         return "inc{b}\t%0";
6675       else
6676         {
6677           gcc_assert (operands[2] == constm1_rtx
6678                       || (CONST_INT_P (operands[2])
6679                           && INTVAL (operands[2]) == 255));
6680           return "dec{b}\t%0";
6681         }
6682
6683     default:
6684       if (x86_maybe_negate_const_int (&operands[2], QImode))
6685         return "sub{b}\t{%2, %0|%0, %2}";
6686
6687       return "add{b}\t{%2, %0|%0, %2}";
6688     }
6689 }
6690   [(set (attr "type")
6691      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6692         (const_string "incdec")
6693         (const_string "alu")))
6694    (set_attr "mode" "QI")])
6695
6696 ; For comparisons against 1, -1 and 128, we may generate better code
6697 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6698 ; is matched then.  We can't accept general immediate, because for
6699 ; case of overflows,  the result is messed up.
6700 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6701 ; only for comparisons not depending on it.
6702
6703 (define_insn "*adddi_4"
6704   [(set (reg FLAGS_REG)
6705         (compare
6706           (match_operand:DI 1 "nonimmediate_operand" "0")
6707           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6708    (clobber (match_scratch:DI 0 "=rm"))]
6709   "TARGET_64BIT
6710    && ix86_match_ccmode (insn, CCGCmode)"
6711 {
6712   switch (get_attr_type (insn))
6713     {
6714     case TYPE_INCDEC:
6715       if (operands[2] == constm1_rtx)
6716         return "inc{q}\t%0";
6717       else
6718         {
6719           gcc_assert (operands[2] == const1_rtx);
6720           return "dec{q}\t%0";
6721         }
6722
6723     default:
6724       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6725       if (x86_maybe_negate_const_int (&operands[2], DImode))
6726         return "add{q}\t{%2, %0|%0, %2}";
6727
6728       return "sub{q}\t{%2, %0|%0, %2}";
6729     }
6730 }
6731   [(set (attr "type")
6732      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6733         (const_string "incdec")
6734         (const_string "alu")))
6735    (set (attr "length_immediate")
6736       (if_then_else
6737         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6738         (const_string "1")
6739         (const_string "*")))
6740    (set_attr "mode" "DI")])
6741
6742 ; For comparisons against 1, -1 and 128, we may generate better code
6743 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6744 ; is matched then.  We can't accept general immediate, because for
6745 ; case of overflows,  the result is messed up.
6746 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6747 ; only for comparisons not depending on it.
6748
6749 (define_insn "*addsi_4"
6750   [(set (reg FLAGS_REG)
6751         (compare
6752           (match_operand:SI 1 "nonimmediate_operand" "0")
6753           (match_operand:SI 2 "const_int_operand" "n")))
6754    (clobber (match_scratch:SI 0 "=rm"))]
6755   "ix86_match_ccmode (insn, CCGCmode)"
6756 {
6757   switch (get_attr_type (insn))
6758     {
6759     case TYPE_INCDEC:
6760       if (operands[2] == constm1_rtx)
6761         return "inc{l}\t%0";
6762       else
6763         {
6764           gcc_assert (operands[2] == const1_rtx);
6765           return "dec{l}\t%0";
6766         }
6767
6768     default:
6769       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6770       if (x86_maybe_negate_const_int (&operands[2], SImode))
6771         return "add{l}\t{%2, %0|%0, %2}";
6772
6773       return "sub{l}\t{%2, %0|%0, %2}";
6774     }
6775 }
6776   [(set (attr "type")
6777      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6778         (const_string "incdec")
6779         (const_string "alu")))
6780    (set (attr "length_immediate")
6781       (if_then_else
6782         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6783         (const_string "1")
6784         (const_string "*")))
6785    (set_attr "mode" "SI")])
6786
6787 ; See comments above addsi_4 for details.
6788
6789 (define_insn "*addhi_4"
6790   [(set (reg FLAGS_REG)
6791         (compare
6792           (match_operand:HI 1 "nonimmediate_operand" "0")
6793           (match_operand:HI 2 "const_int_operand" "n")))
6794    (clobber (match_scratch:HI 0 "=rm"))]
6795   "ix86_match_ccmode (insn, CCGCmode)"
6796 {
6797   switch (get_attr_type (insn))
6798     {
6799     case TYPE_INCDEC:
6800       if (operands[2] == constm1_rtx)
6801         return "inc{w}\t%0";
6802       else
6803         {
6804           gcc_assert (operands[2] == const1_rtx);
6805           return "dec{w}\t%0";
6806         }
6807
6808     default:
6809       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6810       if (x86_maybe_negate_const_int (&operands[2], HImode))
6811         return "add{w}\t{%2, %0|%0, %2}";
6812
6813       return "sub{w}\t{%2, %0|%0, %2}";
6814     }
6815 }
6816   [(set (attr "type")
6817      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6818         (const_string "incdec")
6819         (const_string "alu")))
6820    (set (attr "length_immediate")
6821       (if_then_else
6822         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6823         (const_string "1")
6824         (const_string "*")))
6825    (set_attr "mode" "HI")])
6826
6827 ; See comments above addsi_4 for details.
6828
6829 (define_insn "*addqi_4"
6830   [(set (reg FLAGS_REG)
6831         (compare
6832           (match_operand:QI 1 "nonimmediate_operand" "0")
6833           (match_operand:QI 2 "const_int_operand" "n")))
6834    (clobber (match_scratch:QI 0 "=qm"))]
6835   "ix86_match_ccmode (insn, CCGCmode)"
6836 {
6837   switch (get_attr_type (insn))
6838     {
6839     case TYPE_INCDEC:
6840       if (operands[2] == constm1_rtx
6841           || (CONST_INT_P (operands[2])
6842               && INTVAL (operands[2]) == 255))
6843         return "inc{b}\t%0";
6844       else
6845         {
6846           gcc_assert (operands[2] == const1_rtx);
6847           return "dec{b}\t%0";
6848         }
6849
6850     default:
6851       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6852       if (x86_maybe_negate_const_int (&operands[2], QImode))
6853         return "add{b}\t{%2, %0|%0, %2}";
6854
6855       return "sub{b}\t{%2, %0|%0, %2}";
6856     }
6857 }
6858   [(set (attr "type")
6859      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6860         (const_string "incdec")
6861         (const_string "alu")))
6862    (set_attr "mode" "QI")])
6863
6864 (define_insn "*add<mode>_5"
6865   [(set (reg FLAGS_REG)
6866         (compare
6867           (plus:SWI48
6868             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6869             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6870           (const_int 0)))
6871    (clobber (match_scratch:SWI48 0 "=r"))]
6872   "ix86_match_ccmode (insn, CCGOCmode)
6873    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6874    /* Current assemblers are broken and do not allow @GOTOFF in
6875       ought but a memory context.  */
6876    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6877 {
6878   switch (get_attr_type (insn))
6879     {
6880     case TYPE_INCDEC:
6881       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6882       if (operands[2] == const1_rtx)
6883         return "inc{<imodesuffix>}\t%0";
6884       else
6885         {
6886           gcc_assert (operands[2] == constm1_rtx);
6887           return "dec{<imodesuffix>}\t%0";
6888         }
6889
6890     default:
6891       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6892       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6893         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6894
6895       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6896     }
6897 }
6898   [(set (attr "type")
6899      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6900         (const_string "incdec")
6901         (const_string "alu")))
6902    (set (attr "length_immediate")
6903       (if_then_else
6904         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6905         (const_string "1")
6906         (const_string "*")))
6907    (set_attr "mode" "<MODE>")])
6908
6909 (define_insn "*addhi_5"
6910   [(set (reg FLAGS_REG)
6911         (compare
6912           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6913                    (match_operand:HI 2 "general_operand" "rmn"))
6914           (const_int 0)))
6915    (clobber (match_scratch:HI 0 "=r"))]
6916   "ix86_match_ccmode (insn, CCGOCmode)
6917    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6918 {
6919   switch (get_attr_type (insn))
6920     {
6921     case TYPE_INCDEC:
6922       if (operands[2] == const1_rtx)
6923         return "inc{w}\t%0";
6924       else
6925         {
6926           gcc_assert (operands[2] == constm1_rtx);
6927           return "dec{w}\t%0";
6928         }
6929
6930     default:
6931       if (x86_maybe_negate_const_int (&operands[2], HImode))
6932         return "sub{w}\t{%2, %0|%0, %2}";
6933
6934       return "add{w}\t{%2, %0|%0, %2}";
6935     }
6936 }
6937   [(set (attr "type")
6938      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6939         (const_string "incdec")
6940         (const_string "alu")))
6941    (set (attr "length_immediate")
6942       (if_then_else
6943         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6944         (const_string "1")
6945         (const_string "*")))
6946    (set_attr "mode" "HI")])
6947
6948 (define_insn "*addqi_5"
6949   [(set (reg FLAGS_REG)
6950         (compare
6951           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6952                    (match_operand:QI 2 "general_operand" "qmn"))
6953           (const_int 0)))
6954    (clobber (match_scratch:QI 0 "=q"))]
6955   "ix86_match_ccmode (insn, CCGOCmode)
6956    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6957 {
6958   switch (get_attr_type (insn))
6959     {
6960     case TYPE_INCDEC:
6961       if (operands[2] == const1_rtx)
6962         return "inc{b}\t%0";
6963       else
6964         {
6965           gcc_assert (operands[2] == constm1_rtx
6966                       || (CONST_INT_P (operands[2])
6967                           && INTVAL (operands[2]) == 255));
6968           return "dec{b}\t%0";
6969         }
6970
6971     default:
6972       if (x86_maybe_negate_const_int (&operands[2], QImode))
6973         return "sub{b}\t{%2, %0|%0, %2}";
6974
6975       return "add{b}\t{%2, %0|%0, %2}";
6976     }
6977 }
6978   [(set (attr "type")
6979      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6980         (const_string "incdec")
6981         (const_string "alu")))
6982    (set_attr "mode" "QI")])
6983
6984 (define_insn "*addqi_ext_1_rex64"
6985   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6986                          (const_int 8)
6987                          (const_int 8))
6988         (plus:SI
6989           (zero_extract:SI
6990             (match_operand 1 "ext_register_operand" "0")
6991             (const_int 8)
6992             (const_int 8))
6993           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6994    (clobber (reg:CC FLAGS_REG))]
6995   "TARGET_64BIT"
6996 {
6997   switch (get_attr_type (insn))
6998     {
6999     case TYPE_INCDEC:
7000       if (operands[2] == const1_rtx)
7001         return "inc{b}\t%h0";
7002       else
7003         {
7004           gcc_assert (operands[2] == constm1_rtx
7005                       || (CONST_INT_P (operands[2])
7006                           && INTVAL (operands[2]) == 255));
7007           return "dec{b}\t%h0";
7008         }
7009
7010     default:
7011       return "add{b}\t{%2, %h0|%h0, %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 "modrm" "1")
7019    (set_attr "mode" "QI")])
7020
7021 (define_insn "addqi_ext_1"
7022   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7023                          (const_int 8)
7024                          (const_int 8))
7025         (plus:SI
7026           (zero_extract:SI
7027             (match_operand 1 "ext_register_operand" "0")
7028             (const_int 8)
7029             (const_int 8))
7030           (match_operand:QI 2 "general_operand" "Qmn")))
7031    (clobber (reg:CC FLAGS_REG))]
7032   "!TARGET_64BIT"
7033 {
7034   switch (get_attr_type (insn))
7035     {
7036     case TYPE_INCDEC:
7037       if (operands[2] == const1_rtx)
7038         return "inc{b}\t%h0";
7039       else
7040         {
7041           gcc_assert (operands[2] == constm1_rtx
7042                       || (CONST_INT_P (operands[2])
7043                           && INTVAL (operands[2]) == 255));
7044           return "dec{b}\t%h0";
7045         }
7046
7047     default:
7048       return "add{b}\t{%2, %h0|%h0, %2}";
7049     }
7050 }
7051   [(set (attr "type")
7052      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7053         (const_string "incdec")
7054         (const_string "alu")))
7055    (set_attr "modrm" "1")
7056    (set_attr "mode" "QI")])
7057
7058 (define_insn "*addqi_ext_2"
7059   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7060                          (const_int 8)
7061                          (const_int 8))
7062         (plus:SI
7063           (zero_extract:SI
7064             (match_operand 1 "ext_register_operand" "%0")
7065             (const_int 8)
7066             (const_int 8))
7067           (zero_extract:SI
7068             (match_operand 2 "ext_register_operand" "Q")
7069             (const_int 8)
7070             (const_int 8))))
7071    (clobber (reg:CC FLAGS_REG))]
7072   ""
7073   "add{b}\t{%h2, %h0|%h0, %h2}"
7074   [(set_attr "type" "alu")
7075    (set_attr "mode" "QI")])
7076
7077 ;; The lea patterns for non-Pmodes needs to be matched by
7078 ;; several insns converted to real lea by splitters.
7079
7080 (define_insn_and_split "*lea_general_1"
7081   [(set (match_operand 0 "register_operand" "=r")
7082         (plus (plus (match_operand 1 "index_register_operand" "l")
7083                     (match_operand 2 "register_operand" "r"))
7084               (match_operand 3 "immediate_operand" "i")))]
7085   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7086     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7087    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7088    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7089    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7090    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7091        || GET_MODE (operands[3]) == VOIDmode)"
7092   "#"
7093   "&& reload_completed"
7094   [(const_int 0)]
7095 {
7096   rtx pat;
7097   operands[0] = gen_lowpart (SImode, operands[0]);
7098   operands[1] = gen_lowpart (Pmode, operands[1]);
7099   operands[2] = gen_lowpart (Pmode, operands[2]);
7100   operands[3] = gen_lowpart (Pmode, operands[3]);
7101   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7102                       operands[3]);
7103   if (Pmode != SImode)
7104     pat = gen_rtx_SUBREG (SImode, pat, 0);
7105   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7106   DONE;
7107 }
7108   [(set_attr "type" "lea")
7109    (set_attr "mode" "SI")])
7110
7111 (define_insn_and_split "*lea_general_1_zext"
7112   [(set (match_operand:DI 0 "register_operand" "=r")
7113         (zero_extend:DI
7114           (plus:SI (plus:SI
7115                      (match_operand:SI 1 "index_register_operand" "l")
7116                      (match_operand:SI 2 "register_operand" "r"))
7117                    (match_operand:SI 3 "immediate_operand" "i"))))]
7118   "TARGET_64BIT"
7119   "#"
7120   "&& reload_completed"
7121   [(set (match_dup 0)
7122         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7123                                                      (match_dup 2))
7124                                             (match_dup 3)) 0)))]
7125 {
7126   operands[1] = gen_lowpart (Pmode, operands[1]);
7127   operands[2] = gen_lowpart (Pmode, operands[2]);
7128   operands[3] = gen_lowpart (Pmode, operands[3]);
7129 }
7130   [(set_attr "type" "lea")
7131    (set_attr "mode" "SI")])
7132
7133 (define_insn_and_split "*lea_general_2"
7134   [(set (match_operand 0 "register_operand" "=r")
7135         (plus (mult (match_operand 1 "index_register_operand" "l")
7136                     (match_operand 2 "const248_operand" "i"))
7137               (match_operand 3 "nonmemory_operand" "ri")))]
7138   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7139     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7140    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7141    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7142    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7143        || GET_MODE (operands[3]) == VOIDmode)"
7144   "#"
7145   "&& reload_completed"
7146   [(const_int 0)]
7147 {
7148   rtx pat;
7149   operands[0] = gen_lowpart (SImode, operands[0]);
7150   operands[1] = gen_lowpart (Pmode, operands[1]);
7151   operands[3] = gen_lowpart (Pmode, operands[3]);
7152   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7153                       operands[3]);
7154   if (Pmode != SImode)
7155     pat = gen_rtx_SUBREG (SImode, pat, 0);
7156   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7157   DONE;
7158 }
7159   [(set_attr "type" "lea")
7160    (set_attr "mode" "SI")])
7161
7162 (define_insn_and_split "*lea_general_2_zext"
7163   [(set (match_operand:DI 0 "register_operand" "=r")
7164         (zero_extend:DI
7165           (plus:SI (mult:SI
7166                      (match_operand:SI 1 "index_register_operand" "l")
7167                      (match_operand:SI 2 "const248_operand" "n"))
7168                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7169   "TARGET_64BIT"
7170   "#"
7171   "&& reload_completed"
7172   [(set (match_dup 0)
7173         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7174                                                      (match_dup 2))
7175                                             (match_dup 3)) 0)))]
7176 {
7177   operands[1] = gen_lowpart (Pmode, operands[1]);
7178   operands[3] = gen_lowpart (Pmode, operands[3]);
7179 }
7180   [(set_attr "type" "lea")
7181    (set_attr "mode" "SI")])
7182
7183 (define_insn_and_split "*lea_general_3"
7184   [(set (match_operand 0 "register_operand" "=r")
7185         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7186                           (match_operand 2 "const248_operand" "i"))
7187                     (match_operand 3 "register_operand" "r"))
7188               (match_operand 4 "immediate_operand" "i")))]
7189   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7190     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7191    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7192    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7193    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7194   "#"
7195   "&& reload_completed"
7196   [(const_int 0)]
7197 {
7198   rtx pat;
7199   operands[0] = gen_lowpart (SImode, operands[0]);
7200   operands[1] = gen_lowpart (Pmode, operands[1]);
7201   operands[3] = gen_lowpart (Pmode, operands[3]);
7202   operands[4] = gen_lowpart (Pmode, operands[4]);
7203   pat = gen_rtx_PLUS (Pmode,
7204                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7205                                                          operands[2]),
7206                                     operands[3]),
7207                       operands[4]);
7208   if (Pmode != SImode)
7209     pat = gen_rtx_SUBREG (SImode, pat, 0);
7210   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7211   DONE;
7212 }
7213   [(set_attr "type" "lea")
7214    (set_attr "mode" "SI")])
7215
7216 (define_insn_and_split "*lea_general_3_zext"
7217   [(set (match_operand:DI 0 "register_operand" "=r")
7218         (zero_extend:DI
7219           (plus:SI (plus:SI
7220                      (mult:SI
7221                        (match_operand:SI 1 "index_register_operand" "l")
7222                        (match_operand:SI 2 "const248_operand" "n"))
7223                      (match_operand:SI 3 "register_operand" "r"))
7224                    (match_operand:SI 4 "immediate_operand" "i"))))]
7225   "TARGET_64BIT"
7226   "#"
7227   "&& reload_completed"
7228   [(set (match_dup 0)
7229         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7230                                                               (match_dup 2))
7231                                                      (match_dup 3))
7232                                             (match_dup 4)) 0)))]
7233 {
7234   operands[1] = gen_lowpart (Pmode, operands[1]);
7235   operands[3] = gen_lowpart (Pmode, operands[3]);
7236   operands[4] = gen_lowpart (Pmode, operands[4]);
7237 }
7238   [(set_attr "type" "lea")
7239    (set_attr "mode" "SI")])
7240
7241 ;; Convert lea to the lea pattern to avoid flags dependency.
7242 (define_split
7243   [(set (match_operand:DI 0 "register_operand" "")
7244         (plus:DI (match_operand:DI 1 "register_operand" "")
7245                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7246    (clobber (reg:CC FLAGS_REG))]
7247   "TARGET_64BIT && reload_completed 
7248    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7249   [(set (match_dup 0)
7250         (plus:DI (match_dup 1)
7251                  (match_dup 2)))]
7252   "")
7253
7254 ;; Convert lea to the lea pattern to avoid flags dependency.
7255 (define_split
7256   [(set (match_operand 0 "register_operand" "")
7257         (plus (match_operand 1 "register_operand" "")
7258               (match_operand 2 "nonmemory_operand" "")))
7259    (clobber (reg:CC FLAGS_REG))]
7260   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7261   [(const_int 0)]
7262 {
7263   rtx pat;
7264   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7265      may confuse gen_lowpart.  */
7266   if (GET_MODE (operands[0]) != Pmode)
7267     {
7268       operands[1] = gen_lowpart (Pmode, operands[1]);
7269       operands[2] = gen_lowpart (Pmode, operands[2]);
7270     }
7271   operands[0] = gen_lowpart (SImode, operands[0]);
7272   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7273   if (Pmode != SImode)
7274     pat = gen_rtx_SUBREG (SImode, pat, 0);
7275   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7276   DONE;
7277 })
7278
7279 ;; Convert lea to the lea pattern to avoid flags dependency.
7280 (define_split
7281   [(set (match_operand:DI 0 "register_operand" "")
7282         (zero_extend:DI
7283           (plus:SI (match_operand:SI 1 "register_operand" "")
7284                    (match_operand:SI 2 "nonmemory_operand" ""))))
7285    (clobber (reg:CC FLAGS_REG))]
7286   "TARGET_64BIT && reload_completed
7287    && true_regnum (operands[0]) != true_regnum (operands[1])"
7288   [(set (match_dup 0)
7289         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7290 {
7291   operands[1] = gen_lowpart (Pmode, operands[1]);
7292   operands[2] = gen_lowpart (Pmode, operands[2]);
7293 })
7294 \f
7295 ;; Subtract instructions
7296
7297 (define_expand "sub<mode>3"
7298   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7299         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7300                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7301   ""
7302   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7303
7304 (define_insn_and_split "*sub<dwi>3_doubleword"
7305   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7306         (minus:<DWI>
7307           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7308           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7309    (clobber (reg:CC FLAGS_REG))]
7310   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7311   "#"
7312   "reload_completed"
7313   [(parallel [(set (reg:CC FLAGS_REG)
7314                    (compare:CC (match_dup 1) (match_dup 2)))
7315               (set (match_dup 0)
7316                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7317    (parallel [(set (match_dup 3)
7318                    (minus:DWIH
7319                      (match_dup 4)
7320                      (plus:DWIH
7321                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7322                        (match_dup 5))))
7323               (clobber (reg:CC FLAGS_REG))])]
7324   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7325
7326 (define_insn "*sub<mode>_1"
7327   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7328         (minus:SWI
7329           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7330           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7331    (clobber (reg:CC FLAGS_REG))]
7332   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7333   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7334   [(set_attr "type" "alu")
7335    (set_attr "mode" "<MODE>")])
7336
7337 (define_insn "*subsi_1_zext"
7338   [(set (match_operand:DI 0 "register_operand" "=r")
7339         (zero_extend:DI
7340           (minus:SI (match_operand:SI 1 "register_operand" "0")
7341                     (match_operand:SI 2 "general_operand" "g"))))
7342    (clobber (reg:CC FLAGS_REG))]
7343   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7344   "sub{l}\t{%2, %k0|%k0, %2}"
7345   [(set_attr "type" "alu")
7346    (set_attr "mode" "SI")])
7347
7348 (define_insn "*subqi_1_slp"
7349   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7350         (minus:QI (match_dup 0)
7351                   (match_operand:QI 1 "general_operand" "qn,qm")))
7352    (clobber (reg:CC FLAGS_REG))]
7353   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7354    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7355   "sub{b}\t{%1, %0|%0, %1}"
7356   [(set_attr "type" "alu1")
7357    (set_attr "mode" "QI")])
7358
7359 (define_insn "*sub<mode>_2"
7360   [(set (reg FLAGS_REG)
7361         (compare
7362           (minus:SWI
7363             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7364             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7365           (const_int 0)))
7366    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7367         (minus:SWI (match_dup 1) (match_dup 2)))]
7368   "ix86_match_ccmode (insn, CCGOCmode)
7369    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7370   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7371   [(set_attr "type" "alu")
7372    (set_attr "mode" "<MODE>")])
7373
7374 (define_insn "*subsi_2_zext"
7375   [(set (reg FLAGS_REG)
7376         (compare
7377           (minus:SI (match_operand:SI 1 "register_operand" "0")
7378                     (match_operand:SI 2 "general_operand" "g"))
7379           (const_int 0)))
7380    (set (match_operand:DI 0 "register_operand" "=r")
7381         (zero_extend:DI
7382           (minus:SI (match_dup 1)
7383                     (match_dup 2))))]
7384   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7385    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7386   "sub{l}\t{%2, %k0|%k0, %2}"
7387   [(set_attr "type" "alu")
7388    (set_attr "mode" "SI")])
7389
7390 (define_insn "*sub<mode>_3"
7391   [(set (reg FLAGS_REG)
7392         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7393                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7394    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7395         (minus:SWI (match_dup 1) (match_dup 2)))]
7396   "ix86_match_ccmode (insn, CCmode)
7397    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7398   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7399   [(set_attr "type" "alu")
7400    (set_attr "mode" "<MODE>")])
7401
7402 (define_insn "*subsi_3_zext"
7403   [(set (reg FLAGS_REG)
7404         (compare (match_operand:SI 1 "register_operand" "0")
7405                  (match_operand:SI 2 "general_operand" "g")))
7406    (set (match_operand:DI 0 "register_operand" "=r")
7407         (zero_extend:DI
7408           (minus:SI (match_dup 1)
7409                     (match_dup 2))))]
7410   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7411    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7412   "sub{l}\t{%2, %1|%1, %2}"
7413   [(set_attr "type" "alu")
7414    (set_attr "mode" "SI")])
7415 \f
7416 ;; Add with carry and subtract with borrow
7417
7418 (define_expand "<plusminus_insn><mode>3_carry"
7419   [(parallel
7420     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7421           (plusminus:SWI
7422             (match_operand:SWI 1 "nonimmediate_operand" "")
7423             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7424                        [(match_operand 3 "flags_reg_operand" "")
7425                         (const_int 0)])
7426                       (match_operand:SWI 2 "<general_operand>" ""))))
7427      (clobber (reg:CC FLAGS_REG))])]
7428   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7429   "")
7430
7431 (define_insn "*<plusminus_insn><mode>3_carry"
7432   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7433         (plusminus:SWI
7434           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7435           (plus:SWI
7436             (match_operator 3 "ix86_carry_flag_operator"
7437              [(reg FLAGS_REG) (const_int 0)])
7438             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7439    (clobber (reg:CC FLAGS_REG))]
7440   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7441   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7442   [(set_attr "type" "alu")
7443    (set_attr "use_carry" "1")
7444    (set_attr "pent_pair" "pu")
7445    (set_attr "mode" "<MODE>")])
7446
7447 (define_insn "*addsi3_carry_zext"
7448   [(set (match_operand:DI 0 "register_operand" "=r")
7449         (zero_extend:DI
7450           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7451                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7452                              [(reg FLAGS_REG) (const_int 0)])
7453                             (match_operand:SI 2 "general_operand" "g")))))
7454    (clobber (reg:CC FLAGS_REG))]
7455   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7456   "adc{l}\t{%2, %k0|%k0, %2}"
7457   [(set_attr "type" "alu")
7458    (set_attr "use_carry" "1")
7459    (set_attr "pent_pair" "pu")
7460    (set_attr "mode" "SI")])
7461
7462 (define_insn "*subsi3_carry_zext"
7463   [(set (match_operand:DI 0 "register_operand" "=r")
7464         (zero_extend:DI
7465           (minus:SI (match_operand:SI 1 "register_operand" "0")
7466                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7467                               [(reg FLAGS_REG) (const_int 0)])
7468                              (match_operand:SI 2 "general_operand" "g")))))
7469    (clobber (reg:CC FLAGS_REG))]
7470   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7471   "sbb{l}\t{%2, %k0|%k0, %2}"
7472   [(set_attr "type" "alu")
7473    (set_attr "pent_pair" "pu")
7474    (set_attr "mode" "SI")])
7475 \f
7476 ;; Overflow setting add and subtract instructions
7477
7478 (define_insn "*add<mode>3_cconly_overflow"
7479   [(set (reg:CCC FLAGS_REG)
7480         (compare:CCC
7481           (plus:SWI
7482             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7483             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7484           (match_dup 1)))
7485    (clobber (match_scratch:SWI 0 "=<r>"))]
7486   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7487   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7488   [(set_attr "type" "alu")
7489    (set_attr "mode" "<MODE>")])
7490
7491 (define_insn "*sub<mode>3_cconly_overflow"
7492   [(set (reg:CCC FLAGS_REG)
7493         (compare:CCC
7494           (minus:SWI
7495             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7496             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7497           (match_dup 0)))]
7498   ""
7499   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7500   [(set_attr "type" "icmp")
7501    (set_attr "mode" "<MODE>")])
7502
7503 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7504   [(set (reg:CCC FLAGS_REG)
7505         (compare:CCC
7506             (plusminus:SWI
7507                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7508                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7509             (match_dup 1)))
7510    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7511         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7512   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7513   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7514   [(set_attr "type" "alu")
7515    (set_attr "mode" "<MODE>")])
7516
7517 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7518   [(set (reg:CCC FLAGS_REG)
7519         (compare:CCC
7520           (plusminus:SI
7521             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7522             (match_operand:SI 2 "general_operand" "g"))
7523           (match_dup 1)))
7524    (set (match_operand:DI 0 "register_operand" "=r")
7525         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7526   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7527   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7528   [(set_attr "type" "alu")
7529    (set_attr "mode" "SI")])
7530
7531 ;; The patterns that match these are at the end of this file.
7532
7533 (define_expand "<plusminus_insn>xf3"
7534   [(set (match_operand:XF 0 "register_operand" "")
7535         (plusminus:XF
7536           (match_operand:XF 1 "register_operand" "")
7537           (match_operand:XF 2 "register_operand" "")))]
7538   "TARGET_80387"
7539   "")
7540
7541 (define_expand "<plusminus_insn><mode>3"
7542   [(set (match_operand:MODEF 0 "register_operand" "")
7543         (plusminus:MODEF
7544           (match_operand:MODEF 1 "register_operand" "")
7545           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7546   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7547     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7548   "")
7549 \f
7550 ;; Multiply instructions
7551
7552 (define_expand "mul<mode>3"
7553   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7554                    (mult:SWIM248
7555                      (match_operand:SWIM248 1 "register_operand" "")
7556                      (match_operand:SWIM248 2 "<general_operand>" "")))
7557               (clobber (reg:CC FLAGS_REG))])]
7558   ""
7559   "")
7560
7561 (define_expand "mulqi3"
7562   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7563                    (mult:QI
7564                      (match_operand:QI 1 "register_operand" "")
7565                      (match_operand:QI 2 "nonimmediate_operand" "")))
7566               (clobber (reg:CC FLAGS_REG))])]
7567   "TARGET_QIMODE_MATH"
7568   "")
7569
7570 ;; On AMDFAM10
7571 ;; IMUL reg32/64, reg32/64, imm8        Direct
7572 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7573 ;; IMUL reg32/64, reg32/64, imm32       Direct
7574 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7575 ;; IMUL reg32/64, reg32/64              Direct
7576 ;; IMUL reg32/64, mem32/64              Direct
7577
7578 (define_insn "*mul<mode>3_1"
7579   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7580         (mult:SWI48
7581           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7582           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7583    (clobber (reg:CC FLAGS_REG))]
7584   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7585   "@
7586    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7587    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7588    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7589   [(set_attr "type" "imul")
7590    (set_attr "prefix_0f" "0,0,1")
7591    (set (attr "athlon_decode")
7592         (cond [(eq_attr "cpu" "athlon")
7593                   (const_string "vector")
7594                (eq_attr "alternative" "1")
7595                   (const_string "vector")
7596                (and (eq_attr "alternative" "2")
7597                     (match_operand 1 "memory_operand" ""))
7598                   (const_string "vector")]
7599               (const_string "direct")))
7600    (set (attr "amdfam10_decode")
7601         (cond [(and (eq_attr "alternative" "0,1")
7602                     (match_operand 1 "memory_operand" ""))
7603                   (const_string "vector")]
7604               (const_string "direct")))
7605    (set_attr "mode" "<MODE>")])
7606
7607 (define_insn "*mulsi3_1_zext"
7608   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7609         (zero_extend:DI
7610           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7611                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7612    (clobber (reg:CC FLAGS_REG))]
7613   "TARGET_64BIT
7614    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7615   "@
7616    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7617    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7618    imul{l}\t{%2, %k0|%k0, %2}"
7619   [(set_attr "type" "imul")
7620    (set_attr "prefix_0f" "0,0,1")
7621    (set (attr "athlon_decode")
7622         (cond [(eq_attr "cpu" "athlon")
7623                   (const_string "vector")
7624                (eq_attr "alternative" "1")
7625                   (const_string "vector")
7626                (and (eq_attr "alternative" "2")
7627                     (match_operand 1 "memory_operand" ""))
7628                   (const_string "vector")]
7629               (const_string "direct")))
7630    (set (attr "amdfam10_decode")
7631         (cond [(and (eq_attr "alternative" "0,1")
7632                     (match_operand 1 "memory_operand" ""))
7633                   (const_string "vector")]
7634               (const_string "direct")))
7635    (set_attr "mode" "SI")])
7636
7637 ;; On AMDFAM10
7638 ;; IMUL reg16, reg16, imm8      VectorPath
7639 ;; IMUL reg16, mem16, imm8      VectorPath
7640 ;; IMUL reg16, reg16, imm16     VectorPath
7641 ;; IMUL reg16, mem16, imm16     VectorPath
7642 ;; IMUL reg16, reg16            Direct
7643 ;; IMUL reg16, mem16            Direct
7644
7645 (define_insn "*mulhi3_1"
7646   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7647         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7648                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7649    (clobber (reg:CC FLAGS_REG))]
7650   "TARGET_HIMODE_MATH
7651    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7652   "@
7653    imul{w}\t{%2, %1, %0|%0, %1, %2}
7654    imul{w}\t{%2, %1, %0|%0, %1, %2}
7655    imul{w}\t{%2, %0|%0, %2}"
7656   [(set_attr "type" "imul")
7657    (set_attr "prefix_0f" "0,0,1")
7658    (set (attr "athlon_decode")
7659         (cond [(eq_attr "cpu" "athlon")
7660                   (const_string "vector")
7661                (eq_attr "alternative" "1,2")
7662                   (const_string "vector")]
7663               (const_string "direct")))
7664    (set (attr "amdfam10_decode")
7665         (cond [(eq_attr "alternative" "0,1")
7666                   (const_string "vector")]
7667               (const_string "direct")))
7668    (set_attr "mode" "HI")])
7669
7670 ;;On AMDFAM10
7671 ;; MUL reg8     Direct
7672 ;; MUL mem8     Direct
7673
7674 (define_insn "*mulqi3_1"
7675   [(set (match_operand:QI 0 "register_operand" "=a")
7676         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7677                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7678    (clobber (reg:CC FLAGS_REG))]
7679   "TARGET_QIMODE_MATH
7680    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7681   "mul{b}\t%2"
7682   [(set_attr "type" "imul")
7683    (set_attr "length_immediate" "0")
7684    (set (attr "athlon_decode")
7685      (if_then_else (eq_attr "cpu" "athlon")
7686         (const_string "vector")
7687         (const_string "direct")))
7688    (set_attr "amdfam10_decode" "direct")
7689    (set_attr "mode" "QI")])
7690
7691 (define_expand "<u>mul<mode><dwi>3"
7692   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7693                    (mult:<DWI>
7694                      (any_extend:<DWI>
7695                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7696                      (any_extend:<DWI>
7697                        (match_operand:DWIH 2 "register_operand" ""))))
7698               (clobber (reg:CC FLAGS_REG))])]
7699   ""
7700   "")
7701
7702 (define_expand "<u>mulqihi3"
7703   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7704                    (mult:HI
7705                      (any_extend:HI
7706                        (match_operand:QI 1 "nonimmediate_operand" ""))
7707                      (any_extend:HI
7708                        (match_operand:QI 2 "register_operand" ""))))
7709               (clobber (reg:CC FLAGS_REG))])]
7710   "TARGET_QIMODE_MATH"
7711   "")
7712
7713 (define_insn "*<u>mul<mode><dwi>3_1"
7714   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7715         (mult:<DWI>
7716           (any_extend:<DWI>
7717             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7718           (any_extend:<DWI>
7719             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7720    (clobber (reg:CC FLAGS_REG))]
7721   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7722   "<sgnprefix>mul{<imodesuffix>}\t%2"
7723   [(set_attr "type" "imul")
7724    (set_attr "length_immediate" "0")
7725    (set (attr "athlon_decode")
7726      (if_then_else (eq_attr "cpu" "athlon")
7727         (const_string "vector")
7728         (const_string "double")))
7729    (set_attr "amdfam10_decode" "double")
7730    (set_attr "mode" "<MODE>")])
7731
7732 (define_insn "*<u>mulqihi3_1"
7733   [(set (match_operand:HI 0 "register_operand" "=a")
7734         (mult:HI
7735           (any_extend:HI
7736             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7737           (any_extend:HI
7738             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7739    (clobber (reg:CC FLAGS_REG))]
7740   "TARGET_QIMODE_MATH
7741    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7742   "<sgnprefix>mul{b}\t%2"
7743   [(set_attr "type" "imul")
7744    (set_attr "length_immediate" "0")
7745    (set (attr "athlon_decode")
7746      (if_then_else (eq_attr "cpu" "athlon")
7747         (const_string "vector")
7748         (const_string "direct")))
7749    (set_attr "amdfam10_decode" "direct")
7750    (set_attr "mode" "QI")])
7751
7752 (define_expand "<s>mul<mode>3_highpart"
7753   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7754                    (truncate:SWI48
7755                      (lshiftrt:<DWI>
7756                        (mult:<DWI>
7757                          (any_extend:<DWI>
7758                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7759                          (any_extend:<DWI>
7760                            (match_operand:SWI48 2 "register_operand" "")))
7761                        (match_dup 4))))
7762               (clobber (match_scratch:SWI48 3 ""))
7763               (clobber (reg:CC FLAGS_REG))])]
7764   ""
7765   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7766
7767 (define_insn "*<s>muldi3_highpart_1"
7768   [(set (match_operand:DI 0 "register_operand" "=d")
7769         (truncate:DI
7770           (lshiftrt:TI
7771             (mult:TI
7772               (any_extend:TI
7773                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7774               (any_extend:TI
7775                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7776             (const_int 64))))
7777    (clobber (match_scratch:DI 3 "=1"))
7778    (clobber (reg:CC FLAGS_REG))]
7779   "TARGET_64BIT
7780    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7781   "<sgnprefix>mul{q}\t%2"
7782   [(set_attr "type" "imul")
7783    (set_attr "length_immediate" "0")
7784    (set (attr "athlon_decode")
7785      (if_then_else (eq_attr "cpu" "athlon")
7786         (const_string "vector")
7787         (const_string "double")))
7788    (set_attr "amdfam10_decode" "double")
7789    (set_attr "mode" "DI")])
7790
7791 (define_insn "*<s>mulsi3_highpart_1"
7792   [(set (match_operand:SI 0 "register_operand" "=d")
7793         (truncate:SI
7794           (lshiftrt:DI
7795             (mult:DI
7796               (any_extend:DI
7797                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7798               (any_extend:DI
7799                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7800             (const_int 32))))
7801    (clobber (match_scratch:SI 3 "=1"))
7802    (clobber (reg:CC FLAGS_REG))]
7803   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7804   "<sgnprefix>mul{l}\t%2"
7805   [(set_attr "type" "imul")
7806    (set_attr "length_immediate" "0")
7807    (set (attr "athlon_decode")
7808      (if_then_else (eq_attr "cpu" "athlon")
7809         (const_string "vector")
7810         (const_string "double")))
7811    (set_attr "amdfam10_decode" "double")
7812    (set_attr "mode" "SI")])
7813
7814 (define_insn "*<s>mulsi3_highpart_zext"
7815   [(set (match_operand:DI 0 "register_operand" "=d")
7816         (zero_extend:DI (truncate:SI
7817           (lshiftrt:DI
7818             (mult:DI (any_extend:DI
7819                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7820                      (any_extend:DI
7821                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7822             (const_int 32)))))
7823    (clobber (match_scratch:SI 3 "=1"))
7824    (clobber (reg:CC FLAGS_REG))]
7825   "TARGET_64BIT
7826    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7827   "<sgnprefix>mul{l}\t%2"
7828   [(set_attr "type" "imul")
7829    (set_attr "length_immediate" "0")
7830    (set (attr "athlon_decode")
7831      (if_then_else (eq_attr "cpu" "athlon")
7832         (const_string "vector")
7833         (const_string "double")))
7834    (set_attr "amdfam10_decode" "double")
7835    (set_attr "mode" "SI")])
7836
7837 ;; The patterns that match these are at the end of this file.
7838
7839 (define_expand "mulxf3"
7840   [(set (match_operand:XF 0 "register_operand" "")
7841         (mult:XF (match_operand:XF 1 "register_operand" "")
7842                  (match_operand:XF 2 "register_operand" "")))]
7843   "TARGET_80387"
7844   "")
7845
7846 (define_expand "mul<mode>3"
7847   [(set (match_operand:MODEF 0 "register_operand" "")
7848         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7849                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7850   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7851     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7852   "")
7853 \f
7854 ;; Divide instructions
7855
7856 (define_insn "<u>divqi3"
7857   [(set (match_operand:QI 0 "register_operand" "=a")
7858         (any_div:QI
7859           (match_operand:HI 1 "register_operand" "0")
7860           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7861    (clobber (reg:CC FLAGS_REG))]
7862   "TARGET_QIMODE_MATH"
7863   "<sgnprefix>div{b}\t%2"
7864   [(set_attr "type" "idiv")
7865    (set_attr "mode" "QI")])
7866
7867 ;; The patterns that match these are at the end of this file.
7868
7869 (define_expand "divxf3"
7870   [(set (match_operand:XF 0 "register_operand" "")
7871         (div:XF (match_operand:XF 1 "register_operand" "")
7872                 (match_operand:XF 2 "register_operand" "")))]
7873   "TARGET_80387"
7874   "")
7875
7876 (define_expand "divdf3"
7877   [(set (match_operand:DF 0 "register_operand" "")
7878         (div:DF (match_operand:DF 1 "register_operand" "")
7879                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7880    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7881     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7882    "")
7883
7884 (define_expand "divsf3"
7885   [(set (match_operand:SF 0 "register_operand" "")
7886         (div:SF (match_operand:SF 1 "register_operand" "")
7887                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7888   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7889     || TARGET_SSE_MATH"
7890 {
7891   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7892       && flag_finite_math_only && !flag_trapping_math
7893       && flag_unsafe_math_optimizations)
7894     {
7895       ix86_emit_swdivsf (operands[0], operands[1],
7896                          operands[2], SFmode);
7897       DONE;
7898     }
7899 })
7900 \f
7901 ;; Divmod instructions.
7902
7903 (define_expand "divmod<mode>4"
7904   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7905                    (div:SWIM248
7906                      (match_operand:SWIM248 1 "register_operand" "")
7907                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7908               (set (match_operand:SWIM248 3 "register_operand" "")
7909                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7910               (clobber (reg:CC FLAGS_REG))])]
7911   ""
7912   "")
7913
7914 (define_insn_and_split "*divmod<mode>4"
7915   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7916         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7917                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7918    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7919         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7920    (clobber (reg:CC FLAGS_REG))]
7921   ""
7922   "#"
7923   "reload_completed"
7924   [(parallel [(set (match_dup 1)
7925                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7926               (clobber (reg:CC FLAGS_REG))])
7927    (parallel [(set (match_dup 0)
7928                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7929               (set (match_dup 1)
7930                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7931               (use (match_dup 1))
7932               (clobber (reg:CC FLAGS_REG))])]
7933 {
7934   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7935
7936   if (<MODE>mode != HImode
7937       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7938     operands[4] = operands[2];
7939   else
7940     {
7941       /* Avoid use of cltd in favor of a mov+shift.  */
7942       emit_move_insn (operands[1], operands[2]);
7943       operands[4] = operands[1];
7944     }
7945 }
7946   [(set_attr "type" "multi")
7947    (set_attr "mode" "<MODE>")])
7948
7949 (define_insn "*divmod<mode>4_noext"
7950   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7951         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7952                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7953    (set (match_operand:SWIM248 1 "register_operand" "=d")
7954         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7955    (use (match_operand:SWIM248 4 "register_operand" "1"))
7956    (clobber (reg:CC FLAGS_REG))]
7957   ""
7958   "idiv{<imodesuffix>}\t%3"
7959   [(set_attr "type" "idiv")
7960    (set_attr "mode" "<MODE>")])
7961
7962 (define_expand "udivmod<mode>4"
7963   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7964                    (udiv:SWIM248
7965                      (match_operand:SWIM248 1 "register_operand" "")
7966                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7967               (set (match_operand:SWIM248 3 "register_operand" "")
7968                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7969               (clobber (reg:CC FLAGS_REG))])]
7970   ""
7971   "")
7972
7973 (define_insn_and_split "*udivmod<mode>4"
7974   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7975         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7976                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7977    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7978         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7979    (clobber (reg:CC FLAGS_REG))]
7980   ""
7981   "#"
7982   "reload_completed"
7983   [(set (match_dup 1) (const_int 0))
7984    (parallel [(set (match_dup 0)
7985                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7986               (set (match_dup 1)
7987                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7988               (use (match_dup 1))
7989               (clobber (reg:CC FLAGS_REG))])]
7990   ""
7991   [(set_attr "type" "multi")
7992    (set_attr "mode" "<MODE>")])
7993
7994 (define_insn "*udivmod<mode>4_noext"
7995   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7996         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7997                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7998    (set (match_operand:SWIM248 1 "register_operand" "=d")
7999         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8000    (use (match_operand:SWIM248 4 "register_operand" "1"))
8001    (clobber (reg:CC FLAGS_REG))]
8002   ""
8003   "div{<imodesuffix>}\t%3"
8004   [(set_attr "type" "idiv")
8005    (set_attr "mode" "<MODE>")])
8006
8007 ;; We cannot use div/idiv for double division, because it causes
8008 ;; "division by zero" on the overflow and that's not what we expect
8009 ;; from truncate.  Because true (non truncating) double division is
8010 ;; never generated, we can't create this insn anyway.
8011 ;
8012 ;(define_insn ""
8013 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8014 ;       (truncate:SI
8015 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8016 ;                  (zero_extend:DI
8017 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8018 ;   (set (match_operand:SI 3 "register_operand" "=d")
8019 ;       (truncate:SI
8020 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8021 ;   (clobber (reg:CC FLAGS_REG))]
8022 ;  ""
8023 ;  "div{l}\t{%2, %0|%0, %2}"
8024 ;  [(set_attr "type" "idiv")])
8025 \f
8026 ;;- Logical AND instructions
8027
8028 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8029 ;; Note that this excludes ah.
8030
8031 (define_expand "testsi_ccno_1"
8032   [(set (reg:CCNO FLAGS_REG)
8033         (compare:CCNO
8034           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8035                   (match_operand:SI 1 "nonmemory_operand" ""))
8036           (const_int 0)))]
8037   ""
8038   "")
8039
8040 (define_expand "testqi_ccz_1"
8041   [(set (reg:CCZ FLAGS_REG)
8042         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8043                              (match_operand:QI 1 "nonmemory_operand" ""))
8044                  (const_int 0)))]
8045   ""
8046   "")
8047
8048 (define_insn "*testdi_1"
8049   [(set (reg FLAGS_REG)
8050         (compare
8051          (and:DI
8052           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8053           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8054          (const_int 0)))]
8055   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8056    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8057   "@
8058    test{l}\t{%k1, %k0|%k0, %k1}
8059    test{l}\t{%k1, %k0|%k0, %k1}
8060    test{q}\t{%1, %0|%0, %1}
8061    test{q}\t{%1, %0|%0, %1}
8062    test{q}\t{%1, %0|%0, %1}"
8063   [(set_attr "type" "test")
8064    (set_attr "modrm" "0,1,0,1,1")
8065    (set_attr "mode" "SI,SI,DI,DI,DI")])
8066
8067 (define_insn "*testqi_1_maybe_si"
8068   [(set (reg FLAGS_REG)
8069         (compare
8070           (and:QI
8071             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8072             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8073           (const_int 0)))]
8074    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8075     && ix86_match_ccmode (insn,
8076                          CONST_INT_P (operands[1])
8077                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8078 {
8079   if (which_alternative == 3)
8080     {
8081       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8082         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8083       return "test{l}\t{%1, %k0|%k0, %1}";
8084     }
8085   return "test{b}\t{%1, %0|%0, %1}";
8086 }
8087   [(set_attr "type" "test")
8088    (set_attr "modrm" "0,1,1,1")
8089    (set_attr "mode" "QI,QI,QI,SI")
8090    (set_attr "pent_pair" "uv,np,uv,np")])
8091
8092 (define_insn "*test<mode>_1"
8093   [(set (reg FLAGS_REG)
8094         (compare
8095          (and:SWI124
8096           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8097           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8098          (const_int 0)))]
8099   "ix86_match_ccmode (insn, CCNOmode)
8100    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8101   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8102   [(set_attr "type" "test")
8103    (set_attr "modrm" "0,1,1")
8104    (set_attr "mode" "<MODE>")
8105    (set_attr "pent_pair" "uv,np,uv")])
8106
8107 (define_expand "testqi_ext_ccno_0"
8108   [(set (reg:CCNO FLAGS_REG)
8109         (compare:CCNO
8110           (and:SI
8111             (zero_extract:SI
8112               (match_operand 0 "ext_register_operand" "")
8113               (const_int 8)
8114               (const_int 8))
8115             (match_operand 1 "const_int_operand" ""))
8116           (const_int 0)))]
8117   ""
8118   "")
8119
8120 (define_insn "*testqi_ext_0"
8121   [(set (reg FLAGS_REG)
8122         (compare
8123           (and:SI
8124             (zero_extract:SI
8125               (match_operand 0 "ext_register_operand" "Q")
8126               (const_int 8)
8127               (const_int 8))
8128             (match_operand 1 "const_int_operand" "n"))
8129           (const_int 0)))]
8130   "ix86_match_ccmode (insn, CCNOmode)"
8131   "test{b}\t{%1, %h0|%h0, %1}"
8132   [(set_attr "type" "test")
8133    (set_attr "mode" "QI")
8134    (set_attr "length_immediate" "1")
8135    (set_attr "modrm" "1")
8136    (set_attr "pent_pair" "np")])
8137
8138 (define_insn "*testqi_ext_1_rex64"
8139   [(set (reg FLAGS_REG)
8140         (compare
8141           (and:SI
8142             (zero_extract:SI
8143               (match_operand 0 "ext_register_operand" "Q")
8144               (const_int 8)
8145               (const_int 8))
8146             (zero_extend:SI
8147               (match_operand:QI 1 "register_operand" "Q")))
8148           (const_int 0)))]
8149   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8150   "test{b}\t{%1, %h0|%h0, %1}"
8151   [(set_attr "type" "test")
8152    (set_attr "mode" "QI")])
8153
8154 (define_insn "*testqi_ext_1"
8155   [(set (reg FLAGS_REG)
8156         (compare
8157           (and:SI
8158             (zero_extract:SI
8159               (match_operand 0 "ext_register_operand" "Q")
8160               (const_int 8)
8161               (const_int 8))
8162             (zero_extend:SI
8163               (match_operand:QI 1 "general_operand" "Qm")))
8164           (const_int 0)))]
8165   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8166   "test{b}\t{%1, %h0|%h0, %1}"
8167   [(set_attr "type" "test")
8168    (set_attr "mode" "QI")])
8169
8170 (define_insn "*testqi_ext_2"
8171   [(set (reg FLAGS_REG)
8172         (compare
8173           (and:SI
8174             (zero_extract:SI
8175               (match_operand 0 "ext_register_operand" "Q")
8176               (const_int 8)
8177               (const_int 8))
8178             (zero_extract:SI
8179               (match_operand 1 "ext_register_operand" "Q")
8180               (const_int 8)
8181               (const_int 8)))
8182           (const_int 0)))]
8183   "ix86_match_ccmode (insn, CCNOmode)"
8184   "test{b}\t{%h1, %h0|%h0, %h1}"
8185   [(set_attr "type" "test")
8186    (set_attr "mode" "QI")])
8187
8188 (define_insn "*testqi_ext_3_rex64"
8189   [(set (reg FLAGS_REG)
8190         (compare (zero_extract:DI
8191                    (match_operand 0 "nonimmediate_operand" "rm")
8192                    (match_operand:DI 1 "const_int_operand" "")
8193                    (match_operand:DI 2 "const_int_operand" ""))
8194                  (const_int 0)))]
8195   "TARGET_64BIT
8196    && ix86_match_ccmode (insn, CCNOmode)
8197    && INTVAL (operands[1]) > 0
8198    && INTVAL (operands[2]) >= 0
8199    /* Ensure that resulting mask is zero or sign extended operand.  */
8200    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8201        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8202            && INTVAL (operands[1]) > 32))
8203    && (GET_MODE (operands[0]) == SImode
8204        || GET_MODE (operands[0]) == DImode
8205        || GET_MODE (operands[0]) == HImode
8206        || GET_MODE (operands[0]) == QImode)"
8207   "#")
8208
8209 ;; Combine likes to form bit extractions for some tests.  Humor it.
8210 (define_insn "*testqi_ext_3"
8211   [(set (reg FLAGS_REG)
8212         (compare (zero_extract:SI
8213                    (match_operand 0 "nonimmediate_operand" "rm")
8214                    (match_operand:SI 1 "const_int_operand" "")
8215                    (match_operand:SI 2 "const_int_operand" ""))
8216                  (const_int 0)))]
8217   "ix86_match_ccmode (insn, CCNOmode)
8218    && INTVAL (operands[1]) > 0
8219    && INTVAL (operands[2]) >= 0
8220    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8221    && (GET_MODE (operands[0]) == SImode
8222        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8223        || GET_MODE (operands[0]) == HImode
8224        || GET_MODE (operands[0]) == QImode)"
8225   "#")
8226
8227 (define_split
8228   [(set (match_operand 0 "flags_reg_operand" "")
8229         (match_operator 1 "compare_operator"
8230           [(zero_extract
8231              (match_operand 2 "nonimmediate_operand" "")
8232              (match_operand 3 "const_int_operand" "")
8233              (match_operand 4 "const_int_operand" ""))
8234            (const_int 0)]))]
8235   "ix86_match_ccmode (insn, CCNOmode)"
8236   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8237 {
8238   rtx val = operands[2];
8239   HOST_WIDE_INT len = INTVAL (operands[3]);
8240   HOST_WIDE_INT pos = INTVAL (operands[4]);
8241   HOST_WIDE_INT mask;
8242   enum machine_mode mode, submode;
8243
8244   mode = GET_MODE (val);
8245   if (MEM_P (val))
8246     {
8247       /* ??? Combine likes to put non-volatile mem extractions in QImode
8248          no matter the size of the test.  So find a mode that works.  */
8249       if (! MEM_VOLATILE_P (val))
8250         {
8251           mode = smallest_mode_for_size (pos + len, MODE_INT);
8252           val = adjust_address (val, mode, 0);
8253         }
8254     }
8255   else if (GET_CODE (val) == SUBREG
8256            && (submode = GET_MODE (SUBREG_REG (val)),
8257                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8258            && pos + len <= GET_MODE_BITSIZE (submode)
8259            && GET_MODE_CLASS (submode) == MODE_INT)
8260     {
8261       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8262       mode = submode;
8263       val = SUBREG_REG (val);
8264     }
8265   else if (mode == HImode && pos + len <= 8)
8266     {
8267       /* Small HImode tests can be converted to QImode.  */
8268       mode = QImode;
8269       val = gen_lowpart (QImode, val);
8270     }
8271
8272   if (len == HOST_BITS_PER_WIDE_INT)
8273     mask = -1;
8274   else
8275     mask = ((HOST_WIDE_INT)1 << len) - 1;
8276   mask <<= pos;
8277
8278   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8279 })
8280
8281 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8282 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8283 ;; this is relatively important trick.
8284 ;; Do the conversion only post-reload to avoid limiting of the register class
8285 ;; to QI regs.
8286 (define_split
8287   [(set (match_operand 0 "flags_reg_operand" "")
8288         (match_operator 1 "compare_operator"
8289           [(and (match_operand 2 "register_operand" "")
8290                 (match_operand 3 "const_int_operand" ""))
8291            (const_int 0)]))]
8292    "reload_completed
8293     && QI_REG_P (operands[2])
8294     && GET_MODE (operands[2]) != QImode
8295     && ((ix86_match_ccmode (insn, CCZmode)
8296          && !(INTVAL (operands[3]) & ~(255 << 8)))
8297         || (ix86_match_ccmode (insn, CCNOmode)
8298             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8299   [(set (match_dup 0)
8300         (match_op_dup 1
8301           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8302                    (match_dup 3))
8303            (const_int 0)]))]
8304   "operands[2] = gen_lowpart (SImode, operands[2]);
8305    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8306
8307 (define_split
8308   [(set (match_operand 0 "flags_reg_operand" "")
8309         (match_operator 1 "compare_operator"
8310           [(and (match_operand 2 "nonimmediate_operand" "")
8311                 (match_operand 3 "const_int_operand" ""))
8312            (const_int 0)]))]
8313    "reload_completed
8314     && GET_MODE (operands[2]) != QImode
8315     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8316     && ((ix86_match_ccmode (insn, CCZmode)
8317          && !(INTVAL (operands[3]) & ~255))
8318         || (ix86_match_ccmode (insn, CCNOmode)
8319             && !(INTVAL (operands[3]) & ~127)))"
8320   [(set (match_dup 0)
8321         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8322                          (const_int 0)]))]
8323   "operands[2] = gen_lowpart (QImode, operands[2]);
8324    operands[3] = gen_lowpart (QImode, operands[3]);")
8325
8326 ;; %%% This used to optimize known byte-wide and operations to memory,
8327 ;; and sometimes to QImode registers.  If this is considered useful,
8328 ;; it should be done with splitters.
8329
8330 (define_expand "and<mode>3"
8331   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8332         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8333                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8334   ""
8335   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8336
8337 (define_insn "*anddi_1"
8338   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8339         (and:DI
8340          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8341          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8342    (clobber (reg:CC FLAGS_REG))]
8343   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8344 {
8345   switch (get_attr_type (insn))
8346     {
8347     case TYPE_IMOVX:
8348       {
8349         enum machine_mode mode;
8350
8351         gcc_assert (CONST_INT_P (operands[2]));
8352         if (INTVAL (operands[2]) == 0xff)
8353           mode = QImode;
8354         else
8355           {
8356             gcc_assert (INTVAL (operands[2]) == 0xffff);
8357             mode = HImode;
8358           }
8359
8360         operands[1] = gen_lowpart (mode, operands[1]);
8361         if (mode == QImode)
8362           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8363         else
8364           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8365       }
8366
8367     default:
8368       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8369       if (get_attr_mode (insn) == MODE_SI)
8370         return "and{l}\t{%k2, %k0|%k0, %k2}";
8371       else
8372         return "and{q}\t{%2, %0|%0, %2}";
8373     }
8374 }
8375   [(set_attr "type" "alu,alu,alu,imovx")
8376    (set_attr "length_immediate" "*,*,*,0")
8377    (set (attr "prefix_rex")
8378      (if_then_else
8379        (and (eq_attr "type" "imovx")
8380             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8381                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8382        (const_string "1")
8383        (const_string "*")))
8384    (set_attr "mode" "SI,DI,DI,SI")])
8385
8386 (define_insn "*andsi_1"
8387   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8388         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8389                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8390    (clobber (reg:CC FLAGS_REG))]
8391   "ix86_binary_operator_ok (AND, SImode, operands)"
8392 {
8393   switch (get_attr_type (insn))
8394     {
8395     case TYPE_IMOVX:
8396       {
8397         enum machine_mode mode;
8398
8399         gcc_assert (CONST_INT_P (operands[2]));
8400         if (INTVAL (operands[2]) == 0xff)
8401           mode = QImode;
8402         else
8403           {
8404             gcc_assert (INTVAL (operands[2]) == 0xffff);
8405             mode = HImode;
8406           }
8407
8408         operands[1] = gen_lowpart (mode, operands[1]);
8409         if (mode == QImode)
8410           return "movz{bl|x}\t{%1, %0|%0, %1}";
8411         else
8412           return "movz{wl|x}\t{%1, %0|%0, %1}";
8413       }
8414
8415     default:
8416       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8417       return "and{l}\t{%2, %0|%0, %2}";
8418     }
8419 }
8420   [(set_attr "type" "alu,alu,imovx")
8421    (set (attr "prefix_rex")
8422      (if_then_else
8423        (and (eq_attr "type" "imovx")
8424             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8425                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8426        (const_string "1")
8427        (const_string "*")))
8428    (set_attr "length_immediate" "*,*,0")
8429    (set_attr "mode" "SI")])
8430
8431 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8432 (define_insn "*andsi_1_zext"
8433   [(set (match_operand:DI 0 "register_operand" "=r")
8434         (zero_extend:DI
8435           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8436                   (match_operand:SI 2 "general_operand" "g"))))
8437    (clobber (reg:CC FLAGS_REG))]
8438   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8439   "and{l}\t{%2, %k0|%k0, %2}"
8440   [(set_attr "type" "alu")
8441    (set_attr "mode" "SI")])
8442
8443 (define_insn "*andhi_1"
8444   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8445         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8446                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8447    (clobber (reg:CC FLAGS_REG))]
8448   "ix86_binary_operator_ok (AND, HImode, operands)"
8449 {
8450   switch (get_attr_type (insn))
8451     {
8452     case TYPE_IMOVX:
8453       gcc_assert (CONST_INT_P (operands[2]));
8454       gcc_assert (INTVAL (operands[2]) == 0xff);
8455       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8456
8457     default:
8458       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8459
8460       return "and{w}\t{%2, %0|%0, %2}";
8461     }
8462 }
8463   [(set_attr "type" "alu,alu,imovx")
8464    (set_attr "length_immediate" "*,*,0")
8465    (set (attr "prefix_rex")
8466      (if_then_else
8467        (and (eq_attr "type" "imovx")
8468             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8469        (const_string "1")
8470        (const_string "*")))
8471    (set_attr "mode" "HI,HI,SI")])
8472
8473 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8474 (define_insn "*andqi_1"
8475   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8476         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8477                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "ix86_binary_operator_ok (AND, QImode, operands)"
8480   "@
8481    and{b}\t{%2, %0|%0, %2}
8482    and{b}\t{%2, %0|%0, %2}
8483    and{l}\t{%k2, %k0|%k0, %k2}"
8484   [(set_attr "type" "alu")
8485    (set_attr "mode" "QI,QI,SI")])
8486
8487 (define_insn "*andqi_1_slp"
8488   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8489         (and:QI (match_dup 0)
8490                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8491    (clobber (reg:CC FLAGS_REG))]
8492   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8493    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8494   "and{b}\t{%1, %0|%0, %1}"
8495   [(set_attr "type" "alu1")
8496    (set_attr "mode" "QI")])
8497
8498 (define_split
8499   [(set (match_operand 0 "register_operand" "")
8500         (and (match_dup 0)
8501              (const_int -65536)))
8502    (clobber (reg:CC FLAGS_REG))]
8503   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8504     || optimize_function_for_size_p (cfun)"
8505   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8506   "operands[1] = gen_lowpart (HImode, operands[0]);")
8507
8508 (define_split
8509   [(set (match_operand 0 "ext_register_operand" "")
8510         (and (match_dup 0)
8511              (const_int -256)))
8512    (clobber (reg:CC FLAGS_REG))]
8513   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8514    && reload_completed"
8515   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8516   "operands[1] = gen_lowpart (QImode, operands[0]);")
8517
8518 (define_split
8519   [(set (match_operand 0 "ext_register_operand" "")
8520         (and (match_dup 0)
8521              (const_int -65281)))
8522    (clobber (reg:CC FLAGS_REG))]
8523   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8524    && reload_completed"
8525   [(parallel [(set (zero_extract:SI (match_dup 0)
8526                                     (const_int 8)
8527                                     (const_int 8))
8528                    (xor:SI
8529                      (zero_extract:SI (match_dup 0)
8530                                       (const_int 8)
8531                                       (const_int 8))
8532                      (zero_extract:SI (match_dup 0)
8533                                       (const_int 8)
8534                                       (const_int 8))))
8535               (clobber (reg:CC FLAGS_REG))])]
8536   "operands[0] = gen_lowpart (SImode, operands[0]);")
8537
8538 (define_insn "*anddi_2"
8539   [(set (reg FLAGS_REG)
8540         (compare
8541          (and:DI
8542           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8543           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8544          (const_int 0)))
8545    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8546         (and:DI (match_dup 1) (match_dup 2)))]
8547   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8548    && ix86_binary_operator_ok (AND, DImode, operands)"
8549   "@
8550    and{l}\t{%k2, %k0|%k0, %k2}
8551    and{q}\t{%2, %0|%0, %2}
8552    and{q}\t{%2, %0|%0, %2}"
8553   [(set_attr "type" "alu")
8554    (set_attr "mode" "SI,DI,DI")])
8555
8556 (define_insn "*andqi_2_maybe_si"
8557   [(set (reg FLAGS_REG)
8558         (compare (and:QI
8559                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8560                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8561                  (const_int 0)))
8562    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8563         (and:QI (match_dup 1) (match_dup 2)))]
8564   "ix86_binary_operator_ok (AND, QImode, operands)
8565    && ix86_match_ccmode (insn,
8566                          CONST_INT_P (operands[2])
8567                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8568 {
8569   if (which_alternative == 2)
8570     {
8571       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8572         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8573       return "and{l}\t{%2, %k0|%k0, %2}";
8574     }
8575   return "and{b}\t{%2, %0|%0, %2}";
8576 }
8577   [(set_attr "type" "alu")
8578    (set_attr "mode" "QI,QI,SI")])
8579
8580 (define_insn "*and<mode>_2"
8581   [(set (reg FLAGS_REG)
8582         (compare (and:SWI124
8583                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8584                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8585                  (const_int 0)))
8586    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8587         (and:SWI124 (match_dup 1) (match_dup 2)))]
8588   "ix86_match_ccmode (insn, CCNOmode)
8589    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8590   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8591   [(set_attr "type" "alu")
8592    (set_attr "mode" "<MODE>")])
8593
8594 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8595 (define_insn "*andsi_2_zext"
8596   [(set (reg FLAGS_REG)
8597         (compare (and:SI
8598                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8599                   (match_operand:SI 2 "general_operand" "g"))
8600                  (const_int 0)))
8601    (set (match_operand:DI 0 "register_operand" "=r")
8602         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8603   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8604    && ix86_binary_operator_ok (AND, SImode, operands)"
8605   "and{l}\t{%2, %k0|%k0, %2}"
8606   [(set_attr "type" "alu")
8607    (set_attr "mode" "SI")])
8608
8609 (define_insn "*andqi_2_slp"
8610   [(set (reg FLAGS_REG)
8611         (compare (and:QI
8612                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8613                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8614                  (const_int 0)))
8615    (set (strict_low_part (match_dup 0))
8616         (and:QI (match_dup 0) (match_dup 1)))]
8617   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8618    && ix86_match_ccmode (insn, CCNOmode)
8619    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8620   "and{b}\t{%1, %0|%0, %1}"
8621   [(set_attr "type" "alu1")
8622    (set_attr "mode" "QI")])
8623
8624 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8625 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8626 ;; for a QImode operand, which of course failed.
8627 (define_insn "andqi_ext_0"
8628   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8629                          (const_int 8)
8630                          (const_int 8))
8631         (and:SI
8632           (zero_extract:SI
8633             (match_operand 1 "ext_register_operand" "0")
8634             (const_int 8)
8635             (const_int 8))
8636           (match_operand 2 "const_int_operand" "n")))
8637    (clobber (reg:CC FLAGS_REG))]
8638   ""
8639   "and{b}\t{%2, %h0|%h0, %2}"
8640   [(set_attr "type" "alu")
8641    (set_attr "length_immediate" "1")
8642    (set_attr "modrm" "1")
8643    (set_attr "mode" "QI")])
8644
8645 ;; Generated by peephole translating test to and.  This shows up
8646 ;; often in fp comparisons.
8647 (define_insn "*andqi_ext_0_cc"
8648   [(set (reg FLAGS_REG)
8649         (compare
8650           (and:SI
8651             (zero_extract:SI
8652               (match_operand 1 "ext_register_operand" "0")
8653               (const_int 8)
8654               (const_int 8))
8655             (match_operand 2 "const_int_operand" "n"))
8656           (const_int 0)))
8657    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8658                          (const_int 8)
8659                          (const_int 8))
8660         (and:SI
8661           (zero_extract:SI
8662             (match_dup 1)
8663             (const_int 8)
8664             (const_int 8))
8665           (match_dup 2)))]
8666   "ix86_match_ccmode (insn, CCNOmode)"
8667   "and{b}\t{%2, %h0|%h0, %2}"
8668   [(set_attr "type" "alu")
8669    (set_attr "length_immediate" "1")
8670    (set_attr "modrm" "1")
8671    (set_attr "mode" "QI")])
8672
8673 (define_insn "*andqi_ext_1_rex64"
8674   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8675                          (const_int 8)
8676                          (const_int 8))
8677         (and:SI
8678           (zero_extract:SI
8679             (match_operand 1 "ext_register_operand" "0")
8680             (const_int 8)
8681             (const_int 8))
8682           (zero_extend:SI
8683             (match_operand 2 "ext_register_operand" "Q"))))
8684    (clobber (reg:CC FLAGS_REG))]
8685   "TARGET_64BIT"
8686   "and{b}\t{%2, %h0|%h0, %2}"
8687   [(set_attr "type" "alu")
8688    (set_attr "length_immediate" "0")
8689    (set_attr "mode" "QI")])
8690
8691 (define_insn "*andqi_ext_1"
8692   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8693                          (const_int 8)
8694                          (const_int 8))
8695         (and:SI
8696           (zero_extract:SI
8697             (match_operand 1 "ext_register_operand" "0")
8698             (const_int 8)
8699             (const_int 8))
8700           (zero_extend:SI
8701             (match_operand:QI 2 "general_operand" "Qm"))))
8702    (clobber (reg:CC FLAGS_REG))]
8703   "!TARGET_64BIT"
8704   "and{b}\t{%2, %h0|%h0, %2}"
8705   [(set_attr "type" "alu")
8706    (set_attr "length_immediate" "0")
8707    (set_attr "mode" "QI")])
8708
8709 (define_insn "*andqi_ext_2"
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_extract:SI
8719             (match_operand 2 "ext_register_operand" "Q")
8720             (const_int 8)
8721             (const_int 8))))
8722    (clobber (reg:CC FLAGS_REG))]
8723   ""
8724   "and{b}\t{%h2, %h0|%h0, %h2}"
8725   [(set_attr "type" "alu")
8726    (set_attr "length_immediate" "0")
8727    (set_attr "mode" "QI")])
8728
8729 ;; Convert wide AND instructions with immediate operand to shorter QImode
8730 ;; equivalents when possible.
8731 ;; Don't do the splitting with memory operands, since it introduces risk
8732 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8733 ;; for size, but that can (should?) be handled by generic code instead.
8734 (define_split
8735   [(set (match_operand 0 "register_operand" "")
8736         (and (match_operand 1 "register_operand" "")
8737              (match_operand 2 "const_int_operand" "")))
8738    (clobber (reg:CC FLAGS_REG))]
8739    "reload_completed
8740     && QI_REG_P (operands[0])
8741     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8742     && !(~INTVAL (operands[2]) & ~(255 << 8))
8743     && GET_MODE (operands[0]) != QImode"
8744   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8745                    (and:SI (zero_extract:SI (match_dup 1)
8746                                             (const_int 8) (const_int 8))
8747                            (match_dup 2)))
8748               (clobber (reg:CC FLAGS_REG))])]
8749   "operands[0] = gen_lowpart (SImode, operands[0]);
8750    operands[1] = gen_lowpart (SImode, operands[1]);
8751    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8752
8753 ;; Since AND can be encoded with sign extended immediate, this is only
8754 ;; profitable when 7th bit is not set.
8755 (define_split
8756   [(set (match_operand 0 "register_operand" "")
8757         (and (match_operand 1 "general_operand" "")
8758              (match_operand 2 "const_int_operand" "")))
8759    (clobber (reg:CC FLAGS_REG))]
8760    "reload_completed
8761     && ANY_QI_REG_P (operands[0])
8762     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8763     && !(~INTVAL (operands[2]) & ~255)
8764     && !(INTVAL (operands[2]) & 128)
8765     && GET_MODE (operands[0]) != QImode"
8766   [(parallel [(set (strict_low_part (match_dup 0))
8767                    (and:QI (match_dup 1)
8768                            (match_dup 2)))
8769               (clobber (reg:CC FLAGS_REG))])]
8770   "operands[0] = gen_lowpart (QImode, operands[0]);
8771    operands[1] = gen_lowpart (QImode, operands[1]);
8772    operands[2] = gen_lowpart (QImode, operands[2]);")
8773 \f
8774 ;; Logical inclusive and exclusive OR instructions
8775
8776 ;; %%% This used to optimize known byte-wide and operations to memory.
8777 ;; If this is considered useful, it should be done with splitters.
8778
8779 (define_expand "<code><mode>3"
8780   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8781         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8782                      (match_operand:SWIM 2 "<general_operand>" "")))]
8783   ""
8784   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8785
8786 (define_insn "*<code><mode>_1"
8787   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8788         (any_or:SWI248
8789          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8790          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8791    (clobber (reg:CC FLAGS_REG))]
8792   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8793   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8794   [(set_attr "type" "alu")
8795    (set_attr "mode" "<MODE>")])
8796
8797 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8798 (define_insn "*<code>qi_1"
8799   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8800         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8801                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8802    (clobber (reg:CC FLAGS_REG))]
8803   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8804   "@
8805    <logic>{b}\t{%2, %0|%0, %2}
8806    <logic>{b}\t{%2, %0|%0, %2}
8807    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8808   [(set_attr "type" "alu")
8809    (set_attr "mode" "QI,QI,SI")])
8810
8811 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8812 (define_insn "*<code>si_1_zext"
8813   [(set (match_operand:DI 0 "register_operand" "=r")
8814         (zero_extend:DI
8815          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8816                     (match_operand:SI 2 "general_operand" "g"))))
8817    (clobber (reg:CC FLAGS_REG))]
8818   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8819   "<logic>{l}\t{%2, %k0|%k0, %2}"
8820   [(set_attr "type" "alu")
8821    (set_attr "mode" "SI")])
8822
8823 (define_insn "*<code>si_1_zext_imm"
8824   [(set (match_operand:DI 0 "register_operand" "=r")
8825         (any_or:DI
8826          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8827          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8828    (clobber (reg:CC FLAGS_REG))]
8829   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8830   "<logic>{l}\t{%2, %k0|%k0, %2}"
8831   [(set_attr "type" "alu")
8832    (set_attr "mode" "SI")])
8833
8834 (define_insn "*<code>qi_1_slp"
8835   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8836         (any_or:QI (match_dup 0)
8837                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8838    (clobber (reg:CC FLAGS_REG))]
8839   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8840    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8841   "<logic>{b}\t{%1, %0|%0, %1}"
8842   [(set_attr "type" "alu1")
8843    (set_attr "mode" "QI")])
8844
8845 (define_insn "*<code><mode>_2"
8846   [(set (reg FLAGS_REG)
8847         (compare (any_or:SWI
8848                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8849                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8850                  (const_int 0)))
8851    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8852         (any_or:SWI (match_dup 1) (match_dup 2)))]
8853   "ix86_match_ccmode (insn, CCNOmode)
8854    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8855   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8856   [(set_attr "type" "alu")
8857    (set_attr "mode" "<MODE>")])
8858
8859 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8860 ;; ??? Special case for immediate operand is missing - it is tricky.
8861 (define_insn "*<code>si_2_zext"
8862   [(set (reg FLAGS_REG)
8863         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8864                             (match_operand:SI 2 "general_operand" "g"))
8865                  (const_int 0)))
8866    (set (match_operand:DI 0 "register_operand" "=r")
8867         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8868   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8869    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8870   "<logic>{l}\t{%2, %k0|%k0, %2}"
8871   [(set_attr "type" "alu")
8872    (set_attr "mode" "SI")])
8873
8874 (define_insn "*<code>si_2_zext_imm"
8875   [(set (reg FLAGS_REG)
8876         (compare (any_or:SI
8877                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8878                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8879                  (const_int 0)))
8880    (set (match_operand:DI 0 "register_operand" "=r")
8881         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8882   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8883    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8884   "<logic>{l}\t{%2, %k0|%k0, %2}"
8885   [(set_attr "type" "alu")
8886    (set_attr "mode" "SI")])
8887
8888 (define_insn "*<code>qi_2_slp"
8889   [(set (reg FLAGS_REG)
8890         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8891                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8892                  (const_int 0)))
8893    (set (strict_low_part (match_dup 0))
8894         (any_or:QI (match_dup 0) (match_dup 1)))]
8895   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8896    && ix86_match_ccmode (insn, CCNOmode)
8897    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8898   "<logic>{b}\t{%1, %0|%0, %1}"
8899   [(set_attr "type" "alu1")
8900    (set_attr "mode" "QI")])
8901
8902 (define_insn "*<code><mode>_3"
8903   [(set (reg FLAGS_REG)
8904         (compare (any_or:SWI
8905                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8906                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8907                  (const_int 0)))
8908    (clobber (match_scratch:SWI 0 "=<r>"))]
8909   "ix86_match_ccmode (insn, CCNOmode)
8910    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8911   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8912   [(set_attr "type" "alu")
8913    (set_attr "mode" "<MODE>")])
8914
8915 (define_insn "*<code>qi_ext_0"
8916   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8917                          (const_int 8)
8918                          (const_int 8))
8919         (any_or:SI
8920           (zero_extract:SI
8921             (match_operand 1 "ext_register_operand" "0")
8922             (const_int 8)
8923             (const_int 8))
8924           (match_operand 2 "const_int_operand" "n")))
8925    (clobber (reg:CC FLAGS_REG))]
8926   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8927   "<logic>{b}\t{%2, %h0|%h0, %2}"
8928   [(set_attr "type" "alu")
8929    (set_attr "length_immediate" "1")
8930    (set_attr "modrm" "1")
8931    (set_attr "mode" "QI")])
8932
8933 (define_insn "*<code>qi_ext_1_rex64"
8934   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8935                          (const_int 8)
8936                          (const_int 8))
8937         (any_or:SI
8938           (zero_extract:SI
8939             (match_operand 1 "ext_register_operand" "0")
8940             (const_int 8)
8941             (const_int 8))
8942           (zero_extend:SI
8943             (match_operand 2 "ext_register_operand" "Q"))))
8944    (clobber (reg:CC FLAGS_REG))]
8945   "TARGET_64BIT
8946    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8947   "<logic>{b}\t{%2, %h0|%h0, %2}"
8948   [(set_attr "type" "alu")
8949    (set_attr "length_immediate" "0")
8950    (set_attr "mode" "QI")])
8951
8952 (define_insn "*<code>qi_ext_1"
8953   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8954                          (const_int 8)
8955                          (const_int 8))
8956         (any_or:SI
8957           (zero_extract:SI
8958             (match_operand 1 "ext_register_operand" "0")
8959             (const_int 8)
8960             (const_int 8))
8961           (zero_extend:SI
8962             (match_operand:QI 2 "general_operand" "Qm"))))
8963    (clobber (reg:CC FLAGS_REG))]
8964   "!TARGET_64BIT
8965    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8966   "<logic>{b}\t{%2, %h0|%h0, %2}"
8967   [(set_attr "type" "alu")
8968    (set_attr "length_immediate" "0")
8969    (set_attr "mode" "QI")])
8970
8971 (define_insn "*<code>qi_ext_2"
8972   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8973                          (const_int 8)
8974                          (const_int 8))
8975         (any_or:SI
8976           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8977                            (const_int 8)
8978                            (const_int 8))
8979           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8980                            (const_int 8)
8981                            (const_int 8))))
8982    (clobber (reg:CC FLAGS_REG))]
8983   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8984   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8985   [(set_attr "type" "alu")
8986    (set_attr "length_immediate" "0")
8987    (set_attr "mode" "QI")])
8988
8989 (define_split
8990   [(set (match_operand 0 "register_operand" "")
8991         (any_or (match_operand 1 "register_operand" "")
8992                 (match_operand 2 "const_int_operand" "")))
8993    (clobber (reg:CC FLAGS_REG))]
8994    "reload_completed
8995     && QI_REG_P (operands[0])
8996     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8997     && !(INTVAL (operands[2]) & ~(255 << 8))
8998     && GET_MODE (operands[0]) != QImode"
8999   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9000                    (any_or:SI (zero_extract:SI (match_dup 1)
9001                                                (const_int 8) (const_int 8))
9002                               (match_dup 2)))
9003               (clobber (reg:CC FLAGS_REG))])]
9004   "operands[0] = gen_lowpart (SImode, operands[0]);
9005    operands[1] = gen_lowpart (SImode, operands[1]);
9006    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9007
9008 ;; Since OR can be encoded with sign extended immediate, this is only
9009 ;; profitable when 7th bit is set.
9010 (define_split
9011   [(set (match_operand 0 "register_operand" "")
9012         (any_or (match_operand 1 "general_operand" "")
9013                 (match_operand 2 "const_int_operand" "")))
9014    (clobber (reg:CC FLAGS_REG))]
9015    "reload_completed
9016     && ANY_QI_REG_P (operands[0])
9017     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9018     && !(INTVAL (operands[2]) & ~255)
9019     && (INTVAL (operands[2]) & 128)
9020     && GET_MODE (operands[0]) != QImode"
9021   [(parallel [(set (strict_low_part (match_dup 0))
9022                    (any_or:QI (match_dup 1)
9023                               (match_dup 2)))
9024               (clobber (reg:CC FLAGS_REG))])]
9025   "operands[0] = gen_lowpart (QImode, operands[0]);
9026    operands[1] = gen_lowpart (QImode, operands[1]);
9027    operands[2] = gen_lowpart (QImode, operands[2]);")
9028
9029 (define_expand "xorqi_cc_ext_1"
9030   [(parallel [
9031      (set (reg:CCNO FLAGS_REG)
9032           (compare:CCNO
9033             (xor:SI
9034               (zero_extract:SI
9035                 (match_operand 1 "ext_register_operand" "")
9036                 (const_int 8)
9037                 (const_int 8))
9038               (match_operand:QI 2 "general_operand" ""))
9039             (const_int 0)))
9040      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9041                            (const_int 8)
9042                            (const_int 8))
9043           (xor:SI
9044             (zero_extract:SI
9045              (match_dup 1)
9046              (const_int 8)
9047              (const_int 8))
9048             (match_dup 2)))])]
9049   ""
9050   "")
9051
9052 (define_insn "*xorqi_cc_ext_1_rex64"
9053   [(set (reg FLAGS_REG)
9054         (compare
9055           (xor:SI
9056             (zero_extract:SI
9057               (match_operand 1 "ext_register_operand" "0")
9058               (const_int 8)
9059               (const_int 8))
9060             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9061           (const_int 0)))
9062    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9063                          (const_int 8)
9064                          (const_int 8))
9065         (xor:SI
9066           (zero_extract:SI
9067            (match_dup 1)
9068            (const_int 8)
9069            (const_int 8))
9070           (match_dup 2)))]
9071   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9072   "xor{b}\t{%2, %h0|%h0, %2}"
9073   [(set_attr "type" "alu")
9074    (set_attr "modrm" "1")
9075    (set_attr "mode" "QI")])
9076
9077 (define_insn "*xorqi_cc_ext_1"
9078   [(set (reg FLAGS_REG)
9079         (compare
9080           (xor:SI
9081             (zero_extract:SI
9082               (match_operand 1 "ext_register_operand" "0")
9083               (const_int 8)
9084               (const_int 8))
9085             (match_operand:QI 2 "general_operand" "qmn"))
9086           (const_int 0)))
9087    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9088                          (const_int 8)
9089                          (const_int 8))
9090         (xor:SI
9091           (zero_extract:SI
9092            (match_dup 1)
9093            (const_int 8)
9094            (const_int 8))
9095           (match_dup 2)))]
9096   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9097   "xor{b}\t{%2, %h0|%h0, %2}"
9098   [(set_attr "type" "alu")
9099    (set_attr "modrm" "1")
9100    (set_attr "mode" "QI")])
9101 \f
9102 ;; Negation instructions
9103
9104 (define_expand "neg<mode>2"
9105   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9106         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9107   ""
9108   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9109
9110 (define_insn_and_split "*neg<dwi>2_doubleword"
9111   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9112         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9113    (clobber (reg:CC FLAGS_REG))]
9114   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9115   "#"
9116   "reload_completed"
9117   [(parallel
9118     [(set (reg:CCZ FLAGS_REG)
9119           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9120      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9121    (parallel
9122     [(set (match_dup 2)
9123           (plus:DWIH (match_dup 3)
9124                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9125                                 (const_int 0))))
9126      (clobber (reg:CC FLAGS_REG))])
9127    (parallel
9128     [(set (match_dup 2)
9129           (neg:DWIH (match_dup 2)))
9130      (clobber (reg:CC FLAGS_REG))])]
9131   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9132
9133 (define_insn "*neg<mode>2_1"
9134   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9135         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9136    (clobber (reg:CC FLAGS_REG))]
9137   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9138   "neg{<imodesuffix>}\t%0"
9139   [(set_attr "type" "negnot")
9140    (set_attr "mode" "<MODE>")])
9141
9142 ;; Combine is quite creative about this pattern.
9143 (define_insn "*negsi2_1_zext"
9144   [(set (match_operand:DI 0 "register_operand" "=r")
9145         (lshiftrt:DI
9146           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9147                              (const_int 32)))
9148         (const_int 32)))
9149    (clobber (reg:CC FLAGS_REG))]
9150   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9151   "neg{l}\t%k0"
9152   [(set_attr "type" "negnot")
9153    (set_attr "mode" "SI")])
9154
9155 ;; The problem with neg is that it does not perform (compare x 0),
9156 ;; it really performs (compare 0 x), which leaves us with the zero
9157 ;; flag being the only useful item.
9158
9159 (define_insn "*neg<mode>2_cmpz"
9160   [(set (reg:CCZ FLAGS_REG)
9161         (compare:CCZ
9162           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9163                    (const_int 0)))
9164    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9165         (neg:SWI (match_dup 1)))]
9166   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9167   "neg{<imodesuffix>}\t%0"
9168   [(set_attr "type" "negnot")
9169    (set_attr "mode" "<MODE>")])
9170
9171 (define_insn "*negsi2_cmpz_zext"
9172   [(set (reg:CCZ FLAGS_REG)
9173         (compare:CCZ
9174           (lshiftrt:DI
9175             (neg:DI (ashift:DI
9176                       (match_operand:DI 1 "register_operand" "0")
9177                       (const_int 32)))
9178             (const_int 32))
9179           (const_int 0)))
9180    (set (match_operand:DI 0 "register_operand" "=r")
9181         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9182                                         (const_int 32)))
9183                      (const_int 32)))]
9184   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9185   "neg{l}\t%k0"
9186   [(set_attr "type" "negnot")
9187    (set_attr "mode" "SI")])
9188
9189 ;; Changing of sign for FP values is doable using integer unit too.
9190
9191 (define_expand "<code><mode>2"
9192   [(set (match_operand:X87MODEF 0 "register_operand" "")
9193         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9194   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9195   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9196
9197 (define_insn "*absneg<mode>2_mixed"
9198   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9199         (match_operator:MODEF 3 "absneg_operator"
9200           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9201    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9204   "#")
9205
9206 (define_insn "*absneg<mode>2_sse"
9207   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9208         (match_operator:MODEF 3 "absneg_operator"
9209           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9210    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9211    (clobber (reg:CC FLAGS_REG))]
9212   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9213   "#")
9214
9215 (define_insn "*absneg<mode>2_i387"
9216   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9217         (match_operator:X87MODEF 3 "absneg_operator"
9218           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9219    (use (match_operand 2 "" ""))
9220    (clobber (reg:CC FLAGS_REG))]
9221   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9222   "#")
9223
9224 (define_expand "<code>tf2"
9225   [(set (match_operand:TF 0 "register_operand" "")
9226         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9227   "TARGET_SSE2"
9228   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9229
9230 (define_insn "*absnegtf2_sse"
9231   [(set (match_operand:TF 0 "register_operand" "=x,x")
9232         (match_operator:TF 3 "absneg_operator"
9233           [(match_operand:TF 1 "register_operand" "0,x")]))
9234    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9235    (clobber (reg:CC FLAGS_REG))]
9236   "TARGET_SSE2"
9237   "#")
9238
9239 ;; Splitters for fp abs and neg.
9240
9241 (define_split
9242   [(set (match_operand 0 "fp_register_operand" "")
9243         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9244    (use (match_operand 2 "" ""))
9245    (clobber (reg:CC FLAGS_REG))]
9246   "reload_completed"
9247   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9248
9249 (define_split
9250   [(set (match_operand 0 "register_operand" "")
9251         (match_operator 3 "absneg_operator"
9252           [(match_operand 1 "register_operand" "")]))
9253    (use (match_operand 2 "nonimmediate_operand" ""))
9254    (clobber (reg:CC FLAGS_REG))]
9255   "reload_completed && SSE_REG_P (operands[0])"
9256   [(set (match_dup 0) (match_dup 3))]
9257 {
9258   enum machine_mode mode = GET_MODE (operands[0]);
9259   enum machine_mode vmode = GET_MODE (operands[2]);
9260   rtx tmp;
9261
9262   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9263   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9264   if (operands_match_p (operands[0], operands[2]))
9265     {
9266       tmp = operands[1];
9267       operands[1] = operands[2];
9268       operands[2] = tmp;
9269     }
9270   if (GET_CODE (operands[3]) == ABS)
9271     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9272   else
9273     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9274   operands[3] = tmp;
9275 })
9276
9277 (define_split
9278   [(set (match_operand:SF 0 "register_operand" "")
9279         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9280    (use (match_operand:V4SF 2 "" ""))
9281    (clobber (reg:CC FLAGS_REG))]
9282   "reload_completed"
9283   [(parallel [(set (match_dup 0) (match_dup 1))
9284               (clobber (reg:CC FLAGS_REG))])]
9285 {
9286   rtx tmp;
9287   operands[0] = gen_lowpart (SImode, operands[0]);
9288   if (GET_CODE (operands[1]) == ABS)
9289     {
9290       tmp = gen_int_mode (0x7fffffff, SImode);
9291       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9292     }
9293   else
9294     {
9295       tmp = gen_int_mode (0x80000000, SImode);
9296       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9297     }
9298   operands[1] = tmp;
9299 })
9300
9301 (define_split
9302   [(set (match_operand:DF 0 "register_operand" "")
9303         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9304    (use (match_operand 2 "" ""))
9305    (clobber (reg:CC FLAGS_REG))]
9306   "reload_completed"
9307   [(parallel [(set (match_dup 0) (match_dup 1))
9308               (clobber (reg:CC FLAGS_REG))])]
9309 {
9310   rtx tmp;
9311   if (TARGET_64BIT)
9312     {
9313       tmp = gen_lowpart (DImode, operands[0]);
9314       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9315       operands[0] = tmp;
9316
9317       if (GET_CODE (operands[1]) == ABS)
9318         tmp = const0_rtx;
9319       else
9320         tmp = gen_rtx_NOT (DImode, tmp);
9321     }
9322   else
9323     {
9324       operands[0] = gen_highpart (SImode, operands[0]);
9325       if (GET_CODE (operands[1]) == ABS)
9326         {
9327           tmp = gen_int_mode (0x7fffffff, SImode);
9328           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9329         }
9330       else
9331         {
9332           tmp = gen_int_mode (0x80000000, SImode);
9333           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9334         }
9335     }
9336   operands[1] = tmp;
9337 })
9338
9339 (define_split
9340   [(set (match_operand:XF 0 "register_operand" "")
9341         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9342    (use (match_operand 2 "" ""))
9343    (clobber (reg:CC FLAGS_REG))]
9344   "reload_completed"
9345   [(parallel [(set (match_dup 0) (match_dup 1))
9346               (clobber (reg:CC FLAGS_REG))])]
9347 {
9348   rtx tmp;
9349   operands[0] = gen_rtx_REG (SImode,
9350                              true_regnum (operands[0])
9351                              + (TARGET_64BIT ? 1 : 2));
9352   if (GET_CODE (operands[1]) == ABS)
9353     {
9354       tmp = GEN_INT (0x7fff);
9355       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9356     }
9357   else
9358     {
9359       tmp = GEN_INT (0x8000);
9360       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9361     }
9362   operands[1] = tmp;
9363 })
9364
9365 ;; Conditionalize these after reload. If they match before reload, we
9366 ;; lose the clobber and ability to use integer instructions.
9367
9368 (define_insn "*<code><mode>2_1"
9369   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9370         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9371   "TARGET_80387
9372    && (reload_completed
9373        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9374   "f<absneg_mnemonic>"
9375   [(set_attr "type" "fsgn")
9376    (set_attr "mode" "<MODE>")])
9377
9378 (define_insn "*<code>extendsfdf2"
9379   [(set (match_operand:DF 0 "register_operand" "=f")
9380         (absneg:DF (float_extend:DF
9381                      (match_operand:SF 1 "register_operand" "0"))))]
9382   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9383   "f<absneg_mnemonic>"
9384   [(set_attr "type" "fsgn")
9385    (set_attr "mode" "DF")])
9386
9387 (define_insn "*<code>extendsfxf2"
9388   [(set (match_operand:XF 0 "register_operand" "=f")
9389         (absneg:XF (float_extend:XF
9390                      (match_operand:SF 1 "register_operand" "0"))))]
9391   "TARGET_80387"
9392   "f<absneg_mnemonic>"
9393   [(set_attr "type" "fsgn")
9394    (set_attr "mode" "XF")])
9395
9396 (define_insn "*<code>extenddfxf2"
9397   [(set (match_operand:XF 0 "register_operand" "=f")
9398         (absneg:XF (float_extend:XF
9399                      (match_operand:DF 1 "register_operand" "0"))))]
9400   "TARGET_80387"
9401   "f<absneg_mnemonic>"
9402   [(set_attr "type" "fsgn")
9403    (set_attr "mode" "XF")])
9404
9405 ;; Copysign instructions
9406
9407 (define_mode_iterator CSGNMODE [SF DF TF])
9408 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9409
9410 (define_expand "copysign<mode>3"
9411   [(match_operand:CSGNMODE 0 "register_operand" "")
9412    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9413    (match_operand:CSGNMODE 2 "register_operand" "")]
9414   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9415    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9416 {
9417   ix86_expand_copysign (operands);
9418   DONE;
9419 })
9420
9421 (define_insn_and_split "copysign<mode>3_const"
9422   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9423         (unspec:CSGNMODE
9424           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9425            (match_operand:CSGNMODE 2 "register_operand" "0")
9426            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9427           UNSPEC_COPYSIGN))]
9428   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9429    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9430   "#"
9431   "&& reload_completed"
9432   [(const_int 0)]
9433 {
9434   ix86_split_copysign_const (operands);
9435   DONE;
9436 })
9437
9438 (define_insn "copysign<mode>3_var"
9439   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9440         (unspec:CSGNMODE
9441           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9442            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9443            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9444            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9445           UNSPEC_COPYSIGN))
9446    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9447   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9448    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9449   "#")
9450
9451 (define_split
9452   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9453         (unspec:CSGNMODE
9454           [(match_operand:CSGNMODE 2 "register_operand" "")
9455            (match_operand:CSGNMODE 3 "register_operand" "")
9456            (match_operand:<CSGNVMODE> 4 "" "")
9457            (match_operand:<CSGNVMODE> 5 "" "")]
9458           UNSPEC_COPYSIGN))
9459    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9460   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9461     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9462    && reload_completed"
9463   [(const_int 0)]
9464 {
9465   ix86_split_copysign_var (operands);
9466   DONE;
9467 })
9468 \f
9469 ;; One complement instructions
9470
9471 (define_expand "one_cmpl<mode>2"
9472   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9473         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9474   ""
9475   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9476
9477 (define_insn "*one_cmpl<mode>2_1"
9478   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9479         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9480   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9481   "not{<imodesuffix>}\t%0"
9482   [(set_attr "type" "negnot")
9483    (set_attr "mode" "<MODE>")])
9484
9485 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9486 (define_insn "*one_cmplqi2_1"
9487   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9488         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9489   "ix86_unary_operator_ok (NOT, QImode, operands)"
9490   "@
9491    not{b}\t%0
9492    not{l}\t%k0"
9493   [(set_attr "type" "negnot")
9494    (set_attr "mode" "QI,SI")])
9495
9496 ;; ??? Currently never generated - xor is used instead.
9497 (define_insn "*one_cmplsi2_1_zext"
9498   [(set (match_operand:DI 0 "register_operand" "=r")
9499         (zero_extend:DI
9500           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9501   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9502   "not{l}\t%k0"
9503   [(set_attr "type" "negnot")
9504    (set_attr "mode" "SI")])
9505
9506 (define_insn "*one_cmpl<mode>2_2"
9507   [(set (reg FLAGS_REG)
9508         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9509                  (const_int 0)))
9510    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9511         (not:SWI (match_dup 1)))]
9512   "ix86_match_ccmode (insn, CCNOmode)
9513    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9514   "#"
9515   [(set_attr "type" "alu1")
9516    (set_attr "mode" "<MODE>")])
9517
9518 (define_split
9519   [(set (match_operand 0 "flags_reg_operand" "")
9520         (match_operator 2 "compare_operator"
9521           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9522            (const_int 0)]))
9523    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9524         (not:SWI (match_dup 3)))]
9525   "ix86_match_ccmode (insn, CCNOmode)"
9526   [(parallel [(set (match_dup 0)
9527                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9528                                     (const_int 0)]))
9529               (set (match_dup 1)
9530                    (xor:SWI (match_dup 3) (const_int -1)))])]
9531   "")
9532
9533 ;; ??? Currently never generated - xor is used instead.
9534 (define_insn "*one_cmplsi2_2_zext"
9535   [(set (reg FLAGS_REG)
9536         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9537                  (const_int 0)))
9538    (set (match_operand:DI 0 "register_operand" "=r")
9539         (zero_extend:DI (not:SI (match_dup 1))))]
9540   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9541    && ix86_unary_operator_ok (NOT, SImode, operands)"
9542   "#"
9543   [(set_attr "type" "alu1")
9544    (set_attr "mode" "SI")])
9545
9546 (define_split
9547   [(set (match_operand 0 "flags_reg_operand" "")
9548         (match_operator 2 "compare_operator"
9549           [(not:SI (match_operand:SI 3 "register_operand" ""))
9550            (const_int 0)]))
9551    (set (match_operand:DI 1 "register_operand" "")
9552         (zero_extend:DI (not:SI (match_dup 3))))]
9553   "ix86_match_ccmode (insn, CCNOmode)"
9554   [(parallel [(set (match_dup 0)
9555                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9556                                     (const_int 0)]))
9557               (set (match_dup 1)
9558                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9559   "")
9560 \f
9561 ;; Shift instructions
9562
9563 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9564 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9565 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9566 ;; from the assembler input.
9567 ;;
9568 ;; This instruction shifts the target reg/mem as usual, but instead of
9569 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9570 ;; is a left shift double, bits are taken from the high order bits of
9571 ;; reg, else if the insn is a shift right double, bits are taken from the
9572 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9573 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9574 ;;
9575 ;; Since sh[lr]d does not change the `reg' operand, that is done
9576 ;; separately, making all shifts emit pairs of shift double and normal
9577 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9578 ;; support a 63 bit shift, each shift where the count is in a reg expands
9579 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9580 ;;
9581 ;; If the shift count is a constant, we need never emit more than one
9582 ;; shift pair, instead using moves and sign extension for counts greater
9583 ;; than 31.
9584
9585 (define_expand "ashl<mode>3"
9586   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9587         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9588                       (match_operand:QI 2 "nonmemory_operand" "")))]
9589   ""
9590   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9591
9592 (define_insn "*ashl<mode>3_doubleword"
9593   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9594         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9595                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9596    (clobber (reg:CC FLAGS_REG))]
9597   ""
9598   "#"
9599   [(set_attr "type" "multi")])
9600
9601 (define_split
9602   [(set (match_operand:DWI 0 "register_operand" "")
9603         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9604                     (match_operand:QI 2 "nonmemory_operand" "")))
9605    (clobber (reg:CC FLAGS_REG))]
9606   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9607   [(const_int 0)]
9608   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9609
9610 ;; By default we don't ask for a scratch register, because when DWImode
9611 ;; values are manipulated, registers are already at a premium.  But if
9612 ;; we have one handy, we won't turn it away.
9613
9614 (define_peephole2
9615   [(match_scratch:DWIH 3 "r")
9616    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9617                    (ashift:<DWI>
9618                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9619                      (match_operand:QI 2 "nonmemory_operand" "")))
9620               (clobber (reg:CC FLAGS_REG))])
9621    (match_dup 3)]
9622   "TARGET_CMOVE"
9623   [(const_int 0)]
9624   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9625
9626 (define_insn "x86_64_shld"
9627   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9628         (ior:DI (ashift:DI (match_dup 0)
9629                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9630                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9631                   (minus:QI (const_int 64) (match_dup 2)))))
9632    (clobber (reg:CC FLAGS_REG))]
9633   "TARGET_64BIT"
9634   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9635   [(set_attr "type" "ishift")
9636    (set_attr "prefix_0f" "1")
9637    (set_attr "mode" "DI")
9638    (set_attr "athlon_decode" "vector")
9639    (set_attr "amdfam10_decode" "vector")])
9640
9641 (define_insn "x86_shld"
9642   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9643         (ior:SI (ashift:SI (match_dup 0)
9644                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9645                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9646                   (minus:QI (const_int 32) (match_dup 2)))))
9647    (clobber (reg:CC FLAGS_REG))]
9648   ""
9649   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9650   [(set_attr "type" "ishift")
9651    (set_attr "prefix_0f" "1")
9652    (set_attr "mode" "SI")
9653    (set_attr "pent_pair" "np")
9654    (set_attr "athlon_decode" "vector")
9655    (set_attr "amdfam10_decode" "vector")])
9656
9657 (define_expand "x86_shift<mode>_adj_1"
9658   [(set (reg:CCZ FLAGS_REG)
9659         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9660                              (match_dup 4))
9661                      (const_int 0)))
9662    (set (match_operand:SWI48 0 "register_operand" "")
9663         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9664                             (match_operand:SWI48 1 "register_operand" "")
9665                             (match_dup 0)))
9666    (set (match_dup 1)
9667         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9668                             (match_operand:SWI48 3 "register_operand" "r")
9669                             (match_dup 1)))]
9670   "TARGET_CMOVE"
9671   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9672
9673 (define_expand "x86_shift<mode>_adj_2"
9674   [(use (match_operand:SWI48 0 "register_operand" ""))
9675    (use (match_operand:SWI48 1 "register_operand" ""))
9676    (use (match_operand:QI 2 "register_operand" ""))]
9677   ""
9678 {
9679   rtx label = gen_label_rtx ();
9680   rtx tmp;
9681
9682   emit_insn (gen_testqi_ccz_1 (operands[2],
9683                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9684
9685   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9686   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9687   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9688                               gen_rtx_LABEL_REF (VOIDmode, label),
9689                               pc_rtx);
9690   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9691   JUMP_LABEL (tmp) = label;
9692
9693   emit_move_insn (operands[0], operands[1]);
9694   ix86_expand_clear (operands[1]);
9695
9696   emit_label (label);
9697   LABEL_NUSES (label) = 1;
9698
9699   DONE;
9700 })
9701
9702 (define_insn "*ashl<mode>3_1"
9703   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9704         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9705                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9706    (clobber (reg:CC FLAGS_REG))]
9707   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9708 {
9709   switch (get_attr_type (insn))
9710     {
9711     case TYPE_LEA:
9712       return "#";
9713
9714     case TYPE_ALU:
9715       gcc_assert (operands[2] == const1_rtx);
9716       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9717       return "add{<imodesuffix>}\t%0, %0";
9718
9719     default:
9720       if (operands[2] == const1_rtx
9721           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9722         return "sal{<imodesuffix>}\t%0";
9723       else
9724         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9725     }
9726 }
9727   [(set (attr "type")
9728      (cond [(eq_attr "alternative" "1")
9729               (const_string "lea")
9730             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9731                           (const_int 0))
9732                       (match_operand 0 "register_operand" ""))
9733                  (match_operand 2 "const1_operand" ""))
9734               (const_string "alu")
9735            ]
9736            (const_string "ishift")))
9737    (set (attr "length_immediate")
9738      (if_then_else
9739        (ior (eq_attr "type" "alu")
9740             (and (eq_attr "type" "ishift")
9741                  (and (match_operand 2 "const1_operand" "")
9742                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9743                           (const_int 0)))))
9744        (const_string "0")
9745        (const_string "*")))
9746    (set_attr "mode" "<MODE>")])
9747
9748 (define_insn "*ashlsi3_1_zext"
9749   [(set (match_operand:DI 0 "register_operand" "=r,r")
9750         (zero_extend:DI
9751           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9752                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9753    (clobber (reg:CC FLAGS_REG))]
9754   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9755 {
9756   switch (get_attr_type (insn))
9757     {
9758     case TYPE_LEA:
9759       return "#";
9760
9761     case TYPE_ALU:
9762       gcc_assert (operands[2] == const1_rtx);
9763       return "add{l}\t%k0, %k0";
9764
9765     default:
9766       if (operands[2] == const1_rtx
9767           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9768         return "sal{l}\t%k0";
9769       else
9770         return "sal{l}\t{%2, %k0|%k0, %2}";
9771     }
9772 }
9773   [(set (attr "type")
9774      (cond [(eq_attr "alternative" "1")
9775               (const_string "lea")
9776             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9777                      (const_int 0))
9778                  (match_operand 2 "const1_operand" ""))
9779               (const_string "alu")
9780            ]
9781            (const_string "ishift")))
9782    (set (attr "length_immediate")
9783      (if_then_else
9784        (ior (eq_attr "type" "alu")
9785             (and (eq_attr "type" "ishift")
9786                  (and (match_operand 2 "const1_operand" "")
9787                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9788                           (const_int 0)))))
9789        (const_string "0")
9790        (const_string "*")))
9791    (set_attr "mode" "SI")])
9792
9793 (define_insn "*ashlhi3_1"
9794   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9795         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9796                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9797    (clobber (reg:CC FLAGS_REG))]
9798   "TARGET_PARTIAL_REG_STALL
9799    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9800 {
9801   switch (get_attr_type (insn))
9802     {
9803     case TYPE_ALU:
9804       gcc_assert (operands[2] == const1_rtx);
9805       return "add{w}\t%0, %0";
9806
9807     default:
9808       if (operands[2] == const1_rtx
9809           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9810         return "sal{w}\t%0";
9811       else
9812         return "sal{w}\t{%2, %0|%0, %2}";
9813     }
9814 }
9815   [(set (attr "type")
9816      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9817                           (const_int 0))
9818                       (match_operand 0 "register_operand" ""))
9819                  (match_operand 2 "const1_operand" ""))
9820               (const_string "alu")
9821            ]
9822            (const_string "ishift")))
9823    (set (attr "length_immediate")
9824      (if_then_else
9825        (ior (eq_attr "type" "alu")
9826             (and (eq_attr "type" "ishift")
9827                  (and (match_operand 2 "const1_operand" "")
9828                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9829                           (const_int 0)))))
9830        (const_string "0")
9831        (const_string "*")))
9832    (set_attr "mode" "HI")])
9833
9834 (define_insn "*ashlhi3_1_lea"
9835   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9836         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9837                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9838    (clobber (reg:CC FLAGS_REG))]
9839   "!TARGET_PARTIAL_REG_STALL
9840    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9841 {
9842   switch (get_attr_type (insn))
9843     {
9844     case TYPE_LEA:
9845       return "#";
9846
9847     case TYPE_ALU:
9848       gcc_assert (operands[2] == const1_rtx);
9849       return "add{w}\t%0, %0";
9850
9851     default:
9852       if (operands[2] == const1_rtx
9853           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9854         return "sal{w}\t%0";
9855       else
9856         return "sal{w}\t{%2, %0|%0, %2}";
9857     }
9858 }
9859   [(set (attr "type")
9860      (cond [(eq_attr "alternative" "1")
9861               (const_string "lea")
9862             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9863                           (const_int 0))
9864                       (match_operand 0 "register_operand" ""))
9865                  (match_operand 2 "const1_operand" ""))
9866               (const_string "alu")
9867            ]
9868            (const_string "ishift")))
9869    (set (attr "length_immediate")
9870      (if_then_else
9871        (ior (eq_attr "type" "alu")
9872             (and (eq_attr "type" "ishift")
9873                  (and (match_operand 2 "const1_operand" "")
9874                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9875                           (const_int 0)))))
9876        (const_string "0")
9877        (const_string "*")))
9878    (set_attr "mode" "HI,SI")])
9879
9880 (define_insn "*ashlqi3_1"
9881   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9882         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9883                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9884    (clobber (reg:CC FLAGS_REG))]
9885   "TARGET_PARTIAL_REG_STALL
9886    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9887 {
9888   switch (get_attr_type (insn))
9889     {
9890     case TYPE_ALU:
9891       gcc_assert (operands[2] == const1_rtx);
9892       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9893         return "add{l}\t%k0, %k0";
9894       else
9895         return "add{b}\t%0, %0";
9896
9897     default:
9898       if (operands[2] == const1_rtx
9899           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9900         {
9901           if (get_attr_mode (insn) == MODE_SI)
9902             return "sal{l}\t%k0";
9903           else
9904             return "sal{b}\t%0";
9905         }
9906       else
9907         {
9908           if (get_attr_mode (insn) == MODE_SI)
9909             return "sal{l}\t{%2, %k0|%k0, %2}";
9910           else
9911             return "sal{b}\t{%2, %0|%0, %2}";
9912         }
9913     }
9914 }
9915   [(set (attr "type")
9916      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9917                           (const_int 0))
9918                       (match_operand 0 "register_operand" ""))
9919                  (match_operand 2 "const1_operand" ""))
9920               (const_string "alu")
9921            ]
9922            (const_string "ishift")))
9923    (set (attr "length_immediate")
9924      (if_then_else
9925        (ior (eq_attr "type" "alu")
9926             (and (eq_attr "type" "ishift")
9927                  (and (match_operand 2 "const1_operand" "")
9928                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9929                           (const_int 0)))))
9930        (const_string "0")
9931        (const_string "*")))
9932    (set_attr "mode" "QI,SI")])
9933
9934 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9935 (define_insn "*ashlqi3_1_lea"
9936   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9937         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9938                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9939    (clobber (reg:CC FLAGS_REG))]
9940   "!TARGET_PARTIAL_REG_STALL
9941    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9942 {
9943   switch (get_attr_type (insn))
9944     {
9945     case TYPE_LEA:
9946       return "#";
9947
9948     case TYPE_ALU:
9949       gcc_assert (operands[2] == const1_rtx);
9950       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9951         return "add{l}\t%k0, %k0";
9952       else
9953         return "add{b}\t%0, %0";
9954
9955     default:
9956       if (operands[2] == const1_rtx
9957           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9958         {
9959           if (get_attr_mode (insn) == MODE_SI)
9960             return "sal{l}\t%k0";
9961           else
9962             return "sal{b}\t%0";
9963         }
9964       else
9965         {
9966           if (get_attr_mode (insn) == MODE_SI)
9967             return "sal{l}\t{%2, %k0|%k0, %2}";
9968           else
9969             return "sal{b}\t{%2, %0|%0, %2}";
9970         }
9971     }
9972 }
9973   [(set (attr "type")
9974      (cond [(eq_attr "alternative" "2")
9975               (const_string "lea")
9976             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9977                           (const_int 0))
9978                       (match_operand 0 "register_operand" ""))
9979                  (match_operand 2 "const1_operand" ""))
9980               (const_string "alu")
9981            ]
9982            (const_string "ishift")))
9983    (set (attr "length_immediate")
9984      (if_then_else
9985        (ior (eq_attr "type" "alu")
9986             (and (eq_attr "type" "ishift")
9987                  (and (match_operand 2 "const1_operand" "")
9988                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9989                           (const_int 0)))))
9990        (const_string "0")
9991        (const_string "*")))
9992    (set_attr "mode" "QI,SI,SI")])
9993
9994 (define_insn "*ashlqi3_1_slp"
9995   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9996         (ashift:QI (match_dup 0)
9997                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9998    (clobber (reg:CC FLAGS_REG))]
9999   "(optimize_function_for_size_p (cfun)
10000     || !TARGET_PARTIAL_FLAG_REG_STALL
10001     || (operands[1] == const1_rtx
10002         && (TARGET_SHIFT1
10003             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10004 {
10005   switch (get_attr_type (insn))
10006     {
10007     case TYPE_ALU:
10008       gcc_assert (operands[1] == const1_rtx);
10009       return "add{b}\t%0, %0";
10010
10011     default:
10012       if (operands[1] == const1_rtx
10013           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10014         return "sal{b}\t%0";
10015       else
10016         return "sal{b}\t{%1, %0|%0, %1}";
10017     }
10018 }
10019   [(set (attr "type")
10020      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10021                           (const_int 0))
10022                       (match_operand 0 "register_operand" ""))
10023                  (match_operand 1 "const1_operand" ""))
10024               (const_string "alu")
10025            ]
10026            (const_string "ishift1")))
10027    (set (attr "length_immediate")
10028      (if_then_else
10029        (ior (eq_attr "type" "alu")
10030             (and (eq_attr "type" "ishift1")
10031                  (and (match_operand 1 "const1_operand" "")
10032                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10033                           (const_int 0)))))
10034        (const_string "0")
10035        (const_string "*")))
10036    (set_attr "mode" "QI")])
10037
10038 ;; Convert lea to the lea pattern to avoid flags dependency.
10039 (define_split
10040   [(set (match_operand:DI 0 "register_operand" "")
10041         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10042                    (match_operand:QI 2 "const_int_operand" "")))
10043    (clobber (reg:CC FLAGS_REG))]
10044   "TARGET_64BIT && reload_completed
10045    && true_regnum (operands[0]) != true_regnum (operands[1])"
10046   [(set (match_dup 0)
10047         (mult:DI (match_dup 1)
10048                  (match_dup 2)))]
10049   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10050
10051 ;; Convert lea to the lea pattern to avoid flags dependency.
10052 (define_split
10053   [(set (match_operand 0 "register_operand" "")
10054         (ashift (match_operand 1 "index_register_operand" "")
10055                 (match_operand:QI 2 "const_int_operand" "")))
10056    (clobber (reg:CC FLAGS_REG))]
10057   "reload_completed
10058    && true_regnum (operands[0]) != true_regnum (operands[1])
10059    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10060   [(const_int 0)]
10061 {
10062   rtx pat;
10063   enum machine_mode mode = GET_MODE (operands[0]);
10064
10065   if (GET_MODE_SIZE (mode) < 4)
10066     operands[0] = gen_lowpart (SImode, operands[0]);
10067   if (mode != Pmode)
10068     operands[1] = gen_lowpart (Pmode, operands[1]);
10069   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10070
10071   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10072   if (Pmode != SImode)
10073     pat = gen_rtx_SUBREG (SImode, pat, 0);
10074   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10075   DONE;
10076 })
10077
10078 ;; Rare case of shifting RSP is handled by generating move and shift
10079 (define_split
10080   [(set (match_operand 0 "register_operand" "")
10081         (ashift (match_operand 1 "register_operand" "")
10082                 (match_operand:QI 2 "const_int_operand" "")))
10083    (clobber (reg:CC FLAGS_REG))]
10084   "reload_completed
10085    && true_regnum (operands[0]) != true_regnum (operands[1])"
10086   [(const_int 0)]
10087 {
10088   rtx pat, clob;
10089   emit_move_insn (operands[0], operands[1]);
10090   pat = gen_rtx_SET (VOIDmode, operands[0],
10091                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10092                                      operands[0], operands[2]));
10093   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10094   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10095   DONE;
10096 })
10097
10098 ;; Convert lea to the lea pattern to avoid flags dependency.
10099 (define_split
10100   [(set (match_operand:DI 0 "register_operand" "")
10101         (zero_extend:DI
10102           (ashift:SI (match_operand:SI 1 "register_operand" "")
10103                      (match_operand:QI 2 "const_int_operand" ""))))
10104    (clobber (reg:CC FLAGS_REG))]
10105   "TARGET_64BIT && reload_completed
10106    && true_regnum (operands[0]) != true_regnum (operands[1])"
10107   [(set (match_dup 0)
10108         (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10109 {
10110   operands[1] = gen_lowpart (Pmode, operands[1]);
10111   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10112 })
10113
10114 ;; This pattern can't accept a variable shift count, since shifts by
10115 ;; zero don't affect the flags.  We assume that shifts by constant
10116 ;; zero are optimized away.
10117 (define_insn "*ashl<mode>3_cmp"
10118   [(set (reg FLAGS_REG)
10119         (compare
10120           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10121                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10122           (const_int 0)))
10123    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10124         (ashift:SWI (match_dup 1) (match_dup 2)))]
10125   "(optimize_function_for_size_p (cfun)
10126     || !TARGET_PARTIAL_FLAG_REG_STALL
10127     || (operands[2] == const1_rtx
10128         && (TARGET_SHIFT1
10129             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10130    && ix86_match_ccmode (insn, CCGOCmode)
10131    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10132 {
10133   switch (get_attr_type (insn))
10134     {
10135     case TYPE_ALU:
10136       gcc_assert (operands[2] == const1_rtx);
10137       return "add{<imodesuffix>}\t%0, %0";
10138
10139     default:
10140       if (operands[2] == const1_rtx
10141           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10142         return "sal{<imodesuffix>}\t%0";
10143       else
10144         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10145     }
10146 }
10147   [(set (attr "type")
10148      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10149                           (const_int 0))
10150                       (match_operand 0 "register_operand" ""))
10151                  (match_operand 2 "const1_operand" ""))
10152               (const_string "alu")
10153            ]
10154            (const_string "ishift")))
10155    (set (attr "length_immediate")
10156      (if_then_else
10157        (ior (eq_attr "type" "alu")
10158             (and (eq_attr "type" "ishift")
10159                  (and (match_operand 2 "const1_operand" "")
10160                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10161                           (const_int 0)))))
10162        (const_string "0")
10163        (const_string "*")))
10164    (set_attr "mode" "<MODE>")])
10165
10166 (define_insn "*ashlsi3_cmp_zext"
10167   [(set (reg FLAGS_REG)
10168         (compare
10169           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10170                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10171           (const_int 0)))
10172    (set (match_operand:DI 0 "register_operand" "=r")
10173         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10174   "TARGET_64BIT
10175    && (optimize_function_for_size_p (cfun)
10176        || !TARGET_PARTIAL_FLAG_REG_STALL
10177        || (operands[2] == const1_rtx
10178            && (TARGET_SHIFT1
10179                || TARGET_DOUBLE_WITH_ADD)))
10180    && ix86_match_ccmode (insn, CCGOCmode)
10181    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10182 {
10183   switch (get_attr_type (insn))
10184     {
10185     case TYPE_ALU:
10186       gcc_assert (operands[2] == const1_rtx);
10187       return "add{l}\t%k0, %k0";
10188
10189     default:
10190       if (operands[2] == const1_rtx
10191           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10192         return "sal{l}\t%k0";
10193       else
10194         return "sal{l}\t{%2, %k0|%k0, %2}";
10195     }
10196 }
10197   [(set (attr "type")
10198      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10199                      (const_int 0))
10200                  (match_operand 2 "const1_operand" ""))
10201               (const_string "alu")
10202            ]
10203            (const_string "ishift")))
10204    (set (attr "length_immediate")
10205      (if_then_else
10206        (ior (eq_attr "type" "alu")
10207             (and (eq_attr "type" "ishift")
10208                  (and (match_operand 2 "const1_operand" "")
10209                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10210                           (const_int 0)))))
10211        (const_string "0")
10212        (const_string "*")))
10213    (set_attr "mode" "SI")])
10214
10215 (define_insn "*ashl<mode>3_cconly"
10216   [(set (reg FLAGS_REG)
10217         (compare
10218           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10219                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10220           (const_int 0)))
10221    (clobber (match_scratch:SWI 0 "=<r>"))]
10222   "(optimize_function_for_size_p (cfun)
10223     || !TARGET_PARTIAL_FLAG_REG_STALL
10224     || (operands[2] == const1_rtx
10225         && (TARGET_SHIFT1
10226             || TARGET_DOUBLE_WITH_ADD)))
10227    && ix86_match_ccmode (insn, CCGOCmode)
10228    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10229 {
10230   switch (get_attr_type (insn))
10231     {
10232     case TYPE_ALU:
10233       gcc_assert (operands[2] == const1_rtx);
10234       return "add{<imodesuffix>}\t%0, %0";
10235
10236     default:
10237       if (operands[2] == const1_rtx
10238           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10239         return "sal{<imodesuffix>}\t%0";
10240       else
10241         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10242     }
10243 }
10244   [(set (attr "type")
10245      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10246                           (const_int 0))
10247                       (match_operand 0 "register_operand" ""))
10248                  (match_operand 2 "const1_operand" ""))
10249               (const_string "alu")
10250            ]
10251            (const_string "ishift")))
10252    (set (attr "length_immediate")
10253      (if_then_else
10254        (ior (eq_attr "type" "alu")
10255             (and (eq_attr "type" "ishift")
10256                  (and (match_operand 2 "const1_operand" "")
10257                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10258                           (const_int 0)))))
10259        (const_string "0")
10260        (const_string "*")))
10261    (set_attr "mode" "<MODE>")])
10262
10263 ;; See comment above `ashl<mode>3' about how this works.
10264
10265 (define_expand "<shiftrt_insn><mode>3"
10266   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
10267         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
10268                            (match_operand:QI 2 "nonmemory_operand" "")))]
10269   ""
10270   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10271
10272 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
10273   [(set (match_operand:DWI 0 "register_operand" "=r")
10274         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10275                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10276    (clobber (reg:CC FLAGS_REG))]
10277   ""
10278   "#"
10279   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10280   [(const_int 0)]
10281   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10282   [(set_attr "type" "multi")])
10283
10284 ;; By default we don't ask for a scratch register, because when DWImode
10285 ;; values are manipulated, registers are already at a premium.  But if
10286 ;; we have one handy, we won't turn it away.
10287
10288 (define_peephole2
10289   [(match_scratch:DWIH 3 "r")
10290    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
10291                    (any_shiftrt:<DWI>
10292                      (match_operand:<DWI> 1 "register_operand" "")
10293                      (match_operand:QI 2 "nonmemory_operand" "")))
10294               (clobber (reg:CC FLAGS_REG))])
10295    (match_dup 3)]
10296   "TARGET_CMOVE"
10297   [(const_int 0)]
10298   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10299
10300 (define_insn "x86_64_shrd"
10301   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10302         (ior:DI (ashiftrt:DI (match_dup 0)
10303                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10304                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10305                   (minus:QI (const_int 64) (match_dup 2)))))
10306    (clobber (reg:CC FLAGS_REG))]
10307   "TARGET_64BIT"
10308   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10309   [(set_attr "type" "ishift")
10310    (set_attr "prefix_0f" "1")
10311    (set_attr "mode" "DI")
10312    (set_attr "athlon_decode" "vector")
10313    (set_attr "amdfam10_decode" "vector")])
10314
10315 (define_insn "x86_shrd"
10316   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10317         (ior:SI (ashiftrt:SI (match_dup 0)
10318                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10319                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10320                   (minus:QI (const_int 32) (match_dup 2)))))
10321    (clobber (reg:CC FLAGS_REG))]
10322   ""
10323   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10324   [(set_attr "type" "ishift")
10325    (set_attr "prefix_0f" "1")
10326    (set_attr "mode" "SI")
10327    (set_attr "pent_pair" "np")
10328    (set_attr "athlon_decode" "vector")
10329    (set_attr "amdfam10_decode" "vector")])
10330
10331 (define_insn "ashrdi3_cvt"
10332   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10333         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10334                      (match_operand:QI 2 "const_int_operand" "")))
10335    (clobber (reg:CC FLAGS_REG))]
10336   "TARGET_64BIT && INTVAL (operands[2]) == 63
10337    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10338    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10339   "@
10340    {cqto|cqo}
10341    sar{q}\t{%2, %0|%0, %2}"
10342   [(set_attr "type" "imovx,ishift")
10343    (set_attr "prefix_0f" "0,*")
10344    (set_attr "length_immediate" "0,*")
10345    (set_attr "modrm" "0,1")
10346    (set_attr "mode" "DI")])
10347
10348 (define_insn "ashrsi3_cvt"
10349   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10350         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10351                      (match_operand:QI 2 "const_int_operand" "")))
10352    (clobber (reg:CC FLAGS_REG))]
10353   "INTVAL (operands[2]) == 31
10354    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10355    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10356   "@
10357    {cltd|cdq}
10358    sar{l}\t{%2, %0|%0, %2}"
10359   [(set_attr "type" "imovx,ishift")
10360    (set_attr "prefix_0f" "0,*")
10361    (set_attr "length_immediate" "0,*")
10362    (set_attr "modrm" "0,1")
10363    (set_attr "mode" "SI")])
10364
10365 (define_insn "*ashrsi3_cvt_zext"
10366   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10367         (zero_extend:DI
10368           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10369                        (match_operand:QI 2 "const_int_operand" ""))))
10370    (clobber (reg:CC FLAGS_REG))]
10371   "TARGET_64BIT && INTVAL (operands[2]) == 31
10372    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10373    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10374   "@
10375    {cltd|cdq}
10376    sar{l}\t{%2, %k0|%k0, %2}"
10377   [(set_attr "type" "imovx,ishift")
10378    (set_attr "prefix_0f" "0,*")
10379    (set_attr "length_immediate" "0,*")
10380    (set_attr "modrm" "0,1")
10381    (set_attr "mode" "SI")])
10382
10383 (define_expand "x86_shift<mode>_adj_3"
10384   [(use (match_operand:SWI48 0 "register_operand" ""))
10385    (use (match_operand:SWI48 1 "register_operand" ""))
10386    (use (match_operand:QI 2 "register_operand" ""))]
10387   ""
10388 {
10389   rtx label = gen_label_rtx ();
10390   rtx tmp;
10391
10392   emit_insn (gen_testqi_ccz_1 (operands[2],
10393                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10394
10395   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10396   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10397   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10398                               gen_rtx_LABEL_REF (VOIDmode, label),
10399                               pc_rtx);
10400   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10401   JUMP_LABEL (tmp) = label;
10402
10403   emit_move_insn (operands[0], operands[1]);
10404   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10405                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10406   emit_label (label);
10407   LABEL_NUSES (label) = 1;
10408
10409   DONE;
10410 })
10411
10412 (define_insn "*<shiftrt_insn><mode>3_1"
10413   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10414         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10415                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10416    (clobber (reg:CC FLAGS_REG))]
10417   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10418 {
10419   if (operands[2] == const1_rtx
10420       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10421     return "<shiftrt>{<imodesuffix>}\t%0";
10422   else
10423     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10424 }
10425   [(set_attr "type" "ishift")
10426    (set (attr "length_immediate")
10427      (if_then_else
10428        (and (match_operand 2 "const1_operand" "")
10429             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10430                 (const_int 0)))
10431        (const_string "0")
10432        (const_string "*")))
10433    (set_attr "mode" "<MODE>")])
10434
10435 (define_insn "*<shiftrt_insn>si3_1_zext"
10436   [(set (match_operand:DI 0 "register_operand" "=r")
10437         (zero_extend:DI
10438           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10439                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
10440    (clobber (reg:CC FLAGS_REG))]
10441   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10442 {
10443   if (operands[2] == const1_rtx
10444       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10445     return "<shiftrt>{l}\t%k0";
10446   else
10447     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10448 }
10449   [(set_attr "type" "ishift")
10450    (set (attr "length_immediate")
10451      (if_then_else
10452        (and (match_operand 2 "const1_operand" "")
10453             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10454                 (const_int 0)))
10455        (const_string "0")
10456        (const_string "*")))
10457    (set_attr "mode" "SI")])
10458
10459 (define_insn "*<shiftrt_insn>qi3_1_slp"
10460   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10461         (any_shiftrt:QI (match_dup 0)
10462                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10463    (clobber (reg:CC FLAGS_REG))]
10464   "(optimize_function_for_size_p (cfun)
10465     || !TARGET_PARTIAL_REG_STALL
10466     || (operands[1] == const1_rtx
10467         && TARGET_SHIFT1))"
10468 {
10469   if (operands[1] == const1_rtx
10470       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10471     return "<shiftrt>{b}\t%0";
10472   else
10473     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10474 }
10475   [(set_attr "type" "ishift1")
10476    (set (attr "length_immediate")
10477      (if_then_else
10478        (and (match_operand 1 "const1_operand" "")
10479             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10480                 (const_int 0)))
10481        (const_string "0")
10482        (const_string "*")))
10483    (set_attr "mode" "QI")])
10484
10485 ;; This pattern can't accept a variable shift count, since shifts by
10486 ;; zero don't affect the flags.  We assume that shifts by constant
10487 ;; zero are optimized away.
10488 (define_insn "*<shiftrt_insn><mode>3_cmp"
10489   [(set (reg FLAGS_REG)
10490         (compare
10491           (any_shiftrt:SWI
10492             (match_operand:SWI 1 "nonimmediate_operand" "0")
10493             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10494           (const_int 0)))
10495    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10496         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10497   "(optimize_function_for_size_p (cfun)
10498     || !TARGET_PARTIAL_FLAG_REG_STALL
10499     || (operands[2] == const1_rtx
10500         && TARGET_SHIFT1))
10501    && ix86_match_ccmode (insn, CCGOCmode)
10502    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10503 {
10504   if (operands[2] == const1_rtx
10505       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10506     return "<shiftrt>{<imodesuffix>}\t%0";
10507   else
10508     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10509 }
10510   [(set_attr "type" "ishift")
10511    (set (attr "length_immediate")
10512      (if_then_else
10513        (and (match_operand 2 "const1_operand" "")
10514             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10515                 (const_int 0)))
10516        (const_string "0")
10517        (const_string "*")))
10518    (set_attr "mode" "<MODE>")])
10519
10520 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10521   [(set (reg FLAGS_REG)
10522         (compare
10523           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10524                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10525           (const_int 0)))
10526    (set (match_operand:DI 0 "register_operand" "=r")
10527         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10528   "TARGET_64BIT
10529    && (optimize_function_for_size_p (cfun)
10530        || !TARGET_PARTIAL_FLAG_REG_STALL
10531        || (operands[2] == const1_rtx
10532            && TARGET_SHIFT1))
10533    && ix86_match_ccmode (insn, CCGOCmode)
10534    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10535 {
10536   if (operands[2] == const1_rtx
10537       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10538     return "<shiftrt>{l}\t%k0";
10539   else
10540     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10541 }
10542   [(set_attr "type" "ishift")
10543    (set (attr "length_immediate")
10544      (if_then_else
10545        (and (match_operand 2 "const1_operand" "")
10546             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10547                 (const_int 0)))
10548        (const_string "0")
10549        (const_string "*")))
10550    (set_attr "mode" "SI")])
10551
10552 (define_insn "*<shiftrt_insn><mode>3_cconly"
10553   [(set (reg FLAGS_REG)
10554         (compare
10555           (any_shiftrt:SWI
10556             (match_operand:SWI 1 "nonimmediate_operand" "0")
10557             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10558           (const_int 0)))
10559    (clobber (match_scratch:SWI 0 "=<r>"))]
10560   "(optimize_function_for_size_p (cfun)
10561     || !TARGET_PARTIAL_FLAG_REG_STALL
10562     || (operands[2] == const1_rtx
10563         && TARGET_SHIFT1))
10564    && ix86_match_ccmode (insn, CCGOCmode)
10565    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10566 {
10567   if (operands[2] == const1_rtx
10568       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10569     return "<shiftrt>{<imodesuffix>}\t%0";
10570   else
10571     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10572 }
10573   [(set_attr "type" "ishift")
10574    (set (attr "length_immediate")
10575      (if_then_else
10576        (and (match_operand 2 "const1_operand" "")
10577             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10578                 (const_int 0)))
10579        (const_string "0")
10580        (const_string "*")))
10581    (set_attr "mode" "<MODE>")])
10582 \f
10583 ;; Rotate instructions
10584
10585 (define_expand "<rotate_insn>ti3"
10586   [(set (match_operand:TI 0 "register_operand" "")
10587         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10588                        (match_operand:QI 2 "nonmemory_operand" "")))]
10589   "TARGET_64BIT"
10590 {
10591   if (const_1_to_63_operand (operands[2], VOIDmode))
10592     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10593                 (operands[0], operands[1], operands[2]));
10594   else
10595     FAIL;
10596
10597   DONE;
10598 })
10599
10600 (define_expand "<rotate_insn>di3"
10601   [(set (match_operand:DI 0 "shiftdi_operand" "")
10602         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10603                        (match_operand:QI 2 "nonmemory_operand" "")))]
10604  ""
10605 {
10606   if (TARGET_64BIT)
10607     ix86_expand_binary_operator (<CODE>, DImode, operands);
10608   else if (const_1_to_31_operand (operands[2], VOIDmode))
10609     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10610                 (operands[0], operands[1], operands[2]));
10611   else
10612     FAIL;
10613
10614   DONE;
10615 })
10616
10617 (define_expand "<rotate_insn><mode>3"
10618   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10619         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10620                             (match_operand:QI 2 "nonmemory_operand" "")))]
10621   ""
10622   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10623
10624 ;; Implement rotation using two double-precision
10625 ;; shift instructions and a scratch register.
10626
10627 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10628  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10629        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10630                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10631   (clobber (reg:CC FLAGS_REG))
10632   (clobber (match_scratch:DWIH 3 "=&r"))]
10633  ""
10634  "#"
10635  "reload_completed"
10636  [(set (match_dup 3) (match_dup 4))
10637   (parallel
10638    [(set (match_dup 4)
10639          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10640                    (lshiftrt:DWIH (match_dup 5)
10641                                   (minus:QI (match_dup 6) (match_dup 2)))))
10642     (clobber (reg:CC FLAGS_REG))])
10643   (parallel
10644    [(set (match_dup 5)
10645          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10646                    (lshiftrt:DWIH (match_dup 3)
10647                                   (minus:QI (match_dup 6) (match_dup 2)))))
10648     (clobber (reg:CC FLAGS_REG))])]
10649 {
10650   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10651
10652   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10653 })
10654
10655 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10656  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10657        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10658                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10659   (clobber (reg:CC FLAGS_REG))
10660   (clobber (match_scratch:DWIH 3 "=&r"))]
10661  ""
10662  "#"
10663  "reload_completed"
10664  [(set (match_dup 3) (match_dup 4))
10665   (parallel
10666    [(set (match_dup 4)
10667          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10668                    (ashift:DWIH (match_dup 5)
10669                                 (minus:QI (match_dup 6) (match_dup 2)))))
10670     (clobber (reg:CC FLAGS_REG))])
10671   (parallel
10672    [(set (match_dup 5)
10673          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10674                    (ashift:DWIH (match_dup 3)
10675                                 (minus:QI (match_dup 6) (match_dup 2)))))
10676     (clobber (reg:CC FLAGS_REG))])]
10677 {
10678   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10679
10680   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10681 })
10682
10683 (define_insn "*<rotate_insn><mode>3_1"
10684   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10685         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10686                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10687    (clobber (reg:CC FLAGS_REG))]
10688   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10689 {
10690   if (operands[2] == const1_rtx
10691       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10692     return "<rotate>{<imodesuffix>}\t%0";
10693   else
10694     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10695 }
10696   [(set_attr "type" "rotate")
10697    (set (attr "length_immediate")
10698      (if_then_else
10699        (and (match_operand 2 "const1_operand" "")
10700             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10701                 (const_int 0)))
10702        (const_string "0")
10703        (const_string "*")))
10704    (set_attr "mode" "<MODE>")])
10705
10706 (define_insn "*<rotate_insn>si3_1_zext"
10707   [(set (match_operand:DI 0 "register_operand" "=r")
10708         (zero_extend:DI
10709           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10710                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10711    (clobber (reg:CC FLAGS_REG))]
10712   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10713 {
10714     if (operands[2] == const1_rtx
10715         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10716     return "<rotate>{l}\t%k0";
10717   else
10718     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10719 }
10720   [(set_attr "type" "rotate")
10721    (set (attr "length_immediate")
10722      (if_then_else
10723        (and (match_operand 2 "const1_operand" "")
10724             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10725                 (const_int 0)))
10726        (const_string "0")
10727        (const_string "*")))
10728    (set_attr "mode" "SI")])
10729
10730 (define_insn "*<rotate_insn>qi3_1_slp"
10731   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10732         (any_rotate:QI (match_dup 0)
10733                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10734    (clobber (reg:CC FLAGS_REG))]
10735   "(optimize_function_for_size_p (cfun)
10736     || !TARGET_PARTIAL_REG_STALL
10737     || (operands[1] == const1_rtx
10738         && TARGET_SHIFT1))"
10739 {
10740   if (operands[1] == const1_rtx
10741       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10742     return "<rotate>{b}\t%0";
10743   else
10744     return "<rotate>{b}\t{%1, %0|%0, %1}";
10745 }
10746   [(set_attr "type" "rotate1")
10747    (set (attr "length_immediate")
10748      (if_then_else
10749        (and (match_operand 1 "const1_operand" "")
10750             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10751                 (const_int 0)))
10752        (const_string "0")
10753        (const_string "*")))
10754    (set_attr "mode" "QI")])
10755
10756 (define_split
10757  [(set (match_operand:HI 0 "register_operand" "")
10758        (any_rotate:HI (match_dup 0) (const_int 8)))
10759   (clobber (reg:CC FLAGS_REG))]
10760  "reload_completed
10761   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10762  [(parallel [(set (strict_low_part (match_dup 0))
10763                   (bswap:HI (match_dup 0)))
10764              (clobber (reg:CC FLAGS_REG))])]
10765  "")
10766 \f
10767 ;; Bit set / bit test instructions
10768
10769 (define_expand "extv"
10770   [(set (match_operand:SI 0 "register_operand" "")
10771         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10772                          (match_operand:SI 2 "const8_operand" "")
10773                          (match_operand:SI 3 "const8_operand" "")))]
10774   ""
10775 {
10776   /* Handle extractions from %ah et al.  */
10777   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10778     FAIL;
10779
10780   /* From mips.md: extract_bit_field doesn't verify that our source
10781      matches the predicate, so check it again here.  */
10782   if (! ext_register_operand (operands[1], VOIDmode))
10783     FAIL;
10784 })
10785
10786 (define_expand "extzv"
10787   [(set (match_operand:SI 0 "register_operand" "")
10788         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10789                          (match_operand:SI 2 "const8_operand" "")
10790                          (match_operand:SI 3 "const8_operand" "")))]
10791   ""
10792 {
10793   /* Handle extractions from %ah et al.  */
10794   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10795     FAIL;
10796
10797   /* From mips.md: extract_bit_field doesn't verify that our source
10798      matches the predicate, so check it again here.  */
10799   if (! ext_register_operand (operands[1], VOIDmode))
10800     FAIL;
10801 })
10802
10803 (define_expand "insv"
10804   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10805                       (match_operand 1 "const8_operand" "")
10806                       (match_operand 2 "const8_operand" ""))
10807         (match_operand 3 "register_operand" ""))]
10808   ""
10809 {
10810   /* Handle insertions to %ah et al.  */
10811   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10812     FAIL;
10813
10814   /* From mips.md: insert_bit_field doesn't verify that our source
10815      matches the predicate, so check it again here.  */
10816   if (! ext_register_operand (operands[0], VOIDmode))
10817     FAIL;
10818
10819   if (TARGET_64BIT)
10820     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10821   else
10822     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10823
10824   DONE;
10825 })
10826
10827 ;; %%% bts, btr, btc, bt.
10828 ;; In general these instructions are *slow* when applied to memory,
10829 ;; since they enforce atomic operation.  When applied to registers,
10830 ;; it depends on the cpu implementation.  They're never faster than
10831 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10832 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10833 ;; within the instruction itself, so operating on bits in the high
10834 ;; 32-bits of a register becomes easier.
10835 ;;
10836 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10837 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10838 ;; negdf respectively, so they can never be disabled entirely.
10839
10840 (define_insn "*btsq"
10841   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10842                          (const_int 1)
10843                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10844         (const_int 1))
10845    (clobber (reg:CC FLAGS_REG))]
10846   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10847   "bts{q}\t{%1, %0|%0, %1}"
10848   [(set_attr "type" "alu1")
10849    (set_attr "prefix_0f" "1")
10850    (set_attr "mode" "DI")])
10851
10852 (define_insn "*btrq"
10853   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10854                          (const_int 1)
10855                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10856         (const_int 0))
10857    (clobber (reg:CC FLAGS_REG))]
10858   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10859   "btr{q}\t{%1, %0|%0, %1}"
10860   [(set_attr "type" "alu1")
10861    (set_attr "prefix_0f" "1")
10862    (set_attr "mode" "DI")])
10863
10864 (define_insn "*btcq"
10865   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10866                          (const_int 1)
10867                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10868         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10869    (clobber (reg:CC FLAGS_REG))]
10870   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10871   "btc{q}\t{%1, %0|%0, %1}"
10872   [(set_attr "type" "alu1")
10873    (set_attr "prefix_0f" "1")
10874    (set_attr "mode" "DI")])
10875
10876 ;; Allow Nocona to avoid these instructions if a register is available.
10877
10878 (define_peephole2
10879   [(match_scratch:DI 2 "r")
10880    (parallel [(set (zero_extract:DI
10881                      (match_operand:DI 0 "register_operand" "")
10882                      (const_int 1)
10883                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10884                    (const_int 1))
10885               (clobber (reg:CC FLAGS_REG))])]
10886   "TARGET_64BIT && !TARGET_USE_BT"
10887   [(const_int 0)]
10888 {
10889   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10890   rtx op1;
10891
10892   if (HOST_BITS_PER_WIDE_INT >= 64)
10893     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10894   else if (i < HOST_BITS_PER_WIDE_INT)
10895     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10896   else
10897     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10898
10899   op1 = immed_double_const (lo, hi, DImode);
10900   if (i >= 31)
10901     {
10902       emit_move_insn (operands[2], op1);
10903       op1 = operands[2];
10904     }
10905
10906   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10907   DONE;
10908 })
10909
10910 (define_peephole2
10911   [(match_scratch:DI 2 "r")
10912    (parallel [(set (zero_extract:DI
10913                      (match_operand:DI 0 "register_operand" "")
10914                      (const_int 1)
10915                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10916                    (const_int 0))
10917               (clobber (reg:CC FLAGS_REG))])]
10918   "TARGET_64BIT && !TARGET_USE_BT"
10919   [(const_int 0)]
10920 {
10921   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10922   rtx op1;
10923
10924   if (HOST_BITS_PER_WIDE_INT >= 64)
10925     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10926   else if (i < HOST_BITS_PER_WIDE_INT)
10927     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10928   else
10929     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10930
10931   op1 = immed_double_const (~lo, ~hi, DImode);
10932   if (i >= 32)
10933     {
10934       emit_move_insn (operands[2], op1);
10935       op1 = operands[2];
10936     }
10937
10938   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10939   DONE;
10940 })
10941
10942 (define_peephole2
10943   [(match_scratch:DI 2 "r")
10944    (parallel [(set (zero_extract:DI
10945                      (match_operand:DI 0 "register_operand" "")
10946                      (const_int 1)
10947                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10948               (not:DI (zero_extract:DI
10949                         (match_dup 0) (const_int 1) (match_dup 1))))
10950               (clobber (reg:CC FLAGS_REG))])]
10951   "TARGET_64BIT && !TARGET_USE_BT"
10952   [(const_int 0)]
10953 {
10954   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10955   rtx op1;
10956
10957   if (HOST_BITS_PER_WIDE_INT >= 64)
10958     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10959   else if (i < HOST_BITS_PER_WIDE_INT)
10960     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10961   else
10962     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10963
10964   op1 = immed_double_const (lo, hi, DImode);
10965   if (i >= 31)
10966     {
10967       emit_move_insn (operands[2], op1);
10968       op1 = operands[2];
10969     }
10970
10971   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10972   DONE;
10973 })
10974
10975 (define_insn "*bt<mode>"
10976   [(set (reg:CCC FLAGS_REG)
10977         (compare:CCC
10978           (zero_extract:SWI48
10979             (match_operand:SWI48 0 "register_operand" "r")
10980             (const_int 1)
10981             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10982           (const_int 0)))]
10983   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10984   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10985   [(set_attr "type" "alu1")
10986    (set_attr "prefix_0f" "1")
10987    (set_attr "mode" "<MODE>")])
10988 \f
10989 ;; Store-flag instructions.
10990
10991 ;; For all sCOND expanders, also expand the compare or test insn that
10992 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10993
10994 (define_insn_and_split "*setcc_di_1"
10995   [(set (match_operand:DI 0 "register_operand" "=q")
10996         (match_operator:DI 1 "ix86_comparison_operator"
10997           [(reg FLAGS_REG) (const_int 0)]))]
10998   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10999   "#"
11000   "&& reload_completed"
11001   [(set (match_dup 2) (match_dup 1))
11002    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11003 {
11004   PUT_MODE (operands[1], QImode);
11005   operands[2] = gen_lowpart (QImode, operands[0]);
11006 })
11007
11008 (define_insn_and_split "*setcc_si_1_and"
11009   [(set (match_operand:SI 0 "register_operand" "=q")
11010         (match_operator:SI 1 "ix86_comparison_operator"
11011           [(reg FLAGS_REG) (const_int 0)]))
11012    (clobber (reg:CC FLAGS_REG))]
11013   "!TARGET_PARTIAL_REG_STALL
11014    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11015   "#"
11016   "&& reload_completed"
11017   [(set (match_dup 2) (match_dup 1))
11018    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11019               (clobber (reg:CC FLAGS_REG))])]
11020 {
11021   PUT_MODE (operands[1], QImode);
11022   operands[2] = gen_lowpart (QImode, operands[0]);
11023 })
11024
11025 (define_insn_and_split "*setcc_si_1_movzbl"
11026   [(set (match_operand:SI 0 "register_operand" "=q")
11027         (match_operator:SI 1 "ix86_comparison_operator"
11028           [(reg FLAGS_REG) (const_int 0)]))]
11029   "!TARGET_PARTIAL_REG_STALL
11030    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11031   "#"
11032   "&& reload_completed"
11033   [(set (match_dup 2) (match_dup 1))
11034    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11035 {
11036   PUT_MODE (operands[1], QImode);
11037   operands[2] = gen_lowpart (QImode, operands[0]);
11038 })
11039
11040 (define_insn "*setcc_qi"
11041   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11042         (match_operator:QI 1 "ix86_comparison_operator"
11043           [(reg FLAGS_REG) (const_int 0)]))]
11044   ""
11045   "set%C1\t%0"
11046   [(set_attr "type" "setcc")
11047    (set_attr "mode" "QI")])
11048
11049 (define_insn "*setcc_qi_slp"
11050   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11051         (match_operator:QI 1 "ix86_comparison_operator"
11052           [(reg FLAGS_REG) (const_int 0)]))]
11053   ""
11054   "set%C1\t%0"
11055   [(set_attr "type" "setcc")
11056    (set_attr "mode" "QI")])
11057
11058 ;; In general it is not safe to assume too much about CCmode registers,
11059 ;; so simplify-rtx stops when it sees a second one.  Under certain
11060 ;; conditions this is safe on x86, so help combine not create
11061 ;;
11062 ;;      seta    %al
11063 ;;      testb   %al, %al
11064 ;;      sete    %al
11065
11066 (define_split
11067   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11068         (ne:QI (match_operator 1 "ix86_comparison_operator"
11069                  [(reg FLAGS_REG) (const_int 0)])
11070             (const_int 0)))]
11071   ""
11072   [(set (match_dup 0) (match_dup 1))]
11073 {
11074   PUT_MODE (operands[1], QImode);
11075 })
11076
11077 (define_split
11078   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11079         (ne:QI (match_operator 1 "ix86_comparison_operator"
11080                  [(reg FLAGS_REG) (const_int 0)])
11081             (const_int 0)))]
11082   ""
11083   [(set (match_dup 0) (match_dup 1))]
11084 {
11085   PUT_MODE (operands[1], QImode);
11086 })
11087
11088 (define_split
11089   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11090         (eq:QI (match_operator 1 "ix86_comparison_operator"
11091                  [(reg FLAGS_REG) (const_int 0)])
11092             (const_int 0)))]
11093   ""
11094   [(set (match_dup 0) (match_dup 1))]
11095 {
11096   rtx new_op1 = copy_rtx (operands[1]);
11097   operands[1] = new_op1;
11098   PUT_MODE (new_op1, QImode);
11099   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11100                                              GET_MODE (XEXP (new_op1, 0))));
11101
11102   /* Make sure that (a) the CCmode we have for the flags is strong
11103      enough for the reversed compare or (b) we have a valid FP compare.  */
11104   if (! ix86_comparison_operator (new_op1, VOIDmode))
11105     FAIL;
11106 })
11107
11108 (define_split
11109   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11110         (eq:QI (match_operator 1 "ix86_comparison_operator"
11111                  [(reg FLAGS_REG) (const_int 0)])
11112             (const_int 0)))]
11113   ""
11114   [(set (match_dup 0) (match_dup 1))]
11115 {
11116   rtx new_op1 = copy_rtx (operands[1]);
11117   operands[1] = new_op1;
11118   PUT_MODE (new_op1, QImode);
11119   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11120                                              GET_MODE (XEXP (new_op1, 0))));
11121
11122   /* Make sure that (a) the CCmode we have for the flags is strong
11123      enough for the reversed compare or (b) we have a valid FP compare.  */
11124   if (! ix86_comparison_operator (new_op1, VOIDmode))
11125     FAIL;
11126 })
11127
11128 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11129 ;; subsequent logical operations are used to imitate conditional moves.
11130 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11131 ;; it directly.
11132
11133 (define_insn "*avx_setcc<mode>"
11134   [(set (match_operand:MODEF 0 "register_operand" "=x")
11135         (match_operator:MODEF 1 "avx_comparison_float_operator"
11136           [(match_operand:MODEF 2 "register_operand" "x")
11137            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11138   "TARGET_AVX"
11139   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
11140   [(set_attr "type" "ssecmp")
11141    (set_attr "prefix" "vex")
11142    (set_attr "length_immediate" "1")
11143    (set_attr "mode" "<MODE>")])
11144
11145 (define_insn "*sse_setcc<mode>"
11146   [(set (match_operand:MODEF 0 "register_operand" "=x")
11147         (match_operator:MODEF 1 "sse_comparison_operator"
11148           [(match_operand:MODEF 2 "register_operand" "0")
11149            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11150   "SSE_FLOAT_MODE_P (<MODE>mode)"
11151   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
11152   [(set_attr "type" "ssecmp")
11153    (set_attr "length_immediate" "1")
11154    (set_attr "mode" "<MODE>")])
11155 \f
11156 ;; Basic conditional jump instructions.
11157 ;; We ignore the overflow flag for signed branch instructions.
11158
11159 (define_insn "*jcc_1"
11160   [(set (pc)
11161         (if_then_else (match_operator 1 "ix86_comparison_operator"
11162                                       [(reg FLAGS_REG) (const_int 0)])
11163                       (label_ref (match_operand 0 "" ""))
11164                       (pc)))]
11165   ""
11166   "%+j%C1\t%l0"
11167   [(set_attr "type" "ibr")
11168    (set_attr "modrm" "0")
11169    (set (attr "length")
11170            (if_then_else (and (ge (minus (match_dup 0) (pc))
11171                                   (const_int -126))
11172                               (lt (minus (match_dup 0) (pc))
11173                                   (const_int 128)))
11174              (const_int 2)
11175              (const_int 6)))])
11176
11177 (define_insn "*jcc_2"
11178   [(set (pc)
11179         (if_then_else (match_operator 1 "ix86_comparison_operator"
11180                                       [(reg FLAGS_REG) (const_int 0)])
11181                       (pc)
11182                       (label_ref (match_operand 0 "" ""))))]
11183   ""
11184   "%+j%c1\t%l0"
11185   [(set_attr "type" "ibr")
11186    (set_attr "modrm" "0")
11187    (set (attr "length")
11188            (if_then_else (and (ge (minus (match_dup 0) (pc))
11189                                   (const_int -126))
11190                               (lt (minus (match_dup 0) (pc))
11191                                   (const_int 128)))
11192              (const_int 2)
11193              (const_int 6)))])
11194
11195 ;; In general it is not safe to assume too much about CCmode registers,
11196 ;; so simplify-rtx stops when it sees a second one.  Under certain
11197 ;; conditions this is safe on x86, so help combine not create
11198 ;;
11199 ;;      seta    %al
11200 ;;      testb   %al, %al
11201 ;;      je      Lfoo
11202
11203 (define_split
11204   [(set (pc)
11205         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11206                                       [(reg FLAGS_REG) (const_int 0)])
11207                           (const_int 0))
11208                       (label_ref (match_operand 1 "" ""))
11209                       (pc)))]
11210   ""
11211   [(set (pc)
11212         (if_then_else (match_dup 0)
11213                       (label_ref (match_dup 1))
11214                       (pc)))]
11215 {
11216   PUT_MODE (operands[0], VOIDmode);
11217 })
11218
11219 (define_split
11220   [(set (pc)
11221         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11222                                       [(reg FLAGS_REG) (const_int 0)])
11223                           (const_int 0))
11224                       (label_ref (match_operand 1 "" ""))
11225                       (pc)))]
11226   ""
11227   [(set (pc)
11228         (if_then_else (match_dup 0)
11229                       (label_ref (match_dup 1))
11230                       (pc)))]
11231 {
11232   rtx new_op0 = copy_rtx (operands[0]);
11233   operands[0] = new_op0;
11234   PUT_MODE (new_op0, VOIDmode);
11235   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11236                                              GET_MODE (XEXP (new_op0, 0))));
11237
11238   /* Make sure that (a) the CCmode we have for the flags is strong
11239      enough for the reversed compare or (b) we have a valid FP compare.  */
11240   if (! ix86_comparison_operator (new_op0, VOIDmode))
11241     FAIL;
11242 })
11243
11244 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11245 ;; pass generates from shift insn with QImode operand.  Actually, the mode
11246 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11247 ;; appropriate modulo of the bit offset value.
11248
11249 (define_insn_and_split "*jcc_bt<mode>"
11250   [(set (pc)
11251         (if_then_else (match_operator 0 "bt_comparison_operator"
11252                         [(zero_extract:SWI48
11253                            (match_operand:SWI48 1 "register_operand" "r")
11254                            (const_int 1)
11255                            (zero_extend:SI
11256                              (match_operand:QI 2 "register_operand" "r")))
11257                          (const_int 0)])
11258                       (label_ref (match_operand 3 "" ""))
11259                       (pc)))
11260    (clobber (reg:CC FLAGS_REG))]
11261   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11262   "#"
11263   "&& 1"
11264   [(set (reg:CCC FLAGS_REG)
11265         (compare:CCC
11266           (zero_extract:SWI48
11267             (match_dup 1)
11268             (const_int 1)
11269             (match_dup 2))
11270           (const_int 0)))
11271    (set (pc)
11272         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11273                       (label_ref (match_dup 3))
11274                       (pc)))]
11275 {
11276   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11277
11278   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11279 })
11280
11281 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
11282 ;; also for DImode, this is what combine produces.
11283 (define_insn_and_split "*jcc_bt<mode>_mask"
11284   [(set (pc)
11285         (if_then_else (match_operator 0 "bt_comparison_operator"
11286                         [(zero_extract:SWI48
11287                            (match_operand:SWI48 1 "register_operand" "r")
11288                            (const_int 1)
11289                            (and:SI
11290                              (match_operand:SI 2 "register_operand" "r")
11291                              (match_operand:SI 3 "const_int_operand" "n")))])
11292                       (label_ref (match_operand 4 "" ""))
11293                       (pc)))
11294    (clobber (reg:CC FLAGS_REG))]
11295   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11296    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11297       == GET_MODE_BITSIZE (<MODE>mode)-1"
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 4))
11310                       (pc)))]
11311 {
11312   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11313
11314   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11315 })
11316
11317 (define_insn_and_split "*jcc_btsi_1"
11318   [(set (pc)
11319         (if_then_else (match_operator 0 "bt_comparison_operator"
11320                         [(and:SI
11321                            (lshiftrt:SI
11322                              (match_operand:SI 1 "register_operand" "r")
11323                              (match_operand:QI 2 "register_operand" "r"))
11324                            (const_int 1))
11325                          (const_int 0)])
11326                       (label_ref (match_operand 3 "" ""))
11327                       (pc)))
11328    (clobber (reg:CC FLAGS_REG))]
11329   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11330   "#"
11331   "&& 1"
11332   [(set (reg:CCC FLAGS_REG)
11333         (compare:CCC
11334           (zero_extract:SI
11335             (match_dup 1)
11336             (const_int 1)
11337             (match_dup 2))
11338           (const_int 0)))
11339    (set (pc)
11340         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11341                       (label_ref (match_dup 3))
11342                       (pc)))]
11343 {
11344   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11345
11346   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11347 })
11348
11349 ;; avoid useless masking of bit offset operand
11350 (define_insn_and_split "*jcc_btsi_mask_1"
11351   [(set (pc)
11352         (if_then_else
11353           (match_operator 0 "bt_comparison_operator"
11354             [(and:SI
11355                (lshiftrt:SI
11356                  (match_operand:SI 1 "register_operand" "r")
11357                  (subreg:QI
11358                    (and:SI
11359                      (match_operand:SI 2 "register_operand" "r")
11360                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11361                (const_int 1))
11362              (const_int 0)])
11363           (label_ref (match_operand 4 "" ""))
11364           (pc)))
11365    (clobber (reg:CC FLAGS_REG))]
11366   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11367    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11368   "#"
11369   "&& 1"
11370   [(set (reg:CCC FLAGS_REG)
11371         (compare:CCC
11372           (zero_extract:SI
11373             (match_dup 1)
11374             (const_int 1)
11375             (match_dup 2))
11376           (const_int 0)))
11377    (set (pc)
11378         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11379                       (label_ref (match_dup 4))
11380                       (pc)))]
11381   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11382
11383 ;; Define combination compare-and-branch fp compare instructions to help
11384 ;; combine.
11385
11386 (define_insn "*fp_jcc_3_387"
11387   [(set (pc)
11388         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11389                         [(match_operand 1 "register_operand" "f")
11390                          (match_operand 2 "nonimmediate_operand" "fm")])
11391           (label_ref (match_operand 3 "" ""))
11392           (pc)))
11393    (clobber (reg:CCFP FPSR_REG))
11394    (clobber (reg:CCFP FLAGS_REG))
11395    (clobber (match_scratch:HI 4 "=a"))]
11396   "TARGET_80387
11397    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11398    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11399    && SELECT_CC_MODE (GET_CODE (operands[0]),
11400                       operands[1], operands[2]) == CCFPmode
11401    && !TARGET_CMOVE"
11402   "#")
11403
11404 (define_insn "*fp_jcc_4_387"
11405   [(set (pc)
11406         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11407                         [(match_operand 1 "register_operand" "f")
11408                          (match_operand 2 "nonimmediate_operand" "fm")])
11409           (pc)
11410           (label_ref (match_operand 3 "" ""))))
11411    (clobber (reg:CCFP FPSR_REG))
11412    (clobber (reg:CCFP FLAGS_REG))
11413    (clobber (match_scratch:HI 4 "=a"))]
11414   "TARGET_80387
11415    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11416    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11417    && SELECT_CC_MODE (GET_CODE (operands[0]),
11418                       operands[1], operands[2]) == CCFPmode
11419    && !TARGET_CMOVE"
11420   "#")
11421
11422 (define_insn "*fp_jcc_5_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 "register_operand" "f")])
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   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11433    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11434    && !TARGET_CMOVE"
11435   "#")
11436
11437 (define_insn "*fp_jcc_6_387"
11438   [(set (pc)
11439         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11440                         [(match_operand 1 "register_operand" "f")
11441                          (match_operand 2 "register_operand" "f")])
11442           (pc)
11443           (label_ref (match_operand 3 "" ""))))
11444    (clobber (reg:CCFP FPSR_REG))
11445    (clobber (reg:CCFP FLAGS_REG))
11446    (clobber (match_scratch:HI 4 "=a"))]
11447   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11448    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11449    && !TARGET_CMOVE"
11450   "#")
11451
11452 (define_insn "*fp_jcc_7_387"
11453   [(set (pc)
11454         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11455                         [(match_operand 1 "register_operand" "f")
11456                          (match_operand 2 "const0_operand" "")])
11457           (label_ref (match_operand 3 "" ""))
11458           (pc)))
11459    (clobber (reg:CCFP FPSR_REG))
11460    (clobber (reg:CCFP FLAGS_REG))
11461    (clobber (match_scratch:HI 4 "=a"))]
11462   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11463    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11464    && SELECT_CC_MODE (GET_CODE (operands[0]),
11465                       operands[1], operands[2]) == CCFPmode
11466    && !TARGET_CMOVE"
11467   "#")
11468
11469 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11470 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11471 ;; with a precedence over other operators and is always put in the first
11472 ;; place. Swap condition and operands to match ficom instruction.
11473
11474 (define_insn "*fp_jcc_8<mode>_387"
11475   [(set (pc)
11476         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11477                         [(match_operator 1 "float_operator"
11478                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11479                            (match_operand 3 "register_operand" "f,f")])
11480           (label_ref (match_operand 4 "" ""))
11481           (pc)))
11482    (clobber (reg:CCFP FPSR_REG))
11483    (clobber (reg:CCFP FLAGS_REG))
11484    (clobber (match_scratch:HI 5 "=a,a"))]
11485   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11486    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11487    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11488    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11489    && !TARGET_CMOVE"
11490   "#")
11491
11492 (define_split
11493   [(set (pc)
11494         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11495                         [(match_operand 1 "register_operand" "")
11496                          (match_operand 2 "nonimmediate_operand" "")])
11497           (match_operand 3 "" "")
11498           (match_operand 4 "" "")))
11499    (clobber (reg:CCFP FPSR_REG))
11500    (clobber (reg:CCFP FLAGS_REG))]
11501   "reload_completed"
11502   [(const_int 0)]
11503 {
11504   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11505                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11506   DONE;
11507 })
11508
11509 (define_split
11510   [(set (pc)
11511         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11512                         [(match_operand 1 "register_operand" "")
11513                          (match_operand 2 "general_operand" "")])
11514           (match_operand 3 "" "")
11515           (match_operand 4 "" "")))
11516    (clobber (reg:CCFP FPSR_REG))
11517    (clobber (reg:CCFP FLAGS_REG))
11518    (clobber (match_scratch:HI 5 "=a"))]
11519   "reload_completed"
11520   [(const_int 0)]
11521 {
11522   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11523                         operands[3], operands[4], operands[5], NULL_RTX);
11524   DONE;
11525 })
11526
11527 (define_split
11528   [(set (pc)
11529         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11530                         [(match_operator 1 "float_operator"
11531                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
11532                            (match_operand 3 "register_operand" "")])
11533           (match_operand 4 "" "")
11534           (match_operand 5 "" "")))
11535    (clobber (reg:CCFP FPSR_REG))
11536    (clobber (reg:CCFP FLAGS_REG))
11537    (clobber (match_scratch:HI 6 "=a"))]
11538   "reload_completed"
11539   [(const_int 0)]
11540 {
11541   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11542
11543   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11544                         operands[3], operands[7],
11545                         operands[4], operands[5], operands[6], NULL_RTX);
11546   DONE;
11547 })
11548
11549 ;; %%% Kill this when reload knows how to do it.
11550 (define_split
11551   [(set (pc)
11552         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11553                         [(match_operator 1 "float_operator"
11554                            [(match_operand:X87MODEI12 2 "register_operand" "")])
11555                            (match_operand 3 "register_operand" "")])
11556           (match_operand 4 "" "")
11557           (match_operand 5 "" "")))
11558    (clobber (reg:CCFP FPSR_REG))
11559    (clobber (reg:CCFP FLAGS_REG))
11560    (clobber (match_scratch:HI 6 "=a"))]
11561   "reload_completed"
11562   [(const_int 0)]
11563 {
11564   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11565   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11566
11567   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11568                         operands[3], operands[7],
11569                         operands[4], operands[5], operands[6], operands[2]);
11570   DONE;
11571 })
11572 \f
11573 ;; Unconditional and other jump instructions
11574
11575 (define_insn "jump"
11576   [(set (pc)
11577         (label_ref (match_operand 0 "" "")))]
11578   ""
11579   "jmp\t%l0"
11580   [(set_attr "type" "ibr")
11581    (set (attr "length")
11582            (if_then_else (and (ge (minus (match_dup 0) (pc))
11583                                   (const_int -126))
11584                               (lt (minus (match_dup 0) (pc))
11585                                   (const_int 128)))
11586              (const_int 2)
11587              (const_int 5)))
11588    (set_attr "modrm" "0")])
11589
11590 (define_expand "indirect_jump"
11591   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11592   ""
11593   "")
11594
11595 (define_insn "*indirect_jump"
11596   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11597   ""
11598   "jmp\t%A0"
11599   [(set_attr "type" "ibr")
11600    (set_attr "length_immediate" "0")])
11601
11602 (define_expand "tablejump"
11603   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11604               (use (label_ref (match_operand 1 "" "")))])]
11605   ""
11606 {
11607   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11608      relative.  Convert the relative address to an absolute address.  */
11609   if (flag_pic)
11610     {
11611       rtx op0, op1;
11612       enum rtx_code code;
11613
11614       /* We can't use @GOTOFF for text labels on VxWorks;
11615          see gotoff_operand.  */
11616       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11617         {
11618           code = PLUS;
11619           op0 = operands[0];
11620           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11621         }
11622       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11623         {
11624           code = PLUS;
11625           op0 = operands[0];
11626           op1 = pic_offset_table_rtx;
11627         }
11628       else
11629         {
11630           code = MINUS;
11631           op0 = pic_offset_table_rtx;
11632           op1 = operands[0];
11633         }
11634
11635       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11636                                          OPTAB_DIRECT);
11637     }
11638 })
11639
11640 (define_insn "*tablejump_1"
11641   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11642    (use (label_ref (match_operand 1 "" "")))]
11643   ""
11644   "jmp\t%A0"
11645   [(set_attr "type" "ibr")
11646    (set_attr "length_immediate" "0")])
11647 \f
11648 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11649
11650 (define_peephole2
11651   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11652    (set (match_operand:QI 1 "register_operand" "")
11653         (match_operator:QI 2 "ix86_comparison_operator"
11654           [(reg FLAGS_REG) (const_int 0)]))
11655    (set (match_operand 3 "q_regs_operand" "")
11656         (zero_extend (match_dup 1)))]
11657   "(peep2_reg_dead_p (3, operands[1])
11658     || operands_match_p (operands[1], operands[3]))
11659    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11660   [(set (match_dup 4) (match_dup 0))
11661    (set (strict_low_part (match_dup 5))
11662         (match_dup 2))]
11663 {
11664   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11665   operands[5] = gen_lowpart (QImode, operands[3]);
11666   ix86_expand_clear (operands[3]);
11667 })
11668
11669 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11670
11671 (define_peephole2
11672   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11673    (set (match_operand:QI 1 "register_operand" "")
11674         (match_operator:QI 2 "ix86_comparison_operator"
11675           [(reg FLAGS_REG) (const_int 0)]))
11676    (parallel [(set (match_operand 3 "q_regs_operand" "")
11677                    (zero_extend (match_dup 1)))
11678               (clobber (reg:CC FLAGS_REG))])]
11679   "(peep2_reg_dead_p (3, operands[1])
11680     || operands_match_p (operands[1], operands[3]))
11681    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11682   [(set (match_dup 4) (match_dup 0))
11683    (set (strict_low_part (match_dup 5))
11684         (match_dup 2))]
11685 {
11686   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11687   operands[5] = gen_lowpart (QImode, operands[3]);
11688   ix86_expand_clear (operands[3]);
11689 })
11690 \f
11691 ;; Call instructions.
11692
11693 ;; The predicates normally associated with named expanders are not properly
11694 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11695 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11696
11697 ;; P6 processors will jump to the address after the decrement when %esp
11698 ;; is used as a call operand, so they will execute return address as a code.
11699 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11700  
11701 ;; Call subroutine returning no value.
11702
11703 (define_expand "call_pop"
11704   [(parallel [(call (match_operand:QI 0 "" "")
11705                     (match_operand:SI 1 "" ""))
11706               (set (reg:SI SP_REG)
11707                    (plus:SI (reg:SI SP_REG)
11708                             (match_operand:SI 3 "" "")))])]
11709   "!TARGET_64BIT"
11710 {
11711   ix86_expand_call (NULL, operands[0], operands[1],
11712                     operands[2], operands[3], 0);
11713   DONE;
11714 })
11715
11716 (define_insn "*call_pop_0"
11717   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11718          (match_operand:SI 1 "" ""))
11719    (set (reg:SI SP_REG)
11720         (plus:SI (reg:SI SP_REG)
11721                  (match_operand:SI 2 "immediate_operand" "")))]
11722   "!TARGET_64BIT"
11723 {
11724   if (SIBLING_CALL_P (insn))
11725     return "jmp\t%P0";
11726   else
11727     return "call\t%P0";
11728 }
11729   [(set_attr "type" "call")])
11730
11731 (define_insn "*call_pop_1"
11732   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11733          (match_operand:SI 1 "" ""))
11734    (set (reg:SI SP_REG)
11735         (plus:SI (reg:SI SP_REG)
11736                  (match_operand:SI 2 "immediate_operand" "i")))]
11737   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11738 {
11739   if (constant_call_address_operand (operands[0], Pmode))
11740     return "call\t%P0";
11741   return "call\t%A0";
11742 }
11743   [(set_attr "type" "call")])
11744
11745 (define_insn "*sibcall_pop_1"
11746   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11747          (match_operand:SI 1 "" ""))
11748    (set (reg:SI SP_REG)
11749         (plus:SI (reg:SI SP_REG)
11750                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11751   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11752   "@
11753    jmp\t%P0
11754    jmp\t%A0"
11755   [(set_attr "type" "call")])
11756
11757 (define_expand "call"
11758   [(call (match_operand:QI 0 "" "")
11759          (match_operand 1 "" ""))
11760    (use (match_operand 2 "" ""))]
11761   ""
11762 {
11763   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11764   DONE;
11765 })
11766
11767 (define_expand "sibcall"
11768   [(call (match_operand:QI 0 "" "")
11769          (match_operand 1 "" ""))
11770    (use (match_operand 2 "" ""))]
11771   ""
11772 {
11773   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11774   DONE;
11775 })
11776
11777 (define_insn "*call_0"
11778   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11779          (match_operand 1 "" ""))]
11780   ""
11781 {
11782   if (SIBLING_CALL_P (insn))
11783     return "jmp\t%P0";
11784   else
11785     return "call\t%P0";
11786 }
11787   [(set_attr "type" "call")])
11788
11789 (define_insn "*call_1"
11790   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11791          (match_operand 1 "" ""))]
11792   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11793 {
11794   if (constant_call_address_operand (operands[0], Pmode))
11795     return "call\t%P0";
11796   return "call\t%A0";
11797 }
11798   [(set_attr "type" "call")])
11799
11800 (define_insn "*sibcall_1"
11801   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11802          (match_operand 1 "" ""))]
11803   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11804   "@
11805    jmp\t%P0
11806    jmp\t%A0"
11807   [(set_attr "type" "call")])
11808
11809 (define_insn "*call_1_rex64"
11810   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11811          (match_operand 1 "" ""))]
11812   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11813    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11814 {
11815   if (constant_call_address_operand (operands[0], Pmode))
11816     return "call\t%P0";
11817   return "call\t%A0";
11818 }
11819   [(set_attr "type" "call")])
11820
11821 (define_insn "*call_1_rex64_ms_sysv"
11822   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11823          (match_operand 1 "" ""))
11824    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11825    (clobber (reg:TI XMM6_REG))
11826    (clobber (reg:TI XMM7_REG))
11827    (clobber (reg:TI XMM8_REG))
11828    (clobber (reg:TI XMM9_REG))
11829    (clobber (reg:TI XMM10_REG))
11830    (clobber (reg:TI XMM11_REG))
11831    (clobber (reg:TI XMM12_REG))
11832    (clobber (reg:TI XMM13_REG))
11833    (clobber (reg:TI XMM14_REG))
11834    (clobber (reg:TI XMM15_REG))
11835    (clobber (reg:DI SI_REG))
11836    (clobber (reg:DI DI_REG))]
11837   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11838 {
11839   if (constant_call_address_operand (operands[0], Pmode))
11840     return "call\t%P0";
11841   return "call\t%A0";
11842 }
11843   [(set_attr "type" "call")])
11844
11845 (define_insn "*call_1_rex64_large"
11846   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11847          (match_operand 1 "" ""))]
11848   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11849   "call\t%A0"
11850   [(set_attr "type" "call")])
11851
11852 (define_insn "*sibcall_1_rex64"
11853   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11854          (match_operand 1 "" ""))]
11855   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11856   "@
11857    jmp\t%P0
11858    jmp\t%A0"
11859   [(set_attr "type" "call")])
11860
11861 ;; Call subroutine, returning value in operand 0
11862 (define_expand "call_value_pop"
11863   [(parallel [(set (match_operand 0 "" "")
11864                    (call (match_operand:QI 1 "" "")
11865                          (match_operand:SI 2 "" "")))
11866               (set (reg:SI SP_REG)
11867                    (plus:SI (reg:SI SP_REG)
11868                             (match_operand:SI 4 "" "")))])]
11869   "!TARGET_64BIT"
11870 {
11871   ix86_expand_call (operands[0], operands[1], operands[2],
11872                     operands[3], operands[4], 0);
11873   DONE;
11874 })
11875
11876 (define_expand "call_value"
11877   [(set (match_operand 0 "" "")
11878         (call (match_operand:QI 1 "" "")
11879               (match_operand:SI 2 "" "")))
11880    (use (match_operand:SI 3 "" ""))]
11881   ;; Operand 3 is not used on the i386.
11882   ""
11883 {
11884   ix86_expand_call (operands[0], operands[1], operands[2],
11885                     operands[3], NULL, 0);
11886   DONE;
11887 })
11888
11889 (define_expand "sibcall_value"
11890   [(set (match_operand 0 "" "")
11891         (call (match_operand:QI 1 "" "")
11892               (match_operand:SI 2 "" "")))
11893    (use (match_operand:SI 3 "" ""))]
11894   ;; Operand 3 is not used on the i386.
11895   ""
11896 {
11897   ix86_expand_call (operands[0], operands[1], operands[2],
11898                     operands[3], NULL, 1);
11899   DONE;
11900 })
11901
11902 ;; Call subroutine returning any type.
11903
11904 (define_expand "untyped_call"
11905   [(parallel [(call (match_operand 0 "" "")
11906                     (const_int 0))
11907               (match_operand 1 "" "")
11908               (match_operand 2 "" "")])]
11909   ""
11910 {
11911   int i;
11912
11913   /* In order to give reg-stack an easier job in validating two
11914      coprocessor registers as containing a possible return value,
11915      simply pretend the untyped call returns a complex long double
11916      value. 
11917
11918      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11919      and should have the default ABI.  */
11920
11921   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11922                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11923                     operands[0], const0_rtx,
11924                     GEN_INT ((TARGET_64BIT
11925                               ? (ix86_abi == SYSV_ABI
11926                                  ? X86_64_SSE_REGPARM_MAX
11927                                  : X86_64_MS_SSE_REGPARM_MAX)
11928                               : X86_32_SSE_REGPARM_MAX)
11929                              - 1),
11930                     NULL, 0);
11931
11932   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11933     {
11934       rtx set = XVECEXP (operands[2], 0, i);
11935       emit_move_insn (SET_DEST (set), SET_SRC (set));
11936     }
11937
11938   /* The optimizer does not know that the call sets the function value
11939      registers we stored in the result block.  We avoid problems by
11940      claiming that all hard registers are used and clobbered at this
11941      point.  */
11942   emit_insn (gen_blockage ());
11943
11944   DONE;
11945 })
11946 \f
11947 ;; Prologue and epilogue instructions
11948
11949 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11950 ;; all of memory.  This blocks insns from being moved across this point.
11951
11952 (define_insn "blockage"
11953   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11954   ""
11955   ""
11956   [(set_attr "length" "0")])
11957
11958 ;; Do not schedule instructions accessing memory across this point.
11959
11960 (define_expand "memory_blockage"
11961   [(set (match_dup 0)
11962         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11963   ""
11964 {
11965   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11966   MEM_VOLATILE_P (operands[0]) = 1;
11967 })
11968
11969 (define_insn "*memory_blockage"
11970   [(set (match_operand:BLK 0 "" "")
11971         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11972   ""
11973   ""
11974   [(set_attr "length" "0")])
11975
11976 ;; As USE insns aren't meaningful after reload, this is used instead
11977 ;; to prevent deleting instructions setting registers for PIC code
11978 (define_insn "prologue_use"
11979   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11980   ""
11981   ""
11982   [(set_attr "length" "0")])
11983
11984 ;; Insn emitted into the body of a function to return from a function.
11985 ;; This is only done if the function's epilogue is known to be simple.
11986 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11987
11988 (define_expand "return"
11989   [(return)]
11990   "ix86_can_use_return_insn_p ()"
11991 {
11992   if (crtl->args.pops_args)
11993     {
11994       rtx popc = GEN_INT (crtl->args.pops_args);
11995       emit_jump_insn (gen_return_pop_internal (popc));
11996       DONE;
11997     }
11998 })
11999
12000 (define_insn "return_internal"
12001   [(return)]
12002   "reload_completed"
12003   "ret"
12004   [(set_attr "length" "1")
12005    (set_attr "atom_unit" "jeu")
12006    (set_attr "length_immediate" "0")
12007    (set_attr "modrm" "0")])
12008
12009 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12010 ;; instruction Athlon and K8 have.
12011
12012 (define_insn "return_internal_long"
12013   [(return)
12014    (unspec [(const_int 0)] UNSPEC_REP)]
12015   "reload_completed"
12016   "rep\;ret"
12017   [(set_attr "length" "2")
12018    (set_attr "atom_unit" "jeu")
12019    (set_attr "length_immediate" "0")
12020    (set_attr "prefix_rep" "1")
12021    (set_attr "modrm" "0")])
12022
12023 (define_insn "return_pop_internal"
12024   [(return)
12025    (use (match_operand:SI 0 "const_int_operand" ""))]
12026   "reload_completed"
12027   "ret\t%0"
12028   [(set_attr "length" "3")
12029    (set_attr "atom_unit" "jeu")
12030    (set_attr "length_immediate" "2")
12031    (set_attr "modrm" "0")])
12032
12033 (define_insn "return_indirect_internal"
12034   [(return)
12035    (use (match_operand:SI 0 "register_operand" "r"))]
12036   "reload_completed"
12037   "jmp\t%A0"
12038   [(set_attr "type" "ibr")
12039    (set_attr "length_immediate" "0")])
12040
12041 (define_insn "nop"
12042   [(const_int 0)]
12043   ""
12044   "nop"
12045   [(set_attr "length" "1")
12046    (set_attr "length_immediate" "0")
12047    (set_attr "modrm" "0")])
12048
12049 (define_insn "vswapmov"
12050   [(set (match_operand:SI 0 "register_operand" "=r")
12051         (match_operand:SI 1 "register_operand" "r"))
12052    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
12053   ""
12054   "movl.s\t{%1, %0|%0, %1}"
12055   [(set_attr "length" "2")
12056    (set_attr "length_immediate" "0")
12057    (set_attr "modrm" "0")])
12058
12059 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12060 ;; branch prediction penalty for the third jump in a 16-byte
12061 ;; block on K8.
12062
12063 (define_insn "pad"
12064   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
12065   ""
12066 {
12067 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12068   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12069 #else
12070   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12071      The align insn is used to avoid 3 jump instructions in the row to improve
12072      branch prediction and the benefits hardly outweigh the cost of extra 8
12073      nops on the average inserted by full alignment pseudo operation.  */
12074 #endif
12075   return "";
12076 }
12077   [(set_attr "length" "16")])
12078
12079 (define_expand "prologue"
12080   [(const_int 0)]
12081   ""
12082   "ix86_expand_prologue (); DONE;")
12083
12084 (define_insn "set_got"
12085   [(set (match_operand:SI 0 "register_operand" "=r")
12086         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12087    (clobber (reg:CC FLAGS_REG))]
12088   "!TARGET_64BIT"
12089   { return output_set_got (operands[0], NULL_RTX); }
12090   [(set_attr "type" "multi")
12091    (set_attr "length" "12")])
12092
12093 (define_insn "set_got_labelled"
12094   [(set (match_operand:SI 0 "register_operand" "=r")
12095         (unspec:SI [(label_ref (match_operand 1 "" ""))]
12096          UNSPEC_SET_GOT))
12097    (clobber (reg:CC FLAGS_REG))]
12098   "!TARGET_64BIT"
12099   { return output_set_got (operands[0], operands[1]); }
12100   [(set_attr "type" "multi")
12101    (set_attr "length" "12")])
12102
12103 (define_insn "set_got_rex64"
12104   [(set (match_operand:DI 0 "register_operand" "=r")
12105         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12106   "TARGET_64BIT"
12107   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12108   [(set_attr "type" "lea")
12109    (set_attr "length_address" "4")
12110    (set_attr "mode" "DI")])
12111
12112 (define_insn "set_rip_rex64"
12113   [(set (match_operand:DI 0 "register_operand" "=r")
12114         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
12115   "TARGET_64BIT"
12116   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12117   [(set_attr "type" "lea")
12118    (set_attr "length_address" "4")
12119    (set_attr "mode" "DI")])
12120
12121 (define_insn "set_got_offset_rex64"
12122   [(set (match_operand:DI 0 "register_operand" "=r")
12123         (unspec:DI
12124           [(label_ref (match_operand 1 "" ""))]
12125           UNSPEC_SET_GOT_OFFSET))]
12126   "TARGET_64BIT"
12127   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12128   [(set_attr "type" "imov")
12129    (set_attr "length_immediate" "0")
12130    (set_attr "length_address" "8")
12131    (set_attr "mode" "DI")])
12132
12133 (define_expand "epilogue"
12134   [(const_int 0)]
12135   ""
12136   "ix86_expand_epilogue (1); DONE;")
12137
12138 (define_expand "sibcall_epilogue"
12139   [(const_int 0)]
12140   ""
12141   "ix86_expand_epilogue (0); DONE;")
12142
12143 (define_expand "eh_return"
12144   [(use (match_operand 0 "register_operand" ""))]
12145   ""
12146 {
12147   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12148
12149   /* Tricky bit: we write the address of the handler to which we will
12150      be returning into someone else's stack frame, one word below the
12151      stack address we wish to restore.  */
12152   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12153   tmp = plus_constant (tmp, -UNITS_PER_WORD);
12154   tmp = gen_rtx_MEM (Pmode, tmp);
12155   emit_move_insn (tmp, ra);
12156
12157   emit_jump_insn (gen_eh_return_internal ());
12158   emit_barrier ();
12159   DONE;
12160 })
12161
12162 (define_insn_and_split "eh_return_internal"
12163   [(eh_return)]
12164   ""
12165   "#"
12166   "epilogue_completed"
12167   [(const_int 0)]
12168   "ix86_expand_epilogue (2); DONE;")
12169
12170 (define_insn "leave"
12171   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12172    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12173    (clobber (mem:BLK (scratch)))]
12174   "!TARGET_64BIT"
12175   "leave"
12176   [(set_attr "type" "leave")])
12177
12178 (define_insn "leave_rex64"
12179   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12180    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12181    (clobber (mem:BLK (scratch)))]
12182   "TARGET_64BIT"
12183   "leave"
12184   [(set_attr "type" "leave")])
12185 \f
12186 ;; Bit manipulation instructions.
12187
12188 (define_expand "ffs<mode>2"
12189   [(set (match_dup 2) (const_int -1))
12190    (parallel [(set (reg:CCZ FLAGS_REG)
12191                    (compare:CCZ
12192                      (match_operand:SWI48 1 "nonimmediate_operand" "")
12193                      (const_int 0)))
12194               (set (match_operand:SWI48 0 "register_operand" "")
12195                    (ctz:SWI48 (match_dup 1)))])
12196    (set (match_dup 0) (if_then_else:SWI48
12197                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12198                         (match_dup 2)
12199                         (match_dup 0)))
12200    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12201               (clobber (reg:CC FLAGS_REG))])]
12202   ""
12203 {
12204   if (<MODE>mode == SImode && !TARGET_CMOVE)
12205     {
12206       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12207       DONE;
12208     }
12209   operands[2] = gen_reg_rtx (<MODE>mode);
12210 })
12211
12212 (define_insn_and_split "ffssi2_no_cmove"
12213   [(set (match_operand:SI 0 "register_operand" "=r")
12214         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12215    (clobber (match_scratch:SI 2 "=&q"))
12216    (clobber (reg:CC FLAGS_REG))]
12217   "!TARGET_CMOVE"
12218   "#"
12219   "&& reload_completed"
12220   [(parallel [(set (reg:CCZ FLAGS_REG)
12221                    (compare:CCZ (match_dup 1) (const_int 0)))
12222               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12223    (set (strict_low_part (match_dup 3))
12224         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12225    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12226               (clobber (reg:CC FLAGS_REG))])
12227    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12228               (clobber (reg:CC FLAGS_REG))])
12229    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12230               (clobber (reg:CC FLAGS_REG))])]
12231 {
12232   operands[3] = gen_lowpart (QImode, operands[2]);
12233   ix86_expand_clear (operands[2]);
12234 })
12235
12236 (define_insn "*ffs<mode>_1"
12237   [(set (reg:CCZ FLAGS_REG)
12238         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12239                      (const_int 0)))
12240    (set (match_operand:SWI48 0 "register_operand" "=r")
12241         (ctz:SWI48 (match_dup 1)))]
12242   ""
12243   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12244   [(set_attr "type" "alu1")
12245    (set_attr "prefix_0f" "1")
12246    (set_attr "mode" "<MODE>")])
12247
12248 (define_insn "ctz<mode>2"
12249   [(set (match_operand:SWI48 0 "register_operand" "=r")
12250         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12251    (clobber (reg:CC FLAGS_REG))]
12252   ""
12253   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12254   [(set_attr "type" "alu1")
12255    (set_attr "prefix_0f" "1")
12256    (set_attr "mode" "<MODE>")])
12257
12258 (define_expand "clz<mode>2"
12259   [(parallel
12260      [(set (match_operand:SWI248 0 "register_operand" "")
12261            (minus:SWI248
12262              (match_dup 2)
12263              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12264       (clobber (reg:CC FLAGS_REG))])
12265    (parallel
12266      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12267       (clobber (reg:CC FLAGS_REG))])]
12268   ""
12269 {
12270   if (TARGET_ABM)
12271     {
12272       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12273       DONE;
12274     }
12275   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12276 })
12277
12278 (define_insn "clz<mode>2_abm"
12279   [(set (match_operand:SWI248 0 "register_operand" "=r")
12280         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12281    (clobber (reg:CC FLAGS_REG))]
12282   "TARGET_ABM"
12283   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12284   [(set_attr "prefix_rep" "1")
12285    (set_attr "type" "bitmanip")
12286    (set_attr "mode" "<MODE>")])
12287
12288 (define_insn "bsr_rex64"
12289   [(set (match_operand:DI 0 "register_operand" "=r")
12290         (minus:DI (const_int 63)
12291                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12292    (clobber (reg:CC FLAGS_REG))]
12293   "TARGET_64BIT"
12294   "bsr{q}\t{%1, %0|%0, %1}"
12295   [(set_attr "type" "alu1")
12296    (set_attr "prefix_0f" "1")
12297    (set_attr "mode" "DI")])
12298
12299 (define_insn "bsr"
12300   [(set (match_operand:SI 0 "register_operand" "=r")
12301         (minus:SI (const_int 31)
12302                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12303    (clobber (reg:CC FLAGS_REG))]
12304   ""
12305   "bsr{l}\t{%1, %0|%0, %1}"
12306   [(set_attr "type" "alu1")
12307    (set_attr "prefix_0f" "1")
12308    (set_attr "mode" "SI")])
12309
12310 (define_insn "*bsrhi"
12311   [(set (match_operand:HI 0 "register_operand" "=r")
12312         (minus:HI (const_int 15)
12313                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12314    (clobber (reg:CC FLAGS_REG))]
12315   ""
12316   "bsr{w}\t{%1, %0|%0, %1}"
12317   [(set_attr "type" "alu1")
12318    (set_attr "prefix_0f" "1")
12319    (set_attr "mode" "HI")])
12320
12321 (define_insn "popcount<mode>2"
12322   [(set (match_operand:SWI248 0 "register_operand" "=r")
12323         (popcount:SWI248
12324           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12325    (clobber (reg:CC FLAGS_REG))]
12326   "TARGET_POPCNT"
12327 {
12328 #if TARGET_MACHO
12329   return "popcnt\t{%1, %0|%0, %1}";
12330 #else
12331   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12332 #endif
12333 }
12334   [(set_attr "prefix_rep" "1")
12335    (set_attr "type" "bitmanip")
12336    (set_attr "mode" "<MODE>")])
12337
12338 (define_insn "*popcount<mode>2_cmp"
12339   [(set (reg FLAGS_REG)
12340         (compare
12341           (popcount:SWI248
12342             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12343           (const_int 0)))
12344    (set (match_operand:SWI248 0 "register_operand" "=r")
12345         (popcount:SWI248 (match_dup 1)))]
12346   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12347 {
12348 #if TARGET_MACHO
12349   return "popcnt\t{%1, %0|%0, %1}";
12350 #else
12351   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12352 #endif
12353 }
12354   [(set_attr "prefix_rep" "1")
12355    (set_attr "type" "bitmanip")
12356    (set_attr "mode" "<MODE>")])
12357
12358 (define_insn "*popcountsi2_cmp_zext"
12359   [(set (reg FLAGS_REG)
12360         (compare
12361           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12362           (const_int 0)))
12363    (set (match_operand:DI 0 "register_operand" "=r")
12364         (zero_extend:DI(popcount:SI (match_dup 1))))]
12365   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12366 {
12367 #if TARGET_MACHO
12368   return "popcnt\t{%1, %0|%0, %1}";
12369 #else
12370   return "popcnt{l}\t{%1, %0|%0, %1}";
12371 #endif
12372 }
12373   [(set_attr "prefix_rep" "1")
12374    (set_attr "type" "bitmanip")
12375    (set_attr "mode" "SI")])
12376
12377 (define_expand "bswap<mode>2"
12378   [(set (match_operand:SWI48 0 "register_operand" "")
12379         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12380   ""
12381 {
12382   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12383     {
12384       rtx x = operands[0];
12385
12386       emit_move_insn (x, operands[1]);
12387       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12388       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12389       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12390       DONE;
12391     }
12392 })
12393
12394 (define_insn "*bswap<mode>2_movbe"
12395   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12396         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12397   "TARGET_MOVBE
12398    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12399   "@
12400     bswap\t%0
12401     movbe\t{%1, %0|%0, %1}
12402     movbe\t{%1, %0|%0, %1}"
12403   [(set_attr "type" "bitmanip,imov,imov")
12404    (set_attr "modrm" "0,1,1")
12405    (set_attr "prefix_0f" "*,1,1")
12406    (set_attr "prefix_extra" "*,1,1")
12407    (set_attr "mode" "<MODE>")])
12408
12409 (define_insn "*bswap<mode>2_1"
12410   [(set (match_operand:SWI48 0 "register_operand" "=r")
12411         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12412   "TARGET_BSWAP"
12413   "bswap\t%0"
12414   [(set_attr "type" "bitmanip")
12415    (set_attr "modrm" "0")
12416    (set_attr "mode" "<MODE>")])
12417
12418 (define_insn "*bswaphi_lowpart_1"
12419   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12420         (bswap:HI (match_dup 0)))
12421    (clobber (reg:CC FLAGS_REG))]
12422   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12423   "@
12424     xchg{b}\t{%h0, %b0|%b0, %h0}
12425     rol{w}\t{$8, %0|%0, 8}"
12426   [(set_attr "length" "2,4")
12427    (set_attr "mode" "QI,HI")])
12428
12429 (define_insn "bswaphi_lowpart"
12430   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12431         (bswap:HI (match_dup 0)))
12432    (clobber (reg:CC FLAGS_REG))]
12433   ""
12434   "rol{w}\t{$8, %0|%0, 8}"
12435   [(set_attr "length" "4")
12436    (set_attr "mode" "HI")])
12437
12438 (define_expand "paritydi2"
12439   [(set (match_operand:DI 0 "register_operand" "")
12440         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12441   "! TARGET_POPCNT"
12442 {
12443   rtx scratch = gen_reg_rtx (QImode);
12444   rtx cond;
12445
12446   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12447                                 NULL_RTX, operands[1]));
12448
12449   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12450                          gen_rtx_REG (CCmode, FLAGS_REG),
12451                          const0_rtx);
12452   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12453
12454   if (TARGET_64BIT)
12455     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12456   else
12457     {
12458       rtx tmp = gen_reg_rtx (SImode);
12459
12460       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12461       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12462     }
12463   DONE;
12464 })
12465
12466 (define_expand "paritysi2"
12467   [(set (match_operand:SI 0 "register_operand" "")
12468         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12469   "! TARGET_POPCNT"
12470 {
12471   rtx scratch = gen_reg_rtx (QImode);
12472   rtx cond;
12473
12474   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12475
12476   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12477                          gen_rtx_REG (CCmode, FLAGS_REG),
12478                          const0_rtx);
12479   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12480
12481   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12482   DONE;
12483 })
12484
12485 (define_insn_and_split "paritydi2_cmp"
12486   [(set (reg:CC FLAGS_REG)
12487         (parity:CC (match_operand:DI 3 "register_operand" "0")))
12488    (clobber (match_scratch:DI 0 "=r"))
12489    (clobber (match_scratch:SI 1 "=&r"))
12490    (clobber (match_scratch:HI 2 "=Q"))]
12491   "! TARGET_POPCNT"
12492   "#"
12493   "&& reload_completed"
12494   [(parallel
12495      [(set (match_dup 1)
12496            (xor:SI (match_dup 1) (match_dup 4)))
12497       (clobber (reg:CC FLAGS_REG))])
12498    (parallel
12499      [(set (reg:CC FLAGS_REG)
12500            (parity:CC (match_dup 1)))
12501       (clobber (match_dup 1))
12502       (clobber (match_dup 2))])]
12503 {
12504   operands[4] = gen_lowpart (SImode, operands[3]);
12505
12506   if (TARGET_64BIT)
12507     {
12508       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12509       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12510     }
12511   else
12512     operands[1] = gen_highpart (SImode, operands[3]);
12513 })
12514
12515 (define_insn_and_split "paritysi2_cmp"
12516   [(set (reg:CC FLAGS_REG)
12517         (parity:CC (match_operand:SI 2 "register_operand" "0")))
12518    (clobber (match_scratch:SI 0 "=r"))
12519    (clobber (match_scratch:HI 1 "=&Q"))]
12520   "! TARGET_POPCNT"
12521   "#"
12522   "&& reload_completed"
12523   [(parallel
12524      [(set (match_dup 1)
12525            (xor:HI (match_dup 1) (match_dup 3)))
12526       (clobber (reg:CC FLAGS_REG))])
12527    (parallel
12528      [(set (reg:CC FLAGS_REG)
12529            (parity:CC (match_dup 1)))
12530       (clobber (match_dup 1))])]
12531 {
12532   operands[3] = gen_lowpart (HImode, operands[2]);
12533
12534   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12535   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12536 })
12537
12538 (define_insn "*parityhi2_cmp"
12539   [(set (reg:CC FLAGS_REG)
12540         (parity:CC (match_operand:HI 1 "register_operand" "0")))
12541    (clobber (match_scratch:HI 0 "=Q"))]
12542   "! TARGET_POPCNT"
12543   "xor{b}\t{%h0, %b0|%b0, %h0}"
12544   [(set_attr "length" "2")
12545    (set_attr "mode" "HI")])
12546
12547 (define_insn "*parityqi2_cmp"
12548   [(set (reg:CC FLAGS_REG)
12549         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12550   "! TARGET_POPCNT"
12551   "test{b}\t%0, %0"
12552   [(set_attr "length" "2")
12553    (set_attr "mode" "QI")])
12554 \f
12555 ;; Thread-local storage patterns for ELF.
12556 ;;
12557 ;; Note that these code sequences must appear exactly as shown
12558 ;; in order to allow linker relaxation.
12559
12560 (define_insn "*tls_global_dynamic_32_gnu"
12561   [(set (match_operand:SI 0 "register_operand" "=a")
12562         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12563                     (match_operand:SI 2 "tls_symbolic_operand" "")
12564                     (match_operand:SI 3 "call_insn_operand" "")]
12565                     UNSPEC_TLS_GD))
12566    (clobber (match_scratch:SI 4 "=d"))
12567    (clobber (match_scratch:SI 5 "=c"))
12568    (clobber (reg:CC FLAGS_REG))]
12569   "!TARGET_64BIT && TARGET_GNU_TLS"
12570   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12571   [(set_attr "type" "multi")
12572    (set_attr "length" "12")])
12573
12574 (define_expand "tls_global_dynamic_32"
12575   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12576                    (unspec:SI
12577                     [(match_dup 2)
12578                      (match_operand:SI 1 "tls_symbolic_operand" "")
12579                      (match_dup 3)]
12580                     UNSPEC_TLS_GD))
12581               (clobber (match_scratch:SI 4 ""))
12582               (clobber (match_scratch:SI 5 ""))
12583               (clobber (reg:CC FLAGS_REG))])]
12584   ""
12585 {
12586   if (flag_pic)
12587     operands[2] = pic_offset_table_rtx;
12588   else
12589     {
12590       operands[2] = gen_reg_rtx (Pmode);
12591       emit_insn (gen_set_got (operands[2]));
12592     }
12593   if (TARGET_GNU2_TLS)
12594     {
12595        emit_insn (gen_tls_dynamic_gnu2_32
12596                   (operands[0], operands[1], operands[2]));
12597        DONE;
12598     }
12599   operands[3] = ix86_tls_get_addr ();
12600 })
12601
12602 (define_insn "*tls_global_dynamic_64"
12603   [(set (match_operand:DI 0 "register_operand" "=a")
12604         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12605                  (match_operand:DI 3 "" "")))
12606    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12607               UNSPEC_TLS_GD)]
12608   "TARGET_64BIT"
12609   { 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"; }
12610   [(set_attr "type" "multi")
12611    (set_attr "length" "16")])
12612
12613 (define_expand "tls_global_dynamic_64"
12614   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12615                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12616               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12617                          UNSPEC_TLS_GD)])]
12618   ""
12619 {
12620   if (TARGET_GNU2_TLS)
12621     {
12622        emit_insn (gen_tls_dynamic_gnu2_64
12623                   (operands[0], operands[1]));
12624        DONE;
12625     }
12626   operands[2] = ix86_tls_get_addr ();
12627 })
12628
12629 (define_insn "*tls_local_dynamic_base_32_gnu"
12630   [(set (match_operand:SI 0 "register_operand" "=a")
12631         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12632                     (match_operand:SI 2 "call_insn_operand" "")]
12633                    UNSPEC_TLS_LD_BASE))
12634    (clobber (match_scratch:SI 3 "=d"))
12635    (clobber (match_scratch:SI 4 "=c"))
12636    (clobber (reg:CC FLAGS_REG))]
12637   "!TARGET_64BIT && TARGET_GNU_TLS"
12638   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12639   [(set_attr "type" "multi")
12640    (set_attr "length" "11")])
12641
12642 (define_expand "tls_local_dynamic_base_32"
12643   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12644                    (unspec:SI [(match_dup 1) (match_dup 2)]
12645                               UNSPEC_TLS_LD_BASE))
12646               (clobber (match_scratch:SI 3 ""))
12647               (clobber (match_scratch:SI 4 ""))
12648               (clobber (reg:CC FLAGS_REG))])]
12649   ""
12650 {
12651   if (flag_pic)
12652     operands[1] = pic_offset_table_rtx;
12653   else
12654     {
12655       operands[1] = gen_reg_rtx (Pmode);
12656       emit_insn (gen_set_got (operands[1]));
12657     }
12658   if (TARGET_GNU2_TLS)
12659     {
12660        emit_insn (gen_tls_dynamic_gnu2_32
12661                   (operands[0], ix86_tls_module_base (), operands[1]));
12662        DONE;
12663     }
12664   operands[2] = ix86_tls_get_addr ();
12665 })
12666
12667 (define_insn "*tls_local_dynamic_base_64"
12668   [(set (match_operand:DI 0 "register_operand" "=a")
12669         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12670                  (match_operand:DI 2 "" "")))
12671    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12672   "TARGET_64BIT"
12673   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12674   [(set_attr "type" "multi")
12675    (set_attr "length" "12")])
12676
12677 (define_expand "tls_local_dynamic_base_64"
12678   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12679                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12680               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12681   ""
12682 {
12683   if (TARGET_GNU2_TLS)
12684     {
12685        emit_insn (gen_tls_dynamic_gnu2_64
12686                   (operands[0], ix86_tls_module_base ()));
12687        DONE;
12688     }
12689   operands[1] = ix86_tls_get_addr ();
12690 })
12691
12692 ;; Local dynamic of a single variable is a lose.  Show combine how
12693 ;; to convert that back to global dynamic.
12694
12695 (define_insn_and_split "*tls_local_dynamic_32_once"
12696   [(set (match_operand:SI 0 "register_operand" "=a")
12697         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12698                              (match_operand:SI 2 "call_insn_operand" "")]
12699                             UNSPEC_TLS_LD_BASE)
12700                  (const:SI (unspec:SI
12701                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12702                             UNSPEC_DTPOFF))))
12703    (clobber (match_scratch:SI 4 "=d"))
12704    (clobber (match_scratch:SI 5 "=c"))
12705    (clobber (reg:CC FLAGS_REG))]
12706   ""
12707   "#"
12708   ""
12709   [(parallel [(set (match_dup 0)
12710                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12711                               UNSPEC_TLS_GD))
12712               (clobber (match_dup 4))
12713               (clobber (match_dup 5))
12714               (clobber (reg:CC FLAGS_REG))])]
12715   "")
12716
12717 ;; Load and add the thread base pointer from %gs:0.
12718
12719 (define_insn "*load_tp_si"
12720   [(set (match_operand:SI 0 "register_operand" "=r")
12721         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12722   "!TARGET_64BIT"
12723   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12724   [(set_attr "type" "imov")
12725    (set_attr "modrm" "0")
12726    (set_attr "length" "7")
12727    (set_attr "memory" "load")
12728    (set_attr "imm_disp" "false")])
12729
12730 (define_insn "*add_tp_si"
12731   [(set (match_operand:SI 0 "register_operand" "=r")
12732         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12733                  (match_operand:SI 1 "register_operand" "0")))
12734    (clobber (reg:CC FLAGS_REG))]
12735   "!TARGET_64BIT"
12736   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12737   [(set_attr "type" "alu")
12738    (set_attr "modrm" "0")
12739    (set_attr "length" "7")
12740    (set_attr "memory" "load")
12741    (set_attr "imm_disp" "false")])
12742
12743 (define_insn "*load_tp_di"
12744   [(set (match_operand:DI 0 "register_operand" "=r")
12745         (unspec:DI [(const_int 0)] UNSPEC_TP))]
12746   "TARGET_64BIT"
12747   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12748   [(set_attr "type" "imov")
12749    (set_attr "modrm" "0")
12750    (set_attr "length" "7")
12751    (set_attr "memory" "load")
12752    (set_attr "imm_disp" "false")])
12753
12754 (define_insn "*add_tp_di"
12755   [(set (match_operand:DI 0 "register_operand" "=r")
12756         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12757                  (match_operand:DI 1 "register_operand" "0")))
12758    (clobber (reg:CC FLAGS_REG))]
12759   "TARGET_64BIT"
12760   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12761   [(set_attr "type" "alu")
12762    (set_attr "modrm" "0")
12763    (set_attr "length" "7")
12764    (set_attr "memory" "load")
12765    (set_attr "imm_disp" "false")])
12766
12767 ;; GNU2 TLS patterns can be split.
12768
12769 (define_expand "tls_dynamic_gnu2_32"
12770   [(set (match_dup 3)
12771         (plus:SI (match_operand:SI 2 "register_operand" "")
12772                  (const:SI
12773                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12774                              UNSPEC_TLSDESC))))
12775    (parallel
12776     [(set (match_operand:SI 0 "register_operand" "")
12777           (unspec:SI [(match_dup 1) (match_dup 3)
12778                       (match_dup 2) (reg:SI SP_REG)]
12779                       UNSPEC_TLSDESC))
12780      (clobber (reg:CC FLAGS_REG))])]
12781   "!TARGET_64BIT && TARGET_GNU2_TLS"
12782 {
12783   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12784   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12785 })
12786
12787 (define_insn "*tls_dynamic_lea_32"
12788   [(set (match_operand:SI 0 "register_operand" "=r")
12789         (plus:SI (match_operand:SI 1 "register_operand" "b")
12790                  (const:SI
12791                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12792                               UNSPEC_TLSDESC))))]
12793   "!TARGET_64BIT && TARGET_GNU2_TLS"
12794   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12795   [(set_attr "type" "lea")
12796    (set_attr "mode" "SI")
12797    (set_attr "length" "6")
12798    (set_attr "length_address" "4")])
12799
12800 (define_insn "*tls_dynamic_call_32"
12801   [(set (match_operand:SI 0 "register_operand" "=a")
12802         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12803                     (match_operand:SI 2 "register_operand" "0")
12804                     ;; we have to make sure %ebx still points to the GOT
12805                     (match_operand:SI 3 "register_operand" "b")
12806                     (reg:SI SP_REG)]
12807                    UNSPEC_TLSDESC))
12808    (clobber (reg:CC FLAGS_REG))]
12809   "!TARGET_64BIT && TARGET_GNU2_TLS"
12810   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12811   [(set_attr "type" "call")
12812    (set_attr "length" "2")
12813    (set_attr "length_address" "0")])
12814
12815 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12816   [(set (match_operand:SI 0 "register_operand" "=&a")
12817         (plus:SI
12818          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12819                      (match_operand:SI 4 "" "")
12820                      (match_operand:SI 2 "register_operand" "b")
12821                      (reg:SI SP_REG)]
12822                     UNSPEC_TLSDESC)
12823          (const:SI (unspec:SI
12824                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12825                     UNSPEC_DTPOFF))))
12826    (clobber (reg:CC FLAGS_REG))]
12827   "!TARGET_64BIT && TARGET_GNU2_TLS"
12828   "#"
12829   ""
12830   [(set (match_dup 0) (match_dup 5))]
12831 {
12832   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12833   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12834 })
12835
12836 (define_expand "tls_dynamic_gnu2_64"
12837   [(set (match_dup 2)
12838         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12839                    UNSPEC_TLSDESC))
12840    (parallel
12841     [(set (match_operand:DI 0 "register_operand" "")
12842           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12843                      UNSPEC_TLSDESC))
12844      (clobber (reg:CC FLAGS_REG))])]
12845   "TARGET_64BIT && TARGET_GNU2_TLS"
12846 {
12847   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12848   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12849 })
12850
12851 (define_insn "*tls_dynamic_lea_64"
12852   [(set (match_operand:DI 0 "register_operand" "=r")
12853         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12854                    UNSPEC_TLSDESC))]
12855   "TARGET_64BIT && TARGET_GNU2_TLS"
12856   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12857   [(set_attr "type" "lea")
12858    (set_attr "mode" "DI")
12859    (set_attr "length" "7")
12860    (set_attr "length_address" "4")])
12861
12862 (define_insn "*tls_dynamic_call_64"
12863   [(set (match_operand:DI 0 "register_operand" "=a")
12864         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12865                     (match_operand:DI 2 "register_operand" "0")
12866                     (reg:DI SP_REG)]
12867                    UNSPEC_TLSDESC))
12868    (clobber (reg:CC FLAGS_REG))]
12869   "TARGET_64BIT && TARGET_GNU2_TLS"
12870   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12871   [(set_attr "type" "call")
12872    (set_attr "length" "2")
12873    (set_attr "length_address" "0")])
12874
12875 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12876   [(set (match_operand:DI 0 "register_operand" "=&a")
12877         (plus:DI
12878          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12879                      (match_operand:DI 3 "" "")
12880                      (reg:DI SP_REG)]
12881                     UNSPEC_TLSDESC)
12882          (const:DI (unspec:DI
12883                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12884                     UNSPEC_DTPOFF))))
12885    (clobber (reg:CC FLAGS_REG))]
12886   "TARGET_64BIT && TARGET_GNU2_TLS"
12887   "#"
12888   ""
12889   [(set (match_dup 0) (match_dup 4))]
12890 {
12891   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12892   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12893 })
12894
12895 ;;
12896 \f
12897 ;; These patterns match the binary 387 instructions for addM3, subM3,
12898 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12899 ;; SFmode.  The first is the normal insn, the second the same insn but
12900 ;; with one operand a conversion, and the third the same insn but with
12901 ;; the other operand a conversion.  The conversion may be SFmode or
12902 ;; SImode if the target mode DFmode, but only SImode if the target mode
12903 ;; is SFmode.
12904
12905 ;; Gcc is slightly more smart about handling normal two address instructions
12906 ;; so use special patterns for add and mull.
12907
12908 (define_insn "*fop_<mode>_comm_mixed_avx"
12909   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12910         (match_operator:MODEF 3 "binary_fp_operator"
12911           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12912            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12913   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12914    && COMMUTATIVE_ARITH_P (operands[3])
12915    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12916   "* return output_387_binary_op (insn, operands);"
12917   [(set (attr "type")
12918         (if_then_else (eq_attr "alternative" "1")
12919            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12920               (const_string "ssemul")
12921               (const_string "sseadd"))
12922            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12923               (const_string "fmul")
12924               (const_string "fop"))))
12925    (set_attr "prefix" "orig,maybe_vex")
12926    (set_attr "mode" "<MODE>")])
12927
12928 (define_insn "*fop_<mode>_comm_mixed"
12929   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12930         (match_operator:MODEF 3 "binary_fp_operator"
12931           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12932            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12933   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12934    && COMMUTATIVE_ARITH_P (operands[3])
12935    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12936   "* return output_387_binary_op (insn, operands);"
12937   [(set (attr "type")
12938         (if_then_else (eq_attr "alternative" "1")
12939            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12940               (const_string "ssemul")
12941               (const_string "sseadd"))
12942            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12943               (const_string "fmul")
12944               (const_string "fop"))))
12945    (set_attr "mode" "<MODE>")])
12946
12947 (define_insn "*fop_<mode>_comm_avx"
12948   [(set (match_operand:MODEF 0 "register_operand" "=x")
12949         (match_operator:MODEF 3 "binary_fp_operator"
12950           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12951            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12952   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12953    && COMMUTATIVE_ARITH_P (operands[3])
12954    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12955   "* return output_387_binary_op (insn, operands);"
12956   [(set (attr "type")
12957         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12958            (const_string "ssemul")
12959            (const_string "sseadd")))
12960    (set_attr "prefix" "vex")
12961    (set_attr "mode" "<MODE>")])
12962
12963 (define_insn "*fop_<mode>_comm_sse"
12964   [(set (match_operand:MODEF 0 "register_operand" "=x")
12965         (match_operator:MODEF 3 "binary_fp_operator"
12966           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12967            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12968   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12969    && COMMUTATIVE_ARITH_P (operands[3])
12970    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12971   "* return output_387_binary_op (insn, operands);"
12972   [(set (attr "type")
12973         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12974            (const_string "ssemul")
12975            (const_string "sseadd")))
12976    (set_attr "mode" "<MODE>")])
12977
12978 (define_insn "*fop_<mode>_comm_i387"
12979   [(set (match_operand:MODEF 0 "register_operand" "=f")
12980         (match_operator:MODEF 3 "binary_fp_operator"
12981           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12982            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12983   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12984    && COMMUTATIVE_ARITH_P (operands[3])
12985    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12986   "* return output_387_binary_op (insn, operands);"
12987   [(set (attr "type")
12988         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12989            (const_string "fmul")
12990            (const_string "fop")))
12991    (set_attr "mode" "<MODE>")])
12992
12993 (define_insn "*fop_<mode>_1_mixed_avx"
12994   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12995         (match_operator:MODEF 3 "binary_fp_operator"
12996           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12997            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12998   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12999    && !COMMUTATIVE_ARITH_P (operands[3])
13000    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13001   "* return output_387_binary_op (insn, operands);"
13002   [(set (attr "type")
13003         (cond [(and (eq_attr "alternative" "2")
13004                     (match_operand:MODEF 3 "mult_operator" ""))
13005                  (const_string "ssemul")
13006                (and (eq_attr "alternative" "2")
13007                     (match_operand:MODEF 3 "div_operator" ""))
13008                  (const_string "ssediv")
13009                (eq_attr "alternative" "2")
13010                  (const_string "sseadd")
13011                (match_operand:MODEF 3 "mult_operator" "")
13012                  (const_string "fmul")
13013                (match_operand:MODEF 3 "div_operator" "")
13014                  (const_string "fdiv")
13015               ]
13016               (const_string "fop")))
13017    (set_attr "prefix" "orig,orig,maybe_vex")
13018    (set_attr "mode" "<MODE>")])
13019
13020 (define_insn "*fop_<mode>_1_mixed"
13021   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13022         (match_operator:MODEF 3 "binary_fp_operator"
13023           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
13024            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13025   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13026    && !COMMUTATIVE_ARITH_P (operands[3])
13027    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13028   "* return output_387_binary_op (insn, operands);"
13029   [(set (attr "type")
13030         (cond [(and (eq_attr "alternative" "2")
13031                     (match_operand:MODEF 3 "mult_operator" ""))
13032                  (const_string "ssemul")
13033                (and (eq_attr "alternative" "2")
13034                     (match_operand:MODEF 3 "div_operator" ""))
13035                  (const_string "ssediv")
13036                (eq_attr "alternative" "2")
13037                  (const_string "sseadd")
13038                (match_operand:MODEF 3 "mult_operator" "")
13039                  (const_string "fmul")
13040                (match_operand:MODEF 3 "div_operator" "")
13041                  (const_string "fdiv")
13042               ]
13043               (const_string "fop")))
13044    (set_attr "mode" "<MODE>")])
13045
13046 (define_insn "*rcpsf2_sse"
13047   [(set (match_operand:SF 0 "register_operand" "=x")
13048         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13049                    UNSPEC_RCP))]
13050   "TARGET_SSE_MATH"
13051   "%vrcpss\t{%1, %d0|%d0, %1}"
13052   [(set_attr "type" "sse")
13053    (set_attr "atom_sse_attr" "rcp")
13054    (set_attr "prefix" "maybe_vex")
13055    (set_attr "mode" "SF")])
13056
13057 (define_insn "*fop_<mode>_1_avx"
13058   [(set (match_operand:MODEF 0 "register_operand" "=x")
13059         (match_operator:MODEF 3 "binary_fp_operator"
13060           [(match_operand:MODEF 1 "register_operand" "x")
13061            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13062   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13063    && !COMMUTATIVE_ARITH_P (operands[3])"
13064   "* return output_387_binary_op (insn, operands);"
13065   [(set (attr "type")
13066         (cond [(match_operand:MODEF 3 "mult_operator" "")
13067                  (const_string "ssemul")
13068                (match_operand:MODEF 3 "div_operator" "")
13069                  (const_string "ssediv")
13070               ]
13071               (const_string "sseadd")))
13072    (set_attr "prefix" "vex")
13073    (set_attr "mode" "<MODE>")])
13074
13075 (define_insn "*fop_<mode>_1_sse"
13076   [(set (match_operand:MODEF 0 "register_operand" "=x")
13077         (match_operator:MODEF 3 "binary_fp_operator"
13078           [(match_operand:MODEF 1 "register_operand" "0")
13079            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13080   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13081    && !COMMUTATIVE_ARITH_P (operands[3])"
13082   "* return output_387_binary_op (insn, operands);"
13083   [(set (attr "type")
13084         (cond [(match_operand:MODEF 3 "mult_operator" "")
13085                  (const_string "ssemul")
13086                (match_operand:MODEF 3 "div_operator" "")
13087                  (const_string "ssediv")
13088               ]
13089               (const_string "sseadd")))
13090    (set_attr "mode" "<MODE>")])
13091
13092 ;; This pattern is not fully shadowed by the pattern above.
13093 (define_insn "*fop_<mode>_1_i387"
13094   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13095         (match_operator:MODEF 3 "binary_fp_operator"
13096           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13097            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13098   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13099    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13100    && !COMMUTATIVE_ARITH_P (operands[3])
13101    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13102   "* return output_387_binary_op (insn, operands);"
13103   [(set (attr "type")
13104         (cond [(match_operand:MODEF 3 "mult_operator" "")
13105                  (const_string "fmul")
13106                (match_operand:MODEF 3 "div_operator" "")
13107                  (const_string "fdiv")
13108               ]
13109               (const_string "fop")))
13110    (set_attr "mode" "<MODE>")])
13111
13112 ;; ??? Add SSE splitters for these!
13113 (define_insn "*fop_<MODEF:mode>_2_i387"
13114   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13115         (match_operator:MODEF 3 "binary_fp_operator"
13116           [(float:MODEF
13117              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13118            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13119   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13120    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13121    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13122   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13123   [(set (attr "type")
13124         (cond [(match_operand:MODEF 3 "mult_operator" "")
13125                  (const_string "fmul")
13126                (match_operand:MODEF 3 "div_operator" "")
13127                  (const_string "fdiv")
13128               ]
13129               (const_string "fop")))
13130    (set_attr "fp_int_src" "true")
13131    (set_attr "mode" "<X87MODEI12:MODE>")])
13132
13133 (define_insn "*fop_<MODEF:mode>_3_i387"
13134   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13135         (match_operator:MODEF 3 "binary_fp_operator"
13136           [(match_operand:MODEF 1 "register_operand" "0,0")
13137            (float:MODEF
13138              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13139   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13140    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13141    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13142   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13143   [(set (attr "type")
13144         (cond [(match_operand:MODEF 3 "mult_operator" "")
13145                  (const_string "fmul")
13146                (match_operand:MODEF 3 "div_operator" "")
13147                  (const_string "fdiv")
13148               ]
13149               (const_string "fop")))
13150    (set_attr "fp_int_src" "true")
13151    (set_attr "mode" "<MODE>")])
13152
13153 (define_insn "*fop_df_4_i387"
13154   [(set (match_operand:DF 0 "register_operand" "=f,f")
13155         (match_operator:DF 3 "binary_fp_operator"
13156            [(float_extend:DF
13157              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13158             (match_operand:DF 2 "register_operand" "0,f")]))]
13159   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13160    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13161    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13162   "* return output_387_binary_op (insn, operands);"
13163   [(set (attr "type")
13164         (cond [(match_operand:DF 3 "mult_operator" "")
13165                  (const_string "fmul")
13166                (match_operand:DF 3 "div_operator" "")
13167                  (const_string "fdiv")
13168               ]
13169               (const_string "fop")))
13170    (set_attr "mode" "SF")])
13171
13172 (define_insn "*fop_df_5_i387"
13173   [(set (match_operand:DF 0 "register_operand" "=f,f")
13174         (match_operator:DF 3 "binary_fp_operator"
13175           [(match_operand:DF 1 "register_operand" "0,f")
13176            (float_extend:DF
13177             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13178   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13179    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13180   "* return output_387_binary_op (insn, operands);"
13181   [(set (attr "type")
13182         (cond [(match_operand:DF 3 "mult_operator" "")
13183                  (const_string "fmul")
13184                (match_operand:DF 3 "div_operator" "")
13185                  (const_string "fdiv")
13186               ]
13187               (const_string "fop")))
13188    (set_attr "mode" "SF")])
13189
13190 (define_insn "*fop_df_6_i387"
13191   [(set (match_operand:DF 0 "register_operand" "=f,f")
13192         (match_operator:DF 3 "binary_fp_operator"
13193           [(float_extend:DF
13194             (match_operand:SF 1 "register_operand" "0,f"))
13195            (float_extend:DF
13196             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13197   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13198    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13199   "* return output_387_binary_op (insn, operands);"
13200   [(set (attr "type")
13201         (cond [(match_operand:DF 3 "mult_operator" "")
13202                  (const_string "fmul")
13203                (match_operand:DF 3 "div_operator" "")
13204                  (const_string "fdiv")
13205               ]
13206               (const_string "fop")))
13207    (set_attr "mode" "SF")])
13208
13209 (define_insn "*fop_xf_comm_i387"
13210   [(set (match_operand:XF 0 "register_operand" "=f")
13211         (match_operator:XF 3 "binary_fp_operator"
13212                         [(match_operand:XF 1 "register_operand" "%0")
13213                          (match_operand:XF 2 "register_operand" "f")]))]
13214   "TARGET_80387
13215    && COMMUTATIVE_ARITH_P (operands[3])"
13216   "* return output_387_binary_op (insn, operands);"
13217   [(set (attr "type")
13218         (if_then_else (match_operand:XF 3 "mult_operator" "")
13219            (const_string "fmul")
13220            (const_string "fop")))
13221    (set_attr "mode" "XF")])
13222
13223 (define_insn "*fop_xf_1_i387"
13224   [(set (match_operand:XF 0 "register_operand" "=f,f")
13225         (match_operator:XF 3 "binary_fp_operator"
13226                         [(match_operand:XF 1 "register_operand" "0,f")
13227                          (match_operand:XF 2 "register_operand" "f,0")]))]
13228   "TARGET_80387
13229    && !COMMUTATIVE_ARITH_P (operands[3])"
13230   "* return output_387_binary_op (insn, operands);"
13231   [(set (attr "type")
13232         (cond [(match_operand:XF 3 "mult_operator" "")
13233                  (const_string "fmul")
13234                (match_operand:XF 3 "div_operator" "")
13235                  (const_string "fdiv")
13236               ]
13237               (const_string "fop")))
13238    (set_attr "mode" "XF")])
13239
13240 (define_insn "*fop_xf_2_i387"
13241   [(set (match_operand:XF 0 "register_operand" "=f,f")
13242         (match_operator:XF 3 "binary_fp_operator"
13243           [(float:XF
13244              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13245            (match_operand:XF 2 "register_operand" "0,0")]))]
13246   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13247   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13248   [(set (attr "type")
13249         (cond [(match_operand:XF 3 "mult_operator" "")
13250                  (const_string "fmul")
13251                (match_operand:XF 3 "div_operator" "")
13252                  (const_string "fdiv")
13253               ]
13254               (const_string "fop")))
13255    (set_attr "fp_int_src" "true")
13256    (set_attr "mode" "<MODE>")])
13257
13258 (define_insn "*fop_xf_3_i387"
13259   [(set (match_operand:XF 0 "register_operand" "=f,f")
13260         (match_operator:XF 3 "binary_fp_operator"
13261           [(match_operand:XF 1 "register_operand" "0,0")
13262            (float:XF
13263              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13264   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13265   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13266   [(set (attr "type")
13267         (cond [(match_operand:XF 3 "mult_operator" "")
13268                  (const_string "fmul")
13269                (match_operand:XF 3 "div_operator" "")
13270                  (const_string "fdiv")
13271               ]
13272               (const_string "fop")))
13273    (set_attr "fp_int_src" "true")
13274    (set_attr "mode" "<MODE>")])
13275
13276 (define_insn "*fop_xf_4_i387"
13277   [(set (match_operand:XF 0 "register_operand" "=f,f")
13278         (match_operator:XF 3 "binary_fp_operator"
13279            [(float_extend:XF
13280               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13281             (match_operand:XF 2 "register_operand" "0,f")]))]
13282   "TARGET_80387"
13283   "* return 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 "mode" "<MODE>")])
13292
13293 (define_insn "*fop_xf_5_i387"
13294   [(set (match_operand:XF 0 "register_operand" "=f,f")
13295         (match_operator:XF 3 "binary_fp_operator"
13296           [(match_operand:XF 1 "register_operand" "0,f")
13297            (float_extend:XF
13298              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13299   "TARGET_80387"
13300   "* return output_387_binary_op (insn, operands);"
13301   [(set (attr "type")
13302         (cond [(match_operand:XF 3 "mult_operator" "")
13303                  (const_string "fmul")
13304                (match_operand:XF 3 "div_operator" "")
13305                  (const_string "fdiv")
13306               ]
13307               (const_string "fop")))
13308    (set_attr "mode" "<MODE>")])
13309
13310 (define_insn "*fop_xf_6_i387"
13311   [(set (match_operand:XF 0 "register_operand" "=f,f")
13312         (match_operator:XF 3 "binary_fp_operator"
13313           [(float_extend:XF
13314              (match_operand:MODEF 1 "register_operand" "0,f"))
13315            (float_extend:XF
13316              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13317   "TARGET_80387"
13318   "* return output_387_binary_op (insn, operands);"
13319   [(set (attr "type")
13320         (cond [(match_operand:XF 3 "mult_operator" "")
13321                  (const_string "fmul")
13322                (match_operand:XF 3 "div_operator" "")
13323                  (const_string "fdiv")
13324               ]
13325               (const_string "fop")))
13326    (set_attr "mode" "<MODE>")])
13327
13328 (define_split
13329   [(set (match_operand 0 "register_operand" "")
13330         (match_operator 3 "binary_fp_operator"
13331            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13332             (match_operand 2 "register_operand" "")]))]
13333   "reload_completed
13334    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13335    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13336   [(const_int 0)]
13337 {
13338   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13339   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13340   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13341                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13342                                           GET_MODE (operands[3]),
13343                                           operands[4],
13344                                           operands[2])));
13345   ix86_free_from_memory (GET_MODE (operands[1]));
13346   DONE;
13347 })
13348
13349 (define_split
13350   [(set (match_operand 0 "register_operand" "")
13351         (match_operator 3 "binary_fp_operator"
13352            [(match_operand 1 "register_operand" "")
13353             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13354   "reload_completed
13355    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13356    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13357   [(const_int 0)]
13358 {
13359   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13360   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13361   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13362                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13363                                           GET_MODE (operands[3]),
13364                                           operands[1],
13365                                           operands[4])));
13366   ix86_free_from_memory (GET_MODE (operands[2]));
13367   DONE;
13368 })
13369 \f
13370 ;; FPU special functions.
13371
13372 ;; This pattern implements a no-op XFmode truncation for
13373 ;; all fancy i386 XFmode math functions.
13374
13375 (define_insn "truncxf<mode>2_i387_noop_unspec"
13376   [(set (match_operand:MODEF 0 "register_operand" "=f")
13377         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13378         UNSPEC_TRUNC_NOOP))]
13379   "TARGET_USE_FANCY_MATH_387"
13380   "* return output_387_reg_move (insn, operands);"
13381   [(set_attr "type" "fmov")
13382    (set_attr "mode" "<MODE>")])
13383
13384 (define_insn "sqrtxf2"
13385   [(set (match_operand:XF 0 "register_operand" "=f")
13386         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13387   "TARGET_USE_FANCY_MATH_387"
13388   "fsqrt"
13389   [(set_attr "type" "fpspc")
13390    (set_attr "mode" "XF")
13391    (set_attr "athlon_decode" "direct")
13392    (set_attr "amdfam10_decode" "direct")])
13393
13394 (define_insn "sqrt_extend<mode>xf2_i387"
13395   [(set (match_operand:XF 0 "register_operand" "=f")
13396         (sqrt:XF
13397           (float_extend:XF
13398             (match_operand:MODEF 1 "register_operand" "0"))))]
13399   "TARGET_USE_FANCY_MATH_387"
13400   "fsqrt"
13401   [(set_attr "type" "fpspc")
13402    (set_attr "mode" "XF")
13403    (set_attr "athlon_decode" "direct")
13404    (set_attr "amdfam10_decode" "direct")])
13405
13406 (define_insn "*rsqrtsf2_sse"
13407   [(set (match_operand:SF 0 "register_operand" "=x")
13408         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13409                    UNSPEC_RSQRT))]
13410   "TARGET_SSE_MATH"
13411   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13412   [(set_attr "type" "sse")
13413    (set_attr "atom_sse_attr" "rcp")
13414    (set_attr "prefix" "maybe_vex")
13415    (set_attr "mode" "SF")])
13416
13417 (define_expand "rsqrtsf2"
13418   [(set (match_operand:SF 0 "register_operand" "")
13419         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13420                    UNSPEC_RSQRT))]
13421   "TARGET_SSE_MATH"
13422 {
13423   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13424   DONE;
13425 })
13426
13427 (define_insn "*sqrt<mode>2_sse"
13428   [(set (match_operand:MODEF 0 "register_operand" "=x")
13429         (sqrt:MODEF
13430           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13431   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13432   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13433   [(set_attr "type" "sse")
13434    (set_attr "atom_sse_attr" "sqrt")
13435    (set_attr "prefix" "maybe_vex")
13436    (set_attr "mode" "<MODE>")
13437    (set_attr "athlon_decode" "*")
13438    (set_attr "amdfam10_decode" "*")])
13439
13440 (define_expand "sqrt<mode>2"
13441   [(set (match_operand:MODEF 0 "register_operand" "")
13442         (sqrt:MODEF
13443           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13444   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13445    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13446 {
13447   if (<MODE>mode == SFmode
13448       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13449       && flag_finite_math_only && !flag_trapping_math
13450       && flag_unsafe_math_optimizations)
13451     {
13452       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13453       DONE;
13454     }
13455
13456   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13457     {
13458       rtx op0 = gen_reg_rtx (XFmode);
13459       rtx op1 = force_reg (<MODE>mode, operands[1]);
13460
13461       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13462       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13463       DONE;
13464    }
13465 })
13466
13467 (define_insn "fpremxf4_i387"
13468   [(set (match_operand:XF 0 "register_operand" "=f")
13469         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13470                     (match_operand:XF 3 "register_operand" "1")]
13471                    UNSPEC_FPREM_F))
13472    (set (match_operand:XF 1 "register_operand" "=u")
13473         (unspec:XF [(match_dup 2) (match_dup 3)]
13474                    UNSPEC_FPREM_U))
13475    (set (reg:CCFP FPSR_REG)
13476         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13477                      UNSPEC_C2_FLAG))]
13478   "TARGET_USE_FANCY_MATH_387"
13479   "fprem"
13480   [(set_attr "type" "fpspc")
13481    (set_attr "mode" "XF")])
13482
13483 (define_expand "fmodxf3"
13484   [(use (match_operand:XF 0 "register_operand" ""))
13485    (use (match_operand:XF 1 "general_operand" ""))
13486    (use (match_operand:XF 2 "general_operand" ""))]
13487   "TARGET_USE_FANCY_MATH_387"
13488 {
13489   rtx label = gen_label_rtx ();
13490
13491   rtx op1 = gen_reg_rtx (XFmode);
13492   rtx op2 = gen_reg_rtx (XFmode);
13493
13494   emit_move_insn (op2, operands[2]);
13495   emit_move_insn (op1, operands[1]);
13496
13497   emit_label (label);
13498   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13499   ix86_emit_fp_unordered_jump (label);
13500   LABEL_NUSES (label) = 1;
13501
13502   emit_move_insn (operands[0], op1);
13503   DONE;
13504 })
13505
13506 (define_expand "fmod<mode>3"
13507   [(use (match_operand:MODEF 0 "register_operand" ""))
13508    (use (match_operand:MODEF 1 "general_operand" ""))
13509    (use (match_operand:MODEF 2 "general_operand" ""))]
13510   "TARGET_USE_FANCY_MATH_387"
13511 {
13512   rtx label = gen_label_rtx ();
13513
13514   rtx op1 = gen_reg_rtx (XFmode);
13515   rtx op2 = gen_reg_rtx (XFmode);
13516
13517   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13518   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13519
13520   emit_label (label);
13521   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13522   ix86_emit_fp_unordered_jump (label);
13523   LABEL_NUSES (label) = 1;
13524
13525   /* Truncate the result properly for strict SSE math.  */
13526   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13527       && !TARGET_MIX_SSE_I387)
13528     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13529   else
13530     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13531
13532   DONE;
13533 })
13534
13535 (define_insn "fprem1xf4_i387"
13536   [(set (match_operand:XF 0 "register_operand" "=f")
13537         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13538                     (match_operand:XF 3 "register_operand" "1")]
13539                    UNSPEC_FPREM1_F))
13540    (set (match_operand:XF 1 "register_operand" "=u")
13541         (unspec:XF [(match_dup 2) (match_dup 3)]
13542                    UNSPEC_FPREM1_U))
13543    (set (reg:CCFP FPSR_REG)
13544         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13545                      UNSPEC_C2_FLAG))]
13546   "TARGET_USE_FANCY_MATH_387"
13547   "fprem1"
13548   [(set_attr "type" "fpspc")
13549    (set_attr "mode" "XF")])
13550
13551 (define_expand "remainderxf3"
13552   [(use (match_operand:XF 0 "register_operand" ""))
13553    (use (match_operand:XF 1 "general_operand" ""))
13554    (use (match_operand:XF 2 "general_operand" ""))]
13555   "TARGET_USE_FANCY_MATH_387"
13556 {
13557   rtx label = gen_label_rtx ();
13558
13559   rtx op1 = gen_reg_rtx (XFmode);
13560   rtx op2 = gen_reg_rtx (XFmode);
13561
13562   emit_move_insn (op2, operands[2]);
13563   emit_move_insn (op1, operands[1]);
13564
13565   emit_label (label);
13566   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13567   ix86_emit_fp_unordered_jump (label);
13568   LABEL_NUSES (label) = 1;
13569
13570   emit_move_insn (operands[0], op1);
13571   DONE;
13572 })
13573
13574 (define_expand "remainder<mode>3"
13575   [(use (match_operand:MODEF 0 "register_operand" ""))
13576    (use (match_operand:MODEF 1 "general_operand" ""))
13577    (use (match_operand:MODEF 2 "general_operand" ""))]
13578   "TARGET_USE_FANCY_MATH_387"
13579 {
13580   rtx label = gen_label_rtx ();
13581
13582   rtx op1 = gen_reg_rtx (XFmode);
13583   rtx op2 = gen_reg_rtx (XFmode);
13584
13585   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13586   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13587
13588   emit_label (label);
13589
13590   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13591   ix86_emit_fp_unordered_jump (label);
13592   LABEL_NUSES (label) = 1;
13593
13594   /* Truncate the result properly for strict SSE math.  */
13595   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13596       && !TARGET_MIX_SSE_I387)
13597     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13598   else
13599     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13600
13601   DONE;
13602 })
13603
13604 (define_insn "*sinxf2_i387"
13605   [(set (match_operand:XF 0 "register_operand" "=f")
13606         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13607   "TARGET_USE_FANCY_MATH_387
13608    && flag_unsafe_math_optimizations"
13609   "fsin"
13610   [(set_attr "type" "fpspc")
13611    (set_attr "mode" "XF")])
13612
13613 (define_insn "*sin_extend<mode>xf2_i387"
13614   [(set (match_operand:XF 0 "register_operand" "=f")
13615         (unspec:XF [(float_extend:XF
13616                       (match_operand:MODEF 1 "register_operand" "0"))]
13617                    UNSPEC_SIN))]
13618   "TARGET_USE_FANCY_MATH_387
13619    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13620        || TARGET_MIX_SSE_I387)
13621    && flag_unsafe_math_optimizations"
13622   "fsin"
13623   [(set_attr "type" "fpspc")
13624    (set_attr "mode" "XF")])
13625
13626 (define_insn "*cosxf2_i387"
13627   [(set (match_operand:XF 0 "register_operand" "=f")
13628         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13629   "TARGET_USE_FANCY_MATH_387
13630    && flag_unsafe_math_optimizations"
13631   "fcos"
13632   [(set_attr "type" "fpspc")
13633    (set_attr "mode" "XF")])
13634
13635 (define_insn "*cos_extend<mode>xf2_i387"
13636   [(set (match_operand:XF 0 "register_operand" "=f")
13637         (unspec:XF [(float_extend:XF
13638                       (match_operand:MODEF 1 "register_operand" "0"))]
13639                    UNSPEC_COS))]
13640   "TARGET_USE_FANCY_MATH_387
13641    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13642        || TARGET_MIX_SSE_I387)
13643    && flag_unsafe_math_optimizations"
13644   "fcos"
13645   [(set_attr "type" "fpspc")
13646    (set_attr "mode" "XF")])
13647
13648 ;; When sincos pattern is defined, sin and cos builtin functions will be
13649 ;; expanded to sincos pattern with one of its outputs left unused.
13650 ;; CSE pass will figure out if two sincos patterns can be combined,
13651 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13652 ;; depending on the unused output.
13653
13654 (define_insn "sincosxf3"
13655   [(set (match_operand:XF 0 "register_operand" "=f")
13656         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13657                    UNSPEC_SINCOS_COS))
13658    (set (match_operand:XF 1 "register_operand" "=u")
13659         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13660   "TARGET_USE_FANCY_MATH_387
13661    && flag_unsafe_math_optimizations"
13662   "fsincos"
13663   [(set_attr "type" "fpspc")
13664    (set_attr "mode" "XF")])
13665
13666 (define_split
13667   [(set (match_operand:XF 0 "register_operand" "")
13668         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13669                    UNSPEC_SINCOS_COS))
13670    (set (match_operand:XF 1 "register_operand" "")
13671         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13672   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13673    && !(reload_completed || reload_in_progress)"
13674   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13675   "")
13676
13677 (define_split
13678   [(set (match_operand:XF 0 "register_operand" "")
13679         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13680                    UNSPEC_SINCOS_COS))
13681    (set (match_operand:XF 1 "register_operand" "")
13682         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13683   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13684    && !(reload_completed || reload_in_progress)"
13685   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13686   "")
13687
13688 (define_insn "sincos_extend<mode>xf3_i387"
13689   [(set (match_operand:XF 0 "register_operand" "=f")
13690         (unspec:XF [(float_extend:XF
13691                       (match_operand:MODEF 2 "register_operand" "0"))]
13692                    UNSPEC_SINCOS_COS))
13693    (set (match_operand:XF 1 "register_operand" "=u")
13694         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13695   "TARGET_USE_FANCY_MATH_387
13696    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13697        || TARGET_MIX_SSE_I387)
13698    && flag_unsafe_math_optimizations"
13699   "fsincos"
13700   [(set_attr "type" "fpspc")
13701    (set_attr "mode" "XF")])
13702
13703 (define_split
13704   [(set (match_operand:XF 0 "register_operand" "")
13705         (unspec:XF [(float_extend:XF
13706                       (match_operand:MODEF 2 "register_operand" ""))]
13707                    UNSPEC_SINCOS_COS))
13708    (set (match_operand:XF 1 "register_operand" "")
13709         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13710   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13711    && !(reload_completed || reload_in_progress)"
13712   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13713   "")
13714
13715 (define_split
13716   [(set (match_operand:XF 0 "register_operand" "")
13717         (unspec:XF [(float_extend:XF
13718                       (match_operand:MODEF 2 "register_operand" ""))]
13719                    UNSPEC_SINCOS_COS))
13720    (set (match_operand:XF 1 "register_operand" "")
13721         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13722   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13723    && !(reload_completed || reload_in_progress)"
13724   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13725   "")
13726
13727 (define_expand "sincos<mode>3"
13728   [(use (match_operand:MODEF 0 "register_operand" ""))
13729    (use (match_operand:MODEF 1 "register_operand" ""))
13730    (use (match_operand:MODEF 2 "register_operand" ""))]
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 {
13736   rtx op0 = gen_reg_rtx (XFmode);
13737   rtx op1 = gen_reg_rtx (XFmode);
13738
13739   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13740   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13741   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13742   DONE;
13743 })
13744
13745 (define_insn "fptanxf4_i387"
13746   [(set (match_operand:XF 0 "register_operand" "=f")
13747         (match_operand:XF 3 "const_double_operand" "F"))
13748    (set (match_operand:XF 1 "register_operand" "=u")
13749         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13750                    UNSPEC_TAN))]
13751   "TARGET_USE_FANCY_MATH_387
13752    && flag_unsafe_math_optimizations
13753    && standard_80387_constant_p (operands[3]) == 2"
13754   "fptan"
13755   [(set_attr "type" "fpspc")
13756    (set_attr "mode" "XF")])
13757
13758 (define_insn "fptan_extend<mode>xf4_i387"
13759   [(set (match_operand:MODEF 0 "register_operand" "=f")
13760         (match_operand:MODEF 3 "const_double_operand" "F"))
13761    (set (match_operand:XF 1 "register_operand" "=u")
13762         (unspec:XF [(float_extend:XF
13763                       (match_operand:MODEF 2 "register_operand" "0"))]
13764                    UNSPEC_TAN))]
13765   "TARGET_USE_FANCY_MATH_387
13766    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13767        || TARGET_MIX_SSE_I387)
13768    && flag_unsafe_math_optimizations
13769    && standard_80387_constant_p (operands[3]) == 2"
13770   "fptan"
13771   [(set_attr "type" "fpspc")
13772    (set_attr "mode" "XF")])
13773
13774 (define_expand "tanxf2"
13775   [(use (match_operand:XF 0 "register_operand" ""))
13776    (use (match_operand:XF 1 "register_operand" ""))]
13777   "TARGET_USE_FANCY_MATH_387
13778    && flag_unsafe_math_optimizations"
13779 {
13780   rtx one = gen_reg_rtx (XFmode);
13781   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13782
13783   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13784   DONE;
13785 })
13786
13787 (define_expand "tan<mode>2"
13788   [(use (match_operand:MODEF 0 "register_operand" ""))
13789    (use (match_operand:MODEF 1 "register_operand" ""))]
13790   "TARGET_USE_FANCY_MATH_387
13791    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13792        || TARGET_MIX_SSE_I387)
13793    && flag_unsafe_math_optimizations"
13794 {
13795   rtx op0 = gen_reg_rtx (XFmode);
13796
13797   rtx one = gen_reg_rtx (<MODE>mode);
13798   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13799
13800   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13801                                              operands[1], op2));
13802   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13803   DONE;
13804 })
13805
13806 (define_insn "*fpatanxf3_i387"
13807   [(set (match_operand:XF 0 "register_operand" "=f")
13808         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13809                     (match_operand:XF 2 "register_operand" "u")]
13810                    UNSPEC_FPATAN))
13811    (clobber (match_scratch:XF 3 "=2"))]
13812   "TARGET_USE_FANCY_MATH_387
13813    && flag_unsafe_math_optimizations"
13814   "fpatan"
13815   [(set_attr "type" "fpspc")
13816    (set_attr "mode" "XF")])
13817
13818 (define_insn "fpatan_extend<mode>xf3_i387"
13819   [(set (match_operand:XF 0 "register_operand" "=f")
13820         (unspec:XF [(float_extend:XF
13821                       (match_operand:MODEF 1 "register_operand" "0"))
13822                     (float_extend:XF
13823                       (match_operand:MODEF 2 "register_operand" "u"))]
13824                    UNSPEC_FPATAN))
13825    (clobber (match_scratch:XF 3 "=2"))]
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   "fpatan"
13831   [(set_attr "type" "fpspc")
13832    (set_attr "mode" "XF")])
13833
13834 (define_expand "atan2xf3"
13835   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13836                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13837                                (match_operand:XF 1 "register_operand" "")]
13838                               UNSPEC_FPATAN))
13839               (clobber (match_scratch:XF 3 ""))])]
13840   "TARGET_USE_FANCY_MATH_387
13841    && flag_unsafe_math_optimizations"
13842   "")
13843
13844 (define_expand "atan2<mode>3"
13845   [(use (match_operand:MODEF 0 "register_operand" ""))
13846    (use (match_operand:MODEF 1 "register_operand" ""))
13847    (use (match_operand:MODEF 2 "register_operand" ""))]
13848   "TARGET_USE_FANCY_MATH_387
13849    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13850        || TARGET_MIX_SSE_I387)
13851    && flag_unsafe_math_optimizations"
13852 {
13853   rtx op0 = gen_reg_rtx (XFmode);
13854
13855   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13856   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13857   DONE;
13858 })
13859
13860 (define_expand "atanxf2"
13861   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13862                    (unspec:XF [(match_dup 2)
13863                                (match_operand:XF 1 "register_operand" "")]
13864                               UNSPEC_FPATAN))
13865               (clobber (match_scratch:XF 3 ""))])]
13866   "TARGET_USE_FANCY_MATH_387
13867    && flag_unsafe_math_optimizations"
13868 {
13869   operands[2] = gen_reg_rtx (XFmode);
13870   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13871 })
13872
13873 (define_expand "atan<mode>2"
13874   [(use (match_operand:MODEF 0 "register_operand" ""))
13875    (use (match_operand:MODEF 1 "register_operand" ""))]
13876   "TARGET_USE_FANCY_MATH_387
13877    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13878        || TARGET_MIX_SSE_I387)
13879    && flag_unsafe_math_optimizations"
13880 {
13881   rtx op0 = gen_reg_rtx (XFmode);
13882
13883   rtx op2 = gen_reg_rtx (<MODE>mode);
13884   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13885
13886   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13887   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13888   DONE;
13889 })
13890
13891 (define_expand "asinxf2"
13892   [(set (match_dup 2)
13893         (mult:XF (match_operand:XF 1 "register_operand" "")
13894                  (match_dup 1)))
13895    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13896    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13897    (parallel [(set (match_operand:XF 0 "register_operand" "")
13898                    (unspec:XF [(match_dup 5) (match_dup 1)]
13899                               UNSPEC_FPATAN))
13900               (clobber (match_scratch:XF 6 ""))])]
13901   "TARGET_USE_FANCY_MATH_387
13902    && flag_unsafe_math_optimizations"
13903 {
13904   int i;
13905
13906   if (optimize_insn_for_size_p ())
13907     FAIL;
13908
13909   for (i = 2; i < 6; i++)
13910     operands[i] = gen_reg_rtx (XFmode);
13911
13912   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13913 })
13914
13915 (define_expand "asin<mode>2"
13916   [(use (match_operand:MODEF 0 "register_operand" ""))
13917    (use (match_operand:MODEF 1 "general_operand" ""))]
13918  "TARGET_USE_FANCY_MATH_387
13919    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13920        || TARGET_MIX_SSE_I387)
13921    && flag_unsafe_math_optimizations"
13922 {
13923   rtx op0 = gen_reg_rtx (XFmode);
13924   rtx op1 = gen_reg_rtx (XFmode);
13925
13926   if (optimize_insn_for_size_p ())
13927     FAIL;
13928
13929   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13930   emit_insn (gen_asinxf2 (op0, op1));
13931   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13932   DONE;
13933 })
13934
13935 (define_expand "acosxf2"
13936   [(set (match_dup 2)
13937         (mult:XF (match_operand:XF 1 "register_operand" "")
13938                  (match_dup 1)))
13939    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13940    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13941    (parallel [(set (match_operand:XF 0 "register_operand" "")
13942                    (unspec:XF [(match_dup 1) (match_dup 5)]
13943                               UNSPEC_FPATAN))
13944               (clobber (match_scratch:XF 6 ""))])]
13945   "TARGET_USE_FANCY_MATH_387
13946    && flag_unsafe_math_optimizations"
13947 {
13948   int i;
13949
13950   if (optimize_insn_for_size_p ())
13951     FAIL;
13952
13953   for (i = 2; i < 6; i++)
13954     operands[i] = gen_reg_rtx (XFmode);
13955
13956   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13957 })
13958
13959 (define_expand "acos<mode>2"
13960   [(use (match_operand:MODEF 0 "register_operand" ""))
13961    (use (match_operand:MODEF 1 "general_operand" ""))]
13962  "TARGET_USE_FANCY_MATH_387
13963    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13964        || TARGET_MIX_SSE_I387)
13965    && flag_unsafe_math_optimizations"
13966 {
13967   rtx op0 = gen_reg_rtx (XFmode);
13968   rtx op1 = gen_reg_rtx (XFmode);
13969
13970   if (optimize_insn_for_size_p ())
13971     FAIL;
13972
13973   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13974   emit_insn (gen_acosxf2 (op0, op1));
13975   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13976   DONE;
13977 })
13978
13979 (define_insn "fyl2xxf3_i387"
13980   [(set (match_operand:XF 0 "register_operand" "=f")
13981         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13982                     (match_operand:XF 2 "register_operand" "u")]
13983                    UNSPEC_FYL2X))
13984    (clobber (match_scratch:XF 3 "=2"))]
13985   "TARGET_USE_FANCY_MATH_387
13986    && flag_unsafe_math_optimizations"
13987   "fyl2x"
13988   [(set_attr "type" "fpspc")
13989    (set_attr "mode" "XF")])
13990
13991 (define_insn "fyl2x_extend<mode>xf3_i387"
13992   [(set (match_operand:XF 0 "register_operand" "=f")
13993         (unspec:XF [(float_extend:XF
13994                       (match_operand:MODEF 1 "register_operand" "0"))
13995                     (match_operand:XF 2 "register_operand" "u")]
13996                    UNSPEC_FYL2X))
13997    (clobber (match_scratch:XF 3 "=2"))]
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   "fyl2x"
14003   [(set_attr "type" "fpspc")
14004    (set_attr "mode" "XF")])
14005
14006 (define_expand "logxf2"
14007   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14008                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14009                                (match_dup 2)] UNSPEC_FYL2X))
14010               (clobber (match_scratch:XF 3 ""))])]
14011   "TARGET_USE_FANCY_MATH_387
14012    && flag_unsafe_math_optimizations"
14013 {
14014   operands[2] = gen_reg_rtx (XFmode);
14015   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14016 })
14017
14018 (define_expand "log<mode>2"
14019   [(use (match_operand:MODEF 0 "register_operand" ""))
14020    (use (match_operand:MODEF 1 "register_operand" ""))]
14021   "TARGET_USE_FANCY_MATH_387
14022    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14023        || TARGET_MIX_SSE_I387)
14024    && flag_unsafe_math_optimizations"
14025 {
14026   rtx op0 = gen_reg_rtx (XFmode);
14027
14028   rtx op2 = gen_reg_rtx (XFmode);
14029   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14030
14031   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14032   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14033   DONE;
14034 })
14035
14036 (define_expand "log10xf2"
14037   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14038                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14039                                (match_dup 2)] UNSPEC_FYL2X))
14040               (clobber (match_scratch:XF 3 ""))])]
14041   "TARGET_USE_FANCY_MATH_387
14042    && flag_unsafe_math_optimizations"
14043 {
14044   operands[2] = gen_reg_rtx (XFmode);
14045   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14046 })
14047
14048 (define_expand "log10<mode>2"
14049   [(use (match_operand:MODEF 0 "register_operand" ""))
14050    (use (match_operand:MODEF 1 "register_operand" ""))]
14051   "TARGET_USE_FANCY_MATH_387
14052    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14053        || TARGET_MIX_SSE_I387)
14054    && flag_unsafe_math_optimizations"
14055 {
14056   rtx op0 = gen_reg_rtx (XFmode);
14057
14058   rtx op2 = gen_reg_rtx (XFmode);
14059   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14060
14061   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14062   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14063   DONE;
14064 })
14065
14066 (define_expand "log2xf2"
14067   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14068                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14069                                (match_dup 2)] UNSPEC_FYL2X))
14070               (clobber (match_scratch:XF 3 ""))])]
14071   "TARGET_USE_FANCY_MATH_387
14072    && flag_unsafe_math_optimizations"
14073 {
14074   operands[2] = gen_reg_rtx (XFmode);
14075   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14076 })
14077
14078 (define_expand "log2<mode>2"
14079   [(use (match_operand:MODEF 0 "register_operand" ""))
14080    (use (match_operand:MODEF 1 "register_operand" ""))]
14081   "TARGET_USE_FANCY_MATH_387
14082    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14083        || TARGET_MIX_SSE_I387)
14084    && flag_unsafe_math_optimizations"
14085 {
14086   rtx op0 = gen_reg_rtx (XFmode);
14087
14088   rtx op2 = gen_reg_rtx (XFmode);
14089   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14090
14091   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14092   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14093   DONE;
14094 })
14095
14096 (define_insn "fyl2xp1xf3_i387"
14097   [(set (match_operand:XF 0 "register_operand" "=f")
14098         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14099                     (match_operand:XF 2 "register_operand" "u")]
14100                    UNSPEC_FYL2XP1))
14101    (clobber (match_scratch:XF 3 "=2"))]
14102   "TARGET_USE_FANCY_MATH_387
14103    && flag_unsafe_math_optimizations"
14104   "fyl2xp1"
14105   [(set_attr "type" "fpspc")
14106    (set_attr "mode" "XF")])
14107
14108 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14109   [(set (match_operand:XF 0 "register_operand" "=f")
14110         (unspec:XF [(float_extend:XF
14111                       (match_operand:MODEF 1 "register_operand" "0"))
14112                     (match_operand:XF 2 "register_operand" "u")]
14113                    UNSPEC_FYL2XP1))
14114    (clobber (match_scratch:XF 3 "=2"))]
14115   "TARGET_USE_FANCY_MATH_387
14116    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14117        || TARGET_MIX_SSE_I387)
14118    && flag_unsafe_math_optimizations"
14119   "fyl2xp1"
14120   [(set_attr "type" "fpspc")
14121    (set_attr "mode" "XF")])
14122
14123 (define_expand "log1pxf2"
14124   [(use (match_operand:XF 0 "register_operand" ""))
14125    (use (match_operand:XF 1 "register_operand" ""))]
14126   "TARGET_USE_FANCY_MATH_387
14127    && flag_unsafe_math_optimizations"
14128 {
14129   if (optimize_insn_for_size_p ())
14130     FAIL;
14131
14132   ix86_emit_i387_log1p (operands[0], operands[1]);
14133   DONE;
14134 })
14135
14136 (define_expand "log1p<mode>2"
14137   [(use (match_operand:MODEF 0 "register_operand" ""))
14138    (use (match_operand:MODEF 1 "register_operand" ""))]
14139   "TARGET_USE_FANCY_MATH_387
14140    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14141        || TARGET_MIX_SSE_I387)
14142    && flag_unsafe_math_optimizations"
14143 {
14144   rtx op0;
14145
14146   if (optimize_insn_for_size_p ())
14147     FAIL;
14148
14149   op0 = gen_reg_rtx (XFmode);
14150
14151   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14152
14153   ix86_emit_i387_log1p (op0, operands[1]);
14154   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14155   DONE;
14156 })
14157
14158 (define_insn "fxtractxf3_i387"
14159   [(set (match_operand:XF 0 "register_operand" "=f")
14160         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14161                    UNSPEC_XTRACT_FRACT))
14162    (set (match_operand:XF 1 "register_operand" "=u")
14163         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14164   "TARGET_USE_FANCY_MATH_387
14165    && flag_unsafe_math_optimizations"
14166   "fxtract"
14167   [(set_attr "type" "fpspc")
14168    (set_attr "mode" "XF")])
14169
14170 (define_insn "fxtract_extend<mode>xf3_i387"
14171   [(set (match_operand:XF 0 "register_operand" "=f")
14172         (unspec:XF [(float_extend:XF
14173                       (match_operand:MODEF 2 "register_operand" "0"))]
14174                    UNSPEC_XTRACT_FRACT))
14175    (set (match_operand:XF 1 "register_operand" "=u")
14176         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14177   "TARGET_USE_FANCY_MATH_387
14178    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14179        || TARGET_MIX_SSE_I387)
14180    && flag_unsafe_math_optimizations"
14181   "fxtract"
14182   [(set_attr "type" "fpspc")
14183    (set_attr "mode" "XF")])
14184
14185 (define_expand "logbxf2"
14186   [(parallel [(set (match_dup 2)
14187                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14188                               UNSPEC_XTRACT_FRACT))
14189               (set (match_operand:XF 0 "register_operand" "")
14190                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14191   "TARGET_USE_FANCY_MATH_387
14192    && flag_unsafe_math_optimizations"
14193 {
14194   operands[2] = gen_reg_rtx (XFmode);
14195 })
14196
14197 (define_expand "logb<mode>2"
14198   [(use (match_operand:MODEF 0 "register_operand" ""))
14199    (use (match_operand:MODEF 1 "register_operand" ""))]
14200   "TARGET_USE_FANCY_MATH_387
14201    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14202        || TARGET_MIX_SSE_I387)
14203    && flag_unsafe_math_optimizations"
14204 {
14205   rtx op0 = gen_reg_rtx (XFmode);
14206   rtx op1 = gen_reg_rtx (XFmode);
14207
14208   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14209   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14210   DONE;
14211 })
14212
14213 (define_expand "ilogbxf2"
14214   [(use (match_operand:SI 0 "register_operand" ""))
14215    (use (match_operand:XF 1 "register_operand" ""))]
14216   "TARGET_USE_FANCY_MATH_387
14217    && flag_unsafe_math_optimizations"
14218 {
14219   rtx op0, op1;
14220
14221   if (optimize_insn_for_size_p ())
14222     FAIL;
14223
14224   op0 = gen_reg_rtx (XFmode);
14225   op1 = gen_reg_rtx (XFmode);
14226
14227   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14228   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14229   DONE;
14230 })
14231
14232 (define_expand "ilogb<mode>2"
14233   [(use (match_operand:SI 0 "register_operand" ""))
14234    (use (match_operand:MODEF 1 "register_operand" ""))]
14235   "TARGET_USE_FANCY_MATH_387
14236    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14237        || TARGET_MIX_SSE_I387)
14238    && flag_unsafe_math_optimizations"
14239 {
14240   rtx op0, op1;
14241
14242   if (optimize_insn_for_size_p ())
14243     FAIL;
14244
14245   op0 = gen_reg_rtx (XFmode);
14246   op1 = gen_reg_rtx (XFmode);
14247
14248   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14249   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14250   DONE;
14251 })
14252
14253 (define_insn "*f2xm1xf2_i387"
14254   [(set (match_operand:XF 0 "register_operand" "=f")
14255         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14256                    UNSPEC_F2XM1))]
14257   "TARGET_USE_FANCY_MATH_387
14258    && flag_unsafe_math_optimizations"
14259   "f2xm1"
14260   [(set_attr "type" "fpspc")
14261    (set_attr "mode" "XF")])
14262
14263 (define_insn "*fscalexf4_i387"
14264   [(set (match_operand:XF 0 "register_operand" "=f")
14265         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14266                     (match_operand:XF 3 "register_operand" "1")]
14267                    UNSPEC_FSCALE_FRACT))
14268    (set (match_operand:XF 1 "register_operand" "=u")
14269         (unspec:XF [(match_dup 2) (match_dup 3)]
14270                    UNSPEC_FSCALE_EXP))]
14271   "TARGET_USE_FANCY_MATH_387
14272    && flag_unsafe_math_optimizations"
14273   "fscale"
14274   [(set_attr "type" "fpspc")
14275    (set_attr "mode" "XF")])
14276
14277 (define_expand "expNcorexf3"
14278   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14279                                (match_operand:XF 2 "register_operand" "")))
14280    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14281    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14282    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14283    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14284    (parallel [(set (match_operand:XF 0 "register_operand" "")
14285                    (unspec:XF [(match_dup 8) (match_dup 4)]
14286                               UNSPEC_FSCALE_FRACT))
14287               (set (match_dup 9)
14288                    (unspec:XF [(match_dup 8) (match_dup 4)]
14289                               UNSPEC_FSCALE_EXP))])]
14290   "TARGET_USE_FANCY_MATH_387
14291    && flag_unsafe_math_optimizations"
14292 {
14293   int i;
14294
14295   if (optimize_insn_for_size_p ())
14296     FAIL;
14297
14298   for (i = 3; i < 10; i++)
14299     operands[i] = gen_reg_rtx (XFmode);
14300
14301   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14302 })
14303
14304 (define_expand "expxf2"
14305   [(use (match_operand:XF 0 "register_operand" ""))
14306    (use (match_operand:XF 1 "register_operand" ""))]
14307   "TARGET_USE_FANCY_MATH_387
14308    && flag_unsafe_math_optimizations"
14309 {
14310   rtx op2;
14311
14312   if (optimize_insn_for_size_p ())
14313     FAIL;
14314
14315   op2 = gen_reg_rtx (XFmode);
14316   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14317
14318   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14319   DONE;
14320 })
14321
14322 (define_expand "exp<mode>2"
14323   [(use (match_operand:MODEF 0 "register_operand" ""))
14324    (use (match_operand:MODEF 1 "general_operand" ""))]
14325  "TARGET_USE_FANCY_MATH_387
14326    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14327        || TARGET_MIX_SSE_I387)
14328    && flag_unsafe_math_optimizations"
14329 {
14330   rtx op0, op1;
14331
14332   if (optimize_insn_for_size_p ())
14333     FAIL;
14334
14335   op0 = gen_reg_rtx (XFmode);
14336   op1 = gen_reg_rtx (XFmode);
14337
14338   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14339   emit_insn (gen_expxf2 (op0, op1));
14340   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14341   DONE;
14342 })
14343
14344 (define_expand "exp10xf2"
14345   [(use (match_operand:XF 0 "register_operand" ""))
14346    (use (match_operand:XF 1 "register_operand" ""))]
14347   "TARGET_USE_FANCY_MATH_387
14348    && flag_unsafe_math_optimizations"
14349 {
14350   rtx op2;
14351
14352   if (optimize_insn_for_size_p ())
14353     FAIL;
14354
14355   op2 = gen_reg_rtx (XFmode);
14356   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14357
14358   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14359   DONE;
14360 })
14361
14362 (define_expand "exp10<mode>2"
14363   [(use (match_operand:MODEF 0 "register_operand" ""))
14364    (use (match_operand:MODEF 1 "general_operand" ""))]
14365  "TARGET_USE_FANCY_MATH_387
14366    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14367        || TARGET_MIX_SSE_I387)
14368    && flag_unsafe_math_optimizations"
14369 {
14370   rtx op0, op1;
14371
14372   if (optimize_insn_for_size_p ())
14373     FAIL;
14374
14375   op0 = gen_reg_rtx (XFmode);
14376   op1 = gen_reg_rtx (XFmode);
14377
14378   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14379   emit_insn (gen_exp10xf2 (op0, op1));
14380   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14381   DONE;
14382 })
14383
14384 (define_expand "exp2xf2"
14385   [(use (match_operand:XF 0 "register_operand" ""))
14386    (use (match_operand:XF 1 "register_operand" ""))]
14387   "TARGET_USE_FANCY_MATH_387
14388    && flag_unsafe_math_optimizations"
14389 {
14390   rtx op2;
14391
14392   if (optimize_insn_for_size_p ())
14393     FAIL;
14394
14395   op2 = gen_reg_rtx (XFmode);
14396   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14397
14398   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14399   DONE;
14400 })
14401
14402 (define_expand "exp2<mode>2"
14403   [(use (match_operand:MODEF 0 "register_operand" ""))
14404    (use (match_operand:MODEF 1 "general_operand" ""))]
14405  "TARGET_USE_FANCY_MATH_387
14406    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14407        || TARGET_MIX_SSE_I387)
14408    && flag_unsafe_math_optimizations"
14409 {
14410   rtx op0, op1;
14411
14412   if (optimize_insn_for_size_p ())
14413     FAIL;
14414
14415   op0 = gen_reg_rtx (XFmode);
14416   op1 = gen_reg_rtx (XFmode);
14417
14418   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14419   emit_insn (gen_exp2xf2 (op0, op1));
14420   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14421   DONE;
14422 })
14423
14424 (define_expand "expm1xf2"
14425   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14426                                (match_dup 2)))
14427    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14428    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14429    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14430    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14431    (parallel [(set (match_dup 7)
14432                    (unspec:XF [(match_dup 6) (match_dup 4)]
14433                               UNSPEC_FSCALE_FRACT))
14434               (set (match_dup 8)
14435                    (unspec:XF [(match_dup 6) (match_dup 4)]
14436                               UNSPEC_FSCALE_EXP))])
14437    (parallel [(set (match_dup 10)
14438                    (unspec:XF [(match_dup 9) (match_dup 8)]
14439                               UNSPEC_FSCALE_FRACT))
14440               (set (match_dup 11)
14441                    (unspec:XF [(match_dup 9) (match_dup 8)]
14442                               UNSPEC_FSCALE_EXP))])
14443    (set (match_dup 12) (minus:XF (match_dup 10)
14444                                  (float_extend:XF (match_dup 13))))
14445    (set (match_operand:XF 0 "register_operand" "")
14446         (plus:XF (match_dup 12) (match_dup 7)))]
14447   "TARGET_USE_FANCY_MATH_387
14448    && flag_unsafe_math_optimizations"
14449 {
14450   int i;
14451
14452   if (optimize_insn_for_size_p ())
14453     FAIL;
14454
14455   for (i = 2; i < 13; i++)
14456     operands[i] = gen_reg_rtx (XFmode);
14457
14458   operands[13]
14459     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14460
14461   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14462 })
14463
14464 (define_expand "expm1<mode>2"
14465   [(use (match_operand:MODEF 0 "register_operand" ""))
14466    (use (match_operand:MODEF 1 "general_operand" ""))]
14467  "TARGET_USE_FANCY_MATH_387
14468    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14469        || TARGET_MIX_SSE_I387)
14470    && flag_unsafe_math_optimizations"
14471 {
14472   rtx op0, op1;
14473
14474   if (optimize_insn_for_size_p ())
14475     FAIL;
14476
14477   op0 = gen_reg_rtx (XFmode);
14478   op1 = gen_reg_rtx (XFmode);
14479
14480   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14481   emit_insn (gen_expm1xf2 (op0, op1));
14482   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14483   DONE;
14484 })
14485
14486 (define_expand "ldexpxf3"
14487   [(set (match_dup 3)
14488         (float:XF (match_operand:SI 2 "register_operand" "")))
14489    (parallel [(set (match_operand:XF 0 " register_operand" "")
14490                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14491                                (match_dup 3)]
14492                               UNSPEC_FSCALE_FRACT))
14493               (set (match_dup 4)
14494                    (unspec:XF [(match_dup 1) (match_dup 3)]
14495                               UNSPEC_FSCALE_EXP))])]
14496   "TARGET_USE_FANCY_MATH_387
14497    && flag_unsafe_math_optimizations"
14498 {
14499   if (optimize_insn_for_size_p ())
14500     FAIL;
14501
14502   operands[3] = gen_reg_rtx (XFmode);
14503   operands[4] = gen_reg_rtx (XFmode);
14504 })
14505
14506 (define_expand "ldexp<mode>3"
14507   [(use (match_operand:MODEF 0 "register_operand" ""))
14508    (use (match_operand:MODEF 1 "general_operand" ""))
14509    (use (match_operand:SI 2 "register_operand" ""))]
14510  "TARGET_USE_FANCY_MATH_387
14511    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14512        || TARGET_MIX_SSE_I387)
14513    && flag_unsafe_math_optimizations"
14514 {
14515   rtx op0, op1;
14516
14517   if (optimize_insn_for_size_p ())
14518     FAIL;
14519
14520   op0 = gen_reg_rtx (XFmode);
14521   op1 = gen_reg_rtx (XFmode);
14522
14523   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14524   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14525   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14526   DONE;
14527 })
14528
14529 (define_expand "scalbxf3"
14530   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14531                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14532                                (match_operand:XF 2 "register_operand" "")]
14533                               UNSPEC_FSCALE_FRACT))
14534               (set (match_dup 3)
14535                    (unspec:XF [(match_dup 1) (match_dup 2)]
14536                               UNSPEC_FSCALE_EXP))])]
14537   "TARGET_USE_FANCY_MATH_387
14538    && flag_unsafe_math_optimizations"
14539 {
14540   if (optimize_insn_for_size_p ())
14541     FAIL;
14542
14543   operands[3] = gen_reg_rtx (XFmode);
14544 })
14545
14546 (define_expand "scalb<mode>3"
14547   [(use (match_operand:MODEF 0 "register_operand" ""))
14548    (use (match_operand:MODEF 1 "general_operand" ""))
14549    (use (match_operand:MODEF 2 "general_operand" ""))]
14550  "TARGET_USE_FANCY_MATH_387
14551    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14552        || TARGET_MIX_SSE_I387)
14553    && flag_unsafe_math_optimizations"
14554 {
14555   rtx op0, op1, op2;
14556
14557   if (optimize_insn_for_size_p ())
14558     FAIL;
14559
14560   op0 = gen_reg_rtx (XFmode);
14561   op1 = gen_reg_rtx (XFmode);
14562   op2 = gen_reg_rtx (XFmode);
14563
14564   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14565   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14566   emit_insn (gen_scalbxf3 (op0, op1, op2));
14567   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14568   DONE;
14569 })
14570
14571 (define_expand "significandxf2"
14572   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14573                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14574                               UNSPEC_XTRACT_FRACT))
14575               (set (match_dup 2)
14576                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14577   "TARGET_USE_FANCY_MATH_387
14578    && flag_unsafe_math_optimizations"
14579 {
14580   operands[2] = gen_reg_rtx (XFmode);
14581 })
14582
14583 (define_expand "significand<mode>2"
14584   [(use (match_operand:MODEF 0 "register_operand" ""))
14585    (use (match_operand:MODEF 1 "register_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 = gen_reg_rtx (XFmode);
14592   rtx op1 = gen_reg_rtx (XFmode);
14593
14594   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14595   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14596   DONE;
14597 })
14598 \f
14599
14600 (define_insn "sse4_1_round<mode>2"
14601   [(set (match_operand:MODEF 0 "register_operand" "=x")
14602         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14603                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14604                       UNSPEC_ROUND))]
14605   "TARGET_ROUND"
14606   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14607   [(set_attr "type" "ssecvt")
14608    (set_attr "prefix_extra" "1")
14609    (set_attr "prefix" "maybe_vex")
14610    (set_attr "mode" "<MODE>")])
14611
14612 (define_insn "rintxf2"
14613   [(set (match_operand:XF 0 "register_operand" "=f")
14614         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14615                    UNSPEC_FRNDINT))]
14616   "TARGET_USE_FANCY_MATH_387
14617    && flag_unsafe_math_optimizations"
14618   "frndint"
14619   [(set_attr "type" "fpspc")
14620    (set_attr "mode" "XF")])
14621
14622 (define_expand "rint<mode>2"
14623   [(use (match_operand:MODEF 0 "register_operand" ""))
14624    (use (match_operand:MODEF 1 "register_operand" ""))]
14625   "(TARGET_USE_FANCY_MATH_387
14626     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14627         || TARGET_MIX_SSE_I387)
14628     && flag_unsafe_math_optimizations)
14629    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14630        && !flag_trapping_math)"
14631 {
14632   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14633       && !flag_trapping_math)
14634     {
14635       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14636         FAIL;
14637       if (TARGET_ROUND)
14638         emit_insn (gen_sse4_1_round<mode>2
14639                    (operands[0], operands[1], GEN_INT (0x04)));
14640       else
14641         ix86_expand_rint (operand0, operand1);
14642     }
14643   else
14644     {
14645       rtx op0 = gen_reg_rtx (XFmode);
14646       rtx op1 = gen_reg_rtx (XFmode);
14647
14648       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14649       emit_insn (gen_rintxf2 (op0, op1));
14650
14651       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14652     }
14653   DONE;
14654 })
14655
14656 (define_expand "round<mode>2"
14657   [(match_operand:MODEF 0 "register_operand" "")
14658    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14659   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14660    && !flag_trapping_math && !flag_rounding_math"
14661 {
14662   if (optimize_insn_for_size_p ())
14663     FAIL;
14664   if (TARGET_64BIT || (<MODE>mode != DFmode))
14665     ix86_expand_round (operand0, operand1);
14666   else
14667     ix86_expand_rounddf_32 (operand0, operand1);
14668   DONE;
14669 })
14670
14671 (define_insn_and_split "*fistdi2_1"
14672   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14673         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14674                    UNSPEC_FIST))]
14675   "TARGET_USE_FANCY_MATH_387
14676    && can_create_pseudo_p ()"
14677   "#"
14678   "&& 1"
14679   [(const_int 0)]
14680 {
14681   if (memory_operand (operands[0], VOIDmode))
14682     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14683   else
14684     {
14685       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14686       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14687                                          operands[2]));
14688     }
14689   DONE;
14690 }
14691   [(set_attr "type" "fpspc")
14692    (set_attr "mode" "DI")])
14693
14694 (define_insn "fistdi2"
14695   [(set (match_operand:DI 0 "memory_operand" "=m")
14696         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14697                    UNSPEC_FIST))
14698    (clobber (match_scratch:XF 2 "=&1f"))]
14699   "TARGET_USE_FANCY_MATH_387"
14700   "* return output_fix_trunc (insn, operands, 0);"
14701   [(set_attr "type" "fpspc")
14702    (set_attr "mode" "DI")])
14703
14704 (define_insn "fistdi2_with_temp"
14705   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14706         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14707                    UNSPEC_FIST))
14708    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14709    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14710   "TARGET_USE_FANCY_MATH_387"
14711   "#"
14712   [(set_attr "type" "fpspc")
14713    (set_attr "mode" "DI")])
14714
14715 (define_split
14716   [(set (match_operand:DI 0 "register_operand" "")
14717         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14718                    UNSPEC_FIST))
14719    (clobber (match_operand:DI 2 "memory_operand" ""))
14720    (clobber (match_scratch 3 ""))]
14721   "reload_completed"
14722   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14723               (clobber (match_dup 3))])
14724    (set (match_dup 0) (match_dup 2))]
14725   "")
14726
14727 (define_split
14728   [(set (match_operand:DI 0 "memory_operand" "")
14729         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14730                    UNSPEC_FIST))
14731    (clobber (match_operand:DI 2 "memory_operand" ""))
14732    (clobber (match_scratch 3 ""))]
14733   "reload_completed"
14734   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14735               (clobber (match_dup 3))])]
14736   "")
14737
14738 (define_insn_and_split "*fist<mode>2_1"
14739   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14740         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14741                            UNSPEC_FIST))]
14742   "TARGET_USE_FANCY_MATH_387
14743    && can_create_pseudo_p ()"
14744   "#"
14745   "&& 1"
14746   [(const_int 0)]
14747 {
14748   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14749   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14750                                         operands[2]));
14751   DONE;
14752 }
14753   [(set_attr "type" "fpspc")
14754    (set_attr "mode" "<MODE>")])
14755
14756 (define_insn "fist<mode>2"
14757   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14758         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14759                            UNSPEC_FIST))]
14760   "TARGET_USE_FANCY_MATH_387"
14761   "* return output_fix_trunc (insn, operands, 0);"
14762   [(set_attr "type" "fpspc")
14763    (set_attr "mode" "<MODE>")])
14764
14765 (define_insn "fist<mode>2_with_temp"
14766   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14767         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14768                            UNSPEC_FIST))
14769    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14770   "TARGET_USE_FANCY_MATH_387"
14771   "#"
14772   [(set_attr "type" "fpspc")
14773    (set_attr "mode" "<MODE>")])
14774
14775 (define_split
14776   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14777         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14778                            UNSPEC_FIST))
14779    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14780   "reload_completed"
14781   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14782    (set (match_dup 0) (match_dup 2))]
14783   "")
14784
14785 (define_split
14786   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14787         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14788                            UNSPEC_FIST))
14789    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14790   "reload_completed"
14791   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14792   "")
14793
14794 (define_expand "lrintxf<mode>2"
14795   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14796      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14797                       UNSPEC_FIST))]
14798   "TARGET_USE_FANCY_MATH_387"
14799   "")
14800
14801 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14802   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14803      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14804                         UNSPEC_FIX_NOTRUNC))]
14805   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14806    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14807   "")
14808
14809 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14810   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14811    (match_operand:MODEF 1 "register_operand" "")]
14812   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14813    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14814    && !flag_trapping_math && !flag_rounding_math"
14815 {
14816   if (optimize_insn_for_size_p ())
14817     FAIL;
14818   ix86_expand_lround (operand0, operand1);
14819   DONE;
14820 })
14821
14822 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14823 (define_insn_and_split "frndintxf2_floor"
14824   [(set (match_operand:XF 0 "register_operand" "")
14825         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14826          UNSPEC_FRNDINT_FLOOR))
14827    (clobber (reg:CC FLAGS_REG))]
14828   "TARGET_USE_FANCY_MATH_387
14829    && flag_unsafe_math_optimizations
14830    && can_create_pseudo_p ()"
14831   "#"
14832   "&& 1"
14833   [(const_int 0)]
14834 {
14835   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14836
14837   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14838   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14839
14840   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14841                                         operands[2], operands[3]));
14842   DONE;
14843 }
14844   [(set_attr "type" "frndint")
14845    (set_attr "i387_cw" "floor")
14846    (set_attr "mode" "XF")])
14847
14848 (define_insn "frndintxf2_floor_i387"
14849   [(set (match_operand:XF 0 "register_operand" "=f")
14850         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14851          UNSPEC_FRNDINT_FLOOR))
14852    (use (match_operand:HI 2 "memory_operand" "m"))
14853    (use (match_operand:HI 3 "memory_operand" "m"))]
14854   "TARGET_USE_FANCY_MATH_387
14855    && flag_unsafe_math_optimizations"
14856   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14857   [(set_attr "type" "frndint")
14858    (set_attr "i387_cw" "floor")
14859    (set_attr "mode" "XF")])
14860
14861 (define_expand "floorxf2"
14862   [(use (match_operand:XF 0 "register_operand" ""))
14863    (use (match_operand:XF 1 "register_operand" ""))]
14864   "TARGET_USE_FANCY_MATH_387
14865    && flag_unsafe_math_optimizations"
14866 {
14867   if (optimize_insn_for_size_p ())
14868     FAIL;
14869   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14870   DONE;
14871 })
14872
14873 (define_expand "floor<mode>2"
14874   [(use (match_operand:MODEF 0 "register_operand" ""))
14875    (use (match_operand:MODEF 1 "register_operand" ""))]
14876   "(TARGET_USE_FANCY_MATH_387
14877     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14878         || TARGET_MIX_SSE_I387)
14879     && flag_unsafe_math_optimizations)
14880    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14881        && !flag_trapping_math)"
14882 {
14883   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14884       && !flag_trapping_math
14885       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14886     {
14887       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14888         FAIL;
14889       if (TARGET_ROUND)
14890         emit_insn (gen_sse4_1_round<mode>2
14891                    (operands[0], operands[1], GEN_INT (0x01)));
14892       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14893         ix86_expand_floorceil (operand0, operand1, true);
14894       else
14895         ix86_expand_floorceildf_32 (operand0, operand1, true);
14896     }
14897   else
14898     {
14899       rtx op0, op1;
14900
14901       if (optimize_insn_for_size_p ())
14902         FAIL;
14903
14904       op0 = gen_reg_rtx (XFmode);
14905       op1 = gen_reg_rtx (XFmode);
14906       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14907       emit_insn (gen_frndintxf2_floor (op0, op1));
14908
14909       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14910     }
14911   DONE;
14912 })
14913
14914 (define_insn_and_split "*fist<mode>2_floor_1"
14915   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14916         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14917          UNSPEC_FIST_FLOOR))
14918    (clobber (reg:CC FLAGS_REG))]
14919   "TARGET_USE_FANCY_MATH_387
14920    && flag_unsafe_math_optimizations
14921    && can_create_pseudo_p ()"
14922   "#"
14923   "&& 1"
14924   [(const_int 0)]
14925 {
14926   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14927
14928   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14929   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14930   if (memory_operand (operands[0], VOIDmode))
14931     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14932                                       operands[2], operands[3]));
14933   else
14934     {
14935       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14936       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14937                                                   operands[2], operands[3],
14938                                                   operands[4]));
14939     }
14940   DONE;
14941 }
14942   [(set_attr "type" "fistp")
14943    (set_attr "i387_cw" "floor")
14944    (set_attr "mode" "<MODE>")])
14945
14946 (define_insn "fistdi2_floor"
14947   [(set (match_operand:DI 0 "memory_operand" "=m")
14948         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14949          UNSPEC_FIST_FLOOR))
14950    (use (match_operand:HI 2 "memory_operand" "m"))
14951    (use (match_operand:HI 3 "memory_operand" "m"))
14952    (clobber (match_scratch:XF 4 "=&1f"))]
14953   "TARGET_USE_FANCY_MATH_387
14954    && flag_unsafe_math_optimizations"
14955   "* return output_fix_trunc (insn, operands, 0);"
14956   [(set_attr "type" "fistp")
14957    (set_attr "i387_cw" "floor")
14958    (set_attr "mode" "DI")])
14959
14960 (define_insn "fistdi2_floor_with_temp"
14961   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14962         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14963          UNSPEC_FIST_FLOOR))
14964    (use (match_operand:HI 2 "memory_operand" "m,m"))
14965    (use (match_operand:HI 3 "memory_operand" "m,m"))
14966    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14967    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14968   "TARGET_USE_FANCY_MATH_387
14969    && flag_unsafe_math_optimizations"
14970   "#"
14971   [(set_attr "type" "fistp")
14972    (set_attr "i387_cw" "floor")
14973    (set_attr "mode" "DI")])
14974
14975 (define_split
14976   [(set (match_operand:DI 0 "register_operand" "")
14977         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14978          UNSPEC_FIST_FLOOR))
14979    (use (match_operand:HI 2 "memory_operand" ""))
14980    (use (match_operand:HI 3 "memory_operand" ""))
14981    (clobber (match_operand:DI 4 "memory_operand" ""))
14982    (clobber (match_scratch 5 ""))]
14983   "reload_completed"
14984   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14985               (use (match_dup 2))
14986               (use (match_dup 3))
14987               (clobber (match_dup 5))])
14988    (set (match_dup 0) (match_dup 4))]
14989   "")
14990
14991 (define_split
14992   [(set (match_operand:DI 0 "memory_operand" "")
14993         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14994          UNSPEC_FIST_FLOOR))
14995    (use (match_operand:HI 2 "memory_operand" ""))
14996    (use (match_operand:HI 3 "memory_operand" ""))
14997    (clobber (match_operand:DI 4 "memory_operand" ""))
14998    (clobber (match_scratch 5 ""))]
14999   "reload_completed"
15000   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15001               (use (match_dup 2))
15002               (use (match_dup 3))
15003               (clobber (match_dup 5))])]
15004   "")
15005
15006 (define_insn "fist<mode>2_floor"
15007   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15008         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15009          UNSPEC_FIST_FLOOR))
15010    (use (match_operand:HI 2 "memory_operand" "m"))
15011    (use (match_operand:HI 3 "memory_operand" "m"))]
15012   "TARGET_USE_FANCY_MATH_387
15013    && flag_unsafe_math_optimizations"
15014   "* return output_fix_trunc (insn, operands, 0);"
15015   [(set_attr "type" "fistp")
15016    (set_attr "i387_cw" "floor")
15017    (set_attr "mode" "<MODE>")])
15018
15019 (define_insn "fist<mode>2_floor_with_temp"
15020   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15021         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15022          UNSPEC_FIST_FLOOR))
15023    (use (match_operand:HI 2 "memory_operand" "m,m"))
15024    (use (match_operand:HI 3 "memory_operand" "m,m"))
15025    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15026   "TARGET_USE_FANCY_MATH_387
15027    && flag_unsafe_math_optimizations"
15028   "#"
15029   [(set_attr "type" "fistp")
15030    (set_attr "i387_cw" "floor")
15031    (set_attr "mode" "<MODE>")])
15032
15033 (define_split
15034   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15035         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15036          UNSPEC_FIST_FLOOR))
15037    (use (match_operand:HI 2 "memory_operand" ""))
15038    (use (match_operand:HI 3 "memory_operand" ""))
15039    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15040   "reload_completed"
15041   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15042                                   UNSPEC_FIST_FLOOR))
15043               (use (match_dup 2))
15044               (use (match_dup 3))])
15045    (set (match_dup 0) (match_dup 4))]
15046   "")
15047
15048 (define_split
15049   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15050         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15051          UNSPEC_FIST_FLOOR))
15052    (use (match_operand:HI 2 "memory_operand" ""))
15053    (use (match_operand:HI 3 "memory_operand" ""))
15054    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15055   "reload_completed"
15056   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15057                                   UNSPEC_FIST_FLOOR))
15058               (use (match_dup 2))
15059               (use (match_dup 3))])]
15060   "")
15061
15062 (define_expand "lfloorxf<mode>2"
15063   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15064                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15065                     UNSPEC_FIST_FLOOR))
15066               (clobber (reg:CC FLAGS_REG))])]
15067   "TARGET_USE_FANCY_MATH_387
15068    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15069    && flag_unsafe_math_optimizations"
15070   "")
15071
15072 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15073   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15074    (match_operand:MODEF 1 "register_operand" "")]
15075   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15076    && !flag_trapping_math"
15077 {
15078   if (TARGET_64BIT && optimize_insn_for_size_p ())
15079     FAIL;
15080   ix86_expand_lfloorceil (operand0, operand1, true);
15081   DONE;
15082 })
15083
15084 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15085 (define_insn_and_split "frndintxf2_ceil"
15086   [(set (match_operand:XF 0 "register_operand" "")
15087         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15088          UNSPEC_FRNDINT_CEIL))
15089    (clobber (reg:CC FLAGS_REG))]
15090   "TARGET_USE_FANCY_MATH_387
15091    && flag_unsafe_math_optimizations
15092    && can_create_pseudo_p ()"
15093   "#"
15094   "&& 1"
15095   [(const_int 0)]
15096 {
15097   ix86_optimize_mode_switching[I387_CEIL] = 1;
15098
15099   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15100   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15101
15102   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15103                                        operands[2], operands[3]));
15104   DONE;
15105 }
15106   [(set_attr "type" "frndint")
15107    (set_attr "i387_cw" "ceil")
15108    (set_attr "mode" "XF")])
15109
15110 (define_insn "frndintxf2_ceil_i387"
15111   [(set (match_operand:XF 0 "register_operand" "=f")
15112         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15113          UNSPEC_FRNDINT_CEIL))
15114    (use (match_operand:HI 2 "memory_operand" "m"))
15115    (use (match_operand:HI 3 "memory_operand" "m"))]
15116   "TARGET_USE_FANCY_MATH_387
15117    && flag_unsafe_math_optimizations"
15118   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15119   [(set_attr "type" "frndint")
15120    (set_attr "i387_cw" "ceil")
15121    (set_attr "mode" "XF")])
15122
15123 (define_expand "ceilxf2"
15124   [(use (match_operand:XF 0 "register_operand" ""))
15125    (use (match_operand:XF 1 "register_operand" ""))]
15126   "TARGET_USE_FANCY_MATH_387
15127    && flag_unsafe_math_optimizations"
15128 {
15129   if (optimize_insn_for_size_p ())
15130     FAIL;
15131   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15132   DONE;
15133 })
15134
15135 (define_expand "ceil<mode>2"
15136   [(use (match_operand:MODEF 0 "register_operand" ""))
15137    (use (match_operand:MODEF 1 "register_operand" ""))]
15138   "(TARGET_USE_FANCY_MATH_387
15139     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15140         || TARGET_MIX_SSE_I387)
15141     && flag_unsafe_math_optimizations)
15142    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15143        && !flag_trapping_math)"
15144 {
15145   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15146       && !flag_trapping_math
15147       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15148     {
15149       if (TARGET_ROUND)
15150         emit_insn (gen_sse4_1_round<mode>2
15151                    (operands[0], operands[1], GEN_INT (0x02)));
15152       else if (optimize_insn_for_size_p ())
15153         FAIL;
15154       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15155         ix86_expand_floorceil (operand0, operand1, false);
15156       else
15157         ix86_expand_floorceildf_32 (operand0, operand1, false);
15158     }
15159   else
15160     {
15161       rtx op0, op1;
15162
15163       if (optimize_insn_for_size_p ())
15164         FAIL;
15165
15166       op0 = gen_reg_rtx (XFmode);
15167       op1 = gen_reg_rtx (XFmode);
15168       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15169       emit_insn (gen_frndintxf2_ceil (op0, op1));
15170
15171       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15172     }
15173   DONE;
15174 })
15175
15176 (define_insn_and_split "*fist<mode>2_ceil_1"
15177   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15178         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15179          UNSPEC_FIST_CEIL))
15180    (clobber (reg:CC FLAGS_REG))]
15181   "TARGET_USE_FANCY_MATH_387
15182    && flag_unsafe_math_optimizations
15183    && can_create_pseudo_p ()"
15184   "#"
15185   "&& 1"
15186   [(const_int 0)]
15187 {
15188   ix86_optimize_mode_switching[I387_CEIL] = 1;
15189
15190   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15191   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15192   if (memory_operand (operands[0], VOIDmode))
15193     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15194                                      operands[2], operands[3]));
15195   else
15196     {
15197       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15198       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15199                                                  operands[2], operands[3],
15200                                                  operands[4]));
15201     }
15202   DONE;
15203 }
15204   [(set_attr "type" "fistp")
15205    (set_attr "i387_cw" "ceil")
15206    (set_attr "mode" "<MODE>")])
15207
15208 (define_insn "fistdi2_ceil"
15209   [(set (match_operand:DI 0 "memory_operand" "=m")
15210         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15211          UNSPEC_FIST_CEIL))
15212    (use (match_operand:HI 2 "memory_operand" "m"))
15213    (use (match_operand:HI 3 "memory_operand" "m"))
15214    (clobber (match_scratch:XF 4 "=&1f"))]
15215   "TARGET_USE_FANCY_MATH_387
15216    && flag_unsafe_math_optimizations"
15217   "* return output_fix_trunc (insn, operands, 0);"
15218   [(set_attr "type" "fistp")
15219    (set_attr "i387_cw" "ceil")
15220    (set_attr "mode" "DI")])
15221
15222 (define_insn "fistdi2_ceil_with_temp"
15223   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15224         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15225          UNSPEC_FIST_CEIL))
15226    (use (match_operand:HI 2 "memory_operand" "m,m"))
15227    (use (match_operand:HI 3 "memory_operand" "m,m"))
15228    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15229    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15230   "TARGET_USE_FANCY_MATH_387
15231    && flag_unsafe_math_optimizations"
15232   "#"
15233   [(set_attr "type" "fistp")
15234    (set_attr "i387_cw" "ceil")
15235    (set_attr "mode" "DI")])
15236
15237 (define_split
15238   [(set (match_operand:DI 0 "register_operand" "")
15239         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15240          UNSPEC_FIST_CEIL))
15241    (use (match_operand:HI 2 "memory_operand" ""))
15242    (use (match_operand:HI 3 "memory_operand" ""))
15243    (clobber (match_operand:DI 4 "memory_operand" ""))
15244    (clobber (match_scratch 5 ""))]
15245   "reload_completed"
15246   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15247               (use (match_dup 2))
15248               (use (match_dup 3))
15249               (clobber (match_dup 5))])
15250    (set (match_dup 0) (match_dup 4))]
15251   "")
15252
15253 (define_split
15254   [(set (match_operand:DI 0 "memory_operand" "")
15255         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15256          UNSPEC_FIST_CEIL))
15257    (use (match_operand:HI 2 "memory_operand" ""))
15258    (use (match_operand:HI 3 "memory_operand" ""))
15259    (clobber (match_operand:DI 4 "memory_operand" ""))
15260    (clobber (match_scratch 5 ""))]
15261   "reload_completed"
15262   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15263               (use (match_dup 2))
15264               (use (match_dup 3))
15265               (clobber (match_dup 5))])]
15266   "")
15267
15268 (define_insn "fist<mode>2_ceil"
15269   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15270         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15271          UNSPEC_FIST_CEIL))
15272    (use (match_operand:HI 2 "memory_operand" "m"))
15273    (use (match_operand:HI 3 "memory_operand" "m"))]
15274   "TARGET_USE_FANCY_MATH_387
15275    && flag_unsafe_math_optimizations"
15276   "* return output_fix_trunc (insn, operands, 0);"
15277   [(set_attr "type" "fistp")
15278    (set_attr "i387_cw" "ceil")
15279    (set_attr "mode" "<MODE>")])
15280
15281 (define_insn "fist<mode>2_ceil_with_temp"
15282   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15283         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15284          UNSPEC_FIST_CEIL))
15285    (use (match_operand:HI 2 "memory_operand" "m,m"))
15286    (use (match_operand:HI 3 "memory_operand" "m,m"))
15287    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15288   "TARGET_USE_FANCY_MATH_387
15289    && flag_unsafe_math_optimizations"
15290   "#"
15291   [(set_attr "type" "fistp")
15292    (set_attr "i387_cw" "ceil")
15293    (set_attr "mode" "<MODE>")])
15294
15295 (define_split
15296   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15297         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15298          UNSPEC_FIST_CEIL))
15299    (use (match_operand:HI 2 "memory_operand" ""))
15300    (use (match_operand:HI 3 "memory_operand" ""))
15301    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15302   "reload_completed"
15303   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15304                                   UNSPEC_FIST_CEIL))
15305               (use (match_dup 2))
15306               (use (match_dup 3))])
15307    (set (match_dup 0) (match_dup 4))]
15308   "")
15309
15310 (define_split
15311   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15312         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15313          UNSPEC_FIST_CEIL))
15314    (use (match_operand:HI 2 "memory_operand" ""))
15315    (use (match_operand:HI 3 "memory_operand" ""))
15316    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15317   "reload_completed"
15318   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15319                                   UNSPEC_FIST_CEIL))
15320               (use (match_dup 2))
15321               (use (match_dup 3))])]
15322   "")
15323
15324 (define_expand "lceilxf<mode>2"
15325   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15326                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15327                     UNSPEC_FIST_CEIL))
15328               (clobber (reg:CC FLAGS_REG))])]
15329   "TARGET_USE_FANCY_MATH_387
15330    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15331    && flag_unsafe_math_optimizations"
15332   "")
15333
15334 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15335   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15336    (match_operand:MODEF 1 "register_operand" "")]
15337   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15338    && !flag_trapping_math"
15339 {
15340   ix86_expand_lfloorceil (operand0, operand1, false);
15341   DONE;
15342 })
15343
15344 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15345 (define_insn_and_split "frndintxf2_trunc"
15346   [(set (match_operand:XF 0 "register_operand" "")
15347         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15348          UNSPEC_FRNDINT_TRUNC))
15349    (clobber (reg:CC FLAGS_REG))]
15350   "TARGET_USE_FANCY_MATH_387
15351    && flag_unsafe_math_optimizations
15352    && can_create_pseudo_p ()"
15353   "#"
15354   "&& 1"
15355   [(const_int 0)]
15356 {
15357   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15358
15359   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15360   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15361
15362   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15363                                         operands[2], operands[3]));
15364   DONE;
15365 }
15366   [(set_attr "type" "frndint")
15367    (set_attr "i387_cw" "trunc")
15368    (set_attr "mode" "XF")])
15369
15370 (define_insn "frndintxf2_trunc_i387"
15371   [(set (match_operand:XF 0 "register_operand" "=f")
15372         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15373          UNSPEC_FRNDINT_TRUNC))
15374    (use (match_operand:HI 2 "memory_operand" "m"))
15375    (use (match_operand:HI 3 "memory_operand" "m"))]
15376   "TARGET_USE_FANCY_MATH_387
15377    && flag_unsafe_math_optimizations"
15378   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15379   [(set_attr "type" "frndint")
15380    (set_attr "i387_cw" "trunc")
15381    (set_attr "mode" "XF")])
15382
15383 (define_expand "btruncxf2"
15384   [(use (match_operand:XF 0 "register_operand" ""))
15385    (use (match_operand:XF 1 "register_operand" ""))]
15386   "TARGET_USE_FANCY_MATH_387
15387    && flag_unsafe_math_optimizations"
15388 {
15389   if (optimize_insn_for_size_p ())
15390     FAIL;
15391   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15392   DONE;
15393 })
15394
15395 (define_expand "btrunc<mode>2"
15396   [(use (match_operand:MODEF 0 "register_operand" ""))
15397    (use (match_operand:MODEF 1 "register_operand" ""))]
15398   "(TARGET_USE_FANCY_MATH_387
15399     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15400         || TARGET_MIX_SSE_I387)
15401     && flag_unsafe_math_optimizations)
15402    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15403        && !flag_trapping_math)"
15404 {
15405   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15406       && !flag_trapping_math
15407       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15408     {
15409       if (TARGET_ROUND)
15410         emit_insn (gen_sse4_1_round<mode>2
15411                    (operands[0], operands[1], GEN_INT (0x03)));
15412       else if (optimize_insn_for_size_p ())
15413         FAIL;
15414       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15415         ix86_expand_trunc (operand0, operand1);
15416       else
15417         ix86_expand_truncdf_32 (operand0, operand1);
15418     }
15419   else
15420     {
15421       rtx op0, op1;
15422
15423       if (optimize_insn_for_size_p ())
15424         FAIL;
15425
15426       op0 = gen_reg_rtx (XFmode);
15427       op1 = gen_reg_rtx (XFmode);
15428       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15429       emit_insn (gen_frndintxf2_trunc (op0, op1));
15430
15431       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15432     }
15433   DONE;
15434 })
15435
15436 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15437 (define_insn_and_split "frndintxf2_mask_pm"
15438   [(set (match_operand:XF 0 "register_operand" "")
15439         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15440          UNSPEC_FRNDINT_MASK_PM))
15441    (clobber (reg:CC FLAGS_REG))]
15442   "TARGET_USE_FANCY_MATH_387
15443    && flag_unsafe_math_optimizations
15444    && can_create_pseudo_p ()"
15445   "#"
15446   "&& 1"
15447   [(const_int 0)]
15448 {
15449   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15450
15451   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15452   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15453
15454   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15455                                           operands[2], operands[3]));
15456   DONE;
15457 }
15458   [(set_attr "type" "frndint")
15459    (set_attr "i387_cw" "mask_pm")
15460    (set_attr "mode" "XF")])
15461
15462 (define_insn "frndintxf2_mask_pm_i387"
15463   [(set (match_operand:XF 0 "register_operand" "=f")
15464         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15465          UNSPEC_FRNDINT_MASK_PM))
15466    (use (match_operand:HI 2 "memory_operand" "m"))
15467    (use (match_operand:HI 3 "memory_operand" "m"))]
15468   "TARGET_USE_FANCY_MATH_387
15469    && flag_unsafe_math_optimizations"
15470   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15471   [(set_attr "type" "frndint")
15472    (set_attr "i387_cw" "mask_pm")
15473    (set_attr "mode" "XF")])
15474
15475 (define_expand "nearbyintxf2"
15476   [(use (match_operand:XF 0 "register_operand" ""))
15477    (use (match_operand:XF 1 "register_operand" ""))]
15478   "TARGET_USE_FANCY_MATH_387
15479    && flag_unsafe_math_optimizations"
15480 {
15481   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15482
15483   DONE;
15484 })
15485
15486 (define_expand "nearbyint<mode>2"
15487   [(use (match_operand:MODEF 0 "register_operand" ""))
15488    (use (match_operand:MODEF 1 "register_operand" ""))]
15489   "TARGET_USE_FANCY_MATH_387
15490    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15491        || TARGET_MIX_SSE_I387)
15492    && flag_unsafe_math_optimizations"
15493 {
15494   rtx op0 = gen_reg_rtx (XFmode);
15495   rtx op1 = gen_reg_rtx (XFmode);
15496
15497   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15498   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15499
15500   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15501   DONE;
15502 })
15503
15504 (define_insn "fxam<mode>2_i387"
15505   [(set (match_operand:HI 0 "register_operand" "=a")
15506         (unspec:HI
15507           [(match_operand:X87MODEF 1 "register_operand" "f")]
15508           UNSPEC_FXAM))]
15509   "TARGET_USE_FANCY_MATH_387"
15510   "fxam\n\tfnstsw\t%0"
15511   [(set_attr "type" "multi")
15512    (set_attr "length" "4")
15513    (set_attr "unit" "i387")
15514    (set_attr "mode" "<MODE>")])
15515
15516 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15517   [(set (match_operand:HI 0 "register_operand" "")
15518         (unspec:HI
15519           [(match_operand:MODEF 1 "memory_operand" "")]
15520           UNSPEC_FXAM_MEM))]
15521   "TARGET_USE_FANCY_MATH_387
15522    && can_create_pseudo_p ()"
15523   "#"
15524   "&& 1"
15525   [(set (match_dup 2)(match_dup 1))
15526    (set (match_dup 0)
15527         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15528 {
15529   operands[2] = gen_reg_rtx (<MODE>mode);
15530
15531   MEM_VOLATILE_P (operands[1]) = 1;
15532 }
15533   [(set_attr "type" "multi")
15534    (set_attr "unit" "i387")
15535    (set_attr "mode" "<MODE>")])
15536
15537 (define_expand "isinfxf2"
15538   [(use (match_operand:SI 0 "register_operand" ""))
15539    (use (match_operand:XF 1 "register_operand" ""))]
15540   "TARGET_USE_FANCY_MATH_387
15541    && TARGET_C99_FUNCTIONS"
15542 {
15543   rtx mask = GEN_INT (0x45);
15544   rtx val = GEN_INT (0x05);
15545
15546   rtx cond;
15547
15548   rtx scratch = gen_reg_rtx (HImode);
15549   rtx res = gen_reg_rtx (QImode);
15550
15551   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15552
15553   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15554   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15555   cond = gen_rtx_fmt_ee (EQ, QImode,
15556                          gen_rtx_REG (CCmode, FLAGS_REG),
15557                          const0_rtx);
15558   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15559   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15560   DONE;
15561 })
15562
15563 (define_expand "isinf<mode>2"
15564   [(use (match_operand:SI 0 "register_operand" ""))
15565    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15566   "TARGET_USE_FANCY_MATH_387
15567    && TARGET_C99_FUNCTIONS
15568    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15569 {
15570   rtx mask = GEN_INT (0x45);
15571   rtx val = GEN_INT (0x05);
15572
15573   rtx cond;
15574
15575   rtx scratch = gen_reg_rtx (HImode);
15576   rtx res = gen_reg_rtx (QImode);
15577
15578   /* Remove excess precision by forcing value through memory. */
15579   if (memory_operand (operands[1], VOIDmode))
15580     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15581   else
15582     {
15583       enum ix86_stack_slot slot = (virtuals_instantiated
15584                                    ? SLOT_TEMP
15585                                    : SLOT_VIRTUAL);
15586       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15587
15588       emit_move_insn (temp, operands[1]);
15589       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15590     }
15591
15592   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15593   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15594   cond = gen_rtx_fmt_ee (EQ, QImode,
15595                          gen_rtx_REG (CCmode, FLAGS_REG),
15596                          const0_rtx);
15597   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15598   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15599   DONE;
15600 })
15601
15602 (define_expand "signbit<mode>2"
15603   [(use (match_operand:SI 0 "register_operand" ""))
15604    (use (match_operand:X87MODEF 1 "register_operand" ""))]
15605   "TARGET_USE_FANCY_MATH_387
15606    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15607 {
15608   rtx mask = GEN_INT (0x0200);
15609
15610   rtx scratch = gen_reg_rtx (HImode);
15611
15612   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15613   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15614   DONE;
15615 })
15616 \f
15617 ;; Block operation instructions
15618
15619 (define_insn "cld"
15620   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15621   ""
15622   "cld"
15623   [(set_attr "length" "1")
15624    (set_attr "length_immediate" "0")
15625    (set_attr "modrm" "0")])
15626
15627 (define_expand "movmemsi"
15628   [(use (match_operand:BLK 0 "memory_operand" ""))
15629    (use (match_operand:BLK 1 "memory_operand" ""))
15630    (use (match_operand:SI 2 "nonmemory_operand" ""))
15631    (use (match_operand:SI 3 "const_int_operand" ""))
15632    (use (match_operand:SI 4 "const_int_operand" ""))
15633    (use (match_operand:SI 5 "const_int_operand" ""))]
15634   ""
15635 {
15636  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15637                          operands[4], operands[5]))
15638    DONE;
15639  else
15640    FAIL;
15641 })
15642
15643 (define_expand "movmemdi"
15644   [(use (match_operand:BLK 0 "memory_operand" ""))
15645    (use (match_operand:BLK 1 "memory_operand" ""))
15646    (use (match_operand:DI 2 "nonmemory_operand" ""))
15647    (use (match_operand:DI 3 "const_int_operand" ""))
15648    (use (match_operand:SI 4 "const_int_operand" ""))
15649    (use (match_operand:SI 5 "const_int_operand" ""))]
15650   "TARGET_64BIT"
15651 {
15652  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15653                          operands[4], operands[5]))
15654    DONE;
15655  else
15656    FAIL;
15657 })
15658
15659 ;; Most CPUs don't like single string operations
15660 ;; Handle this case here to simplify previous expander.
15661
15662 (define_expand "strmov"
15663   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15664    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15665    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15666               (clobber (reg:CC FLAGS_REG))])
15667    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15668               (clobber (reg:CC FLAGS_REG))])]
15669   ""
15670 {
15671   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15672
15673   /* If .md ever supports :P for Pmode, these can be directly
15674      in the pattern above.  */
15675   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15676   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15677
15678   /* Can't use this if the user has appropriated esi or edi.  */
15679   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15680       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15681     {
15682       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15683                                       operands[2], operands[3],
15684                                       operands[5], operands[6]));
15685       DONE;
15686     }
15687
15688   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15689 })
15690
15691 (define_expand "strmov_singleop"
15692   [(parallel [(set (match_operand 1 "memory_operand" "")
15693                    (match_operand 3 "memory_operand" ""))
15694               (set (match_operand 0 "register_operand" "")
15695                    (match_operand 4 "" ""))
15696               (set (match_operand 2 "register_operand" "")
15697                    (match_operand 5 "" ""))])]
15698   ""
15699   "ix86_current_function_needs_cld = 1;")
15700
15701 (define_insn "*strmovdi_rex_1"
15702   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15703         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15704    (set (match_operand:DI 0 "register_operand" "=D")
15705         (plus:DI (match_dup 2)
15706                  (const_int 8)))
15707    (set (match_operand:DI 1 "register_operand" "=S")
15708         (plus:DI (match_dup 3)
15709                  (const_int 8)))]
15710   "TARGET_64BIT"
15711   "movsq"
15712   [(set_attr "type" "str")
15713    (set_attr "mode" "DI")
15714    (set_attr "memory" "both")])
15715
15716 (define_insn "*strmovsi_1"
15717   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15718         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15719    (set (match_operand:SI 0 "register_operand" "=D")
15720         (plus:SI (match_dup 2)
15721                  (const_int 4)))
15722    (set (match_operand:SI 1 "register_operand" "=S")
15723         (plus:SI (match_dup 3)
15724                  (const_int 4)))]
15725   "!TARGET_64BIT"
15726   "movs{l|d}"
15727   [(set_attr "type" "str")
15728    (set_attr "mode" "SI")
15729    (set_attr "memory" "both")])
15730
15731 (define_insn "*strmovsi_rex_1"
15732   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15733         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15734    (set (match_operand:DI 0 "register_operand" "=D")
15735         (plus:DI (match_dup 2)
15736                  (const_int 4)))
15737    (set (match_operand:DI 1 "register_operand" "=S")
15738         (plus:DI (match_dup 3)
15739                  (const_int 4)))]
15740   "TARGET_64BIT"
15741   "movs{l|d}"
15742   [(set_attr "type" "str")
15743    (set_attr "mode" "SI")
15744    (set_attr "memory" "both")])
15745
15746 (define_insn "*strmovhi_1"
15747   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15748         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15749    (set (match_operand:SI 0 "register_operand" "=D")
15750         (plus:SI (match_dup 2)
15751                  (const_int 2)))
15752    (set (match_operand:SI 1 "register_operand" "=S")
15753         (plus:SI (match_dup 3)
15754                  (const_int 2)))]
15755   "!TARGET_64BIT"
15756   "movsw"
15757   [(set_attr "type" "str")
15758    (set_attr "memory" "both")
15759    (set_attr "mode" "HI")])
15760
15761 (define_insn "*strmovhi_rex_1"
15762   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15763         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15764    (set (match_operand:DI 0 "register_operand" "=D")
15765         (plus:DI (match_dup 2)
15766                  (const_int 2)))
15767    (set (match_operand:DI 1 "register_operand" "=S")
15768         (plus:DI (match_dup 3)
15769                  (const_int 2)))]
15770   "TARGET_64BIT"
15771   "movsw"
15772   [(set_attr "type" "str")
15773    (set_attr "memory" "both")
15774    (set_attr "mode" "HI")])
15775
15776 (define_insn "*strmovqi_1"
15777   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15778         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15779    (set (match_operand:SI 0 "register_operand" "=D")
15780         (plus:SI (match_dup 2)
15781                  (const_int 1)))
15782    (set (match_operand:SI 1 "register_operand" "=S")
15783         (plus:SI (match_dup 3)
15784                  (const_int 1)))]
15785   "!TARGET_64BIT"
15786   "movsb"
15787   [(set_attr "type" "str")
15788    (set_attr "memory" "both")
15789    (set_attr "mode" "QI")])
15790
15791 (define_insn "*strmovqi_rex_1"
15792   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15793         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15794    (set (match_operand:DI 0 "register_operand" "=D")
15795         (plus:DI (match_dup 2)
15796                  (const_int 1)))
15797    (set (match_operand:DI 1 "register_operand" "=S")
15798         (plus:DI (match_dup 3)
15799                  (const_int 1)))]
15800   "TARGET_64BIT"
15801   "movsb"
15802   [(set_attr "type" "str")
15803    (set_attr "memory" "both")
15804    (set_attr "prefix_rex" "0")
15805    (set_attr "mode" "QI")])
15806
15807 (define_expand "rep_mov"
15808   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15809               (set (match_operand 0 "register_operand" "")
15810                    (match_operand 5 "" ""))
15811               (set (match_operand 2 "register_operand" "")
15812                    (match_operand 6 "" ""))
15813               (set (match_operand 1 "memory_operand" "")
15814                    (match_operand 3 "memory_operand" ""))
15815               (use (match_dup 4))])]
15816   ""
15817   "ix86_current_function_needs_cld = 1;")
15818
15819 (define_insn "*rep_movdi_rex64"
15820   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15821    (set (match_operand:DI 0 "register_operand" "=D")
15822         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15823                             (const_int 3))
15824                  (match_operand:DI 3 "register_operand" "0")))
15825    (set (match_operand:DI 1 "register_operand" "=S")
15826         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15827                  (match_operand:DI 4 "register_operand" "1")))
15828    (set (mem:BLK (match_dup 3))
15829         (mem:BLK (match_dup 4)))
15830    (use (match_dup 5))]
15831   "TARGET_64BIT"
15832   "rep movsq"
15833   [(set_attr "type" "str")
15834    (set_attr "prefix_rep" "1")
15835    (set_attr "memory" "both")
15836    (set_attr "mode" "DI")])
15837
15838 (define_insn "*rep_movsi"
15839   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15840    (set (match_operand:SI 0 "register_operand" "=D")
15841         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15842                             (const_int 2))
15843                  (match_operand:SI 3 "register_operand" "0")))
15844    (set (match_operand:SI 1 "register_operand" "=S")
15845         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15846                  (match_operand:SI 4 "register_operand" "1")))
15847    (set (mem:BLK (match_dup 3))
15848         (mem:BLK (match_dup 4)))
15849    (use (match_dup 5))]
15850   "!TARGET_64BIT"
15851   "rep movs{l|d}"
15852   [(set_attr "type" "str")
15853    (set_attr "prefix_rep" "1")
15854    (set_attr "memory" "both")
15855    (set_attr "mode" "SI")])
15856
15857 (define_insn "*rep_movsi_rex64"
15858   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15859    (set (match_operand:DI 0 "register_operand" "=D")
15860         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15861                             (const_int 2))
15862                  (match_operand:DI 3 "register_operand" "0")))
15863    (set (match_operand:DI 1 "register_operand" "=S")
15864         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15865                  (match_operand:DI 4 "register_operand" "1")))
15866    (set (mem:BLK (match_dup 3))
15867         (mem:BLK (match_dup 4)))
15868    (use (match_dup 5))]
15869   "TARGET_64BIT"
15870   "rep movs{l|d}"
15871   [(set_attr "type" "str")
15872    (set_attr "prefix_rep" "1")
15873    (set_attr "memory" "both")
15874    (set_attr "mode" "SI")])
15875
15876 (define_insn "*rep_movqi"
15877   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15878    (set (match_operand:SI 0 "register_operand" "=D")
15879         (plus:SI (match_operand:SI 3 "register_operand" "0")
15880                  (match_operand:SI 5 "register_operand" "2")))
15881    (set (match_operand:SI 1 "register_operand" "=S")
15882         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15883    (set (mem:BLK (match_dup 3))
15884         (mem:BLK (match_dup 4)))
15885    (use (match_dup 5))]
15886   "!TARGET_64BIT"
15887   "rep movsb"
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_movqi_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 (match_operand:DI 3 "register_operand" "0")
15897                  (match_operand:DI 5 "register_operand" "2")))
15898    (set (match_operand:DI 1 "register_operand" "=S")
15899         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15900    (set (mem:BLK (match_dup 3))
15901         (mem:BLK (match_dup 4)))
15902    (use (match_dup 5))]
15903   "TARGET_64BIT"
15904   "rep movsb"
15905   [(set_attr "type" "str")
15906    (set_attr "prefix_rep" "1")
15907    (set_attr "memory" "both")
15908    (set_attr "mode" "SI")])
15909
15910 (define_expand "setmemsi"
15911    [(use (match_operand:BLK 0 "memory_operand" ""))
15912     (use (match_operand:SI 1 "nonmemory_operand" ""))
15913     (use (match_operand 2 "const_int_operand" ""))
15914     (use (match_operand 3 "const_int_operand" ""))
15915     (use (match_operand:SI 4 "const_int_operand" ""))
15916     (use (match_operand:SI 5 "const_int_operand" ""))]
15917   ""
15918 {
15919  if (ix86_expand_setmem (operands[0], operands[1],
15920                          operands[2], operands[3],
15921                          operands[4], operands[5]))
15922    DONE;
15923  else
15924    FAIL;
15925 })
15926
15927 (define_expand "setmemdi"
15928    [(use (match_operand:BLK 0 "memory_operand" ""))
15929     (use (match_operand:DI 1 "nonmemory_operand" ""))
15930     (use (match_operand 2 "const_int_operand" ""))
15931     (use (match_operand 3 "const_int_operand" ""))
15932     (use (match_operand 4 "const_int_operand" ""))
15933     (use (match_operand 5 "const_int_operand" ""))]
15934   "TARGET_64BIT"
15935 {
15936  if (ix86_expand_setmem (operands[0], operands[1],
15937                          operands[2], operands[3],
15938                          operands[4], operands[5]))
15939    DONE;
15940  else
15941    FAIL;
15942 })
15943
15944 ;; Most CPUs don't like single string operations
15945 ;; Handle this case here to simplify previous expander.
15946
15947 (define_expand "strset"
15948   [(set (match_operand 1 "memory_operand" "")
15949         (match_operand 2 "register_operand" ""))
15950    (parallel [(set (match_operand 0 "register_operand" "")
15951                    (match_dup 3))
15952               (clobber (reg:CC FLAGS_REG))])]
15953   ""
15954 {
15955   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15956     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15957
15958   /* If .md ever supports :P for Pmode, this can be directly
15959      in the pattern above.  */
15960   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15961                               GEN_INT (GET_MODE_SIZE (GET_MODE
15962                                                       (operands[2]))));
15963   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15964     {
15965       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15966                                       operands[3]));
15967       DONE;
15968     }
15969 })
15970
15971 (define_expand "strset_singleop"
15972   [(parallel [(set (match_operand 1 "memory_operand" "")
15973                    (match_operand 2 "register_operand" ""))
15974               (set (match_operand 0 "register_operand" "")
15975                    (match_operand 3 "" ""))])]
15976   ""
15977   "ix86_current_function_needs_cld = 1;")
15978
15979 (define_insn "*strsetdi_rex_1"
15980   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15981         (match_operand:DI 2 "register_operand" "a"))
15982    (set (match_operand:DI 0 "register_operand" "=D")
15983         (plus:DI (match_dup 1)
15984                  (const_int 8)))]
15985   "TARGET_64BIT"
15986   "stosq"
15987   [(set_attr "type" "str")
15988    (set_attr "memory" "store")
15989    (set_attr "mode" "DI")])
15990
15991 (define_insn "*strsetsi_1"
15992   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15993         (match_operand:SI 2 "register_operand" "a"))
15994    (set (match_operand:SI 0 "register_operand" "=D")
15995         (plus:SI (match_dup 1)
15996                  (const_int 4)))]
15997   "!TARGET_64BIT"
15998   "stos{l|d}"
15999   [(set_attr "type" "str")
16000    (set_attr "memory" "store")
16001    (set_attr "mode" "SI")])
16002
16003 (define_insn "*strsetsi_rex_1"
16004   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16005         (match_operand:SI 2 "register_operand" "a"))
16006    (set (match_operand:DI 0 "register_operand" "=D")
16007         (plus:DI (match_dup 1)
16008                  (const_int 4)))]
16009   "TARGET_64BIT"
16010   "stos{l|d}"
16011   [(set_attr "type" "str")
16012    (set_attr "memory" "store")
16013    (set_attr "mode" "SI")])
16014
16015 (define_insn "*strsethi_1"
16016   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16017         (match_operand:HI 2 "register_operand" "a"))
16018    (set (match_operand:SI 0 "register_operand" "=D")
16019         (plus:SI (match_dup 1)
16020                  (const_int 2)))]
16021   "!TARGET_64BIT"
16022   "stosw"
16023   [(set_attr "type" "str")
16024    (set_attr "memory" "store")
16025    (set_attr "mode" "HI")])
16026
16027 (define_insn "*strsethi_rex_1"
16028   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16029         (match_operand:HI 2 "register_operand" "a"))
16030    (set (match_operand:DI 0 "register_operand" "=D")
16031         (plus:DI (match_dup 1)
16032                  (const_int 2)))]
16033   "TARGET_64BIT"
16034   "stosw"
16035   [(set_attr "type" "str")
16036    (set_attr "memory" "store")
16037    (set_attr "mode" "HI")])
16038
16039 (define_insn "*strsetqi_1"
16040   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16041         (match_operand:QI 2 "register_operand" "a"))
16042    (set (match_operand:SI 0 "register_operand" "=D")
16043         (plus:SI (match_dup 1)
16044                  (const_int 1)))]
16045   "!TARGET_64BIT"
16046   "stosb"
16047   [(set_attr "type" "str")
16048    (set_attr "memory" "store")
16049    (set_attr "mode" "QI")])
16050
16051 (define_insn "*strsetqi_rex_1"
16052   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16053         (match_operand:QI 2 "register_operand" "a"))
16054    (set (match_operand:DI 0 "register_operand" "=D")
16055         (plus:DI (match_dup 1)
16056                  (const_int 1)))]
16057   "TARGET_64BIT"
16058   "stosb"
16059   [(set_attr "type" "str")
16060    (set_attr "memory" "store")
16061    (set_attr "prefix_rex" "0")
16062    (set_attr "mode" "QI")])
16063
16064 (define_expand "rep_stos"
16065   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16066               (set (match_operand 0 "register_operand" "")
16067                    (match_operand 4 "" ""))
16068               (set (match_operand 2 "memory_operand" "") (const_int 0))
16069               (use (match_operand 3 "register_operand" ""))
16070               (use (match_dup 1))])]
16071   ""
16072   "ix86_current_function_needs_cld = 1;")
16073
16074 (define_insn "*rep_stosdi_rex64"
16075   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16076    (set (match_operand:DI 0 "register_operand" "=D")
16077         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16078                             (const_int 3))
16079                  (match_operand:DI 3 "register_operand" "0")))
16080    (set (mem:BLK (match_dup 3))
16081         (const_int 0))
16082    (use (match_operand:DI 2 "register_operand" "a"))
16083    (use (match_dup 4))]
16084   "TARGET_64BIT"
16085   "rep stosq"
16086   [(set_attr "type" "str")
16087    (set_attr "prefix_rep" "1")
16088    (set_attr "memory" "store")
16089    (set_attr "mode" "DI")])
16090
16091 (define_insn "*rep_stossi"
16092   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16093    (set (match_operand:SI 0 "register_operand" "=D")
16094         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16095                             (const_int 2))
16096                  (match_operand:SI 3 "register_operand" "0")))
16097    (set (mem:BLK (match_dup 3))
16098         (const_int 0))
16099    (use (match_operand:SI 2 "register_operand" "a"))
16100    (use (match_dup 4))]
16101   "!TARGET_64BIT"
16102   "rep stos{l|d}"
16103   [(set_attr "type" "str")
16104    (set_attr "prefix_rep" "1")
16105    (set_attr "memory" "store")
16106    (set_attr "mode" "SI")])
16107
16108 (define_insn "*rep_stossi_rex64"
16109   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16110    (set (match_operand:DI 0 "register_operand" "=D")
16111         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16112                             (const_int 2))
16113                  (match_operand:DI 3 "register_operand" "0")))
16114    (set (mem:BLK (match_dup 3))
16115         (const_int 0))
16116    (use (match_operand:SI 2 "register_operand" "a"))
16117    (use (match_dup 4))]
16118   "TARGET_64BIT"
16119   "rep stos{l|d}"
16120   [(set_attr "type" "str")
16121    (set_attr "prefix_rep" "1")
16122    (set_attr "memory" "store")
16123    (set_attr "mode" "SI")])
16124
16125 (define_insn "*rep_stosqi"
16126   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16127    (set (match_operand:SI 0 "register_operand" "=D")
16128         (plus:SI (match_operand:SI 3 "register_operand" "0")
16129                  (match_operand:SI 4 "register_operand" "1")))
16130    (set (mem:BLK (match_dup 3))
16131         (const_int 0))
16132    (use (match_operand:QI 2 "register_operand" "a"))
16133    (use (match_dup 4))]
16134   "!TARGET_64BIT"
16135   "rep stosb"
16136   [(set_attr "type" "str")
16137    (set_attr "prefix_rep" "1")
16138    (set_attr "memory" "store")
16139    (set_attr "mode" "QI")])
16140
16141 (define_insn "*rep_stosqi_rex64"
16142   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16143    (set (match_operand:DI 0 "register_operand" "=D")
16144         (plus:DI (match_operand:DI 3 "register_operand" "0")
16145                  (match_operand:DI 4 "register_operand" "1")))
16146    (set (mem:BLK (match_dup 3))
16147         (const_int 0))
16148    (use (match_operand:QI 2 "register_operand" "a"))
16149    (use (match_dup 4))]
16150   "TARGET_64BIT"
16151   "rep stosb"
16152   [(set_attr "type" "str")
16153    (set_attr "prefix_rep" "1")
16154    (set_attr "memory" "store")
16155    (set_attr "prefix_rex" "0")
16156    (set_attr "mode" "QI")])
16157
16158 (define_expand "cmpstrnsi"
16159   [(set (match_operand:SI 0 "register_operand" "")
16160         (compare:SI (match_operand:BLK 1 "general_operand" "")
16161                     (match_operand:BLK 2 "general_operand" "")))
16162    (use (match_operand 3 "general_operand" ""))
16163    (use (match_operand 4 "immediate_operand" ""))]
16164   ""
16165 {
16166   rtx addr1, addr2, out, outlow, count, countreg, align;
16167
16168   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16169     FAIL;
16170
16171   /* Can't use this if the user has appropriated esi or edi.  */
16172   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
16173     FAIL;
16174
16175   out = operands[0];
16176   if (!REG_P (out))
16177     out = gen_reg_rtx (SImode);
16178
16179   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16180   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16181   if (addr1 != XEXP (operands[1], 0))
16182     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16183   if (addr2 != XEXP (operands[2], 0))
16184     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16185
16186   count = operands[3];
16187   countreg = ix86_zero_extend_to_Pmode (count);
16188
16189   /* %%% Iff we are testing strict equality, we can use known alignment
16190      to good advantage.  This may be possible with combine, particularly
16191      once cc0 is dead.  */
16192   align = operands[4];
16193
16194   if (CONST_INT_P (count))
16195     {
16196       if (INTVAL (count) == 0)
16197         {
16198           emit_move_insn (operands[0], const0_rtx);
16199           DONE;
16200         }
16201       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16202                                      operands[1], operands[2]));
16203     }
16204   else
16205     {
16206       rtx (*cmp_insn)(rtx, rtx);
16207
16208       if (TARGET_64BIT)
16209         cmp_insn = gen_cmpdi_1;
16210       else
16211         cmp_insn = gen_cmpsi_1;
16212       emit_insn (cmp_insn (countreg, countreg));
16213       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16214                                   operands[1], operands[2]));
16215     }
16216
16217   outlow = gen_lowpart (QImode, out);
16218   emit_insn (gen_cmpintqi (outlow));
16219   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16220
16221   if (operands[0] != out)
16222     emit_move_insn (operands[0], out);
16223
16224   DONE;
16225 })
16226
16227 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16228
16229 (define_expand "cmpintqi"
16230   [(set (match_dup 1)
16231         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16232    (set (match_dup 2)
16233         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16234    (parallel [(set (match_operand:QI 0 "register_operand" "")
16235                    (minus:QI (match_dup 1)
16236                              (match_dup 2)))
16237               (clobber (reg:CC FLAGS_REG))])]
16238   ""
16239   "operands[1] = gen_reg_rtx (QImode);
16240    operands[2] = gen_reg_rtx (QImode);")
16241
16242 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16243 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16244
16245 (define_expand "cmpstrnqi_nz_1"
16246   [(parallel [(set (reg:CC FLAGS_REG)
16247                    (compare:CC (match_operand 4 "memory_operand" "")
16248                                (match_operand 5 "memory_operand" "")))
16249               (use (match_operand 2 "register_operand" ""))
16250               (use (match_operand:SI 3 "immediate_operand" ""))
16251               (clobber (match_operand 0 "register_operand" ""))
16252               (clobber (match_operand 1 "register_operand" ""))
16253               (clobber (match_dup 2))])]
16254   ""
16255   "ix86_current_function_needs_cld = 1;")
16256
16257 (define_insn "*cmpstrnqi_nz_1"
16258   [(set (reg:CC FLAGS_REG)
16259         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16260                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16261    (use (match_operand:SI 6 "register_operand" "2"))
16262    (use (match_operand:SI 3 "immediate_operand" "i"))
16263    (clobber (match_operand:SI 0 "register_operand" "=S"))
16264    (clobber (match_operand:SI 1 "register_operand" "=D"))
16265    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16266   "!TARGET_64BIT"
16267   "repz cmpsb"
16268   [(set_attr "type" "str")
16269    (set_attr "mode" "QI")
16270    (set_attr "prefix_rep" "1")])
16271
16272 (define_insn "*cmpstrnqi_nz_rex_1"
16273   [(set (reg:CC FLAGS_REG)
16274         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16275                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16276    (use (match_operand:DI 6 "register_operand" "2"))
16277    (use (match_operand:SI 3 "immediate_operand" "i"))
16278    (clobber (match_operand:DI 0 "register_operand" "=S"))
16279    (clobber (match_operand:DI 1 "register_operand" "=D"))
16280    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16281   "TARGET_64BIT"
16282   "repz cmpsb"
16283   [(set_attr "type" "str")
16284    (set_attr "mode" "QI")
16285    (set_attr "prefix_rex" "0")
16286    (set_attr "prefix_rep" "1")])
16287
16288 ;; The same, but the count is not known to not be zero.
16289
16290 (define_expand "cmpstrnqi_1"
16291   [(parallel [(set (reg:CC FLAGS_REG)
16292                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16293                                      (const_int 0))
16294                   (compare:CC (match_operand 4 "memory_operand" "")
16295                               (match_operand 5 "memory_operand" ""))
16296                   (const_int 0)))
16297               (use (match_operand:SI 3 "immediate_operand" ""))
16298               (use (reg:CC FLAGS_REG))
16299               (clobber (match_operand 0 "register_operand" ""))
16300               (clobber (match_operand 1 "register_operand" ""))
16301               (clobber (match_dup 2))])]
16302   ""
16303   "ix86_current_function_needs_cld = 1;")
16304
16305 (define_insn "*cmpstrnqi_1"
16306   [(set (reg:CC FLAGS_REG)
16307         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16308                              (const_int 0))
16309           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16310                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16311           (const_int 0)))
16312    (use (match_operand:SI 3 "immediate_operand" "i"))
16313    (use (reg:CC FLAGS_REG))
16314    (clobber (match_operand:SI 0 "register_operand" "=S"))
16315    (clobber (match_operand:SI 1 "register_operand" "=D"))
16316    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16317   "!TARGET_64BIT"
16318   "repz cmpsb"
16319   [(set_attr "type" "str")
16320    (set_attr "mode" "QI")
16321    (set_attr "prefix_rep" "1")])
16322
16323 (define_insn "*cmpstrnqi_rex_1"
16324   [(set (reg:CC FLAGS_REG)
16325         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16326                              (const_int 0))
16327           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16328                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16329           (const_int 0)))
16330    (use (match_operand:SI 3 "immediate_operand" "i"))
16331    (use (reg:CC FLAGS_REG))
16332    (clobber (match_operand:DI 0 "register_operand" "=S"))
16333    (clobber (match_operand:DI 1 "register_operand" "=D"))
16334    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16335   "TARGET_64BIT"
16336   "repz cmpsb"
16337   [(set_attr "type" "str")
16338    (set_attr "mode" "QI")
16339    (set_attr "prefix_rex" "0")
16340    (set_attr "prefix_rep" "1")])
16341
16342 (define_expand "strlensi"
16343   [(set (match_operand:SI 0 "register_operand" "")
16344         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16345                     (match_operand:QI 2 "immediate_operand" "")
16346                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16347   ""
16348 {
16349  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16350    DONE;
16351  else
16352    FAIL;
16353 })
16354
16355 (define_expand "strlendi"
16356   [(set (match_operand:DI 0 "register_operand" "")
16357         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16358                     (match_operand:QI 2 "immediate_operand" "")
16359                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16360   ""
16361 {
16362  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16363    DONE;
16364  else
16365    FAIL;
16366 })
16367
16368 (define_expand "strlenqi_1"
16369   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16370               (clobber (match_operand 1 "register_operand" ""))
16371               (clobber (reg:CC FLAGS_REG))])]
16372   ""
16373   "ix86_current_function_needs_cld = 1;")
16374
16375 (define_insn "*strlenqi_1"
16376   [(set (match_operand:SI 0 "register_operand" "=&c")
16377         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16378                     (match_operand:QI 2 "register_operand" "a")
16379                     (match_operand:SI 3 "immediate_operand" "i")
16380                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16381    (clobber (match_operand:SI 1 "register_operand" "=D"))
16382    (clobber (reg:CC FLAGS_REG))]
16383   "!TARGET_64BIT"
16384   "repnz scasb"
16385   [(set_attr "type" "str")
16386    (set_attr "mode" "QI")
16387    (set_attr "prefix_rep" "1")])
16388
16389 (define_insn "*strlenqi_rex_1"
16390   [(set (match_operand:DI 0 "register_operand" "=&c")
16391         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16392                     (match_operand:QI 2 "register_operand" "a")
16393                     (match_operand:DI 3 "immediate_operand" "i")
16394                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16395    (clobber (match_operand:DI 1 "register_operand" "=D"))
16396    (clobber (reg:CC FLAGS_REG))]
16397   "TARGET_64BIT"
16398   "repnz scasb"
16399   [(set_attr "type" "str")
16400    (set_attr "mode" "QI")
16401    (set_attr "prefix_rex" "0")
16402    (set_attr "prefix_rep" "1")])
16403
16404 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16405 ;; handled in combine, but it is not currently up to the task.
16406 ;; When used for their truth value, the cmpstrn* expanders generate
16407 ;; code like this:
16408 ;;
16409 ;;   repz cmpsb
16410 ;;   seta       %al
16411 ;;   setb       %dl
16412 ;;   cmpb       %al, %dl
16413 ;;   jcc        label
16414 ;;
16415 ;; The intermediate three instructions are unnecessary.
16416
16417 ;; This one handles cmpstrn*_nz_1...
16418 (define_peephole2
16419   [(parallel[
16420      (set (reg:CC FLAGS_REG)
16421           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16422                       (mem:BLK (match_operand 5 "register_operand" ""))))
16423      (use (match_operand 6 "register_operand" ""))
16424      (use (match_operand:SI 3 "immediate_operand" ""))
16425      (clobber (match_operand 0 "register_operand" ""))
16426      (clobber (match_operand 1 "register_operand" ""))
16427      (clobber (match_operand 2 "register_operand" ""))])
16428    (set (match_operand:QI 7 "register_operand" "")
16429         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16430    (set (match_operand:QI 8 "register_operand" "")
16431         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16432    (set (reg FLAGS_REG)
16433         (compare (match_dup 7) (match_dup 8)))
16434   ]
16435   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16436   [(parallel[
16437      (set (reg:CC FLAGS_REG)
16438           (compare:CC (mem:BLK (match_dup 4))
16439                       (mem:BLK (match_dup 5))))
16440      (use (match_dup 6))
16441      (use (match_dup 3))
16442      (clobber (match_dup 0))
16443      (clobber (match_dup 1))
16444      (clobber (match_dup 2))])]
16445   "")
16446
16447 ;; ...and this one handles cmpstrn*_1.
16448 (define_peephole2
16449   [(parallel[
16450      (set (reg:CC FLAGS_REG)
16451           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16452                                (const_int 0))
16453             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16454                         (mem:BLK (match_operand 5 "register_operand" "")))
16455             (const_int 0)))
16456      (use (match_operand:SI 3 "immediate_operand" ""))
16457      (use (reg:CC FLAGS_REG))
16458      (clobber (match_operand 0 "register_operand" ""))
16459      (clobber (match_operand 1 "register_operand" ""))
16460      (clobber (match_operand 2 "register_operand" ""))])
16461    (set (match_operand:QI 7 "register_operand" "")
16462         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16463    (set (match_operand:QI 8 "register_operand" "")
16464         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16465    (set (reg FLAGS_REG)
16466         (compare (match_dup 7) (match_dup 8)))
16467   ]
16468   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16469   [(parallel[
16470      (set (reg:CC FLAGS_REG)
16471           (if_then_else:CC (ne (match_dup 6)
16472                                (const_int 0))
16473             (compare:CC (mem:BLK (match_dup 4))
16474                         (mem:BLK (match_dup 5)))
16475             (const_int 0)))
16476      (use (match_dup 3))
16477      (use (reg:CC FLAGS_REG))
16478      (clobber (match_dup 0))
16479      (clobber (match_dup 1))
16480      (clobber (match_dup 2))])]
16481   "")
16482
16483
16484 \f
16485 ;; Conditional move instructions.
16486
16487 (define_expand "mov<mode>cc"
16488   [(set (match_operand:SWIM 0 "register_operand" "")
16489         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16490                            (match_operand:SWIM 2 "general_operand" "")
16491                            (match_operand:SWIM 3 "general_operand" "")))]
16492   ""
16493   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16494
16495 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16496 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16497 ;; So just document what we're doing explicitly.
16498
16499 (define_expand "x86_mov<mode>cc_0_m1"
16500   [(parallel
16501     [(set (match_operand:SWI48 0 "register_operand" "")
16502           (if_then_else:SWI48
16503             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16504              [(match_operand 1 "flags_reg_operand" "")
16505               (const_int 0)])
16506             (const_int -1)
16507             (const_int 0)))
16508      (clobber (reg:CC FLAGS_REG))])]
16509   ""
16510   "")
16511
16512 (define_insn "*x86_mov<mode>cc_0_m1"
16513   [(set (match_operand:SWI48 0 "register_operand" "=r")
16514         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16515                              [(reg FLAGS_REG) (const_int 0)])
16516           (const_int -1)
16517           (const_int 0)))
16518    (clobber (reg:CC FLAGS_REG))]
16519   ""
16520   "sbb{<imodesuffix>}\t%0, %0"
16521   ; Since we don't have the proper number of operands for an alu insn,
16522   ; fill in all the blanks.
16523   [(set_attr "type" "alu")
16524    (set_attr "use_carry" "1")
16525    (set_attr "pent_pair" "pu")
16526    (set_attr "memory" "none")
16527    (set_attr "imm_disp" "false")
16528    (set_attr "mode" "<MODE>")
16529    (set_attr "length_immediate" "0")])
16530
16531 (define_insn "*x86_mov<mode>cc_0_m1_se"
16532   [(set (match_operand:SWI48 0 "register_operand" "=r")
16533         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16534                              [(reg FLAGS_REG) (const_int 0)])
16535                             (const_int 1)
16536                             (const_int 0)))
16537    (clobber (reg:CC FLAGS_REG))]
16538   ""
16539   "sbb{<imodesuffix>}\t%0, %0"
16540   [(set_attr "type" "alu")
16541    (set_attr "use_carry" "1")
16542    (set_attr "pent_pair" "pu")
16543    (set_attr "memory" "none")
16544    (set_attr "imm_disp" "false")
16545    (set_attr "mode" "<MODE>")
16546    (set_attr "length_immediate" "0")])
16547
16548 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16549   [(set (match_operand:SWI48 0 "register_operand" "=r")
16550         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16551                     [(reg FLAGS_REG) (const_int 0)])))]
16552   ""
16553   "sbb{<imodesuffix>}\t%0, %0"
16554   [(set_attr "type" "alu")
16555    (set_attr "use_carry" "1")
16556    (set_attr "pent_pair" "pu")
16557    (set_attr "memory" "none")
16558    (set_attr "imm_disp" "false")
16559    (set_attr "mode" "<MODE>")
16560    (set_attr "length_immediate" "0")])
16561
16562 (define_insn "*mov<mode>cc_noc"
16563   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16564         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16565                                [(reg FLAGS_REG) (const_int 0)])
16566           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16567           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16568   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16569   "@
16570    cmov%O2%C1\t{%2, %0|%0, %2}
16571    cmov%O2%c1\t{%3, %0|%0, %3}"
16572   [(set_attr "type" "icmov")
16573    (set_attr "mode" "<MODE>")])
16574
16575 (define_insn_and_split "*movqicc_noc"
16576   [(set (match_operand:QI 0 "register_operand" "=r,r")
16577         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16578                            [(match_operand 4 "flags_reg_operand" "")
16579                             (const_int 0)])
16580                       (match_operand:QI 2 "register_operand" "r,0")
16581                       (match_operand:QI 3 "register_operand" "0,r")))]
16582   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16583   "#"
16584   "&& reload_completed"
16585   [(set (match_dup 0)
16586         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16587                       (match_dup 2)
16588                       (match_dup 3)))]
16589   "operands[0] = gen_lowpart (SImode, operands[0]);
16590    operands[2] = gen_lowpart (SImode, operands[2]);
16591    operands[3] = gen_lowpart (SImode, operands[3]);"
16592   [(set_attr "type" "icmov")
16593    (set_attr "mode" "SI")])
16594
16595 (define_expand "mov<mode>cc"
16596   [(set (match_operand:X87MODEF 0 "register_operand" "")
16597         (if_then_else:X87MODEF
16598           (match_operand 1 "ix86_fp_comparison_operator" "")
16599           (match_operand:X87MODEF 2 "register_operand" "")
16600           (match_operand:X87MODEF 3 "register_operand" "")))]
16601   "(TARGET_80387 && TARGET_CMOVE)
16602    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16603   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16604
16605 (define_insn "*movsfcc_1_387"
16606   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16607         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16608                                 [(reg FLAGS_REG) (const_int 0)])
16609                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16610                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16611   "TARGET_80387 && TARGET_CMOVE
16612    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16613   "@
16614    fcmov%F1\t{%2, %0|%0, %2}
16615    fcmov%f1\t{%3, %0|%0, %3}
16616    cmov%O2%C1\t{%2, %0|%0, %2}
16617    cmov%O2%c1\t{%3, %0|%0, %3}"
16618   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16619    (set_attr "mode" "SF,SF,SI,SI")])
16620
16621 (define_insn "*movdfcc_1"
16622   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16623         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16624                                 [(reg FLAGS_REG) (const_int 0)])
16625                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16626                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16627   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16628    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16629   "@
16630    fcmov%F1\t{%2, %0|%0, %2}
16631    fcmov%f1\t{%3, %0|%0, %3}
16632    #
16633    #"
16634   [(set_attr "type" "fcmov,fcmov,multi,multi")
16635    (set_attr "mode" "DF")])
16636
16637 (define_insn "*movdfcc_1_rex64"
16638   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16639         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16640                                 [(reg FLAGS_REG) (const_int 0)])
16641                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16642                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16643   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16644    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16645   "@
16646    fcmov%F1\t{%2, %0|%0, %2}
16647    fcmov%f1\t{%3, %0|%0, %3}
16648    cmov%O2%C1\t{%2, %0|%0, %2}
16649    cmov%O2%c1\t{%3, %0|%0, %3}"
16650   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16651    (set_attr "mode" "DF")])
16652
16653 (define_split
16654   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16655         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16656                                 [(match_operand 4 "flags_reg_operand" "")
16657                                  (const_int 0)])
16658                       (match_operand:DF 2 "nonimmediate_operand" "")
16659                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16660   "!TARGET_64BIT && reload_completed"
16661   [(set (match_dup 2)
16662         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16663                       (match_dup 5)
16664                       (match_dup 6)))
16665    (set (match_dup 3)
16666         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16667                       (match_dup 7)
16668                       (match_dup 8)))]
16669 {
16670   split_di (&operands[2], 2, &operands[5], &operands[7]);
16671   split_di (&operands[0], 1, &operands[2], &operands[3]);
16672 })
16673
16674 (define_insn "*movxfcc_1"
16675   [(set (match_operand:XF 0 "register_operand" "=f,f")
16676         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16677                                 [(reg FLAGS_REG) (const_int 0)])
16678                       (match_operand:XF 2 "register_operand" "f,0")
16679                       (match_operand:XF 3 "register_operand" "0,f")))]
16680   "TARGET_80387 && TARGET_CMOVE"
16681   "@
16682    fcmov%F1\t{%2, %0|%0, %2}
16683    fcmov%f1\t{%3, %0|%0, %3}"
16684   [(set_attr "type" "fcmov")
16685    (set_attr "mode" "XF")])
16686
16687 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16688 ;; the scalar versions to have only XMM registers as operands.
16689
16690 ;; XOP conditional move
16691 (define_insn "*xop_pcmov_<mode>"
16692   [(set (match_operand:MODEF 0 "register_operand" "=x")
16693         (if_then_else:MODEF
16694           (match_operand:MODEF 1 "register_operand" "x")
16695           (match_operand:MODEF 2 "register_operand" "x")
16696           (match_operand:MODEF 3 "register_operand" "x")))]
16697   "TARGET_XOP"
16698   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16699   [(set_attr "type" "sse4arg")])
16700
16701 ;; These versions of the min/max patterns are intentionally ignorant of
16702 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16703 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16704 ;; are undefined in this condition, we're certain this is correct.
16705
16706 (define_insn "*avx_<code><mode>3"
16707   [(set (match_operand:MODEF 0 "register_operand" "=x")
16708         (smaxmin:MODEF
16709           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16710           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16711   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16712   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16713   [(set_attr "type" "sseadd")
16714    (set_attr "prefix" "vex")
16715    (set_attr "mode" "<MODE>")])
16716
16717 (define_insn "<code><mode>3"
16718   [(set (match_operand:MODEF 0 "register_operand" "=x")
16719         (smaxmin:MODEF
16720           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16721           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16722   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16723   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16724   [(set_attr "type" "sseadd")
16725    (set_attr "mode" "<MODE>")])
16726
16727 ;; These versions of the min/max patterns implement exactly the operations
16728 ;;   min = (op1 < op2 ? op1 : op2)
16729 ;;   max = (!(op1 < op2) ? op1 : op2)
16730 ;; Their operands are not commutative, and thus they may be used in the
16731 ;; presence of -0.0 and NaN.
16732
16733 (define_insn "*avx_ieee_smin<mode>3"
16734   [(set (match_operand:MODEF 0 "register_operand" "=x")
16735         (unspec:MODEF
16736           [(match_operand:MODEF 1 "register_operand" "x")
16737            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16738          UNSPEC_IEEE_MIN))]
16739   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16740   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16741   [(set_attr "type" "sseadd")
16742    (set_attr "prefix" "vex")
16743    (set_attr "mode" "<MODE>")])
16744
16745 (define_insn "*ieee_smin<mode>3"
16746   [(set (match_operand:MODEF 0 "register_operand" "=x")
16747         (unspec:MODEF
16748           [(match_operand:MODEF 1 "register_operand" "0")
16749            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16750          UNSPEC_IEEE_MIN))]
16751   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16752   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16753   [(set_attr "type" "sseadd")
16754    (set_attr "mode" "<MODE>")])
16755
16756 (define_insn "*avx_ieee_smax<mode>3"
16757   [(set (match_operand:MODEF 0 "register_operand" "=x")
16758         (unspec:MODEF
16759           [(match_operand:MODEF 1 "register_operand" "0")
16760            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16761          UNSPEC_IEEE_MAX))]
16762   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16763   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16764   [(set_attr "type" "sseadd")
16765    (set_attr "prefix" "vex")
16766    (set_attr "mode" "<MODE>")])
16767
16768 (define_insn "*ieee_smax<mode>3"
16769   [(set (match_operand:MODEF 0 "register_operand" "=x")
16770         (unspec:MODEF
16771           [(match_operand:MODEF 1 "register_operand" "0")
16772            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16773          UNSPEC_IEEE_MAX))]
16774   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16775   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16776   [(set_attr "type" "sseadd")
16777    (set_attr "mode" "<MODE>")])
16778
16779 ;; Make two stack loads independent:
16780 ;;   fld aa              fld aa
16781 ;;   fld %st(0)     ->   fld bb
16782 ;;   fmul bb             fmul %st(1), %st
16783 ;;
16784 ;; Actually we only match the last two instructions for simplicity.
16785 (define_peephole2
16786   [(set (match_operand 0 "fp_register_operand" "")
16787         (match_operand 1 "fp_register_operand" ""))
16788    (set (match_dup 0)
16789         (match_operator 2 "binary_fp_operator"
16790            [(match_dup 0)
16791             (match_operand 3 "memory_operand" "")]))]
16792   "REGNO (operands[0]) != REGNO (operands[1])"
16793   [(set (match_dup 0) (match_dup 3))
16794    (set (match_dup 0) (match_dup 4))]
16795
16796   ;; The % modifier is not operational anymore in peephole2's, so we have to
16797   ;; swap the operands manually in the case of addition and multiplication.
16798   "if (COMMUTATIVE_ARITH_P (operands[2]))
16799      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16800                                  operands[0], operands[1]);
16801    else
16802      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16803                                  operands[1], operands[0]);")
16804
16805 ;; Conditional addition patterns
16806 (define_expand "add<mode>cc"
16807   [(match_operand:SWI 0 "register_operand" "")
16808    (match_operand 1 "comparison_operator" "")
16809    (match_operand:SWI 2 "register_operand" "")
16810    (match_operand:SWI 3 "const_int_operand" "")]
16811   ""
16812   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16813
16814 \f
16815 ;; Misc patterns (?)
16816
16817 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16818 ;; Otherwise there will be nothing to keep
16819 ;;
16820 ;; [(set (reg ebp) (reg esp))]
16821 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16822 ;;  (clobber (eflags)]
16823 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16824 ;;
16825 ;; in proper program order.
16826 (define_insn "pro_epilogue_adjust_stack_1"
16827   [(set (match_operand:SI 0 "register_operand" "=r,r")
16828         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16829                  (match_operand:SI 2 "immediate_operand" "i,i")))
16830    (clobber (reg:CC FLAGS_REG))
16831    (clobber (mem:BLK (scratch)))]
16832   "!TARGET_64BIT"
16833 {
16834   switch (get_attr_type (insn))
16835     {
16836     case TYPE_IMOV:
16837       return "mov{l}\t{%1, %0|%0, %1}";
16838
16839     case TYPE_ALU:
16840       if (CONST_INT_P (operands[2])
16841           && (INTVAL (operands[2]) == 128
16842               || (INTVAL (operands[2]) < 0
16843                   && INTVAL (operands[2]) != -128)))
16844         {
16845           operands[2] = GEN_INT (-INTVAL (operands[2]));
16846           return "sub{l}\t{%2, %0|%0, %2}";
16847         }
16848       return "add{l}\t{%2, %0|%0, %2}";
16849
16850     case TYPE_LEA:
16851       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16852       return "lea{l}\t{%a2, %0|%0, %a2}";
16853
16854     default:
16855       gcc_unreachable ();
16856     }
16857 }
16858   [(set (attr "type")
16859         (cond [(and (eq_attr "alternative" "0") 
16860                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16861                  (const_string "alu")
16862                (match_operand:SI 2 "const0_operand" "")
16863                  (const_string "imov")
16864               ]
16865               (const_string "lea")))
16866    (set (attr "length_immediate")
16867         (cond [(eq_attr "type" "imov")
16868                  (const_string "0")
16869                (and (eq_attr "type" "alu")
16870                     (match_operand 2 "const128_operand" ""))
16871                  (const_string "1")
16872               ]
16873               (const_string "*")))
16874    (set_attr "mode" "SI")])
16875
16876 (define_insn "pro_epilogue_adjust_stack_rex64"
16877   [(set (match_operand:DI 0 "register_operand" "=r,r")
16878         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16879                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16880    (clobber (reg:CC FLAGS_REG))
16881    (clobber (mem:BLK (scratch)))]
16882   "TARGET_64BIT"
16883 {
16884   switch (get_attr_type (insn))
16885     {
16886     case TYPE_IMOV:
16887       return "mov{q}\t{%1, %0|%0, %1}";
16888
16889     case TYPE_ALU:
16890       if (CONST_INT_P (operands[2])
16891           /* Avoid overflows.  */
16892           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16893           && (INTVAL (operands[2]) == 128
16894               || (INTVAL (operands[2]) < 0
16895                   && INTVAL (operands[2]) != -128)))
16896         {
16897           operands[2] = GEN_INT (-INTVAL (operands[2]));
16898           return "sub{q}\t{%2, %0|%0, %2}";
16899         }
16900       return "add{q}\t{%2, %0|%0, %2}";
16901
16902     case TYPE_LEA:
16903       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16904       return "lea{q}\t{%a2, %0|%0, %a2}";
16905
16906     default:
16907       gcc_unreachable ();
16908     }
16909 }
16910   [(set (attr "type")
16911         (cond [(and (eq_attr "alternative" "0")
16912                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16913                  (const_string "alu")
16914                (match_operand:DI 2 "const0_operand" "")
16915                  (const_string "imov")
16916               ]
16917               (const_string "lea")))
16918    (set (attr "length_immediate")
16919         (cond [(eq_attr "type" "imov")
16920                  (const_string "0")
16921                (and (eq_attr "type" "alu")
16922                     (match_operand 2 "const128_operand" ""))
16923                  (const_string "1")
16924               ]
16925               (const_string "*")))
16926    (set_attr "mode" "DI")])
16927
16928 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16929   [(set (match_operand:DI 0 "register_operand" "=r,r")
16930         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16931                  (match_operand:DI 3 "immediate_operand" "i,i")))
16932    (use (match_operand:DI 2 "register_operand" "r,r"))
16933    (clobber (reg:CC FLAGS_REG))
16934    (clobber (mem:BLK (scratch)))]
16935   "TARGET_64BIT"
16936 {
16937   switch (get_attr_type (insn))
16938     {
16939     case TYPE_ALU:
16940       return "add{q}\t{%2, %0|%0, %2}";
16941
16942     case TYPE_LEA:
16943       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16944       return "lea{q}\t{%a2, %0|%0, %a2}";
16945
16946     default:
16947       gcc_unreachable ();
16948     }
16949 }
16950   [(set_attr "type" "alu,lea")
16951    (set_attr "mode" "DI")])
16952
16953 (define_insn "allocate_stack_worker_32"
16954   [(set (match_operand:SI 0 "register_operand" "=a")
16955         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16956                             UNSPECV_STACK_PROBE))
16957    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16958    (clobber (reg:CC FLAGS_REG))]
16959   "!TARGET_64BIT && TARGET_STACK_PROBE"
16960   "call\t___chkstk"
16961   [(set_attr "type" "multi")
16962    (set_attr "length" "5")])
16963
16964 (define_insn "allocate_stack_worker_64"
16965   [(set (match_operand:DI 0 "register_operand" "=a")
16966         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16967                             UNSPECV_STACK_PROBE))
16968    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16969    (clobber (reg:DI R10_REG))
16970    (clobber (reg:DI R11_REG))
16971    (clobber (reg:CC FLAGS_REG))]
16972   "TARGET_64BIT && TARGET_STACK_PROBE"
16973   "call\t___chkstk"
16974   [(set_attr "type" "multi")
16975    (set_attr "length" "5")])
16976
16977 (define_expand "allocate_stack"
16978   [(match_operand 0 "register_operand" "")
16979    (match_operand 1 "general_operand" "")]
16980   "TARGET_STACK_PROBE"
16981 {
16982   rtx x;
16983
16984 #ifndef CHECK_STACK_LIMIT
16985 #define CHECK_STACK_LIMIT 0
16986 #endif
16987
16988   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16989       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16990     {
16991       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16992                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16993       if (x != stack_pointer_rtx)
16994         emit_move_insn (stack_pointer_rtx, x);
16995     }
16996   else
16997     {
16998       x = copy_to_mode_reg (Pmode, operands[1]);
16999       if (TARGET_64BIT)
17000         x = gen_allocate_stack_worker_64 (x, x);
17001       else
17002         x = gen_allocate_stack_worker_32 (x, x);
17003       emit_insn (x);
17004     }
17005
17006   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17007   DONE;
17008 })
17009
17010 ;; Use IOR for stack probes, this is shorter.
17011 (define_expand "probe_stack"
17012   [(match_operand 0 "memory_operand" "")]
17013   ""
17014 {
17015   if (GET_MODE (operands[0]) == DImode)
17016     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
17017   else
17018     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
17019   DONE;
17020 })
17021
17022 (define_expand "builtin_setjmp_receiver"
17023   [(label_ref (match_operand 0 "" ""))]
17024   "!TARGET_64BIT && flag_pic"
17025 {
17026 #if TARGET_MACHO
17027   if (TARGET_MACHO)
17028     {
17029       rtx xops[3];
17030       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17031       rtx label_rtx = gen_label_rtx ();
17032       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17033       xops[0] = xops[1] = picreg;
17034       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17035       ix86_expand_binary_operator (MINUS, SImode, xops);
17036     }
17037   else
17038 #endif
17039     emit_insn (gen_set_got (pic_offset_table_rtx));
17040   DONE;
17041 })
17042 \f
17043 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17044
17045 (define_split
17046   [(set (match_operand 0 "register_operand" "")
17047         (match_operator 3 "promotable_binary_operator"
17048            [(match_operand 1 "register_operand" "")
17049             (match_operand 2 "aligned_operand" "")]))
17050    (clobber (reg:CC FLAGS_REG))]
17051   "! TARGET_PARTIAL_REG_STALL && reload_completed
17052    && ((GET_MODE (operands[0]) == HImode
17053         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17054             /* ??? next two lines just !satisfies_constraint_K (...) */
17055             || !CONST_INT_P (operands[2])
17056             || satisfies_constraint_K (operands[2])))
17057        || (GET_MODE (operands[0]) == QImode
17058            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17059   [(parallel [(set (match_dup 0)
17060                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17061               (clobber (reg:CC FLAGS_REG))])]
17062   "operands[0] = gen_lowpart (SImode, operands[0]);
17063    operands[1] = gen_lowpart (SImode, operands[1]);
17064    if (GET_CODE (operands[3]) != ASHIFT)
17065      operands[2] = gen_lowpart (SImode, operands[2]);
17066    PUT_MODE (operands[3], SImode);")
17067
17068 ; Promote the QImode tests, as i386 has encoding of the AND
17069 ; instruction with 32-bit sign-extended immediate and thus the
17070 ; instruction size is unchanged, except in the %eax case for
17071 ; which it is increased by one byte, hence the ! optimize_size.
17072 (define_split
17073   [(set (match_operand 0 "flags_reg_operand" "")
17074         (match_operator 2 "compare_operator"
17075           [(and (match_operand 3 "aligned_operand" "")
17076                 (match_operand 4 "const_int_operand" ""))
17077            (const_int 0)]))
17078    (set (match_operand 1 "register_operand" "")
17079         (and (match_dup 3) (match_dup 4)))]
17080   "! TARGET_PARTIAL_REG_STALL && reload_completed
17081    && optimize_insn_for_speed_p ()
17082    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17083        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17084    /* Ensure that the operand will remain sign-extended immediate.  */
17085    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17086   [(parallel [(set (match_dup 0)
17087                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17088                                     (const_int 0)]))
17089               (set (match_dup 1)
17090                    (and:SI (match_dup 3) (match_dup 4)))])]
17091 {
17092   operands[4]
17093     = gen_int_mode (INTVAL (operands[4])
17094                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17095   operands[1] = gen_lowpart (SImode, operands[1]);
17096   operands[3] = gen_lowpart (SImode, operands[3]);
17097 })
17098
17099 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17100 ; the TEST instruction with 32-bit sign-extended immediate and thus
17101 ; the instruction size would at least double, which is not what we
17102 ; want even with ! optimize_size.
17103 (define_split
17104   [(set (match_operand 0 "flags_reg_operand" "")
17105         (match_operator 1 "compare_operator"
17106           [(and (match_operand:HI 2 "aligned_operand" "")
17107                 (match_operand:HI 3 "const_int_operand" ""))
17108            (const_int 0)]))]
17109   "! TARGET_PARTIAL_REG_STALL && reload_completed
17110    && ! TARGET_FAST_PREFIX
17111    && optimize_insn_for_speed_p ()
17112    /* Ensure that the operand will remain sign-extended immediate.  */
17113    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17114   [(set (match_dup 0)
17115         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17116                          (const_int 0)]))]
17117 {
17118   operands[3]
17119     = gen_int_mode (INTVAL (operands[3])
17120                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17121   operands[2] = gen_lowpart (SImode, operands[2]);
17122 })
17123
17124 (define_split
17125   [(set (match_operand 0 "register_operand" "")
17126         (neg (match_operand 1 "register_operand" "")))
17127    (clobber (reg:CC FLAGS_REG))]
17128   "! TARGET_PARTIAL_REG_STALL && reload_completed
17129    && (GET_MODE (operands[0]) == HImode
17130        || (GET_MODE (operands[0]) == QImode
17131            && (TARGET_PROMOTE_QImode
17132                || optimize_insn_for_size_p ())))"
17133   [(parallel [(set (match_dup 0)
17134                    (neg:SI (match_dup 1)))
17135               (clobber (reg:CC FLAGS_REG))])]
17136   "operands[0] = gen_lowpart (SImode, operands[0]);
17137    operands[1] = gen_lowpart (SImode, operands[1]);")
17138
17139 (define_split
17140   [(set (match_operand 0 "register_operand" "")
17141         (not (match_operand 1 "register_operand" "")))]
17142   "! TARGET_PARTIAL_REG_STALL && reload_completed
17143    && (GET_MODE (operands[0]) == HImode
17144        || (GET_MODE (operands[0]) == QImode
17145            && (TARGET_PROMOTE_QImode
17146                || optimize_insn_for_size_p ())))"
17147   [(set (match_dup 0)
17148         (not:SI (match_dup 1)))]
17149   "operands[0] = gen_lowpart (SImode, operands[0]);
17150    operands[1] = gen_lowpart (SImode, operands[1]);")
17151
17152 (define_split
17153   [(set (match_operand 0 "register_operand" "")
17154         (if_then_else (match_operator 1 "comparison_operator"
17155                                 [(reg FLAGS_REG) (const_int 0)])
17156                       (match_operand 2 "register_operand" "")
17157                       (match_operand 3 "register_operand" "")))]
17158   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17159    && (GET_MODE (operands[0]) == HImode
17160        || (GET_MODE (operands[0]) == QImode
17161            && (TARGET_PROMOTE_QImode
17162                || optimize_insn_for_size_p ())))"
17163   [(set (match_dup 0)
17164         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17165   "operands[0] = gen_lowpart (SImode, operands[0]);
17166    operands[2] = gen_lowpart (SImode, operands[2]);
17167    operands[3] = gen_lowpart (SImode, operands[3]);")
17168
17169 \f
17170 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17171 ;; transform a complex memory operation into two memory to register operations.
17172
17173 ;; Don't push memory operands
17174 (define_peephole2
17175   [(set (match_operand:SI 0 "push_operand" "")
17176         (match_operand:SI 1 "memory_operand" ""))
17177    (match_scratch:SI 2 "r")]
17178   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17179    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17180   [(set (match_dup 2) (match_dup 1))
17181    (set (match_dup 0) (match_dup 2))]
17182   "")
17183
17184 (define_peephole2
17185   [(set (match_operand:DI 0 "push_operand" "")
17186         (match_operand:DI 1 "memory_operand" ""))
17187    (match_scratch:DI 2 "r")]
17188   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17189    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17190   [(set (match_dup 2) (match_dup 1))
17191    (set (match_dup 0) (match_dup 2))]
17192   "")
17193
17194 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17195 ;; SImode pushes.
17196 (define_peephole2
17197   [(set (match_operand:SF 0 "push_operand" "")
17198         (match_operand:SF 1 "memory_operand" ""))
17199    (match_scratch:SF 2 "r")]
17200   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17201    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17202   [(set (match_dup 2) (match_dup 1))
17203    (set (match_dup 0) (match_dup 2))]
17204   "")
17205
17206 (define_peephole2
17207   [(set (match_operand:HI 0 "push_operand" "")
17208         (match_operand:HI 1 "memory_operand" ""))
17209    (match_scratch:HI 2 "r")]
17210   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17211    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17212   [(set (match_dup 2) (match_dup 1))
17213    (set (match_dup 0) (match_dup 2))]
17214   "")
17215
17216 (define_peephole2
17217   [(set (match_operand:QI 0 "push_operand" "")
17218         (match_operand:QI 1 "memory_operand" ""))
17219    (match_scratch:QI 2 "q")]
17220   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17221    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17222   [(set (match_dup 2) (match_dup 1))
17223    (set (match_dup 0) (match_dup 2))]
17224   "")
17225
17226 ;; Don't move an immediate directly to memory when the instruction
17227 ;; gets too big.
17228 (define_peephole2
17229   [(match_scratch:SI 1 "r")
17230    (set (match_operand:SI 0 "memory_operand" "")
17231         (const_int 0))]
17232   "optimize_insn_for_speed_p ()
17233    && ! TARGET_USE_MOV0
17234    && TARGET_SPLIT_LONG_MOVES
17235    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17236    && peep2_regno_dead_p (0, FLAGS_REG)"
17237   [(parallel [(set (match_dup 1) (const_int 0))
17238               (clobber (reg:CC FLAGS_REG))])
17239    (set (match_dup 0) (match_dup 1))]
17240   "")
17241
17242 (define_peephole2
17243   [(match_scratch:HI 1 "r")
17244    (set (match_operand:HI 0 "memory_operand" "")
17245         (const_int 0))]
17246   "optimize_insn_for_speed_p ()
17247    && ! TARGET_USE_MOV0
17248    && TARGET_SPLIT_LONG_MOVES
17249    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17250    && peep2_regno_dead_p (0, FLAGS_REG)"
17251   [(parallel [(set (match_dup 2) (const_int 0))
17252               (clobber (reg:CC FLAGS_REG))])
17253    (set (match_dup 0) (match_dup 1))]
17254   "operands[2] = gen_lowpart (SImode, operands[1]);")
17255
17256 (define_peephole2
17257   [(match_scratch:QI 1 "q")
17258    (set (match_operand:QI 0 "memory_operand" "")
17259         (const_int 0))]
17260   "optimize_insn_for_speed_p ()
17261    && ! TARGET_USE_MOV0
17262    && TARGET_SPLIT_LONG_MOVES
17263    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17264    && peep2_regno_dead_p (0, FLAGS_REG)"
17265   [(parallel [(set (match_dup 2) (const_int 0))
17266               (clobber (reg:CC FLAGS_REG))])
17267    (set (match_dup 0) (match_dup 1))]
17268   "operands[2] = gen_lowpart (SImode, operands[1]);")
17269
17270 (define_peephole2
17271   [(match_scratch:SI 2 "r")
17272    (set (match_operand:SI 0 "memory_operand" "")
17273         (match_operand:SI 1 "immediate_operand" ""))]
17274   "optimize_insn_for_speed_p ()
17275    && TARGET_SPLIT_LONG_MOVES
17276    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17277   [(set (match_dup 2) (match_dup 1))
17278    (set (match_dup 0) (match_dup 2))]
17279   "")
17280
17281 (define_peephole2
17282   [(match_scratch:HI 2 "r")
17283    (set (match_operand:HI 0 "memory_operand" "")
17284         (match_operand:HI 1 "immediate_operand" ""))]
17285   "optimize_insn_for_speed_p ()
17286    && TARGET_SPLIT_LONG_MOVES
17287    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17288   [(set (match_dup 2) (match_dup 1))
17289    (set (match_dup 0) (match_dup 2))]
17290   "")
17291
17292 (define_peephole2
17293   [(match_scratch:QI 2 "q")
17294    (set (match_operand:QI 0 "memory_operand" "")
17295         (match_operand:QI 1 "immediate_operand" ""))]
17296   "optimize_insn_for_speed_p ()
17297    && TARGET_SPLIT_LONG_MOVES
17298    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17299   [(set (match_dup 2) (match_dup 1))
17300    (set (match_dup 0) (match_dup 2))]
17301   "")
17302
17303 ;; Don't compare memory with zero, load and use a test instead.
17304 (define_peephole2
17305   [(set (match_operand 0 "flags_reg_operand" "")
17306         (match_operator 1 "compare_operator"
17307           [(match_operand:SI 2 "memory_operand" "")
17308            (const_int 0)]))
17309    (match_scratch:SI 3 "r")]
17310   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17311   [(set (match_dup 3) (match_dup 2))
17312    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17313   "")
17314
17315 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17316 ;; Don't split NOTs with a displacement operand, because resulting XOR
17317 ;; will not be pairable anyway.
17318 ;;
17319 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17320 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17321 ;; so this split helps here as well.
17322 ;;
17323 ;; Note: Can't do this as a regular split because we can't get proper
17324 ;; lifetime information then.
17325
17326 (define_peephole2
17327   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17328         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17329   "optimize_insn_for_speed_p ()
17330    && ((TARGET_NOT_UNPAIRABLE
17331         && (!MEM_P (operands[0])
17332             || !memory_displacement_operand (operands[0], SImode)))
17333        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17334    && peep2_regno_dead_p (0, FLAGS_REG)"
17335   [(parallel [(set (match_dup 0)
17336                    (xor:SI (match_dup 1) (const_int -1)))
17337               (clobber (reg:CC FLAGS_REG))])]
17338   "")
17339
17340 (define_peephole2
17341   [(set (match_operand:HI 0 "nonimmediate_operand" "")
17342         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17343   "optimize_insn_for_speed_p ()
17344    && ((TARGET_NOT_UNPAIRABLE
17345         && (!MEM_P (operands[0])
17346             || !memory_displacement_operand (operands[0], HImode)))
17347        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17348    && peep2_regno_dead_p (0, FLAGS_REG)"
17349   [(parallel [(set (match_dup 0)
17350                    (xor:HI (match_dup 1) (const_int -1)))
17351               (clobber (reg:CC FLAGS_REG))])]
17352   "")
17353
17354 (define_peephole2
17355   [(set (match_operand:QI 0 "nonimmediate_operand" "")
17356         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17357   "optimize_insn_for_speed_p ()
17358    && ((TARGET_NOT_UNPAIRABLE
17359         && (!MEM_P (operands[0])
17360             || !memory_displacement_operand (operands[0], QImode)))
17361        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17362    && peep2_regno_dead_p (0, FLAGS_REG)"
17363   [(parallel [(set (match_dup 0)
17364                    (xor:QI (match_dup 1) (const_int -1)))
17365               (clobber (reg:CC FLAGS_REG))])]
17366   "")
17367
17368 ;; Non pairable "test imm, reg" instructions can be translated to
17369 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17370 ;; byte opcode instead of two, have a short form for byte operands),
17371 ;; so do it for other CPUs as well.  Given that the value was dead,
17372 ;; this should not create any new dependencies.  Pass on the sub-word
17373 ;; versions if we're concerned about partial register stalls.
17374
17375 (define_peephole2
17376   [(set (match_operand 0 "flags_reg_operand" "")
17377         (match_operator 1 "compare_operator"
17378           [(and:SI (match_operand:SI 2 "register_operand" "")
17379                    (match_operand:SI 3 "immediate_operand" ""))
17380            (const_int 0)]))]
17381   "ix86_match_ccmode (insn, CCNOmode)
17382    && (true_regnum (operands[2]) != AX_REG
17383        || satisfies_constraint_K (operands[3]))
17384    && peep2_reg_dead_p (1, operands[2])"
17385   [(parallel
17386      [(set (match_dup 0)
17387            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17388                             (const_int 0)]))
17389       (set (match_dup 2)
17390            (and:SI (match_dup 2) (match_dup 3)))])]
17391   "")
17392
17393 ;; We don't need to handle HImode case, because it will be promoted to SImode
17394 ;; on ! TARGET_PARTIAL_REG_STALL
17395
17396 (define_peephole2
17397   [(set (match_operand 0 "flags_reg_operand" "")
17398         (match_operator 1 "compare_operator"
17399           [(and:QI (match_operand:QI 2 "register_operand" "")
17400                    (match_operand:QI 3 "immediate_operand" ""))
17401            (const_int 0)]))]
17402   "! TARGET_PARTIAL_REG_STALL
17403    && ix86_match_ccmode (insn, CCNOmode)
17404    && true_regnum (operands[2]) != AX_REG
17405    && peep2_reg_dead_p (1, operands[2])"
17406   [(parallel
17407      [(set (match_dup 0)
17408            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17409                             (const_int 0)]))
17410       (set (match_dup 2)
17411            (and:QI (match_dup 2) (match_dup 3)))])]
17412   "")
17413
17414 (define_peephole2
17415   [(set (match_operand 0 "flags_reg_operand" "")
17416         (match_operator 1 "compare_operator"
17417           [(and:SI
17418              (zero_extract:SI
17419                (match_operand 2 "ext_register_operand" "")
17420                (const_int 8)
17421                (const_int 8))
17422              (match_operand 3 "const_int_operand" ""))
17423            (const_int 0)]))]
17424   "! TARGET_PARTIAL_REG_STALL
17425    && ix86_match_ccmode (insn, CCNOmode)
17426    && true_regnum (operands[2]) != AX_REG
17427    && peep2_reg_dead_p (1, operands[2])"
17428   [(parallel [(set (match_dup 0)
17429                    (match_op_dup 1
17430                      [(and:SI
17431                         (zero_extract:SI
17432                           (match_dup 2)
17433                           (const_int 8)
17434                           (const_int 8))
17435                         (match_dup 3))
17436                       (const_int 0)]))
17437               (set (zero_extract:SI (match_dup 2)
17438                                     (const_int 8)
17439                                     (const_int 8))
17440                    (and:SI
17441                      (zero_extract:SI
17442                        (match_dup 2)
17443                        (const_int 8)
17444                        (const_int 8))
17445                      (match_dup 3)))])]
17446   "")
17447
17448 ;; Don't do logical operations with memory inputs.
17449 (define_peephole2
17450   [(match_scratch:SI 2 "r")
17451    (parallel [(set (match_operand:SI 0 "register_operand" "")
17452                    (match_operator:SI 3 "arith_or_logical_operator"
17453                      [(match_dup 0)
17454                       (match_operand:SI 1 "memory_operand" "")]))
17455               (clobber (reg:CC FLAGS_REG))])]
17456   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17457   [(set (match_dup 2) (match_dup 1))
17458    (parallel [(set (match_dup 0)
17459                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17460               (clobber (reg:CC FLAGS_REG))])]
17461   "")
17462
17463 (define_peephole2
17464   [(match_scratch:SI 2 "r")
17465    (parallel [(set (match_operand:SI 0 "register_operand" "")
17466                    (match_operator:SI 3 "arith_or_logical_operator"
17467                      [(match_operand:SI 1 "memory_operand" "")
17468                       (match_dup 0)]))
17469               (clobber (reg:CC FLAGS_REG))])]
17470   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17471   [(set (match_dup 2) (match_dup 1))
17472    (parallel [(set (match_dup 0)
17473                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17474               (clobber (reg:CC FLAGS_REG))])]
17475   "")
17476
17477 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17478 ;; refers to the destination of the load!
17479
17480 (define_peephole2
17481   [(set (match_operand:SI 0 "register_operand" "")
17482         (match_operand:SI 1 "register_operand" ""))
17483    (parallel [(set (match_dup 0)
17484                    (match_operator:SI 3 "commutative_operator"
17485                      [(match_dup 0)
17486                       (match_operand:SI 2 "memory_operand" "")]))
17487               (clobber (reg:CC FLAGS_REG))])]
17488   "REGNO (operands[0]) != REGNO (operands[1])
17489    && GENERAL_REGNO_P (REGNO (operands[0]))
17490    && GENERAL_REGNO_P (REGNO (operands[1]))"
17491   [(set (match_dup 0) (match_dup 4))
17492    (parallel [(set (match_dup 0)
17493                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17494               (clobber (reg:CC FLAGS_REG))])]
17495   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17496
17497 (define_peephole2
17498   [(set (match_operand 0 "register_operand" "")
17499         (match_operand 1 "register_operand" ""))
17500    (set (match_dup 0)
17501                    (match_operator 3 "commutative_operator"
17502                      [(match_dup 0)
17503                       (match_operand 2 "memory_operand" "")]))]
17504   "REGNO (operands[0]) != REGNO (operands[1])
17505    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17506        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17507   [(set (match_dup 0) (match_dup 2))
17508    (set (match_dup 0)
17509         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17510   "")
17511
17512 ; Don't do logical operations with memory outputs
17513 ;
17514 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17515 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17516 ; the same decoder scheduling characteristics as the original.
17517
17518 (define_peephole2
17519   [(match_scratch:SI 2 "r")
17520    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17521                    (match_operator:SI 3 "arith_or_logical_operator"
17522                      [(match_dup 0)
17523                       (match_operand:SI 1 "nonmemory_operand" "")]))
17524               (clobber (reg:CC FLAGS_REG))])]
17525   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17526    /* Do not split stack checking probes.  */
17527    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17528   [(set (match_dup 2) (match_dup 0))
17529    (parallel [(set (match_dup 2)
17530                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17531               (clobber (reg:CC FLAGS_REG))])
17532    (set (match_dup 0) (match_dup 2))]
17533   "")
17534
17535 (define_peephole2
17536   [(match_scratch:SI 2 "r")
17537    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17538                    (match_operator:SI 3 "arith_or_logical_operator"
17539                      [(match_operand:SI 1 "nonmemory_operand" "")
17540                       (match_dup 0)]))
17541               (clobber (reg:CC FLAGS_REG))])]
17542   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17543    /* Do not split stack checking probes.  */
17544    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17545   [(set (match_dup 2) (match_dup 0))
17546    (parallel [(set (match_dup 2)
17547                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17548               (clobber (reg:CC FLAGS_REG))])
17549    (set (match_dup 0) (match_dup 2))]
17550   "")
17551
17552 ;; Attempt to always use XOR for zeroing registers.
17553 (define_peephole2
17554   [(set (match_operand 0 "register_operand" "")
17555         (match_operand 1 "const0_operand" ""))]
17556   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17557    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17558    && GENERAL_REG_P (operands[0])
17559    && peep2_regno_dead_p (0, FLAGS_REG)"
17560   [(parallel [(set (match_dup 0) (const_int 0))
17561               (clobber (reg:CC FLAGS_REG))])]
17562 {
17563   operands[0] = gen_lowpart (word_mode, operands[0]);
17564 })
17565
17566 (define_peephole2
17567   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17568         (const_int 0))]
17569   "(GET_MODE (operands[0]) == QImode
17570     || GET_MODE (operands[0]) == HImode)
17571    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17572    && peep2_regno_dead_p (0, FLAGS_REG)"
17573   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17574               (clobber (reg:CC FLAGS_REG))])])
17575
17576 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17577 (define_peephole2
17578   [(set (match_operand 0 "register_operand" "")
17579         (const_int -1))]
17580   "(GET_MODE (operands[0]) == HImode
17581     || GET_MODE (operands[0]) == SImode
17582     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17583    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17584    && peep2_regno_dead_p (0, FLAGS_REG)"
17585   [(parallel [(set (match_dup 0) (const_int -1))
17586               (clobber (reg:CC FLAGS_REG))])]
17587   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17588                               operands[0]);")
17589
17590 ;; Attempt to convert simple leas to adds. These can be created by
17591 ;; move expanders.
17592 (define_peephole2
17593   [(set (match_operand:SI 0 "register_operand" "")
17594         (plus:SI (match_dup 0)
17595                  (match_operand:SI 1 "nonmemory_operand" "")))]
17596   "peep2_regno_dead_p (0, FLAGS_REG)"
17597   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17598               (clobber (reg:CC FLAGS_REG))])]
17599   "")
17600
17601 (define_peephole2
17602   [(set (match_operand:SI 0 "register_operand" "")
17603         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17604                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17605   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17606   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17607               (clobber (reg:CC FLAGS_REG))])]
17608   "operands[2] = gen_lowpart (SImode, operands[2]);")
17609
17610 (define_peephole2
17611   [(set (match_operand:DI 0 "register_operand" "")
17612         (plus:DI (match_dup 0)
17613                  (match_operand:DI 1 "x86_64_general_operand" "")))]
17614   "peep2_regno_dead_p (0, FLAGS_REG)"
17615   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17616               (clobber (reg:CC FLAGS_REG))])]
17617   "")
17618
17619 (define_peephole2
17620   [(set (match_operand:SI 0 "register_operand" "")
17621         (mult:SI (match_dup 0)
17622                  (match_operand:SI 1 "const_int_operand" "")))]
17623   "exact_log2 (INTVAL (operands[1])) >= 0
17624    && peep2_regno_dead_p (0, FLAGS_REG)"
17625   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17626               (clobber (reg:CC FLAGS_REG))])]
17627   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17628
17629 (define_peephole2
17630   [(set (match_operand:DI 0 "register_operand" "")
17631         (mult:DI (match_dup 0)
17632                  (match_operand:DI 1 "const_int_operand" "")))]
17633   "exact_log2 (INTVAL (operands[1])) >= 0
17634    && peep2_regno_dead_p (0, FLAGS_REG)"
17635   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17636               (clobber (reg:CC FLAGS_REG))])]
17637   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17638
17639 (define_peephole2
17640   [(set (match_operand:SI 0 "register_operand" "")
17641         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17642                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17643   "exact_log2 (INTVAL (operands[2])) >= 0
17644    && REGNO (operands[0]) == REGNO (operands[1])
17645    && peep2_regno_dead_p (0, FLAGS_REG)"
17646   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17647               (clobber (reg:CC FLAGS_REG))])]
17648   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17649
17650 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17651 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17652 ;; many CPUs it is also faster, since special hardware to avoid esp
17653 ;; dependencies is present.
17654
17655 ;; While some of these conversions may be done using splitters, we use peepholes
17656 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17657
17658 ;; Convert prologue esp subtractions to push.
17659 ;; We need register to push.  In order to keep verify_flow_info happy we have
17660 ;; two choices
17661 ;; - use scratch and clobber it in order to avoid dependencies
17662 ;; - use already live register
17663 ;; We can't use the second way right now, since there is no reliable way how to
17664 ;; verify that given register is live.  First choice will also most likely in
17665 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17666 ;; call clobbered registers are dead.  We may want to use base pointer as an
17667 ;; alternative when no register is available later.
17668
17669 (define_peephole2
17670   [(match_scratch:SI 0 "r")
17671    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17672               (clobber (reg:CC FLAGS_REG))
17673               (clobber (mem:BLK (scratch)))])]
17674   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17675   [(clobber (match_dup 0))
17676    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17677               (clobber (mem:BLK (scratch)))])])
17678
17679 (define_peephole2
17680   [(match_scratch:SI 0 "r")
17681    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17682               (clobber (reg:CC FLAGS_REG))
17683               (clobber (mem:BLK (scratch)))])]
17684   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17685   [(clobber (match_dup 0))
17686    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17687    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17688               (clobber (mem:BLK (scratch)))])])
17689
17690 ;; Convert esp subtractions to push.
17691 (define_peephole2
17692   [(match_scratch:SI 0 "r")
17693    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17694               (clobber (reg:CC FLAGS_REG))])]
17695   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17696   [(clobber (match_dup 0))
17697    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17698
17699 (define_peephole2
17700   [(match_scratch:SI 0 "r")
17701    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17702               (clobber (reg:CC FLAGS_REG))])]
17703   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17704   [(clobber (match_dup 0))
17705    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17706    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17707
17708 ;; Convert epilogue deallocator to pop.
17709 (define_peephole2
17710   [(match_scratch:SI 0 "r")
17711    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17712               (clobber (reg:CC FLAGS_REG))
17713               (clobber (mem:BLK (scratch)))])]
17714   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17715   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17716               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17717               (clobber (mem:BLK (scratch)))])]
17718   "")
17719
17720 ;; Two pops case is tricky, since pop causes dependency on destination register.
17721 ;; We use two registers if available.
17722 (define_peephole2
17723   [(match_scratch:SI 0 "r")
17724    (match_scratch:SI 1 "r")
17725    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17726               (clobber (reg:CC FLAGS_REG))
17727               (clobber (mem:BLK (scratch)))])]
17728   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17729   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17730               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17731               (clobber (mem:BLK (scratch)))])
17732    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17733               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17734   "")
17735
17736 (define_peephole2
17737   [(match_scratch:SI 0 "r")
17738    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17739               (clobber (reg:CC FLAGS_REG))
17740               (clobber (mem:BLK (scratch)))])]
17741   "optimize_insn_for_size_p ()"
17742   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17743               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17744               (clobber (mem:BLK (scratch)))])
17745    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17746               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17747   "")
17748
17749 ;; Convert esp additions to pop.
17750 (define_peephole2
17751   [(match_scratch:SI 0 "r")
17752    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17753               (clobber (reg:CC FLAGS_REG))])]
17754   ""
17755   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17756               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17757   "")
17758
17759 ;; Two pops case is tricky, since pop causes dependency on destination register.
17760 ;; We use two registers if available.
17761 (define_peephole2
17762   [(match_scratch:SI 0 "r")
17763    (match_scratch:SI 1 "r")
17764    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17765               (clobber (reg:CC FLAGS_REG))])]
17766   ""
17767   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17768               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17769    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17770               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17771   "")
17772
17773 (define_peephole2
17774   [(match_scratch:SI 0 "r")
17775    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17776               (clobber (reg:CC FLAGS_REG))])]
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    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17781               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17782   "")
17783 \f
17784 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17785 ;; required and register dies.  Similarly for 128 to -128.
17786 (define_peephole2
17787   [(set (match_operand 0 "flags_reg_operand" "")
17788         (match_operator 1 "compare_operator"
17789           [(match_operand 2 "register_operand" "")
17790            (match_operand 3 "const_int_operand" "")]))]
17791   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17792      && incdec_operand (operands[3], GET_MODE (operands[3])))
17793     || (!TARGET_FUSE_CMP_AND_BRANCH
17794         && INTVAL (operands[3]) == 128))
17795    && ix86_match_ccmode (insn, CCGCmode)
17796    && peep2_reg_dead_p (1, operands[2])"
17797   [(parallel [(set (match_dup 0)
17798                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17799               (clobber (match_dup 2))])]
17800   "")
17801 \f
17802 (define_peephole2
17803   [(match_scratch:DI 0 "r")
17804    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17805               (clobber (reg:CC FLAGS_REG))
17806               (clobber (mem:BLK (scratch)))])]
17807   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17808   [(clobber (match_dup 0))
17809    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17810               (clobber (mem:BLK (scratch)))])])
17811
17812 (define_peephole2
17813   [(match_scratch:DI 0 "r")
17814    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17815               (clobber (reg:CC FLAGS_REG))
17816               (clobber (mem:BLK (scratch)))])]
17817   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17818   [(clobber (match_dup 0))
17819    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17820    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17821               (clobber (mem:BLK (scratch)))])])
17822
17823 ;; Convert esp subtractions to push.
17824 (define_peephole2
17825   [(match_scratch:DI 0 "r")
17826    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17827               (clobber (reg:CC FLAGS_REG))])]
17828   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17829   [(clobber (match_dup 0))
17830    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17831
17832 (define_peephole2
17833   [(match_scratch:DI 0 "r")
17834    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17835               (clobber (reg:CC FLAGS_REG))])]
17836   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17837   [(clobber (match_dup 0))
17838    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17839    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17840
17841 ;; Convert epilogue deallocator to pop.
17842 (define_peephole2
17843   [(match_scratch:DI 0 "r")
17844    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17845               (clobber (reg:CC FLAGS_REG))
17846               (clobber (mem:BLK (scratch)))])]
17847   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17848   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17849               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17850               (clobber (mem:BLK (scratch)))])]
17851   "")
17852
17853 ;; Two pops case is tricky, since pop causes dependency on destination register.
17854 ;; We use two registers if available.
17855 (define_peephole2
17856   [(match_scratch:DI 0 "r")
17857    (match_scratch:DI 1 "r")
17858    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17859               (clobber (reg:CC FLAGS_REG))
17860               (clobber (mem:BLK (scratch)))])]
17861   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17862   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17863               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17864               (clobber (mem:BLK (scratch)))])
17865    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17866               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17867   "")
17868
17869 (define_peephole2
17870   [(match_scratch:DI 0 "r")
17871    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17872               (clobber (reg:CC FLAGS_REG))
17873               (clobber (mem:BLK (scratch)))])]
17874   "optimize_insn_for_size_p ()"
17875   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17876               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17877               (clobber (mem:BLK (scratch)))])
17878    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17879               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17880   "")
17881
17882 ;; Convert esp additions to pop.
17883 (define_peephole2
17884   [(match_scratch:DI 0 "r")
17885    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17886               (clobber (reg:CC FLAGS_REG))])]
17887   ""
17888   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17889               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17890   "")
17891
17892 ;; Two pops case is tricky, since pop causes dependency on destination register.
17893 ;; We use two registers if available.
17894 (define_peephole2
17895   [(match_scratch:DI 0 "r")
17896    (match_scratch:DI 1 "r")
17897    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17898               (clobber (reg:CC FLAGS_REG))])]
17899   ""
17900   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17901               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17902    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17903               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17904   "")
17905
17906 (define_peephole2
17907   [(match_scratch:DI 0 "r")
17908    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17909               (clobber (reg:CC FLAGS_REG))])]
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    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17914               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17915   "")
17916 \f
17917 ;; Convert imul by three, five and nine into lea
17918 (define_peephole2
17919   [(parallel
17920     [(set (match_operand:SI 0 "register_operand" "")
17921           (mult:SI (match_operand:SI 1 "register_operand" "")
17922                    (match_operand:SI 2 "const_int_operand" "")))
17923      (clobber (reg:CC FLAGS_REG))])]
17924   "INTVAL (operands[2]) == 3
17925    || INTVAL (operands[2]) == 5
17926    || INTVAL (operands[2]) == 9"
17927   [(set (match_dup 0)
17928         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17929                  (match_dup 1)))]
17930   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17931
17932 (define_peephole2
17933   [(parallel
17934     [(set (match_operand:SI 0 "register_operand" "")
17935           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17936                    (match_operand:SI 2 "const_int_operand" "")))
17937      (clobber (reg:CC FLAGS_REG))])]
17938   "optimize_insn_for_speed_p ()
17939    && (INTVAL (operands[2]) == 3
17940        || INTVAL (operands[2]) == 5
17941        || INTVAL (operands[2]) == 9)"
17942   [(set (match_dup 0) (match_dup 1))
17943    (set (match_dup 0)
17944         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17945                  (match_dup 0)))]
17946   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17947
17948 (define_peephole2
17949   [(parallel
17950     [(set (match_operand:DI 0 "register_operand" "")
17951           (mult:DI (match_operand:DI 1 "register_operand" "")
17952                    (match_operand:DI 2 "const_int_operand" "")))
17953      (clobber (reg:CC FLAGS_REG))])]
17954   "TARGET_64BIT
17955    && (INTVAL (operands[2]) == 3
17956        || INTVAL (operands[2]) == 5
17957        || INTVAL (operands[2]) == 9)"
17958   [(set (match_dup 0)
17959         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17960                  (match_dup 1)))]
17961   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17962
17963 (define_peephole2
17964   [(parallel
17965     [(set (match_operand:DI 0 "register_operand" "")
17966           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17967                    (match_operand:DI 2 "const_int_operand" "")))
17968      (clobber (reg:CC FLAGS_REG))])]
17969   "TARGET_64BIT
17970    && optimize_insn_for_speed_p ()
17971    && (INTVAL (operands[2]) == 3
17972        || INTVAL (operands[2]) == 5
17973        || INTVAL (operands[2]) == 9)"
17974   [(set (match_dup 0) (match_dup 1))
17975    (set (match_dup 0)
17976         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17977                  (match_dup 0)))]
17978   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17979
17980 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17981 ;; imul $32bit_imm, reg, reg is direct decoded.
17982 (define_peephole2
17983   [(match_scratch:DI 3 "r")
17984    (parallel [(set (match_operand:DI 0 "register_operand" "")
17985                    (mult:DI (match_operand:DI 1 "memory_operand" "")
17986                             (match_operand:DI 2 "immediate_operand" "")))
17987               (clobber (reg:CC FLAGS_REG))])]
17988   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17989    && !satisfies_constraint_K (operands[2])"
17990   [(set (match_dup 3) (match_dup 1))
17991    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17992               (clobber (reg:CC FLAGS_REG))])]
17993 "")
17994
17995 (define_peephole2
17996   [(match_scratch:SI 3 "r")
17997    (parallel [(set (match_operand:SI 0 "register_operand" "")
17998                    (mult:SI (match_operand:SI 1 "memory_operand" "")
17999                             (match_operand:SI 2 "immediate_operand" "")))
18000               (clobber (reg:CC FLAGS_REG))])]
18001   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18002    && !satisfies_constraint_K (operands[2])"
18003   [(set (match_dup 3) (match_dup 1))
18004    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18005               (clobber (reg:CC FLAGS_REG))])]
18006 "")
18007
18008 (define_peephole2
18009   [(match_scratch:SI 3 "r")
18010    (parallel [(set (match_operand:DI 0 "register_operand" "")
18011                    (zero_extend:DI
18012                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18013                               (match_operand:SI 2 "immediate_operand" ""))))
18014               (clobber (reg:CC FLAGS_REG))])]
18015   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18016    && !satisfies_constraint_K (operands[2])"
18017   [(set (match_dup 3) (match_dup 1))
18018    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18019               (clobber (reg:CC FLAGS_REG))])]
18020 "")
18021
18022 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18023 ;; Convert it into imul reg, reg
18024 ;; It would be better to force assembler to encode instruction using long
18025 ;; immediate, but there is apparently no way to do so.
18026 (define_peephole2
18027   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18028                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18029                             (match_operand:DI 2 "const_int_operand" "")))
18030               (clobber (reg:CC FLAGS_REG))])
18031    (match_scratch:DI 3 "r")]
18032   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18033    && satisfies_constraint_K (operands[2])"
18034   [(set (match_dup 3) (match_dup 2))
18035    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18036               (clobber (reg:CC FLAGS_REG))])]
18037 {
18038   if (!rtx_equal_p (operands[0], operands[1]))
18039     emit_move_insn (operands[0], operands[1]);
18040 })
18041
18042 (define_peephole2
18043   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18044                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18045                             (match_operand:SI 2 "const_int_operand" "")))
18046               (clobber (reg:CC FLAGS_REG))])
18047    (match_scratch:SI 3 "r")]
18048   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18049    && satisfies_constraint_K (operands[2])"
18050   [(set (match_dup 3) (match_dup 2))
18051    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18052               (clobber (reg:CC FLAGS_REG))])]
18053 {
18054   if (!rtx_equal_p (operands[0], operands[1]))
18055     emit_move_insn (operands[0], operands[1]);
18056 })
18057
18058 (define_peephole2
18059   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18060                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18061                             (match_operand:HI 2 "immediate_operand" "")))
18062               (clobber (reg:CC FLAGS_REG))])
18063    (match_scratch:HI 3 "r")]
18064   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
18065   [(set (match_dup 3) (match_dup 2))
18066    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18067               (clobber (reg:CC FLAGS_REG))])]
18068 {
18069   if (!rtx_equal_p (operands[0], operands[1]))
18070     emit_move_insn (operands[0], operands[1]);
18071 })
18072
18073 ;; After splitting up read-modify operations, array accesses with memory
18074 ;; operands might end up in form:
18075 ;;  sall    $2, %eax
18076 ;;  movl    4(%esp), %edx
18077 ;;  addl    %edx, %eax
18078 ;; instead of pre-splitting:
18079 ;;  sall    $2, %eax
18080 ;;  addl    4(%esp), %eax
18081 ;; Turn it into:
18082 ;;  movl    4(%esp), %edx
18083 ;;  leal    (%edx,%eax,4), %eax
18084
18085 (define_peephole2
18086   [(parallel [(set (match_operand 0 "register_operand" "")
18087                    (ashift (match_operand 1 "register_operand" "")
18088                            (match_operand 2 "const_int_operand" "")))
18089                (clobber (reg:CC FLAGS_REG))])
18090    (set (match_operand 3 "register_operand")
18091         (match_operand 4 "x86_64_general_operand" ""))
18092    (parallel [(set (match_operand 5 "register_operand" "")
18093                    (plus (match_operand 6 "register_operand" "")
18094                          (match_operand 7 "register_operand" "")))
18095                    (clobber (reg:CC FLAGS_REG))])]
18096   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
18097    /* Validate MODE for lea.  */
18098    && ((!TARGET_PARTIAL_REG_STALL
18099         && (GET_MODE (operands[0]) == QImode
18100             || GET_MODE (operands[0]) == HImode))
18101        || GET_MODE (operands[0]) == SImode
18102        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18103    /* We reorder load and the shift.  */
18104    && !rtx_equal_p (operands[1], operands[3])
18105    && !reg_overlap_mentioned_p (operands[0], operands[4])
18106    /* Last PLUS must consist of operand 0 and 3.  */
18107    && !rtx_equal_p (operands[0], operands[3])
18108    && (rtx_equal_p (operands[3], operands[6])
18109        || rtx_equal_p (operands[3], operands[7]))
18110    && (rtx_equal_p (operands[0], operands[6])
18111        || rtx_equal_p (operands[0], operands[7]))
18112    /* The intermediate operand 0 must die or be same as output.  */
18113    && (rtx_equal_p (operands[0], operands[5])
18114        || peep2_reg_dead_p (3, operands[0]))"
18115   [(set (match_dup 3) (match_dup 4))
18116    (set (match_dup 0) (match_dup 1))]
18117 {
18118   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
18119   int scale = 1 << INTVAL (operands[2]);
18120   rtx index = gen_lowpart (Pmode, operands[1]);
18121   rtx base = gen_lowpart (Pmode, operands[3]);
18122   rtx dest = gen_lowpart (mode, operands[5]);
18123
18124   operands[1] = gen_rtx_PLUS (Pmode, base,
18125                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
18126   if (mode != Pmode)
18127     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18128   operands[0] = dest;
18129 })
18130 \f
18131 ;; Call-value patterns last so that the wildcard operand does not
18132 ;; disrupt insn-recog's switch tables.
18133
18134 (define_insn "*call_value_pop_0"
18135   [(set (match_operand 0 "" "")
18136         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18137               (match_operand:SI 2 "" "")))
18138    (set (reg:SI SP_REG)
18139         (plus:SI (reg:SI SP_REG)
18140                  (match_operand:SI 3 "immediate_operand" "")))]
18141   "!TARGET_64BIT"
18142 {
18143   if (SIBLING_CALL_P (insn))
18144     return "jmp\t%P1";
18145   else
18146     return "call\t%P1";
18147 }
18148   [(set_attr "type" "callv")])
18149
18150 (define_insn "*call_value_pop_1"
18151   [(set (match_operand 0 "" "")
18152         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18153               (match_operand:SI 2 "" "")))
18154    (set (reg:SI SP_REG)
18155         (plus:SI (reg:SI SP_REG)
18156                  (match_operand:SI 3 "immediate_operand" "i")))]
18157   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18158 {
18159   if (constant_call_address_operand (operands[1], Pmode))
18160     return "call\t%P1";
18161   return "call\t%A1";
18162 }
18163   [(set_attr "type" "callv")])
18164
18165 (define_insn "*sibcall_value_pop_1"
18166   [(set (match_operand 0 "" "")
18167         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18168               (match_operand:SI 2 "" "")))
18169    (set (reg:SI SP_REG)
18170         (plus:SI (reg:SI SP_REG)
18171                  (match_operand:SI 3 "immediate_operand" "i,i")))]
18172   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18173   "@
18174    jmp\t%P1
18175    jmp\t%A1"
18176   [(set_attr "type" "callv")])
18177
18178 (define_insn "*call_value_0"
18179   [(set (match_operand 0 "" "")
18180         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18181               (match_operand:SI 2 "" "")))]
18182   "!TARGET_64BIT"
18183 {
18184   if (SIBLING_CALL_P (insn))
18185     return "jmp\t%P1";
18186   else
18187     return "call\t%P1";
18188 }
18189   [(set_attr "type" "callv")])
18190
18191 (define_insn "*call_value_0_rex64"
18192   [(set (match_operand 0 "" "")
18193         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18194               (match_operand:DI 2 "const_int_operand" "")))]
18195   "TARGET_64BIT"
18196 {
18197   if (SIBLING_CALL_P (insn))
18198     return "jmp\t%P1";
18199   else
18200     return "call\t%P1";
18201 }
18202   [(set_attr "type" "callv")])
18203
18204 (define_insn "*call_value_0_rex64_ms_sysv"
18205   [(set (match_operand 0 "" "")
18206         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18207               (match_operand:DI 2 "const_int_operand" "")))
18208    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18209    (clobber (reg:TI XMM6_REG))
18210    (clobber (reg:TI XMM7_REG))
18211    (clobber (reg:TI XMM8_REG))
18212    (clobber (reg:TI XMM9_REG))
18213    (clobber (reg:TI XMM10_REG))
18214    (clobber (reg:TI XMM11_REG))
18215    (clobber (reg:TI XMM12_REG))
18216    (clobber (reg:TI XMM13_REG))
18217    (clobber (reg:TI XMM14_REG))
18218    (clobber (reg:TI XMM15_REG))
18219    (clobber (reg:DI SI_REG))
18220    (clobber (reg:DI DI_REG))]
18221   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18222 {
18223   if (SIBLING_CALL_P (insn))
18224     return "jmp\t%P1";
18225   else
18226     return "call\t%P1";
18227 }
18228   [(set_attr "type" "callv")])
18229
18230 (define_insn "*call_value_1"
18231   [(set (match_operand 0 "" "")
18232         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18233               (match_operand:SI 2 "" "")))]
18234   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18235 {
18236   if (constant_call_address_operand (operands[1], Pmode))
18237     return "call\t%P1";
18238   return "call\t%A1";
18239 }
18240   [(set_attr "type" "callv")])
18241
18242 (define_insn "*sibcall_value_1"
18243   [(set (match_operand 0 "" "")
18244         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18245               (match_operand:SI 2 "" "")))]
18246   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18247   "@
18248    jmp\t%P1
18249    jmp\t%A1"
18250   [(set_attr "type" "callv")])
18251
18252 (define_insn "*call_value_1_rex64"
18253   [(set (match_operand 0 "" "")
18254         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18255               (match_operand:DI 2 "" "")))]
18256   "TARGET_64BIT && !SIBLING_CALL_P (insn)
18257    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
18258 {
18259   if (constant_call_address_operand (operands[1], Pmode))
18260     return "call\t%P1";
18261   return "call\t%A1";
18262 }
18263   [(set_attr "type" "callv")])
18264
18265 (define_insn "*call_value_1_rex64_ms_sysv"
18266   [(set (match_operand 0 "" "")
18267         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18268               (match_operand:DI 2 "" "")))
18269    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18270    (clobber (reg:TI XMM6_REG))
18271    (clobber (reg:TI XMM7_REG))
18272    (clobber (reg:TI XMM8_REG))
18273    (clobber (reg:TI XMM9_REG))
18274    (clobber (reg:TI XMM10_REG))
18275    (clobber (reg:TI XMM11_REG))
18276    (clobber (reg:TI XMM12_REG))
18277    (clobber (reg:TI XMM13_REG))
18278    (clobber (reg:TI XMM14_REG))
18279    (clobber (reg:TI XMM15_REG))
18280    (clobber (reg:DI SI_REG))
18281    (clobber (reg:DI DI_REG))]
18282   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18283 {
18284   if (constant_call_address_operand (operands[1], Pmode))
18285     return "call\t%P1";
18286   return "call\t%A1";
18287 }
18288   [(set_attr "type" "callv")])
18289
18290 (define_insn "*call_value_1_rex64_large"
18291   [(set (match_operand 0 "" "")
18292         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18293               (match_operand:DI 2 "" "")))]
18294   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18295   "call\t%A1"
18296   [(set_attr "type" "callv")])
18297
18298 (define_insn "*sibcall_value_1_rex64"
18299   [(set (match_operand 0 "" "")
18300         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18301               (match_operand:DI 2 "" "")))]
18302   "TARGET_64BIT && SIBLING_CALL_P (insn)"
18303   "@
18304    jmp\t%P1
18305    jmp\t%A1"
18306   [(set_attr "type" "callv")])
18307 \f
18308 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18309 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18310 ;; caught for use by garbage collectors and the like.  Using an insn that
18311 ;; maps to SIGILL makes it more likely the program will rightfully die.
18312 ;; Keeping with tradition, "6" is in honor of #UD.
18313 (define_insn "trap"
18314   [(trap_if (const_int 1) (const_int 6))]
18315   ""
18316   { return ASM_SHORT "0x0b0f"; }
18317   [(set_attr "length" "2")])
18318
18319 (define_expand "sse_prologue_save"
18320   [(parallel [(set (match_operand:BLK 0 "" "")
18321                    (unspec:BLK [(reg:DI XMM0_REG)
18322                                 (reg:DI XMM1_REG)
18323                                 (reg:DI XMM2_REG)
18324                                 (reg:DI XMM3_REG)
18325                                 (reg:DI XMM4_REG)
18326                                 (reg:DI XMM5_REG)
18327                                 (reg:DI XMM6_REG)
18328                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18329               (clobber (match_operand:DI 1 "register_operand" ""))
18330               (use (match_operand:DI 2 "immediate_operand" ""))
18331               (use (label_ref:DI (match_operand 3 "" "")))
18332               (clobber (match_operand:DI 4 "register_operand" ""))
18333               (use (match_dup 1))])]
18334   "TARGET_64BIT"
18335   "")
18336
18337 ;; Pre-reload version of prologue save.  Until after prologue generation we don't know
18338 ;; what the size of save instruction will be.
18339 ;; Operand 0+operand 6 is the memory save area
18340 ;; Operand 1 is number of registers to save (will get overwritten to operand 5)
18341 ;; Operand 2 is number of non-vaargs SSE arguments
18342 ;; Operand 3 is label starting the save block
18343 ;; Operand 4 is used for temporary computation of jump address
18344 (define_insn "*sse_prologue_save_insn1"
18345   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18346                           (match_operand:DI 6 "const_int_operand" "n")))
18347         (unspec:BLK [(reg:DI XMM0_REG)
18348                      (reg:DI XMM1_REG)
18349                      (reg:DI XMM2_REG)
18350                      (reg:DI XMM3_REG)
18351                      (reg:DI XMM4_REG)
18352                      (reg:DI XMM5_REG)
18353                      (reg:DI XMM6_REG)
18354                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18355    (clobber (match_operand:DI 1 "register_operand" "=r"))
18356    (use (match_operand:DI 2 "const_int_operand" "i"))
18357    (use (label_ref:DI (match_operand 3 "" "X")))
18358    (clobber (match_operand:DI 4 "register_operand" "=&r"))
18359    (use (match_operand:DI 5 "register_operand" "1"))]
18360   "TARGET_64BIT
18361    && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18362    && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
18363   "#"
18364   [(set_attr "type" "other")
18365    (set_attr "memory" "store")
18366    (set_attr "mode" "DI")])
18367
18368 ;; We know size of save instruction; expand the computation of jump address
18369 ;; in the jumptable.
18370 (define_split
18371   [(parallel [(set (match_operand:BLK 0 "" "")
18372                     (unspec:BLK [(reg:DI XMM0_REG)
18373                                  (reg:DI XMM1_REG)
18374                                  (reg:DI XMM2_REG)
18375                                  (reg:DI XMM3_REG)
18376                                  (reg:DI XMM4_REG)
18377                                  (reg:DI XMM5_REG)
18378                                  (reg:DI XMM6_REG)
18379                                  (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18380                (clobber (match_operand:DI 1 "register_operand" ""))
18381                (use (match_operand:DI 2 "const_int_operand" ""))
18382                (use (match_operand 3 "" ""))
18383                (clobber (match_operand:DI 4 "register_operand" ""))
18384                (use (match_operand:DI 5 "register_operand" ""))])]
18385   "reload_completed"
18386   [(parallel [(set (match_dup 0)
18387                    (unspec:BLK [(reg:DI XMM0_REG)
18388                                 (reg:DI XMM1_REG)
18389                                 (reg:DI XMM2_REG)
18390                                 (reg:DI XMM3_REG)
18391                                 (reg:DI XMM4_REG)
18392                                 (reg:DI XMM5_REG)
18393                                 (reg:DI XMM6_REG)
18394                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18395               (use (match_dup 1))
18396               (use (match_dup 2))
18397               (use (match_dup 3))
18398               (use (match_dup 5))])]
18399 {
18400   /* Movaps is 4 bytes, AVX and movsd is 5 bytes.  */
18401   int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
18402
18403   /* Compute address to jump to:
18404      label - eax*size + nnamed_sse_arguments*size. */
18405   if (size == 5)
18406     emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18407                             gen_rtx_PLUS
18408                               (Pmode,
18409                                gen_rtx_MULT (Pmode, operands[1],
18410                                              GEN_INT (4)),
18411                                operands[1])));
18412   else  if (size == 4)
18413     emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18414                             gen_rtx_MULT (Pmode, operands[1],
18415                                           GEN_INT (4))));
18416   else
18417     gcc_unreachable ();
18418   if (INTVAL (operands[2]))
18419     emit_move_insn
18420       (operands[1],
18421        gen_rtx_CONST (DImode,
18422                       gen_rtx_PLUS (DImode,
18423                                     operands[3],
18424                                     GEN_INT (INTVAL (operands[2])
18425                                              * size))));
18426   else
18427     emit_move_insn (operands[1], operands[3]);
18428   emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
18429   operands[5] = GEN_INT (size);
18430 })
18431
18432 (define_insn "sse_prologue_save_insn"
18433   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18434                           (match_operand:DI 4 "const_int_operand" "n")))
18435         (unspec:BLK [(reg:DI XMM0_REG)
18436                      (reg:DI XMM1_REG)
18437                      (reg:DI XMM2_REG)
18438                      (reg:DI XMM3_REG)
18439                      (reg:DI XMM4_REG)
18440                      (reg:DI XMM5_REG)
18441                      (reg:DI XMM6_REG)
18442                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18443    (use (match_operand:DI 1 "register_operand" "r"))
18444    (use (match_operand:DI 2 "const_int_operand" "i"))
18445    (use (label_ref:DI (match_operand 3 "" "X")))
18446    (use (match_operand:DI 5 "const_int_operand" "i"))]
18447   "TARGET_64BIT
18448    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18449    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18450 {
18451   int i;
18452   operands[0] = gen_rtx_MEM (Pmode,
18453                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18454   /* VEX instruction with a REX prefix will #UD.  */
18455   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18456     gcc_unreachable ();
18457
18458   output_asm_insn ("jmp\t%A1", operands);
18459   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18460     {
18461       operands[4] = adjust_address (operands[0], DImode, i*16);
18462       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18463       PUT_MODE (operands[4], TImode);
18464       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18465         output_asm_insn ("rex", operands);
18466       if (crtl->stack_alignment_needed < 128)
18467         output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
18468       else
18469         output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18470     }
18471   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18472                                      CODE_LABEL_NUMBER (operands[3]));
18473   return "";
18474 }
18475   [(set_attr "type" "other")
18476    (set_attr "length_immediate" "0")
18477    (set_attr "length_address" "0")
18478    ;; 2 bytes for jump and opernds[4] bytes for each save.
18479    (set (attr "length")
18480      (plus (const_int 2)
18481            (mult (symbol_ref ("INTVAL (operands[5])"))
18482                  (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
18483    (set_attr "memory" "store")
18484    (set_attr "modrm" "0")
18485    (set_attr "prefix" "maybe_vex")
18486    (set_attr "mode" "DI")])
18487
18488 (define_expand "prefetch"
18489   [(prefetch (match_operand 0 "address_operand" "")
18490              (match_operand:SI 1 "const_int_operand" "")
18491              (match_operand:SI 2 "const_int_operand" ""))]
18492   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18493 {
18494   int rw = INTVAL (operands[1]);
18495   int locality = INTVAL (operands[2]);
18496
18497   gcc_assert (rw == 0 || rw == 1);
18498   gcc_assert (locality >= 0 && locality <= 3);
18499   gcc_assert (GET_MODE (operands[0]) == Pmode
18500               || GET_MODE (operands[0]) == VOIDmode);
18501
18502   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18503      supported by SSE counterpart or the SSE prefetch is not available
18504      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18505      of locality.  */
18506   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18507     operands[2] = GEN_INT (3);
18508   else
18509     operands[1] = const0_rtx;
18510 })
18511
18512 (define_insn "*prefetch_sse"
18513   [(prefetch (match_operand:SI 0 "address_operand" "p")
18514              (const_int 0)
18515              (match_operand:SI 1 "const_int_operand" ""))]
18516   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18517 {
18518   static const char * const patterns[4] = {
18519    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18520   };
18521
18522   int locality = INTVAL (operands[1]);
18523   gcc_assert (locality >= 0 && locality <= 3);
18524
18525   return patterns[locality];
18526 }
18527   [(set_attr "type" "sse")
18528    (set_attr "atom_sse_attr" "prefetch")
18529    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18530    (set_attr "memory" "none")])
18531
18532 (define_insn "*prefetch_sse_rex"
18533   [(prefetch (match_operand:DI 0 "address_operand" "p")
18534              (const_int 0)
18535              (match_operand:SI 1 "const_int_operand" ""))]
18536   "TARGET_PREFETCH_SSE && TARGET_64BIT"
18537 {
18538   static const char * const patterns[4] = {
18539    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18540   };
18541
18542   int locality = INTVAL (operands[1]);
18543   gcc_assert (locality >= 0 && locality <= 3);
18544
18545   return patterns[locality];
18546 }
18547   [(set_attr "type" "sse")
18548    (set_attr "atom_sse_attr" "prefetch")
18549    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18550    (set_attr "memory" "none")])
18551
18552 (define_insn "*prefetch_3dnow"
18553   [(prefetch (match_operand:SI 0 "address_operand" "p")
18554              (match_operand:SI 1 "const_int_operand" "n")
18555              (const_int 3))]
18556   "TARGET_3DNOW && !TARGET_64BIT"
18557 {
18558   if (INTVAL (operands[1]) == 0)
18559     return "prefetch\t%a0";
18560   else
18561     return "prefetchw\t%a0";
18562 }
18563   [(set_attr "type" "mmx")
18564    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18565    (set_attr "memory" "none")])
18566
18567 (define_insn "*prefetch_3dnow_rex"
18568   [(prefetch (match_operand:DI 0 "address_operand" "p")
18569              (match_operand:SI 1 "const_int_operand" "n")
18570              (const_int 3))]
18571   "TARGET_3DNOW && TARGET_64BIT"
18572 {
18573   if (INTVAL (operands[1]) == 0)
18574     return "prefetch\t%a0";
18575   else
18576     return "prefetchw\t%a0";
18577 }
18578   [(set_attr "type" "mmx")
18579    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18580    (set_attr "memory" "none")])
18581
18582 (define_expand "stack_protect_set"
18583   [(match_operand 0 "memory_operand" "")
18584    (match_operand 1 "memory_operand" "")]
18585   ""
18586 {
18587 #ifdef TARGET_THREAD_SSP_OFFSET
18588   if (TARGET_64BIT)
18589     emit_insn (gen_stack_tls_protect_set_di (operands[0],
18590                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18591   else
18592     emit_insn (gen_stack_tls_protect_set_si (operands[0],
18593                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18594 #else
18595   if (TARGET_64BIT)
18596     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18597   else
18598     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18599 #endif
18600   DONE;
18601 })
18602
18603 (define_insn "stack_protect_set_si"
18604   [(set (match_operand:SI 0 "memory_operand" "=m")
18605         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18606    (set (match_scratch:SI 2 "=&r") (const_int 0))
18607    (clobber (reg:CC FLAGS_REG))]
18608   ""
18609   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18610   [(set_attr "type" "multi")])
18611
18612 (define_insn "stack_protect_set_di"
18613   [(set (match_operand:DI 0 "memory_operand" "=m")
18614         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18615    (set (match_scratch:DI 2 "=&r") (const_int 0))
18616    (clobber (reg:CC FLAGS_REG))]
18617   "TARGET_64BIT"
18618   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18619   [(set_attr "type" "multi")])
18620
18621 (define_insn "stack_tls_protect_set_si"
18622   [(set (match_operand:SI 0 "memory_operand" "=m")
18623         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18624    (set (match_scratch:SI 2 "=&r") (const_int 0))
18625    (clobber (reg:CC FLAGS_REG))]
18626   ""
18627   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18628   [(set_attr "type" "multi")])
18629
18630 (define_insn "stack_tls_protect_set_di"
18631   [(set (match_operand:DI 0 "memory_operand" "=m")
18632         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18633    (set (match_scratch:DI 2 "=&r") (const_int 0))
18634    (clobber (reg:CC FLAGS_REG))]
18635   "TARGET_64BIT"
18636   {
18637      /* The kernel uses a different segment register for performance reasons; a
18638         system call would not have to trash the userspace segment register,
18639         which would be expensive */
18640      if (ix86_cmodel != CM_KERNEL)
18641         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18642      else
18643         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18644   }
18645   [(set_attr "type" "multi")])
18646
18647 (define_expand "stack_protect_test"
18648   [(match_operand 0 "memory_operand" "")
18649    (match_operand 1 "memory_operand" "")
18650    (match_operand 2 "" "")]
18651   ""
18652 {
18653   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18654
18655 #ifdef TARGET_THREAD_SSP_OFFSET
18656   if (TARGET_64BIT)
18657     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18658                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18659   else
18660     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18661                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18662 #else
18663   if (TARGET_64BIT)
18664     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18665   else
18666     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18667 #endif
18668
18669   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18670                                   flags, const0_rtx, operands[2]));
18671   DONE;
18672 })
18673
18674 (define_insn "stack_protect_test_si"
18675   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18676         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18677                      (match_operand:SI 2 "memory_operand" "m")]
18678                     UNSPEC_SP_TEST))
18679    (clobber (match_scratch:SI 3 "=&r"))]
18680   ""
18681   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18682   [(set_attr "type" "multi")])
18683
18684 (define_insn "stack_protect_test_di"
18685   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18686         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18687                      (match_operand:DI 2 "memory_operand" "m")]
18688                     UNSPEC_SP_TEST))
18689    (clobber (match_scratch:DI 3 "=&r"))]
18690   "TARGET_64BIT"
18691   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18692   [(set_attr "type" "multi")])
18693
18694 (define_insn "stack_tls_protect_test_si"
18695   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18696         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18697                      (match_operand:SI 2 "const_int_operand" "i")]
18698                     UNSPEC_SP_TLS_TEST))
18699    (clobber (match_scratch:SI 3 "=r"))]
18700   ""
18701   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18702   [(set_attr "type" "multi")])
18703
18704 (define_insn "stack_tls_protect_test_di"
18705   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18706         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18707                      (match_operand:DI 2 "const_int_operand" "i")]
18708                     UNSPEC_SP_TLS_TEST))
18709    (clobber (match_scratch:DI 3 "=r"))]
18710   "TARGET_64BIT"
18711   {
18712      /* The kernel uses a different segment register for performance reasons; a
18713         system call would not have to trash the userspace segment register,
18714         which would be expensive */
18715      if (ix86_cmodel != CM_KERNEL)
18716         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18717      else
18718         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18719   }
18720   [(set_attr "type" "multi")])
18721
18722 (define_insn "sse4_2_crc32<mode>"
18723   [(set (match_operand:SI 0 "register_operand" "=r")
18724         (unspec:SI
18725           [(match_operand:SI 1 "register_operand" "0")
18726            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18727           UNSPEC_CRC32))]
18728   "TARGET_SSE4_2 || TARGET_CRC32"
18729   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18730   [(set_attr "type" "sselog1")
18731    (set_attr "prefix_rep" "1")
18732    (set_attr "prefix_extra" "1")
18733    (set (attr "prefix_data16")
18734      (if_then_else (match_operand:HI 2 "" "")
18735        (const_string "1")
18736        (const_string "*")))
18737    (set (attr "prefix_rex")
18738      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18739        (const_string "1")
18740        (const_string "*")))
18741    (set_attr "mode" "SI")])
18742
18743 (define_insn "sse4_2_crc32di"
18744   [(set (match_operand:DI 0 "register_operand" "=r")
18745         (unspec:DI
18746           [(match_operand:DI 1 "register_operand" "0")
18747            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18748           UNSPEC_CRC32))]
18749   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18750   "crc32{q}\t{%2, %0|%0, %2}"
18751   [(set_attr "type" "sselog1")
18752    (set_attr "prefix_rep" "1")
18753    (set_attr "prefix_extra" "1")
18754    (set_attr "mode" "DI")])
18755
18756 (define_expand "rdpmc"
18757   [(match_operand:DI 0 "register_operand" "")
18758    (match_operand:SI 1 "register_operand" "")]
18759   ""
18760 {
18761   rtx reg = gen_reg_rtx (DImode);
18762   rtx si;
18763
18764   /* Force operand 1 into ECX.  */
18765   rtx ecx = gen_rtx_REG (SImode, CX_REG);
18766   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18767   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18768                                 UNSPECV_RDPMC);
18769
18770   if (TARGET_64BIT)
18771     {
18772       rtvec vec = rtvec_alloc (2);
18773       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18774       rtx upper = gen_reg_rtx (DImode);
18775       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18776                                         gen_rtvec (1, const0_rtx),
18777                                         UNSPECV_RDPMC);
18778       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18779       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18780       emit_insn (load);
18781       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18782                                    NULL, 1, OPTAB_DIRECT);
18783       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18784                                  OPTAB_DIRECT);
18785     }
18786   else
18787     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18788   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18789   DONE;
18790 })
18791
18792 (define_insn "*rdpmc"
18793   [(set (match_operand:DI 0 "register_operand" "=A")
18794         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18795                             UNSPECV_RDPMC))]
18796   "!TARGET_64BIT"
18797   "rdpmc"
18798   [(set_attr "type" "other")
18799    (set_attr "length" "2")])
18800
18801 (define_insn "*rdpmc_rex64"
18802   [(set (match_operand:DI 0 "register_operand" "=a")
18803         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18804                             UNSPECV_RDPMC))
18805   (set (match_operand:DI 1 "register_operand" "=d")
18806        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18807   "TARGET_64BIT"
18808   "rdpmc"
18809   [(set_attr "type" "other")
18810    (set_attr "length" "2")])
18811
18812 (define_expand "rdtsc"
18813   [(set (match_operand:DI 0 "register_operand" "")
18814         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18815   ""
18816 {
18817   if (TARGET_64BIT)
18818     {
18819       rtvec vec = rtvec_alloc (2);
18820       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18821       rtx upper = gen_reg_rtx (DImode);
18822       rtx lower = gen_reg_rtx (DImode);
18823       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18824                                          gen_rtvec (1, const0_rtx),
18825                                          UNSPECV_RDTSC);
18826       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18827       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18828       emit_insn (load);
18829       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18830                                    NULL, 1, OPTAB_DIRECT);
18831       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18832                                    OPTAB_DIRECT);
18833       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18834       DONE;
18835     }
18836 })
18837
18838 (define_insn "*rdtsc"
18839   [(set (match_operand:DI 0 "register_operand" "=A")
18840         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18841   "!TARGET_64BIT"
18842   "rdtsc"
18843   [(set_attr "type" "other")
18844    (set_attr "length" "2")])
18845
18846 (define_insn "*rdtsc_rex64"
18847   [(set (match_operand:DI 0 "register_operand" "=a")
18848         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18849    (set (match_operand:DI 1 "register_operand" "=d")
18850         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18851   "TARGET_64BIT"
18852   "rdtsc"
18853   [(set_attr "type" "other")
18854    (set_attr "length" "2")])
18855
18856 (define_expand "rdtscp"
18857   [(match_operand:DI 0 "register_operand" "")
18858    (match_operand:SI 1 "memory_operand" "")]
18859   ""
18860 {
18861   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18862                                     gen_rtvec (1, const0_rtx),
18863                                     UNSPECV_RDTSCP);
18864   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18865                                     gen_rtvec (1, const0_rtx),
18866                                     UNSPECV_RDTSCP);
18867   rtx reg = gen_reg_rtx (DImode);
18868   rtx tmp = gen_reg_rtx (SImode);
18869
18870   if (TARGET_64BIT)
18871     {
18872       rtvec vec = rtvec_alloc (3);
18873       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18874       rtx upper = gen_reg_rtx (DImode);
18875       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18876       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18877       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18878       emit_insn (load);
18879       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18880                                    NULL, 1, OPTAB_DIRECT);
18881       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18882                                  OPTAB_DIRECT);
18883     }
18884   else
18885     {
18886       rtvec vec = rtvec_alloc (2);
18887       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18888       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18889       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18890       emit_insn (load);
18891     }
18892   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18893   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18894   DONE;
18895 })
18896
18897 (define_insn "*rdtscp"
18898   [(set (match_operand:DI 0 "register_operand" "=A")
18899         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18900    (set (match_operand:SI 1 "register_operand" "=c")
18901         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18902   "!TARGET_64BIT"
18903   "rdtscp"
18904   [(set_attr "type" "other")
18905    (set_attr "length" "3")])
18906
18907 (define_insn "*rdtscp_rex64"
18908   [(set (match_operand:DI 0 "register_operand" "=a")
18909         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18910    (set (match_operand:DI 1 "register_operand" "=d")
18911         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18912    (set (match_operand:SI 2 "register_operand" "=c")
18913         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18914   "TARGET_64BIT"
18915   "rdtscp"
18916   [(set_attr "type" "other")
18917    (set_attr "length" "3")])
18918
18919 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18920 ;;
18921 ;; LWP instructions
18922 ;;
18923 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18924
18925 (define_expand "lwp_llwpcb"
18926   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18927                     UNSPECV_LLWP_INTRINSIC)]
18928   "TARGET_LWP"
18929   "")
18930
18931 (define_insn "*lwp_llwpcb<mode>1"
18932   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18933                     UNSPECV_LLWP_INTRINSIC)]
18934   "TARGET_LWP"
18935   "llwpcb\t%0"
18936   [(set_attr "type" "lwp")
18937    (set_attr "mode" "<MODE>")
18938    (set_attr "length" "5")])
18939
18940 (define_expand "lwp_slwpcb"
18941   [(set (match_operand 0 "register_operand" "=r")
18942         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18943   "TARGET_LWP"
18944   {
18945     if (TARGET_64BIT)
18946       emit_insn (gen_lwp_slwpcbdi (operands[0]));
18947     else
18948       emit_insn (gen_lwp_slwpcbsi (operands[0]));
18949     DONE;
18950   })
18951
18952 (define_insn "lwp_slwpcb<mode>"
18953   [(set (match_operand:P 0 "register_operand" "=r")
18954         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18955   "TARGET_LWP"
18956   "slwpcb\t%0"
18957   [(set_attr "type" "lwp")
18958    (set_attr "mode" "<MODE>")
18959    (set_attr "length" "5")])
18960
18961 (define_expand "lwp_lwpval<mode>3"
18962   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18963                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18964                      (match_operand:SI 3 "const_int_operand" "i")]
18965                     UNSPECV_LWPVAL_INTRINSIC)]
18966   "TARGET_LWP"
18967   "/* Avoid unused variable warning.  */
18968    (void) operand0;")
18969
18970 (define_insn "*lwp_lwpval<mode>3_1"
18971   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18972                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18973                      (match_operand:SI 2 "const_int_operand" "i")]
18974                     UNSPECV_LWPVAL_INTRINSIC)]
18975   "TARGET_LWP"
18976   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18977   [(set_attr "type" "lwp")
18978    (set_attr "mode" "<MODE>")
18979    (set (attr "length")
18980         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18981
18982 (define_expand "lwp_lwpins<mode>3"
18983   [(set (reg:CCC FLAGS_REG)
18984         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18985                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18986                               (match_operand:SI 3 "const_int_operand" "i")]
18987                              UNSPECV_LWPINS_INTRINSIC))
18988    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18989         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18990   "TARGET_LWP"
18991   "")
18992
18993 (define_insn "*lwp_lwpins<mode>3_1"
18994   [(set (reg:CCC FLAGS_REG)
18995         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18996                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18997                               (match_operand:SI 2 "const_int_operand" "i")]
18998                              UNSPECV_LWPINS_INTRINSIC))]
18999   "TARGET_LWP"
19000   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19001   [(set_attr "type" "lwp")
19002    (set_attr "mode" "<MODE>")
19003    (set (attr "length")
19004         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19005
19006 (include "mmx.md")
19007 (include "sse.md")
19008 (include "sync.md")