OSDN Git Service

* config/i386/i386.md (*addqi_2): Do not assert operands[2] == 255
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62
63 ;; UNSPEC usage:
64
65 (define_constants
66   [; Relocation specifiers
67    (UNSPEC_GOT                  0)
68    (UNSPEC_GOTOFF               1)
69    (UNSPEC_GOTPCREL             2)
70    (UNSPEC_GOTTPOFF             3)
71    (UNSPEC_TPOFF                4)
72    (UNSPEC_NTPOFF               5)
73    (UNSPEC_DTPOFF               6)
74    (UNSPEC_GOTNTPOFF            7)
75    (UNSPEC_INDNTPOFF            8)
76    (UNSPEC_PLTOFF               9)
77    (UNSPEC_MACHOPIC_OFFSET      10)
78
79    ; Prologue support
80    (UNSPEC_STACK_ALLOC          11)
81    (UNSPEC_SET_GOT              12)
82    (UNSPEC_SSE_PROLOGUE_SAVE    13)
83    (UNSPEC_REG_SAVE             14)
84    (UNSPEC_DEF_CFA              15)
85    (UNSPEC_SET_RIP              16)
86    (UNSPEC_SET_GOT_OFFSET       17)
87    (UNSPEC_MEMORY_BLOCKAGE      18)
88    (UNSPEC_SSE_PROLOGUE_SAVE_LOW 19)
89
90    ; TLS support
91    (UNSPEC_TP                   20)
92    (UNSPEC_TLS_GD               21)
93    (UNSPEC_TLS_LD_BASE          22)
94    (UNSPEC_TLSDESC              23)
95
96    ; Other random patterns
97    (UNSPEC_SCAS                 30)
98    (UNSPEC_FNSTSW               31)
99    (UNSPEC_SAHF                 32)
100    (UNSPEC_FSTCW                33)
101    (UNSPEC_ADD_CARRY            34)
102    (UNSPEC_FLDCW                35)
103    (UNSPEC_REP                  36)
104    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
105    (UNSPEC_TRUNC_NOOP           39)
106
107    ; For SSE/MMX support:
108    (UNSPEC_FIX_NOTRUNC          40)
109    (UNSPEC_MASKMOV              41)
110    (UNSPEC_MOVMSK               42)
111    (UNSPEC_MOVNT                43)
112    (UNSPEC_MOVU                 44)
113    (UNSPEC_RCP                  45)
114    (UNSPEC_RSQRT                46)
115    (UNSPEC_SFENCE               47)
116    (UNSPEC_PFRCP                49)
117    (UNSPEC_PFRCPIT1             40)
118    (UNSPEC_PFRCPIT2             41)
119    (UNSPEC_PFRSQRT              42)
120    (UNSPEC_PFRSQIT1             43)
121    (UNSPEC_MFENCE               44)
122    (UNSPEC_LFENCE               45)
123    (UNSPEC_PSADBW               46)
124    (UNSPEC_LDDQU                47)
125    (UNSPEC_MS_TO_SYSV_CALL      48)
126
127    ; Generic math support
128    (UNSPEC_COPYSIGN             50)
129    (UNSPEC_IEEE_MIN             51)     ; not commutative
130    (UNSPEC_IEEE_MAX             52)     ; not commutative
131
132    ; x87 Floating point
133    (UNSPEC_SIN                  60)
134    (UNSPEC_COS                  61)
135    (UNSPEC_FPATAN               62)
136    (UNSPEC_FYL2X                63)
137    (UNSPEC_FYL2XP1              64)
138    (UNSPEC_FRNDINT              65)
139    (UNSPEC_FIST                 66)
140    (UNSPEC_F2XM1                67)
141    (UNSPEC_TAN                  68)
142    (UNSPEC_FXAM                 69)
143
144    ; x87 Rounding
145    (UNSPEC_FRNDINT_FLOOR        70)
146    (UNSPEC_FRNDINT_CEIL         71)
147    (UNSPEC_FRNDINT_TRUNC        72)
148    (UNSPEC_FRNDINT_MASK_PM      73)
149    (UNSPEC_FIST_FLOOR           74)
150    (UNSPEC_FIST_CEIL            75)
151
152    ; x87 Double output FP
153    (UNSPEC_SINCOS_COS           80)
154    (UNSPEC_SINCOS_SIN           81)
155    (UNSPEC_XTRACT_FRACT         84)
156    (UNSPEC_XTRACT_EXP           85)
157    (UNSPEC_FSCALE_FRACT         86)
158    (UNSPEC_FSCALE_EXP           87)
159    (UNSPEC_FPREM_F              88)
160    (UNSPEC_FPREM_U              89)
161    (UNSPEC_FPREM1_F             90)
162    (UNSPEC_FPREM1_U             91)
163
164    (UNSPEC_C2_FLAG              95)
165    (UNSPEC_FXAM_MEM             96)
166
167    ; SSP patterns
168    (UNSPEC_SP_SET               100)
169    (UNSPEC_SP_TEST              101)
170    (UNSPEC_SP_TLS_SET           102)
171    (UNSPEC_SP_TLS_TEST          103)
172
173    ; SSSE3
174    (UNSPEC_PSHUFB               120)
175    (UNSPEC_PSIGN                121)
176    (UNSPEC_PALIGNR              122)
177
178    ; For SSE4A support
179    (UNSPEC_EXTRQI               130)
180    (UNSPEC_EXTRQ                131)
181    (UNSPEC_INSERTQI             132)
182    (UNSPEC_INSERTQ              133)
183
184    ; For SSE4.1 support
185    (UNSPEC_BLENDV               134)
186    (UNSPEC_INSERTPS             135)
187    (UNSPEC_DP                   136)
188    (UNSPEC_MOVNTDQA             137)
189    (UNSPEC_MPSADBW              138)
190    (UNSPEC_PHMINPOSUW           139)
191    (UNSPEC_PTEST                140)
192    (UNSPEC_ROUND                141)
193
194    ; For SSE4.2 support
195    (UNSPEC_CRC32                143)
196    (UNSPEC_PCMPESTR             144)
197    (UNSPEC_PCMPISTR             145)
198
199    ; For FMA4 support
200    (UNSPEC_FMA4_INTRINSIC       150)
201    (UNSPEC_FMA4_FMADDSUB        151)
202    (UNSPEC_FMA4_FMSUBADD        152)
203    (UNSPEC_XOP_UNSIGNED_CMP     151)
204    (UNSPEC_XOP_TRUEFALSE        152)
205    (UNSPEC_XOP_PERMUTE          153)
206    (UNSPEC_FRCZ                 154)
207
208    ; For AES support
209    (UNSPEC_AESENC               159)
210    (UNSPEC_AESENCLAST           160)
211    (UNSPEC_AESDEC               161)
212    (UNSPEC_AESDECLAST           162)
213    (UNSPEC_AESIMC               163)
214    (UNSPEC_AESKEYGENASSIST      164)
215
216    ; For PCLMUL support
217    (UNSPEC_PCLMUL               165)
218
219    ; For AVX support
220    (UNSPEC_PCMP                 166)
221    (UNSPEC_VPERMIL              167)
222    (UNSPEC_VPERMIL2             168)
223    (UNSPEC_VPERMIL2F128         169)
224    (UNSPEC_MASKLOAD             170)
225    (UNSPEC_MASKSTORE            171)
226    (UNSPEC_CAST                 172)
227    (UNSPEC_VTESTP               173)
228   ])
229
230 (define_constants
231   [(UNSPECV_BLOCKAGE            0)
232    (UNSPECV_STACK_PROBE         1)
233    (UNSPECV_EMMS                2)
234    (UNSPECV_LDMXCSR             3)
235    (UNSPECV_STMXCSR             4)
236    (UNSPECV_FEMMS               5)
237    (UNSPECV_CLFLUSH             6)
238    (UNSPECV_ALIGN               7)
239    (UNSPECV_MONITOR             8)
240    (UNSPECV_MWAIT               9)
241    (UNSPECV_CMPXCHG             10)
242    (UNSPECV_XCHG                12)
243    (UNSPECV_LOCK                13)
244    (UNSPECV_PROLOGUE_USE        14)
245    (UNSPECV_CLD                 15)
246    (UNSPECV_VZEROALL            16)
247    (UNSPECV_VZEROUPPER          17)
248    (UNSPECV_RDTSC               18)
249    (UNSPECV_RDTSCP              19)
250    (UNSPECV_RDPMC               20)
251    (UNSPECV_VSWAPMOV            21)
252    (UNSPECV_LLWP_INTRINSIC      22)
253    (UNSPECV_SLWP_INTRINSIC      23)
254    (UNSPECV_LWPVAL_INTRINSIC    24)
255    (UNSPECV_LWPINS_INTRINSIC    25)
256   ])
257
258 ;; Constants to represent pcomtrue/pcomfalse variants
259 (define_constants
260   [(PCOM_FALSE                  0)
261    (PCOM_TRUE                   1)
262    (COM_FALSE_S                 2)
263    (COM_FALSE_P                 3)
264    (COM_TRUE_S                  4)
265    (COM_TRUE_P                  5)
266   ])
267
268 ;; Constants used in the XOP pperm instruction
269 (define_constants
270   [(PPERM_SRC                   0x00)   /* copy source */
271    (PPERM_INVERT                0x20)   /* invert source */
272    (PPERM_REVERSE               0x40)   /* bit reverse source */
273    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
274    (PPERM_ZERO                  0x80)   /* all 0's */
275    (PPERM_ONES                  0xa0)   /* all 1's */
276    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
277    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
278    (PPERM_SRC1                  0x00)   /* use first source byte */
279    (PPERM_SRC2                  0x10)   /* use second source byte */
280    ])
281
282 ;; Registers by name.
283 (define_constants
284   [(AX_REG                       0)
285    (DX_REG                       1)
286    (CX_REG                       2)
287    (BX_REG                       3)
288    (SI_REG                       4)
289    (DI_REG                       5)
290    (BP_REG                       6)
291    (SP_REG                       7)
292    (ST0_REG                      8)
293    (ST1_REG                      9)
294    (ST2_REG                     10)
295    (ST3_REG                     11)
296    (ST4_REG                     12)
297    (ST5_REG                     13)
298    (ST6_REG                     14)
299    (ST7_REG                     15)
300    (FLAGS_REG                   17)
301    (FPSR_REG                    18)
302    (FPCR_REG                    19)
303    (XMM0_REG                    21)
304    (XMM1_REG                    22)
305    (XMM2_REG                    23)
306    (XMM3_REG                    24)
307    (XMM4_REG                    25)
308    (XMM5_REG                    26)
309    (XMM6_REG                    27)
310    (XMM7_REG                    28)
311    (MM0_REG                     29)
312    (MM1_REG                     30)
313    (MM2_REG                     31)
314    (MM3_REG                     32)
315    (MM4_REG                     33)
316    (MM5_REG                     34)
317    (MM6_REG                     35)
318    (MM7_REG                     36)
319    (R8_REG                      37)
320    (R9_REG                      38)
321    (R10_REG                     39)
322    (R11_REG                     40)
323    (R12_REG                     41)
324    (R13_REG                     42)
325    (XMM8_REG                    45)
326    (XMM9_REG                    46)
327    (XMM10_REG                   47)
328    (XMM11_REG                   48)
329    (XMM12_REG                   49)
330    (XMM13_REG                   50)
331    (XMM14_REG                   51)
332    (XMM15_REG                   52)
333   ])
334
335 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
336 ;; from i386.c.
337
338 ;; In C guard expressions, put expressions which may be compile-time
339 ;; constants first.  This allows for better optimization.  For
340 ;; example, write "TARGET_64BIT && reload_completed", not
341 ;; "reload_completed && TARGET_64BIT".
342
343 \f
344 ;; Processor type.
345 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
346                     generic64,amdfam10,bdver1"
347   (const (symbol_ref "ix86_schedule")))
348
349 ;; A basic instruction type.  Refinements due to arguments to be
350 ;; provided in other attributes.
351 (define_attr "type"
352   "other,multi,
353    alu,alu1,negnot,imov,imovx,lea,
354    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
355    icmp,test,ibr,setcc,icmov,
356    push,pop,call,callv,leave,
357    str,bitmanip,
358    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
359    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
360    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
361    ssemuladd,sse4arg,lwp,
362    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
363   (const_string "other"))
364
365 ;; Main data type used by the insn
366 (define_attr "mode"
367   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
368   (const_string "unknown"))
369
370 ;; The CPU unit operations uses.
371 (define_attr "unit" "integer,i387,sse,mmx,unknown"
372   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
373            (const_string "i387")
374          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
375                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
376                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
377            (const_string "sse")
378          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
379            (const_string "mmx")
380          (eq_attr "type" "other")
381            (const_string "unknown")]
382          (const_string "integer")))
383
384 ;; The (bounding maximum) length of an instruction immediate.
385 (define_attr "length_immediate" ""
386   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
387                           bitmanip")
388            (const_int 0)
389          (eq_attr "unit" "i387,sse,mmx")
390            (const_int 0)
391          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
392                           imul,icmp,push,pop")
393            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
394          (eq_attr "type" "imov,test")
395            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
396          (eq_attr "type" "call")
397            (if_then_else (match_operand 0 "constant_call_address_operand" "")
398              (const_int 4)
399              (const_int 0))
400          (eq_attr "type" "callv")
401            (if_then_else (match_operand 1 "constant_call_address_operand" "")
402              (const_int 4)
403              (const_int 0))
404          ;; We don't know the size before shorten_branches.  Expect
405          ;; the instruction to fit for better scheduling.
406          (eq_attr "type" "ibr")
407            (const_int 1)
408          ]
409          (symbol_ref "/* Update immediate_length and other attributes! */
410                       gcc_unreachable (),1")))
411
412 ;; The (bounding maximum) length of an instruction address.
413 (define_attr "length_address" ""
414   (cond [(eq_attr "type" "str,other,multi,fxch")
415            (const_int 0)
416          (and (eq_attr "type" "call")
417               (match_operand 0 "constant_call_address_operand" ""))
418              (const_int 0)
419          (and (eq_attr "type" "callv")
420               (match_operand 1 "constant_call_address_operand" ""))
421              (const_int 0)
422          ]
423          (symbol_ref "ix86_attr_length_address_default (insn)")))
424
425 ;; Set when length prefix is used.
426 (define_attr "prefix_data16" ""
427   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
428            (const_int 0)
429          (eq_attr "mode" "HI")
430            (const_int 1)
431          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
432            (const_int 1)
433         ]
434         (const_int 0)))
435
436 ;; Set when string REP prefix is used.
437 (define_attr "prefix_rep" ""
438   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
439            (const_int 0)
440          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
441            (const_int 1)
442         ]
443         (const_int 0)))
444
445 ;; Set when 0f opcode prefix is used.
446 (define_attr "prefix_0f" ""
447   (if_then_else
448     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
449          (eq_attr "unit" "sse,mmx"))
450     (const_int 1)
451     (const_int 0)))
452
453 ;; Set when REX opcode prefix is used.
454 (define_attr "prefix_rex" ""
455   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
456            (const_int 0)
457          (and (eq_attr "mode" "DI")
458               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
459                    (eq_attr "unit" "!mmx")))
460            (const_int 1)
461          (and (eq_attr "mode" "QI")
462               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
463                   (const_int 0)))
464            (const_int 1)
465          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
466              (const_int 0))
467            (const_int 1)
468          (and (eq_attr "type" "imovx")
469               (match_operand:QI 1 "ext_QIreg_operand" ""))
470            (const_int 1)
471         ]
472         (const_int 0)))
473
474 ;; There are also additional prefixes in 3DNOW, SSSE3.
475 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
476 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
477 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
478 (define_attr "prefix_extra" ""
479   (cond [(eq_attr "type" "ssemuladd,sse4arg")
480            (const_int 2)
481          (eq_attr "type" "sseiadd1,ssecvt1")
482            (const_int 1)
483         ]
484         (const_int 0)))
485
486 ;; Prefix used: original, VEX or maybe VEX.
487 (define_attr "prefix" "orig,vex,maybe_vex"
488   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
489     (const_string "vex")
490     (const_string "orig")))
491
492 ;; VEX W bit is used.
493 (define_attr "prefix_vex_w" "" (const_int 0))
494
495 ;; The length of VEX prefix
496 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
497 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
498 ;; still prefix_0f 1, with prefix_extra 1.
499 (define_attr "length_vex" ""
500   (if_then_else (and (eq_attr "prefix_0f" "1")
501                      (eq_attr "prefix_extra" "0"))
502     (if_then_else (eq_attr "prefix_vex_w" "1")
503       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
504       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
505     (if_then_else (eq_attr "prefix_vex_w" "1")
506       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
507       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
508
509 ;; Set when modrm byte is used.
510 (define_attr "modrm" ""
511   (cond [(eq_attr "type" "str,leave")
512            (const_int 0)
513          (eq_attr "unit" "i387")
514            (const_int 0)
515          (and (eq_attr "type" "incdec")
516               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
517                    (ior (match_operand:SI 1 "register_operand" "")
518                         (match_operand:HI 1 "register_operand" ""))))
519            (const_int 0)
520          (and (eq_attr "type" "push")
521               (not (match_operand 1 "memory_operand" "")))
522            (const_int 0)
523          (and (eq_attr "type" "pop")
524               (not (match_operand 0 "memory_operand" "")))
525            (const_int 0)
526          (and (eq_attr "type" "imov")
527               (and (not (eq_attr "mode" "DI"))
528                    (ior (and (match_operand 0 "register_operand" "")
529                              (match_operand 1 "immediate_operand" ""))
530                         (ior (and (match_operand 0 "ax_reg_operand" "")
531                                   (match_operand 1 "memory_displacement_only_operand" ""))
532                              (and (match_operand 0 "memory_displacement_only_operand" "")
533                                   (match_operand 1 "ax_reg_operand" ""))))))
534            (const_int 0)
535          (and (eq_attr "type" "call")
536               (match_operand 0 "constant_call_address_operand" ""))
537              (const_int 0)
538          (and (eq_attr "type" "callv")
539               (match_operand 1 "constant_call_address_operand" ""))
540              (const_int 0)
541          (and (eq_attr "type" "alu,alu1,icmp,test")
542               (match_operand 0 "ax_reg_operand" ""))
543              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
544          ]
545          (const_int 1)))
546
547 ;; The (bounding maximum) length of an instruction in bytes.
548 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
549 ;; Later we may want to split them and compute proper length as for
550 ;; other insns.
551 (define_attr "length" ""
552   (cond [(eq_attr "type" "other,multi,fistp,frndint")
553            (const_int 16)
554          (eq_attr "type" "fcmp")
555            (const_int 4)
556          (eq_attr "unit" "i387")
557            (plus (const_int 2)
558                  (plus (attr "prefix_data16")
559                        (attr "length_address")))
560          (ior (eq_attr "prefix" "vex")
561               (and (eq_attr "prefix" "maybe_vex")
562                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
563            (plus (attr "length_vex")
564                  (plus (attr "length_immediate")
565                        (plus (attr "modrm")
566                              (attr "length_address"))))]
567          (plus (plus (attr "modrm")
568                      (plus (attr "prefix_0f")
569                            (plus (attr "prefix_rex")
570                                  (plus (attr "prefix_extra")
571                                        (const_int 1)))))
572                (plus (attr "prefix_rep")
573                      (plus (attr "prefix_data16")
574                            (plus (attr "length_immediate")
575                                  (attr "length_address")))))))
576
577 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
578 ;; `store' if there is a simple memory reference therein, or `unknown'
579 ;; if the instruction is complex.
580
581 (define_attr "memory" "none,load,store,both,unknown"
582   (cond [(eq_attr "type" "other,multi,str,lwp")
583            (const_string "unknown")
584          (eq_attr "type" "lea,fcmov,fpspc")
585            (const_string "none")
586          (eq_attr "type" "fistp,leave")
587            (const_string "both")
588          (eq_attr "type" "frndint")
589            (const_string "load")
590          (eq_attr "type" "push")
591            (if_then_else (match_operand 1 "memory_operand" "")
592              (const_string "both")
593              (const_string "store"))
594          (eq_attr "type" "pop")
595            (if_then_else (match_operand 0 "memory_operand" "")
596              (const_string "both")
597              (const_string "load"))
598          (eq_attr "type" "setcc")
599            (if_then_else (match_operand 0 "memory_operand" "")
600              (const_string "store")
601              (const_string "none"))
602          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
603            (if_then_else (ior (match_operand 0 "memory_operand" "")
604                               (match_operand 1 "memory_operand" ""))
605              (const_string "load")
606              (const_string "none"))
607          (eq_attr "type" "ibr")
608            (if_then_else (match_operand 0 "memory_operand" "")
609              (const_string "load")
610              (const_string "none"))
611          (eq_attr "type" "call")
612            (if_then_else (match_operand 0 "constant_call_address_operand" "")
613              (const_string "none")
614              (const_string "load"))
615          (eq_attr "type" "callv")
616            (if_then_else (match_operand 1 "constant_call_address_operand" "")
617              (const_string "none")
618              (const_string "load"))
619          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
620               (match_operand 1 "memory_operand" ""))
621            (const_string "both")
622          (and (match_operand 0 "memory_operand" "")
623               (match_operand 1 "memory_operand" ""))
624            (const_string "both")
625          (match_operand 0 "memory_operand" "")
626            (const_string "store")
627          (match_operand 1 "memory_operand" "")
628            (const_string "load")
629          (and (eq_attr "type"
630                  "!alu1,negnot,ishift1,
631                    imov,imovx,icmp,test,bitmanip,
632                    fmov,fcmp,fsgn,
633                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
634                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
635               (match_operand 2 "memory_operand" ""))
636            (const_string "load")
637          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
638               (match_operand 3 "memory_operand" ""))
639            (const_string "load")
640         ]
641         (const_string "none")))
642
643 ;; Indicates if an instruction has both an immediate and a displacement.
644
645 (define_attr "imm_disp" "false,true,unknown"
646   (cond [(eq_attr "type" "other,multi")
647            (const_string "unknown")
648          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
649               (and (match_operand 0 "memory_displacement_operand" "")
650                    (match_operand 1 "immediate_operand" "")))
651            (const_string "true")
652          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
653               (and (match_operand 0 "memory_displacement_operand" "")
654                    (match_operand 2 "immediate_operand" "")))
655            (const_string "true")
656         ]
657         (const_string "false")))
658
659 ;; Indicates if an FP operation has an integer source.
660
661 (define_attr "fp_int_src" "false,true"
662   (const_string "false"))
663
664 ;; Defines rounding mode of an FP operation.
665
666 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
667   (const_string "any"))
668
669 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
670 (define_attr "use_carry" "0,1" (const_string "0"))
671
672 ;; Define attribute to indicate unaligned ssemov insns
673 (define_attr "movu" "0,1" (const_string "0"))
674
675 ;; Describe a user's asm statement.
676 (define_asm_attributes
677   [(set_attr "length" "128")
678    (set_attr "type" "multi")])
679
680 ;; All integer comparison codes.
681 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
682
683 ;; All floating-point comparison codes.
684 (define_code_iterator fp_cond [unordered ordered
685                                uneq unge ungt unle unlt ltgt])
686
687 (define_code_iterator plusminus [plus minus])
688
689 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690
691 ;; Base name for define_insn
692 (define_code_attr plusminus_insn
693   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
694    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695
696 ;; Base name for insn mnemonic.
697 (define_code_attr plusminus_mnemonic
698   [(plus "add") (ss_plus "adds") (us_plus "addus")
699    (minus "sub") (ss_minus "subs") (us_minus "subus")])
700 (define_code_attr plusminus_carry_mnemonic
701   [(plus "adc") (minus "sbb")])
702
703 ;; Mark commutative operators as such in constraints.
704 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
705                         (minus "") (ss_minus "") (us_minus "")])
706
707 ;; Mapping of signed max and min
708 (define_code_iterator smaxmin [smax smin])
709
710 ;; Mapping of unsigned max and min
711 (define_code_iterator umaxmin [umax umin])
712
713 ;; Mapping of signed/unsigned max and min
714 (define_code_iterator maxmin [smax smin umax umin])
715
716 ;; Base name for integer and FP insn mnemonic
717 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
718                               (umax "maxu") (umin "minu")])
719 (define_code_attr maxmin_float [(smax "max") (smin "min")])
720
721 ;; Mapping of logic operators
722 (define_code_iterator any_logic [and ior xor])
723 (define_code_iterator any_or [ior xor])
724
725 ;; Base name for insn mnemonic.
726 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
727
728 ;; Mapping of shift-right operators
729 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730
731 ;; Base name for define_insn
732 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
733
734 ;; Base name for insn mnemonic.
735 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
736
737 ;; Mapping of rotate operators
738 (define_code_iterator any_rotate [rotate rotatert])
739
740 ;; Base name for define_insn
741 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
742
743 ;; Base name for insn mnemonic.
744 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
745
746 ;; Mapping of abs neg operators
747 (define_code_iterator absneg [abs neg])
748
749 ;; Base name for x87 insn mnemonic.
750 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
751
752 ;; Used in signed and unsigned widening multiplications.
753 (define_code_iterator any_extend [sign_extend zero_extend])
754
755 ;; Various insn prefixes for signed and unsigned operations.
756 (define_code_attr u [(sign_extend "") (zero_extend "u")
757                      (div "") (udiv "u")])
758 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
759
760 ;; Used in signed and unsigned divisions.
761 (define_code_iterator any_div [div udiv])
762
763 ;; Instruction prefix for signed and unsigned operations.
764 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
765                              (div "i") (udiv "")])
766
767 ;; All single word integer modes.
768 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
769
770 ;; Single word integer modes without DImode.
771 (define_mode_iterator SWI124 [QI HI SI])
772
773 ;; Single word integer modes without QImode.
774 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
775
776 ;; Single word integer modes without QImode and HImode.
777 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
778
779 ;; All math-dependant single and double word integer modes.
780 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
781                              (HI "TARGET_HIMODE_MATH")
782                              SI DI (TI "TARGET_64BIT")])
783
784 ;; Math-dependant single word integer modes.
785 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
786                             (HI "TARGET_HIMODE_MATH")
787                             SI (DI "TARGET_64BIT")])
788
789 ;; Math-dependant single word integer modes without DImode.
790 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
791                                (HI "TARGET_HIMODE_MATH")
792                                SI])
793
794 ;; Math-dependant single word integer modes without QImode.
795 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
796                                SI (DI "TARGET_64BIT")])
797
798 ;; Double word integer modes.
799 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
800                            (TI "TARGET_64BIT")])
801
802 ;; Double word integer modes as mode attribute.
803 (define_mode_attr DWI [(SI "DI") (DI "TI")])
804 (define_mode_attr dwi [(SI "di") (DI "ti")])
805
806 ;; Half mode for double word integer modes.
807 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
808                             (DI "TARGET_64BIT")])
809
810 ;; Instruction suffix for integer modes.
811 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
812
813 ;; Register class for integer modes.
814 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
815
816 ;; Immediate operand constraint for integer modes.
817 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
818
819 ;; General operand constraint for word modes.
820 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
821
822 ;; Immediate operand constraint for double integer modes.
823 (define_mode_attr di [(SI "iF") (DI "e")])
824
825 ;; Immediate operand constraint for shifts.
826 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
827
828 ;; General operand predicate for integer modes.
829 (define_mode_attr general_operand
830         [(QI "general_operand")
831          (HI "general_operand")
832          (SI "general_operand")
833          (DI "x86_64_general_operand")
834          (TI "x86_64_general_operand")])
835
836 ;; General sign/zero extend operand predicate for integer modes.
837 (define_mode_attr general_szext_operand
838         [(QI "general_operand")
839          (HI "general_operand")
840          (SI "general_operand")
841          (DI "x86_64_szext_general_operand")])
842
843 ;; Operand predicate for shifts.
844 (define_mode_attr shift_operand
845         [(QI "nonimmediate_operand")
846          (HI "nonimmediate_operand")
847          (SI "nonimmediate_operand")
848          (DI "shiftdi_operand")
849          (TI "register_operand")])
850
851 ;; Operand predicate for shift argument.
852 (define_mode_attr shift_immediate_operand
853         [(QI "const_1_to_31_operand")
854          (HI "const_1_to_31_operand")
855          (SI "const_1_to_31_operand")
856          (DI "const_1_to_63_operand")])
857
858 ;; Input operand predicate for arithmetic left shifts.
859 (define_mode_attr ashl_input_operand
860         [(QI "nonimmediate_operand")
861          (HI "nonimmediate_operand")
862          (SI "nonimmediate_operand")
863          (DI "ashldi_input_operand")
864          (TI "reg_or_pm1_operand")])
865
866 ;; SSE and x87 SFmode and DFmode floating point modes
867 (define_mode_iterator MODEF [SF DF])
868
869 ;; All x87 floating point modes
870 (define_mode_iterator X87MODEF [SF DF XF])
871
872 ;; All integer modes handled by x87 fisttp operator.
873 (define_mode_iterator X87MODEI [HI SI DI])
874
875 ;; All integer modes handled by integer x87 operators.
876 (define_mode_iterator X87MODEI12 [HI SI])
877
878 ;; All integer modes handled by SSE cvtts?2si* operators.
879 (define_mode_iterator SSEMODEI24 [SI DI])
880
881 ;; SSE asm suffix for floating point modes
882 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
883
884 ;; SSE vector mode corresponding to a scalar mode
885 (define_mode_attr ssevecmode
886   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
887
888 ;; Instruction suffix for REX 64bit operators.
889 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
890
891 ;; This mode iterator allows :P to be used for patterns that operate on
892 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
893 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
894 \f
895 ;; Scheduling descriptions
896
897 (include "pentium.md")
898 (include "ppro.md")
899 (include "k6.md")
900 (include "athlon.md")
901 (include "geode.md")
902 (include "atom.md")
903
904 \f
905 ;; Operand and operator predicates and constraints
906
907 (include "predicates.md")
908 (include "constraints.md")
909
910 \f
911 ;; Compare and branch/compare and store instructions.
912
913 (define_expand "cbranch<mode>4"
914   [(set (reg:CC FLAGS_REG)
915         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
916                     (match_operand:SDWIM 2 "<general_operand>" "")))
917    (set (pc) (if_then_else
918                (match_operator 0 "comparison_operator"
919                 [(reg:CC FLAGS_REG) (const_int 0)])
920                (label_ref (match_operand 3 "" ""))
921                (pc)))]
922   ""
923 {
924   if (MEM_P (operands[1]) && MEM_P (operands[2]))
925     operands[1] = force_reg (<MODE>mode, operands[1]);
926   ix86_compare_op0 = operands[1];
927   ix86_compare_op1 = operands[2];
928   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
929   DONE;
930 })
931
932 (define_expand "cstore<mode>4"
933   [(set (reg:CC FLAGS_REG)
934         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
935                     (match_operand:SWIM 3 "<general_operand>" "")))
936    (set (match_operand:QI 0 "register_operand" "")
937         (match_operator 1 "comparison_operator"
938           [(reg:CC FLAGS_REG) (const_int 0)]))]
939   ""
940 {
941   if (MEM_P (operands[2]) && MEM_P (operands[3]))
942     operands[2] = force_reg (<MODE>mode, operands[2]);
943   ix86_compare_op0 = operands[2];
944   ix86_compare_op1 = operands[3];
945   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
946   DONE;
947 })
948
949 (define_expand "cmp<mode>_1"
950   [(set (reg:CC FLAGS_REG)
951         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
952                     (match_operand:SWI48 1 "<general_operand>" "")))]
953   ""
954   "")
955
956 (define_insn "*cmp<mode>_ccno_1"
957   [(set (reg FLAGS_REG)
958         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
959                  (match_operand:SWI 1 "const0_operand" "")))]
960   "ix86_match_ccmode (insn, CCNOmode)"
961   "@
962    test{<imodesuffix>}\t%0, %0
963    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
964   [(set_attr "type" "test,icmp")
965    (set_attr "length_immediate" "0,1")
966    (set_attr "mode" "<MODE>")])
967
968 (define_insn "*cmp<mode>_1"
969   [(set (reg FLAGS_REG)
970         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
971                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
972   "ix86_match_ccmode (insn, CCmode)"
973   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
974   [(set_attr "type" "icmp")
975    (set_attr "mode" "<MODE>")])
976
977 (define_insn "*cmp<mode>_minus_1"
978   [(set (reg FLAGS_REG)
979         (compare
980           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
981                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
982           (const_int 0)))]
983   "ix86_match_ccmode (insn, CCGOCmode)"
984   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
985   [(set_attr "type" "icmp")
986    (set_attr "mode" "<MODE>")])
987
988 (define_insn "*cmpqi_ext_1"
989   [(set (reg FLAGS_REG)
990         (compare
991           (match_operand:QI 0 "general_operand" "Qm")
992           (subreg:QI
993             (zero_extract:SI
994               (match_operand 1 "ext_register_operand" "Q")
995               (const_int 8)
996               (const_int 8)) 0)))]
997   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
998   "cmp{b}\t{%h1, %0|%0, %h1}"
999   [(set_attr "type" "icmp")
1000    (set_attr "mode" "QI")])
1001
1002 (define_insn "*cmpqi_ext_1_rex64"
1003   [(set (reg FLAGS_REG)
1004         (compare
1005           (match_operand:QI 0 "register_operand" "Q")
1006           (subreg:QI
1007             (zero_extract:SI
1008               (match_operand 1 "ext_register_operand" "Q")
1009               (const_int 8)
1010               (const_int 8)) 0)))]
1011   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1012   "cmp{b}\t{%h1, %0|%0, %h1}"
1013   [(set_attr "type" "icmp")
1014    (set_attr "mode" "QI")])
1015
1016 (define_insn "*cmpqi_ext_2"
1017   [(set (reg FLAGS_REG)
1018         (compare
1019           (subreg:QI
1020             (zero_extract:SI
1021               (match_operand 0 "ext_register_operand" "Q")
1022               (const_int 8)
1023               (const_int 8)) 0)
1024           (match_operand:QI 1 "const0_operand" "")))]
1025   "ix86_match_ccmode (insn, CCNOmode)"
1026   "test{b}\t%h0, %h0"
1027   [(set_attr "type" "test")
1028    (set_attr "length_immediate" "0")
1029    (set_attr "mode" "QI")])
1030
1031 (define_expand "cmpqi_ext_3"
1032   [(set (reg:CC FLAGS_REG)
1033         (compare:CC
1034           (subreg:QI
1035             (zero_extract:SI
1036               (match_operand 0 "ext_register_operand" "")
1037               (const_int 8)
1038               (const_int 8)) 0)
1039           (match_operand:QI 1 "immediate_operand" "")))]
1040   ""
1041   "")
1042
1043 (define_insn "*cmpqi_ext_3_insn"
1044   [(set (reg FLAGS_REG)
1045         (compare
1046           (subreg:QI
1047             (zero_extract:SI
1048               (match_operand 0 "ext_register_operand" "Q")
1049               (const_int 8)
1050               (const_int 8)) 0)
1051           (match_operand:QI 1 "general_operand" "Qmn")))]
1052   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1053   "cmp{b}\t{%1, %h0|%h0, %1}"
1054   [(set_attr "type" "icmp")
1055    (set_attr "modrm" "1")
1056    (set_attr "mode" "QI")])
1057
1058 (define_insn "*cmpqi_ext_3_insn_rex64"
1059   [(set (reg FLAGS_REG)
1060         (compare
1061           (subreg:QI
1062             (zero_extract:SI
1063               (match_operand 0 "ext_register_operand" "Q")
1064               (const_int 8)
1065               (const_int 8)) 0)
1066           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1067   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1068   "cmp{b}\t{%1, %h0|%h0, %1}"
1069   [(set_attr "type" "icmp")
1070    (set_attr "modrm" "1")
1071    (set_attr "mode" "QI")])
1072
1073 (define_insn "*cmpqi_ext_4"
1074   [(set (reg FLAGS_REG)
1075         (compare
1076           (subreg:QI
1077             (zero_extract:SI
1078               (match_operand 0 "ext_register_operand" "Q")
1079               (const_int 8)
1080               (const_int 8)) 0)
1081           (subreg:QI
1082             (zero_extract:SI
1083               (match_operand 1 "ext_register_operand" "Q")
1084               (const_int 8)
1085               (const_int 8)) 0)))]
1086   "ix86_match_ccmode (insn, CCmode)"
1087   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1088   [(set_attr "type" "icmp")
1089    (set_attr "mode" "QI")])
1090
1091 ;; These implement float point compares.
1092 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1093 ;; which would allow mix and match FP modes on the compares.  Which is what
1094 ;; the old patterns did, but with many more of them.
1095
1096 (define_expand "cbranchxf4"
1097   [(set (reg:CC FLAGS_REG)
1098         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1099                     (match_operand:XF 2 "nonmemory_operand" "")))
1100    (set (pc) (if_then_else
1101               (match_operator 0 "ix86_fp_comparison_operator"
1102                [(reg:CC FLAGS_REG)
1103                 (const_int 0)])
1104               (label_ref (match_operand 3 "" ""))
1105               (pc)))]
1106   "TARGET_80387"
1107 {
1108   ix86_compare_op0 = operands[1];
1109   ix86_compare_op1 = operands[2];
1110   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1111   DONE;
1112 })
1113
1114 (define_expand "cstorexf4"
1115   [(set (reg:CC FLAGS_REG)
1116         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1117                     (match_operand:XF 3 "nonmemory_operand" "")))
1118    (set (match_operand:QI 0 "register_operand" "")
1119               (match_operator 1 "ix86_fp_comparison_operator"
1120                [(reg:CC FLAGS_REG)
1121                 (const_int 0)]))]
1122   "TARGET_80387"
1123 {
1124   ix86_compare_op0 = operands[2];
1125   ix86_compare_op1 = operands[3];
1126   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1127   DONE;
1128 })
1129
1130 (define_expand "cbranch<mode>4"
1131   [(set (reg:CC FLAGS_REG)
1132         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1133                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1134    (set (pc) (if_then_else
1135               (match_operator 0 "ix86_fp_comparison_operator"
1136                [(reg:CC FLAGS_REG)
1137                 (const_int 0)])
1138               (label_ref (match_operand 3 "" ""))
1139               (pc)))]
1140   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1141 {
1142   ix86_compare_op0 = operands[1];
1143   ix86_compare_op1 = operands[2];
1144   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1145   DONE;
1146 })
1147
1148 (define_expand "cstore<mode>4"
1149   [(set (reg:CC FLAGS_REG)
1150         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1151                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1152    (set (match_operand:QI 0 "register_operand" "")
1153               (match_operator 1 "ix86_fp_comparison_operator"
1154                [(reg:CC FLAGS_REG)
1155                 (const_int 0)]))]
1156   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1157 {
1158   ix86_compare_op0 = operands[2];
1159   ix86_compare_op1 = operands[3];
1160   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1161   DONE;
1162 })
1163
1164 (define_expand "cbranchcc4"
1165   [(set (pc) (if_then_else
1166               (match_operator 0 "comparison_operator"
1167                [(match_operand 1 "flags_reg_operand" "")
1168                 (match_operand 2 "const0_operand" "")])
1169               (label_ref (match_operand 3 "" ""))
1170               (pc)))]
1171   ""
1172 {
1173   ix86_compare_op0 = operands[1];
1174   ix86_compare_op1 = operands[2];
1175   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1176   DONE;
1177 })
1178
1179 (define_expand "cstorecc4"
1180   [(set (match_operand:QI 0 "register_operand" "")
1181               (match_operator 1 "comparison_operator"
1182                [(match_operand 2 "flags_reg_operand" "")
1183                 (match_operand 3 "const0_operand" "")]))]
1184   ""
1185 {
1186   ix86_compare_op0 = operands[2];
1187   ix86_compare_op1 = operands[3];
1188   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1189   DONE;
1190 })
1191
1192
1193 ;; FP compares, step 1:
1194 ;; Set the FP condition codes.
1195 ;;
1196 ;; CCFPmode     compare with exceptions
1197 ;; CCFPUmode    compare with no exceptions
1198
1199 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1200 ;; used to manage the reg stack popping would not be preserved.
1201
1202 (define_insn "*cmpfp_0"
1203   [(set (match_operand:HI 0 "register_operand" "=a")
1204         (unspec:HI
1205           [(compare:CCFP
1206              (match_operand 1 "register_operand" "f")
1207              (match_operand 2 "const0_operand" ""))]
1208         UNSPEC_FNSTSW))]
1209   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1210    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1211   "* return output_fp_compare (insn, operands, 0, 0);"
1212   [(set_attr "type" "multi")
1213    (set_attr "unit" "i387")
1214    (set (attr "mode")
1215      (cond [(match_operand:SF 1 "" "")
1216               (const_string "SF")
1217             (match_operand:DF 1 "" "")
1218               (const_string "DF")
1219            ]
1220            (const_string "XF")))])
1221
1222 (define_insn_and_split "*cmpfp_0_cc"
1223   [(set (reg:CCFP FLAGS_REG)
1224         (compare:CCFP
1225           (match_operand 1 "register_operand" "f")
1226           (match_operand 2 "const0_operand" "")))
1227    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1228   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1229    && TARGET_SAHF && !TARGET_CMOVE
1230    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1231   "#"
1232   "&& reload_completed"
1233   [(set (match_dup 0)
1234         (unspec:HI
1235           [(compare:CCFP (match_dup 1)(match_dup 2))]
1236         UNSPEC_FNSTSW))
1237    (set (reg:CC FLAGS_REG)
1238         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1239   ""
1240   [(set_attr "type" "multi")
1241    (set_attr "unit" "i387")
1242    (set (attr "mode")
1243      (cond [(match_operand:SF 1 "" "")
1244               (const_string "SF")
1245             (match_operand:DF 1 "" "")
1246               (const_string "DF")
1247            ]
1248            (const_string "XF")))])
1249
1250 (define_insn "*cmpfp_xf"
1251   [(set (match_operand:HI 0 "register_operand" "=a")
1252         (unspec:HI
1253           [(compare:CCFP
1254              (match_operand:XF 1 "register_operand" "f")
1255              (match_operand:XF 2 "register_operand" "f"))]
1256           UNSPEC_FNSTSW))]
1257   "TARGET_80387"
1258   "* return output_fp_compare (insn, operands, 0, 0);"
1259   [(set_attr "type" "multi")
1260    (set_attr "unit" "i387")
1261    (set_attr "mode" "XF")])
1262
1263 (define_insn_and_split "*cmpfp_xf_cc"
1264   [(set (reg:CCFP FLAGS_REG)
1265         (compare:CCFP
1266           (match_operand:XF 1 "register_operand" "f")
1267           (match_operand:XF 2 "register_operand" "f")))
1268    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1269   "TARGET_80387
1270    && TARGET_SAHF && !TARGET_CMOVE"
1271   "#"
1272   "&& reload_completed"
1273   [(set (match_dup 0)
1274         (unspec:HI
1275           [(compare:CCFP (match_dup 1)(match_dup 2))]
1276         UNSPEC_FNSTSW))
1277    (set (reg:CC FLAGS_REG)
1278         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1279   ""
1280   [(set_attr "type" "multi")
1281    (set_attr "unit" "i387")
1282    (set_attr "mode" "XF")])
1283
1284 (define_insn "*cmpfp_<mode>"
1285   [(set (match_operand:HI 0 "register_operand" "=a")
1286         (unspec:HI
1287           [(compare:CCFP
1288              (match_operand:MODEF 1 "register_operand" "f")
1289              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1290           UNSPEC_FNSTSW))]
1291   "TARGET_80387"
1292   "* return output_fp_compare (insn, operands, 0, 0);"
1293   [(set_attr "type" "multi")
1294    (set_attr "unit" "i387")
1295    (set_attr "mode" "<MODE>")])
1296
1297 (define_insn_and_split "*cmpfp_<mode>_cc"
1298   [(set (reg:CCFP FLAGS_REG)
1299         (compare:CCFP
1300           (match_operand:MODEF 1 "register_operand" "f")
1301           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1302    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1303   "TARGET_80387
1304    && TARGET_SAHF && !TARGET_CMOVE"
1305   "#"
1306   "&& reload_completed"
1307   [(set (match_dup 0)
1308         (unspec:HI
1309           [(compare:CCFP (match_dup 1)(match_dup 2))]
1310         UNSPEC_FNSTSW))
1311    (set (reg:CC FLAGS_REG)
1312         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1313   ""
1314   [(set_attr "type" "multi")
1315    (set_attr "unit" "i387")
1316    (set_attr "mode" "<MODE>")])
1317
1318 (define_insn "*cmpfp_u"
1319   [(set (match_operand:HI 0 "register_operand" "=a")
1320         (unspec:HI
1321           [(compare:CCFPU
1322              (match_operand 1 "register_operand" "f")
1323              (match_operand 2 "register_operand" "f"))]
1324           UNSPEC_FNSTSW))]
1325   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1326    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1327   "* return output_fp_compare (insn, operands, 0, 1);"
1328   [(set_attr "type" "multi")
1329    (set_attr "unit" "i387")
1330    (set (attr "mode")
1331      (cond [(match_operand:SF 1 "" "")
1332               (const_string "SF")
1333             (match_operand:DF 1 "" "")
1334               (const_string "DF")
1335            ]
1336            (const_string "XF")))])
1337
1338 (define_insn_and_split "*cmpfp_u_cc"
1339   [(set (reg:CCFPU FLAGS_REG)
1340         (compare:CCFPU
1341           (match_operand 1 "register_operand" "f")
1342           (match_operand 2 "register_operand" "f")))
1343    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1344   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1345    && TARGET_SAHF && !TARGET_CMOVE
1346    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1347   "#"
1348   "&& reload_completed"
1349   [(set (match_dup 0)
1350         (unspec:HI
1351           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1352         UNSPEC_FNSTSW))
1353    (set (reg:CC FLAGS_REG)
1354         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1355   ""
1356   [(set_attr "type" "multi")
1357    (set_attr "unit" "i387")
1358    (set (attr "mode")
1359      (cond [(match_operand:SF 1 "" "")
1360               (const_string "SF")
1361             (match_operand:DF 1 "" "")
1362               (const_string "DF")
1363            ]
1364            (const_string "XF")))])
1365
1366 (define_insn "*cmpfp_<mode>"
1367   [(set (match_operand:HI 0 "register_operand" "=a")
1368         (unspec:HI
1369           [(compare:CCFP
1370              (match_operand 1 "register_operand" "f")
1371              (match_operator 3 "float_operator"
1372                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1373           UNSPEC_FNSTSW))]
1374   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1375    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1376    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1377   "* return output_fp_compare (insn, operands, 0, 0);"
1378   [(set_attr "type" "multi")
1379    (set_attr "unit" "i387")
1380    (set_attr "fp_int_src" "true")
1381    (set_attr "mode" "<MODE>")])
1382
1383 (define_insn_and_split "*cmpfp_<mode>_cc"
1384   [(set (reg:CCFP FLAGS_REG)
1385         (compare:CCFP
1386           (match_operand 1 "register_operand" "f")
1387           (match_operator 3 "float_operator"
1388             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1389    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1390   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1391    && TARGET_SAHF && !TARGET_CMOVE
1392    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1393    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1394   "#"
1395   "&& reload_completed"
1396   [(set (match_dup 0)
1397         (unspec:HI
1398           [(compare:CCFP
1399              (match_dup 1)
1400              (match_op_dup 3 [(match_dup 2)]))]
1401         UNSPEC_FNSTSW))
1402    (set (reg:CC FLAGS_REG)
1403         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1404   ""
1405   [(set_attr "type" "multi")
1406    (set_attr "unit" "i387")
1407    (set_attr "fp_int_src" "true")
1408    (set_attr "mode" "<MODE>")])
1409
1410 ;; FP compares, step 2
1411 ;; Move the fpsw to ax.
1412
1413 (define_insn "x86_fnstsw_1"
1414   [(set (match_operand:HI 0 "register_operand" "=a")
1415         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1416   "TARGET_80387"
1417   "fnstsw\t%0"
1418   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1419    (set_attr "mode" "SI")
1420    (set_attr "unit" "i387")])
1421
1422 ;; FP compares, step 3
1423 ;; Get ax into flags, general case.
1424
1425 (define_insn "x86_sahf_1"
1426   [(set (reg:CC FLAGS_REG)
1427         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1428                    UNSPEC_SAHF))]
1429   "TARGET_SAHF"
1430 {
1431 #ifndef HAVE_AS_IX86_SAHF
1432   if (TARGET_64BIT)
1433     return ASM_BYTE "0x9e";
1434   else
1435 #endif
1436   return "sahf";
1437 }
1438   [(set_attr "length" "1")
1439    (set_attr "athlon_decode" "vector")
1440    (set_attr "amdfam10_decode" "direct")
1441    (set_attr "mode" "SI")])
1442
1443 ;; Pentium Pro can do steps 1 through 3 in one go.
1444 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1445 (define_insn "*cmpfp_i_mixed"
1446   [(set (reg:CCFP FLAGS_REG)
1447         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1448                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1449   "TARGET_MIX_SSE_I387
1450    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1451    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1452   "* return output_fp_compare (insn, operands, 1, 0);"
1453   [(set_attr "type" "fcmp,ssecomi")
1454    (set_attr "prefix" "orig,maybe_vex")
1455    (set (attr "mode")
1456      (if_then_else (match_operand:SF 1 "" "")
1457         (const_string "SF")
1458         (const_string "DF")))
1459    (set (attr "prefix_rep")
1460         (if_then_else (eq_attr "type" "ssecomi")
1461                       (const_string "0")
1462                       (const_string "*")))
1463    (set (attr "prefix_data16")
1464         (cond [(eq_attr "type" "fcmp")
1465                  (const_string "*")
1466                (eq_attr "mode" "DF")
1467                  (const_string "1")
1468               ]
1469               (const_string "0")))
1470    (set_attr "athlon_decode" "vector")
1471    (set_attr "amdfam10_decode" "direct")])
1472
1473 (define_insn "*cmpfp_i_sse"
1474   [(set (reg:CCFP FLAGS_REG)
1475         (compare:CCFP (match_operand 0 "register_operand" "x")
1476                       (match_operand 1 "nonimmediate_operand" "xm")))]
1477   "TARGET_SSE_MATH
1478    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1479    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1480   "* return output_fp_compare (insn, operands, 1, 0);"
1481   [(set_attr "type" "ssecomi")
1482    (set_attr "prefix" "maybe_vex")
1483    (set (attr "mode")
1484      (if_then_else (match_operand:SF 1 "" "")
1485         (const_string "SF")
1486         (const_string "DF")))
1487    (set_attr "prefix_rep" "0")
1488    (set (attr "prefix_data16")
1489         (if_then_else (eq_attr "mode" "DF")
1490                       (const_string "1")
1491                       (const_string "0")))
1492    (set_attr "athlon_decode" "vector")
1493    (set_attr "amdfam10_decode" "direct")])
1494
1495 (define_insn "*cmpfp_i_i387"
1496   [(set (reg:CCFP FLAGS_REG)
1497         (compare:CCFP (match_operand 0 "register_operand" "f")
1498                       (match_operand 1 "register_operand" "f")))]
1499   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1500    && TARGET_CMOVE
1501    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1502    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503   "* return output_fp_compare (insn, operands, 1, 0);"
1504   [(set_attr "type" "fcmp")
1505    (set (attr "mode")
1506      (cond [(match_operand:SF 1 "" "")
1507               (const_string "SF")
1508             (match_operand:DF 1 "" "")
1509               (const_string "DF")
1510            ]
1511            (const_string "XF")))
1512    (set_attr "athlon_decode" "vector")
1513    (set_attr "amdfam10_decode" "direct")])
1514
1515 (define_insn "*cmpfp_iu_mixed"
1516   [(set (reg:CCFPU FLAGS_REG)
1517         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1518                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1519   "TARGET_MIX_SSE_I387
1520    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1521    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1522   "* return output_fp_compare (insn, operands, 1, 1);"
1523   [(set_attr "type" "fcmp,ssecomi")
1524    (set_attr "prefix" "orig,maybe_vex")
1525    (set (attr "mode")
1526      (if_then_else (match_operand:SF 1 "" "")
1527         (const_string "SF")
1528         (const_string "DF")))
1529    (set (attr "prefix_rep")
1530         (if_then_else (eq_attr "type" "ssecomi")
1531                       (const_string "0")
1532                       (const_string "*")))
1533    (set (attr "prefix_data16")
1534         (cond [(eq_attr "type" "fcmp")
1535                  (const_string "*")
1536                (eq_attr "mode" "DF")
1537                  (const_string "1")
1538               ]
1539               (const_string "0")))
1540    (set_attr "athlon_decode" "vector")
1541    (set_attr "amdfam10_decode" "direct")])
1542
1543 (define_insn "*cmpfp_iu_sse"
1544   [(set (reg:CCFPU FLAGS_REG)
1545         (compare:CCFPU (match_operand 0 "register_operand" "x")
1546                        (match_operand 1 "nonimmediate_operand" "xm")))]
1547   "TARGET_SSE_MATH
1548    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1549    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1550   "* return output_fp_compare (insn, operands, 1, 1);"
1551   [(set_attr "type" "ssecomi")
1552    (set_attr "prefix" "maybe_vex")
1553    (set (attr "mode")
1554      (if_then_else (match_operand:SF 1 "" "")
1555         (const_string "SF")
1556         (const_string "DF")))
1557    (set_attr "prefix_rep" "0")
1558    (set (attr "prefix_data16")
1559         (if_then_else (eq_attr "mode" "DF")
1560                       (const_string "1")
1561                       (const_string "0")))
1562    (set_attr "athlon_decode" "vector")
1563    (set_attr "amdfam10_decode" "direct")])
1564
1565 (define_insn "*cmpfp_iu_387"
1566   [(set (reg:CCFPU FLAGS_REG)
1567         (compare:CCFPU (match_operand 0 "register_operand" "f")
1568                        (match_operand 1 "register_operand" "f")))]
1569   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1570    && TARGET_CMOVE
1571    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1572    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1573   "* return output_fp_compare (insn, operands, 1, 1);"
1574   [(set_attr "type" "fcmp")
1575    (set (attr "mode")
1576      (cond [(match_operand:SF 1 "" "")
1577               (const_string "SF")
1578             (match_operand:DF 1 "" "")
1579               (const_string "DF")
1580            ]
1581            (const_string "XF")))
1582    (set_attr "athlon_decode" "vector")
1583    (set_attr "amdfam10_decode" "direct")])
1584 \f
1585 ;; Move instructions.
1586
1587 ;; General case of fullword move.
1588
1589 (define_expand "movsi"
1590   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1591         (match_operand:SI 1 "general_operand" ""))]
1592   ""
1593   "ix86_expand_move (SImode, operands); DONE;")
1594
1595 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1596 ;; general_operand.
1597 ;;
1598 ;; %%% We don't use a post-inc memory reference because x86 is not a
1599 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1600 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1601 ;; targets without our curiosities, and it is just as easy to represent
1602 ;; this differently.
1603
1604 (define_insn "*pushsi2"
1605   [(set (match_operand:SI 0 "push_operand" "=<")
1606         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1607   "!TARGET_64BIT"
1608   "push{l}\t%1"
1609   [(set_attr "type" "push")
1610    (set_attr "mode" "SI")])
1611
1612 ;; For 64BIT abi we always round up to 8 bytes.
1613 (define_insn "*pushsi2_rex64"
1614   [(set (match_operand:SI 0 "push_operand" "=X")
1615         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1616   "TARGET_64BIT"
1617   "push{q}\t%q1"
1618   [(set_attr "type" "push")
1619    (set_attr "mode" "SI")])
1620
1621 (define_insn "*pushsi2_prologue"
1622   [(set (match_operand:SI 0 "push_operand" "=<")
1623         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1624    (clobber (mem:BLK (scratch)))]
1625   "!TARGET_64BIT"
1626   "push{l}\t%1"
1627   [(set_attr "type" "push")
1628    (set_attr "mode" "SI")])
1629
1630 (define_insn "*popsi1_epilogue"
1631   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1632         (mem:SI (reg:SI SP_REG)))
1633    (set (reg:SI SP_REG)
1634         (plus:SI (reg:SI SP_REG) (const_int 4)))
1635    (clobber (mem:BLK (scratch)))]
1636   "!TARGET_64BIT"
1637   "pop{l}\t%0"
1638   [(set_attr "type" "pop")
1639    (set_attr "mode" "SI")])
1640
1641 (define_insn "popsi1"
1642   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1643         (mem:SI (reg:SI SP_REG)))
1644    (set (reg:SI SP_REG)
1645         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1646   "!TARGET_64BIT"
1647   "pop{l}\t%0"
1648   [(set_attr "type" "pop")
1649    (set_attr "mode" "SI")])
1650
1651 (define_insn "*movsi_xor"
1652   [(set (match_operand:SI 0 "register_operand" "=r")
1653         (match_operand:SI 1 "const0_operand" ""))
1654    (clobber (reg:CC FLAGS_REG))]
1655   "reload_completed"
1656   "xor{l}\t%0, %0"
1657   [(set_attr "type" "alu1")
1658    (set_attr "mode" "SI")
1659    (set_attr "length_immediate" "0")])
1660
1661 (define_insn "*movsi_or"
1662   [(set (match_operand:SI 0 "register_operand" "=r")
1663         (match_operand:SI 1 "immediate_operand" "i"))
1664    (clobber (reg:CC FLAGS_REG))]
1665   "reload_completed
1666    && operands[1] == constm1_rtx"
1667 {
1668   operands[1] = constm1_rtx;
1669   return "or{l}\t{%1, %0|%0, %1}";
1670 }
1671   [(set_attr "type" "alu1")
1672    (set_attr "mode" "SI")
1673    (set_attr "length_immediate" "1")])
1674
1675 (define_insn "*movsi_1"
1676   [(set (match_operand:SI 0 "nonimmediate_operand"
1677                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1678         (match_operand:SI 1 "general_operand"
1679                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1680   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1681 {
1682   switch (get_attr_type (insn))
1683     {
1684     case TYPE_SSELOG1:
1685       if (get_attr_mode (insn) == MODE_TI)
1686         return "%vpxor\t%0, %d0";
1687       return "%vxorps\t%0, %d0";
1688
1689     case TYPE_SSEMOV:
1690       switch (get_attr_mode (insn))
1691         {
1692         case MODE_TI:
1693           return "%vmovdqa\t{%1, %0|%0, %1}";
1694         case MODE_V4SF:
1695           return "%vmovaps\t{%1, %0|%0, %1}";
1696         case MODE_SI:
1697           return "%vmovd\t{%1, %0|%0, %1}";
1698         case MODE_SF:
1699           return "%vmovss\t{%1, %0|%0, %1}";
1700         default:
1701           gcc_unreachable ();
1702         }
1703
1704     case TYPE_MMX:
1705       return "pxor\t%0, %0";
1706
1707     case TYPE_MMXMOV:
1708       if (get_attr_mode (insn) == MODE_DI)
1709         return "movq\t{%1, %0|%0, %1}";
1710       return "movd\t{%1, %0|%0, %1}";
1711
1712     case TYPE_LEA:
1713       return "lea{l}\t{%1, %0|%0, %1}";
1714
1715     default:
1716       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1717       return "mov{l}\t{%1, %0|%0, %1}";
1718     }
1719 }
1720   [(set (attr "type")
1721      (cond [(eq_attr "alternative" "2")
1722               (const_string "mmx")
1723             (eq_attr "alternative" "3,4,5")
1724               (const_string "mmxmov")
1725             (eq_attr "alternative" "6")
1726               (const_string "sselog1")
1727             (eq_attr "alternative" "7,8,9,10,11")
1728               (const_string "ssemov")
1729             (match_operand:DI 1 "pic_32bit_operand" "")
1730               (const_string "lea")
1731            ]
1732            (const_string "imov")))
1733    (set (attr "prefix")
1734      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1735        (const_string "orig")
1736        (const_string "maybe_vex")))
1737    (set (attr "prefix_data16")
1738      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1739        (const_string "1")
1740        (const_string "*")))
1741    (set (attr "mode")
1742      (cond [(eq_attr "alternative" "2,3")
1743               (const_string "DI")
1744             (eq_attr "alternative" "6,7")
1745               (if_then_else
1746                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1747                 (const_string "V4SF")
1748                 (const_string "TI"))
1749             (and (eq_attr "alternative" "8,9,10,11")
1750                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1751               (const_string "SF")
1752            ]
1753            (const_string "SI")))])
1754
1755 ;; Stores and loads of ax to arbitrary constant address.
1756 ;; We fake an second form of instruction to force reload to load address
1757 ;; into register when rax is not available
1758 (define_insn "*movabssi_1_rex64"
1759   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1760         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1761   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1762   "@
1763    movabs{l}\t{%1, %P0|%P0, %1}
1764    mov{l}\t{%1, %a0|%a0, %1}"
1765   [(set_attr "type" "imov")
1766    (set_attr "modrm" "0,*")
1767    (set_attr "length_address" "8,0")
1768    (set_attr "length_immediate" "0,*")
1769    (set_attr "memory" "store")
1770    (set_attr "mode" "SI")])
1771
1772 (define_insn "*movabssi_2_rex64"
1773   [(set (match_operand:SI 0 "register_operand" "=a,r")
1774         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1775   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1776   "@
1777    movabs{l}\t{%P1, %0|%0, %P1}
1778    mov{l}\t{%a1, %0|%0, %a1}"
1779   [(set_attr "type" "imov")
1780    (set_attr "modrm" "0,*")
1781    (set_attr "length_address" "8,0")
1782    (set_attr "length_immediate" "0")
1783    (set_attr "memory" "load")
1784    (set_attr "mode" "SI")])
1785
1786 (define_insn "*swapsi"
1787   [(set (match_operand:SI 0 "register_operand" "+r")
1788         (match_operand:SI 1 "register_operand" "+r"))
1789    (set (match_dup 1)
1790         (match_dup 0))]
1791   ""
1792   "xchg{l}\t%1, %0"
1793   [(set_attr "type" "imov")
1794    (set_attr "mode" "SI")
1795    (set_attr "pent_pair" "np")
1796    (set_attr "athlon_decode" "vector")
1797    (set_attr "amdfam10_decode" "double")])
1798
1799 (define_expand "movhi"
1800   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1801         (match_operand:HI 1 "general_operand" ""))]
1802   ""
1803   "ix86_expand_move (HImode, operands); DONE;")
1804
1805 (define_insn "*pushhi2"
1806   [(set (match_operand:HI 0 "push_operand" "=X")
1807         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1808   "!TARGET_64BIT"
1809   "push{l}\t%k1"
1810   [(set_attr "type" "push")
1811    (set_attr "mode" "SI")])
1812
1813 ;; For 64BIT abi we always round up to 8 bytes.
1814 (define_insn "*pushhi2_rex64"
1815   [(set (match_operand:HI 0 "push_operand" "=X")
1816         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1817   "TARGET_64BIT"
1818   "push{q}\t%q1"
1819   [(set_attr "type" "push")
1820    (set_attr "mode" "DI")])
1821
1822 (define_insn "*movhi_1"
1823   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1824         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1825   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1826 {
1827   switch (get_attr_type (insn))
1828     {
1829     case TYPE_IMOVX:
1830       /* movzwl is faster than movw on p2 due to partial word stalls,
1831          though not as fast as an aligned movl.  */
1832       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1833     default:
1834       if (get_attr_mode (insn) == MODE_SI)
1835         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1836       else
1837         return "mov{w}\t{%1, %0|%0, %1}";
1838     }
1839 }
1840   [(set (attr "type")
1841      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1842               (const_string "imov")
1843             (and (eq_attr "alternative" "0")
1844                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1845                           (const_int 0))
1846                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1847                           (const_int 0))))
1848               (const_string "imov")
1849             (and (eq_attr "alternative" "1,2")
1850                  (match_operand:HI 1 "aligned_operand" ""))
1851               (const_string "imov")
1852             (and (ne (symbol_ref "TARGET_MOVX")
1853                      (const_int 0))
1854                  (eq_attr "alternative" "0,2"))
1855               (const_string "imovx")
1856            ]
1857            (const_string "imov")))
1858     (set (attr "mode")
1859       (cond [(eq_attr "type" "imovx")
1860                (const_string "SI")
1861              (and (eq_attr "alternative" "1,2")
1862                   (match_operand:HI 1 "aligned_operand" ""))
1863                (const_string "SI")
1864              (and (eq_attr "alternative" "0")
1865                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1866                            (const_int 0))
1867                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1868                            (const_int 0))))
1869                (const_string "SI")
1870             ]
1871             (const_string "HI")))])
1872
1873 ;; Stores and loads of ax to arbitrary constant address.
1874 ;; We fake an second form of instruction to force reload to load address
1875 ;; into register when rax is not available
1876 (define_insn "*movabshi_1_rex64"
1877   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1878         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1879   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1880   "@
1881    movabs{w}\t{%1, %P0|%P0, %1}
1882    mov{w}\t{%1, %a0|%a0, %1}"
1883   [(set_attr "type" "imov")
1884    (set_attr "modrm" "0,*")
1885    (set_attr "length_address" "8,0")
1886    (set_attr "length_immediate" "0,*")
1887    (set_attr "memory" "store")
1888    (set_attr "mode" "HI")])
1889
1890 (define_insn "*movabshi_2_rex64"
1891   [(set (match_operand:HI 0 "register_operand" "=a,r")
1892         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1893   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1894   "@
1895    movabs{w}\t{%P1, %0|%0, %P1}
1896    mov{w}\t{%a1, %0|%0, %a1}"
1897   [(set_attr "type" "imov")
1898    (set_attr "modrm" "0,*")
1899    (set_attr "length_address" "8,0")
1900    (set_attr "length_immediate" "0")
1901    (set_attr "memory" "load")
1902    (set_attr "mode" "HI")])
1903
1904 (define_insn "*swaphi_1"
1905   [(set (match_operand:HI 0 "register_operand" "+r")
1906         (match_operand:HI 1 "register_operand" "+r"))
1907    (set (match_dup 1)
1908         (match_dup 0))]
1909   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1910   "xchg{l}\t%k1, %k0"
1911   [(set_attr "type" "imov")
1912    (set_attr "mode" "SI")
1913    (set_attr "pent_pair" "np")
1914    (set_attr "athlon_decode" "vector")
1915    (set_attr "amdfam10_decode" "double")])
1916
1917 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1918 (define_insn "*swaphi_2"
1919   [(set (match_operand:HI 0 "register_operand" "+r")
1920         (match_operand:HI 1 "register_operand" "+r"))
1921    (set (match_dup 1)
1922         (match_dup 0))]
1923   "TARGET_PARTIAL_REG_STALL"
1924   "xchg{w}\t%1, %0"
1925   [(set_attr "type" "imov")
1926    (set_attr "mode" "HI")
1927    (set_attr "pent_pair" "np")
1928    (set_attr "athlon_decode" "vector")])
1929
1930 (define_expand "movstricthi"
1931   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1932         (match_operand:HI 1 "general_operand" ""))]
1933   ""
1934 {
1935   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1936     FAIL;
1937   /* Don't generate memory->memory moves, go through a register */
1938   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1939     operands[1] = force_reg (HImode, operands[1]);
1940 })
1941
1942 (define_insn "*movstricthi_1"
1943   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1944         (match_operand:HI 1 "general_operand" "rn,m"))]
1945   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1946    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1947   "mov{w}\t{%1, %0|%0, %1}"
1948   [(set_attr "type" "imov")
1949    (set_attr "mode" "HI")])
1950
1951 (define_insn "*movstricthi_xor"
1952   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1953         (match_operand:HI 1 "const0_operand" ""))
1954    (clobber (reg:CC FLAGS_REG))]
1955   "reload_completed"
1956   "xor{w}\t%0, %0"
1957   [(set_attr "type" "alu1")
1958    (set_attr "mode" "HI")
1959    (set_attr "length_immediate" "0")])
1960
1961 (define_expand "movqi"
1962   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1963         (match_operand:QI 1 "general_operand" ""))]
1964   ""
1965   "ix86_expand_move (QImode, operands); DONE;")
1966
1967 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1968 ;; "push a byte".  But actually we use pushl, which has the effect
1969 ;; of rounding the amount pushed up to a word.
1970
1971 (define_insn "*pushqi2"
1972   [(set (match_operand:QI 0 "push_operand" "=X")
1973         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1974   "!TARGET_64BIT"
1975   "push{l}\t%k1"
1976   [(set_attr "type" "push")
1977    (set_attr "mode" "SI")])
1978
1979 ;; For 64BIT abi we always round up to 8 bytes.
1980 (define_insn "*pushqi2_rex64"
1981   [(set (match_operand:QI 0 "push_operand" "=X")
1982         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1983   "TARGET_64BIT"
1984   "push{q}\t%q1"
1985   [(set_attr "type" "push")
1986    (set_attr "mode" "DI")])
1987
1988 ;; Situation is quite tricky about when to choose full sized (SImode) move
1989 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1990 ;; partial register dependency machines (such as AMD Athlon), where QImode
1991 ;; moves issue extra dependency and for partial register stalls machines
1992 ;; that don't use QImode patterns (and QImode move cause stall on the next
1993 ;; instruction).
1994 ;;
1995 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1996 ;; register stall machines with, where we use QImode instructions, since
1997 ;; partial register stall can be caused there.  Then we use movzx.
1998 (define_insn "*movqi_1"
1999   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2000         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2001   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2002 {
2003   switch (get_attr_type (insn))
2004     {
2005     case TYPE_IMOVX:
2006       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2007       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2008     default:
2009       if (get_attr_mode (insn) == MODE_SI)
2010         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2011       else
2012         return "mov{b}\t{%1, %0|%0, %1}";
2013     }
2014 }
2015   [(set (attr "type")
2016      (cond [(and (eq_attr "alternative" "5")
2017                  (not (match_operand:QI 1 "aligned_operand" "")))
2018               (const_string "imovx")
2019             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2020               (const_string "imov")
2021             (and (eq_attr "alternative" "3")
2022                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2023                           (const_int 0))
2024                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2025                           (const_int 0))))
2026               (const_string "imov")
2027             (eq_attr "alternative" "3,5")
2028               (const_string "imovx")
2029             (and (ne (symbol_ref "TARGET_MOVX")
2030                      (const_int 0))
2031                  (eq_attr "alternative" "2"))
2032               (const_string "imovx")
2033            ]
2034            (const_string "imov")))
2035    (set (attr "mode")
2036       (cond [(eq_attr "alternative" "3,4,5")
2037                (const_string "SI")
2038              (eq_attr "alternative" "6")
2039                (const_string "QI")
2040              (eq_attr "type" "imovx")
2041                (const_string "SI")
2042              (and (eq_attr "type" "imov")
2043                   (and (eq_attr "alternative" "0,1")
2044                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2045                                 (const_int 0))
2046                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2047                                      (const_int 0))
2048                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2049                                      (const_int 0))))))
2050                (const_string "SI")
2051              ;; Avoid partial register stalls when not using QImode arithmetic
2052              (and (eq_attr "type" "imov")
2053                   (and (eq_attr "alternative" "0,1")
2054                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2055                                 (const_int 0))
2056                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2057                                 (const_int 0)))))
2058                (const_string "SI")
2059            ]
2060            (const_string "QI")))])
2061
2062 (define_insn "*swapqi_1"
2063   [(set (match_operand:QI 0 "register_operand" "+r")
2064         (match_operand:QI 1 "register_operand" "+r"))
2065    (set (match_dup 1)
2066         (match_dup 0))]
2067   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2068   "xchg{l}\t%k1, %k0"
2069   [(set_attr "type" "imov")
2070    (set_attr "mode" "SI")
2071    (set_attr "pent_pair" "np")
2072    (set_attr "athlon_decode" "vector")
2073    (set_attr "amdfam10_decode" "vector")])
2074
2075 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2076 (define_insn "*swapqi_2"
2077   [(set (match_operand:QI 0 "register_operand" "+q")
2078         (match_operand:QI 1 "register_operand" "+q"))
2079    (set (match_dup 1)
2080         (match_dup 0))]
2081   "TARGET_PARTIAL_REG_STALL"
2082   "xchg{b}\t%1, %0"
2083   [(set_attr "type" "imov")
2084    (set_attr "mode" "QI")
2085    (set_attr "pent_pair" "np")
2086    (set_attr "athlon_decode" "vector")])
2087
2088 (define_expand "movstrictqi"
2089   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2090         (match_operand:QI 1 "general_operand" ""))]
2091   ""
2092 {
2093   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2094     FAIL;
2095   /* Don't generate memory->memory moves, go through a register.  */
2096   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2097     operands[1] = force_reg (QImode, operands[1]);
2098 })
2099
2100 (define_insn "*movstrictqi_1"
2101   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2102         (match_operand:QI 1 "general_operand" "*qn,m"))]
2103   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2104    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2105   "mov{b}\t{%1, %0|%0, %1}"
2106   [(set_attr "type" "imov")
2107    (set_attr "mode" "QI")])
2108
2109 (define_insn "*movstrictqi_xor"
2110   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2111         (match_operand:QI 1 "const0_operand" ""))
2112    (clobber (reg:CC FLAGS_REG))]
2113   "reload_completed"
2114   "xor{b}\t%0, %0"
2115   [(set_attr "type" "alu1")
2116    (set_attr "mode" "QI")
2117    (set_attr "length_immediate" "0")])
2118
2119 (define_insn "*movsi_extv_1"
2120   [(set (match_operand:SI 0 "register_operand" "=R")
2121         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2122                          (const_int 8)
2123                          (const_int 8)))]
2124   ""
2125   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2126   [(set_attr "type" "imovx")
2127    (set_attr "mode" "SI")])
2128
2129 (define_insn "*movhi_extv_1"
2130   [(set (match_operand:HI 0 "register_operand" "=R")
2131         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2132                          (const_int 8)
2133                          (const_int 8)))]
2134   ""
2135   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2136   [(set_attr "type" "imovx")
2137    (set_attr "mode" "SI")])
2138
2139 (define_insn "*movqi_extv_1"
2140   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2141         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2142                          (const_int 8)
2143                          (const_int 8)))]
2144   "!TARGET_64BIT"
2145 {
2146   switch (get_attr_type (insn))
2147     {
2148     case TYPE_IMOVX:
2149       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2150     default:
2151       return "mov{b}\t{%h1, %0|%0, %h1}";
2152     }
2153 }
2154   [(set (attr "type")
2155      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2156                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2157                              (ne (symbol_ref "TARGET_MOVX")
2158                                  (const_int 0))))
2159         (const_string "imovx")
2160         (const_string "imov")))
2161    (set (attr "mode")
2162      (if_then_else (eq_attr "type" "imovx")
2163         (const_string "SI")
2164         (const_string "QI")))])
2165
2166 (define_insn "*movqi_extv_1_rex64"
2167   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2168         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2169                          (const_int 8)
2170                          (const_int 8)))]
2171   "TARGET_64BIT"
2172 {
2173   switch (get_attr_type (insn))
2174     {
2175     case TYPE_IMOVX:
2176       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2177     default:
2178       return "mov{b}\t{%h1, %0|%0, %h1}";
2179     }
2180 }
2181   [(set (attr "type")
2182      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2183                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2184                              (ne (symbol_ref "TARGET_MOVX")
2185                                  (const_int 0))))
2186         (const_string "imovx")
2187         (const_string "imov")))
2188    (set (attr "mode")
2189      (if_then_else (eq_attr "type" "imovx")
2190         (const_string "SI")
2191         (const_string "QI")))])
2192
2193 ;; Stores and loads of ax to arbitrary constant address.
2194 ;; We fake an second form of instruction to force reload to load address
2195 ;; into register when rax is not available
2196 (define_insn "*movabsqi_1_rex64"
2197   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2198         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2199   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2200   "@
2201    movabs{b}\t{%1, %P0|%P0, %1}
2202    mov{b}\t{%1, %a0|%a0, %1}"
2203   [(set_attr "type" "imov")
2204    (set_attr "modrm" "0,*")
2205    (set_attr "length_address" "8,0")
2206    (set_attr "length_immediate" "0,*")
2207    (set_attr "memory" "store")
2208    (set_attr "mode" "QI")])
2209
2210 (define_insn "*movabsqi_2_rex64"
2211   [(set (match_operand:QI 0 "register_operand" "=a,r")
2212         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2213   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2214   "@
2215    movabs{b}\t{%P1, %0|%0, %P1}
2216    mov{b}\t{%a1, %0|%0, %a1}"
2217   [(set_attr "type" "imov")
2218    (set_attr "modrm" "0,*")
2219    (set_attr "length_address" "8,0")
2220    (set_attr "length_immediate" "0")
2221    (set_attr "memory" "load")
2222    (set_attr "mode" "QI")])
2223
2224 (define_insn "*movdi_extzv_1"
2225   [(set (match_operand:DI 0 "register_operand" "=R")
2226         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2227                          (const_int 8)
2228                          (const_int 8)))]
2229   "TARGET_64BIT"
2230   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2231   [(set_attr "type" "imovx")
2232    (set_attr "mode" "SI")])
2233
2234 (define_insn "*movsi_extzv_1"
2235   [(set (match_operand:SI 0 "register_operand" "=R")
2236         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2237                          (const_int 8)
2238                          (const_int 8)))]
2239   ""
2240   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2241   [(set_attr "type" "imovx")
2242    (set_attr "mode" "SI")])
2243
2244 (define_insn "*movqi_extzv_2"
2245   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2246         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2247                                     (const_int 8)
2248                                     (const_int 8)) 0))]
2249   "!TARGET_64BIT"
2250 {
2251   switch (get_attr_type (insn))
2252     {
2253     case TYPE_IMOVX:
2254       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2255     default:
2256       return "mov{b}\t{%h1, %0|%0, %h1}";
2257     }
2258 }
2259   [(set (attr "type")
2260      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2261                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2262                              (ne (symbol_ref "TARGET_MOVX")
2263                                  (const_int 0))))
2264         (const_string "imovx")
2265         (const_string "imov")))
2266    (set (attr "mode")
2267      (if_then_else (eq_attr "type" "imovx")
2268         (const_string "SI")
2269         (const_string "QI")))])
2270
2271 (define_insn "*movqi_extzv_2_rex64"
2272   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2273         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2274                                     (const_int 8)
2275                                     (const_int 8)) 0))]
2276   "TARGET_64BIT"
2277 {
2278   switch (get_attr_type (insn))
2279     {
2280     case TYPE_IMOVX:
2281       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2282     default:
2283       return "mov{b}\t{%h1, %0|%0, %h1}";
2284     }
2285 }
2286   [(set (attr "type")
2287      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2288                         (ne (symbol_ref "TARGET_MOVX")
2289                             (const_int 0)))
2290         (const_string "imovx")
2291         (const_string "imov")))
2292    (set (attr "mode")
2293      (if_then_else (eq_attr "type" "imovx")
2294         (const_string "SI")
2295         (const_string "QI")))])
2296
2297 (define_insn "movsi_insv_1"
2298   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2299                          (const_int 8)
2300                          (const_int 8))
2301         (match_operand:SI 1 "general_operand" "Qmn"))]
2302   "!TARGET_64BIT"
2303   "mov{b}\t{%b1, %h0|%h0, %b1}"
2304   [(set_attr "type" "imov")
2305    (set_attr "mode" "QI")])
2306
2307 (define_insn "*movsi_insv_1_rex64"
2308   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2309                          (const_int 8)
2310                          (const_int 8))
2311         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2312   "TARGET_64BIT"
2313   "mov{b}\t{%b1, %h0|%h0, %b1}"
2314   [(set_attr "type" "imov")
2315    (set_attr "mode" "QI")])
2316
2317 (define_insn "movdi_insv_1_rex64"
2318   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2319                          (const_int 8)
2320                          (const_int 8))
2321         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2322   "TARGET_64BIT"
2323   "mov{b}\t{%b1, %h0|%h0, %b1}"
2324   [(set_attr "type" "imov")
2325    (set_attr "mode" "QI")])
2326
2327 (define_insn "*movqi_insv_2"
2328   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2329                          (const_int 8)
2330                          (const_int 8))
2331         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2332                      (const_int 8)))]
2333   ""
2334   "mov{b}\t{%h1, %h0|%h0, %h1}"
2335   [(set_attr "type" "imov")
2336    (set_attr "mode" "QI")])
2337
2338 (define_expand "movdi"
2339   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2340         (match_operand:DI 1 "general_operand" ""))]
2341   ""
2342   "ix86_expand_move (DImode, operands); DONE;")
2343
2344 (define_insn "*pushdi"
2345   [(set (match_operand:DI 0 "push_operand" "=<")
2346         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2347   "!TARGET_64BIT"
2348   "#")
2349
2350 (define_insn "*pushdi2_rex64"
2351   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2352         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2353   "TARGET_64BIT"
2354   "@
2355    push{q}\t%1
2356    #"
2357   [(set_attr "type" "push,multi")
2358    (set_attr "mode" "DI")])
2359
2360 ;; Convert impossible pushes of immediate to existing instructions.
2361 ;; First try to get scratch register and go through it.  In case this
2362 ;; fails, push sign extended lower part first and then overwrite
2363 ;; upper part by 32bit move.
2364 (define_peephole2
2365   [(match_scratch:DI 2 "r")
2366    (set (match_operand:DI 0 "push_operand" "")
2367         (match_operand:DI 1 "immediate_operand" ""))]
2368   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2369    && !x86_64_immediate_operand (operands[1], DImode)"
2370   [(set (match_dup 2) (match_dup 1))
2371    (set (match_dup 0) (match_dup 2))]
2372   "")
2373
2374 ;; We need to define this as both peepholer and splitter for case
2375 ;; peephole2 pass is not run.
2376 ;; "&& 1" is needed to keep it from matching the previous pattern.
2377 (define_peephole2
2378   [(set (match_operand:DI 0 "push_operand" "")
2379         (match_operand:DI 1 "immediate_operand" ""))]
2380   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2381    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2382   [(set (match_dup 0) (match_dup 1))
2383    (set (match_dup 2) (match_dup 3))]
2384 {
2385   split_di (&operands[1], 1, &operands[2], &operands[3]);
2386
2387   operands[1] = gen_lowpart (DImode, operands[2]);
2388   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2389                                                    GEN_INT (4)));
2390 })
2391
2392 (define_split
2393   [(set (match_operand:DI 0 "push_operand" "")
2394         (match_operand:DI 1 "immediate_operand" ""))]
2395   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2396                     ? epilogue_completed : reload_completed)
2397    && !symbolic_operand (operands[1], DImode)
2398    && !x86_64_immediate_operand (operands[1], DImode)"
2399   [(set (match_dup 0) (match_dup 1))
2400    (set (match_dup 2) (match_dup 3))]
2401 {
2402   split_di (&operands[1], 1, &operands[2], &operands[3]);
2403
2404   operands[1] = gen_lowpart (DImode, operands[2]);
2405   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2406                                                    GEN_INT (4)));
2407 })
2408
2409 (define_insn "*pushdi2_prologue_rex64"
2410   [(set (match_operand:DI 0 "push_operand" "=<")
2411         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2412    (clobber (mem:BLK (scratch)))]
2413   "TARGET_64BIT"
2414   "push{q}\t%1"
2415   [(set_attr "type" "push")
2416    (set_attr "mode" "DI")])
2417
2418 (define_insn "*popdi1_epilogue_rex64"
2419   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2420         (mem:DI (reg:DI SP_REG)))
2421    (set (reg:DI SP_REG)
2422         (plus:DI (reg:DI SP_REG) (const_int 8)))
2423    (clobber (mem:BLK (scratch)))]
2424   "TARGET_64BIT"
2425   "pop{q}\t%0"
2426   [(set_attr "type" "pop")
2427    (set_attr "mode" "DI")])
2428
2429 (define_insn "popdi1"
2430   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2431         (mem:DI (reg:DI SP_REG)))
2432    (set (reg:DI SP_REG)
2433         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2434   "TARGET_64BIT"
2435   "pop{q}\t%0"
2436   [(set_attr "type" "pop")
2437    (set_attr "mode" "DI")])
2438
2439 (define_insn "*movdi_xor_rex64"
2440   [(set (match_operand:DI 0 "register_operand" "=r")
2441         (match_operand:DI 1 "const0_operand" ""))
2442    (clobber (reg:CC FLAGS_REG))]
2443   "TARGET_64BIT
2444    && reload_completed"
2445   "xor{l}\t%k0, %k0";
2446   [(set_attr "type" "alu1")
2447    (set_attr "mode" "SI")
2448    (set_attr "length_immediate" "0")])
2449
2450 (define_insn "*movdi_or_rex64"
2451   [(set (match_operand:DI 0 "register_operand" "=r")
2452         (match_operand:DI 1 "const_int_operand" "i"))
2453    (clobber (reg:CC FLAGS_REG))]
2454   "TARGET_64BIT
2455    && reload_completed
2456    && operands[1] == constm1_rtx"
2457 {
2458   operands[1] = constm1_rtx;
2459   return "or{q}\t{%1, %0|%0, %1}";
2460 }
2461   [(set_attr "type" "alu1")
2462    (set_attr "mode" "DI")
2463    (set_attr "length_immediate" "1")])
2464
2465 (define_insn "*movdi_2"
2466   [(set (match_operand:DI 0 "nonimmediate_operand"
2467                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2468         (match_operand:DI 1 "general_operand"
2469                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2470   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2471   "@
2472    #
2473    #
2474    pxor\t%0, %0
2475    movq\t{%1, %0|%0, %1}
2476    movq\t{%1, %0|%0, %1}
2477    %vpxor\t%0, %d0
2478    %vmovq\t{%1, %0|%0, %1}
2479    %vmovdqa\t{%1, %0|%0, %1}
2480    %vmovq\t{%1, %0|%0, %1}
2481    xorps\t%0, %0
2482    movlps\t{%1, %0|%0, %1}
2483    movaps\t{%1, %0|%0, %1}
2484    movlps\t{%1, %0|%0, %1}"
2485   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2486    (set (attr "prefix")
2487      (if_then_else (eq_attr "alternative" "5,6,7,8")
2488        (const_string "vex")
2489        (const_string "orig")))
2490    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2491
2492 (define_split
2493   [(set (match_operand:DI 0 "push_operand" "")
2494         (match_operand:DI 1 "general_operand" ""))]
2495   "!TARGET_64BIT && reload_completed
2496    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2497   [(const_int 0)]
2498   "ix86_split_long_move (operands); DONE;")
2499
2500 ;; %%% This multiword shite has got to go.
2501 (define_split
2502   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2503         (match_operand:DI 1 "general_operand" ""))]
2504   "!TARGET_64BIT && reload_completed
2505    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2506    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2507   [(const_int 0)]
2508   "ix86_split_long_move (operands); DONE;")
2509
2510 (define_insn "*movdi_1_rex64"
2511   [(set (match_operand:DI 0 "nonimmediate_operand"
2512           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2513         (match_operand:DI 1 "general_operand"
2514           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2515   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2516 {
2517   switch (get_attr_type (insn))
2518     {
2519     case TYPE_SSECVT:
2520       if (SSE_REG_P (operands[0]))
2521         return "movq2dq\t{%1, %0|%0, %1}";
2522       else
2523         return "movdq2q\t{%1, %0|%0, %1}";
2524
2525     case TYPE_SSEMOV:
2526       if (TARGET_AVX)
2527         {
2528           if (get_attr_mode (insn) == MODE_TI)
2529             return "vmovdqa\t{%1, %0|%0, %1}";
2530           else
2531             return "vmovq\t{%1, %0|%0, %1}";
2532         }
2533
2534       if (get_attr_mode (insn) == MODE_TI)
2535         return "movdqa\t{%1, %0|%0, %1}";
2536       /* FALLTHRU */
2537
2538     case TYPE_MMXMOV:
2539       /* Moves from and into integer register is done using movd
2540          opcode with REX prefix.  */
2541       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2542         return "movd\t{%1, %0|%0, %1}";
2543       return "movq\t{%1, %0|%0, %1}";
2544
2545     case TYPE_SSELOG1:
2546       return "%vpxor\t%0, %d0";
2547
2548     case TYPE_MMX:
2549       return "pxor\t%0, %0";
2550
2551     case TYPE_MULTI:
2552       return "#";
2553
2554     case TYPE_LEA:
2555       return "lea{q}\t{%a1, %0|%0, %a1}";
2556
2557     default:
2558       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2559       if (get_attr_mode (insn) == MODE_SI)
2560         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2561       else if (which_alternative == 2)
2562         return "movabs{q}\t{%1, %0|%0, %1}";
2563       else
2564         return "mov{q}\t{%1, %0|%0, %1}";
2565     }
2566 }
2567   [(set (attr "type")
2568      (cond [(eq_attr "alternative" "5")
2569               (const_string "mmx")
2570             (eq_attr "alternative" "6,7,8,9,10")
2571               (const_string "mmxmov")
2572             (eq_attr "alternative" "11")
2573               (const_string "sselog1")
2574             (eq_attr "alternative" "12,13,14,15,16")
2575               (const_string "ssemov")
2576             (eq_attr "alternative" "17,18")
2577               (const_string "ssecvt")
2578             (eq_attr "alternative" "4")
2579               (const_string "multi")
2580             (match_operand:DI 1 "pic_32bit_operand" "")
2581               (const_string "lea")
2582            ]
2583            (const_string "imov")))
2584    (set (attr "modrm")
2585      (if_then_else
2586        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2587          (const_string "0")
2588          (const_string "*")))
2589    (set (attr "length_immediate")
2590      (if_then_else
2591        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2592          (const_string "8")
2593          (const_string "*")))
2594    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2595    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2596    (set (attr "prefix")
2597      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2598        (const_string "maybe_vex")
2599        (const_string "orig")))
2600    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2601
2602 ;; Stores and loads of ax to arbitrary constant address.
2603 ;; We fake an second form of instruction to force reload to load address
2604 ;; into register when rax is not available
2605 (define_insn "*movabsdi_1_rex64"
2606   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2607         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2608   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2609   "@
2610    movabs{q}\t{%1, %P0|%P0, %1}
2611    mov{q}\t{%1, %a0|%a0, %1}"
2612   [(set_attr "type" "imov")
2613    (set_attr "modrm" "0,*")
2614    (set_attr "length_address" "8,0")
2615    (set_attr "length_immediate" "0,*")
2616    (set_attr "memory" "store")
2617    (set_attr "mode" "DI")])
2618
2619 (define_insn "*movabsdi_2_rex64"
2620   [(set (match_operand:DI 0 "register_operand" "=a,r")
2621         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2622   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2623   "@
2624    movabs{q}\t{%P1, %0|%0, %P1}
2625    mov{q}\t{%a1, %0|%0, %a1}"
2626   [(set_attr "type" "imov")
2627    (set_attr "modrm" "0,*")
2628    (set_attr "length_address" "8,0")
2629    (set_attr "length_immediate" "0")
2630    (set_attr "memory" "load")
2631    (set_attr "mode" "DI")])
2632
2633 ;; Convert impossible stores of immediate to existing instructions.
2634 ;; First try to get scratch register and go through it.  In case this
2635 ;; fails, move by 32bit parts.
2636 (define_peephole2
2637   [(match_scratch:DI 2 "r")
2638    (set (match_operand:DI 0 "memory_operand" "")
2639         (match_operand:DI 1 "immediate_operand" ""))]
2640   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2641    && !x86_64_immediate_operand (operands[1], DImode)"
2642   [(set (match_dup 2) (match_dup 1))
2643    (set (match_dup 0) (match_dup 2))]
2644   "")
2645
2646 ;; We need to define this as both peepholer and splitter for case
2647 ;; peephole2 pass is not run.
2648 ;; "&& 1" is needed to keep it from matching the previous pattern.
2649 (define_peephole2
2650   [(set (match_operand:DI 0 "memory_operand" "")
2651         (match_operand:DI 1 "immediate_operand" ""))]
2652   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2653    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2654   [(set (match_dup 2) (match_dup 3))
2655    (set (match_dup 4) (match_dup 5))]
2656   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2657
2658 (define_split
2659   [(set (match_operand:DI 0 "memory_operand" "")
2660         (match_operand:DI 1 "immediate_operand" ""))]
2661   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2662                     ? epilogue_completed : reload_completed)
2663    && !symbolic_operand (operands[1], DImode)
2664    && !x86_64_immediate_operand (operands[1], DImode)"
2665   [(set (match_dup 2) (match_dup 3))
2666    (set (match_dup 4) (match_dup 5))]
2667   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2668
2669 (define_insn "*swapdi_rex64"
2670   [(set (match_operand:DI 0 "register_operand" "+r")
2671         (match_operand:DI 1 "register_operand" "+r"))
2672    (set (match_dup 1)
2673         (match_dup 0))]
2674   "TARGET_64BIT"
2675   "xchg{q}\t%1, %0"
2676   [(set_attr "type" "imov")
2677    (set_attr "mode" "DI")
2678    (set_attr "pent_pair" "np")
2679    (set_attr "athlon_decode" "vector")
2680    (set_attr "amdfam10_decode" "double")])
2681
2682 (define_expand "movoi"
2683   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2684         (match_operand:OI 1 "general_operand" ""))]
2685   "TARGET_AVX"
2686   "ix86_expand_move (OImode, operands); DONE;")
2687
2688 (define_insn "*movoi_internal"
2689   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2690         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2691   "TARGET_AVX
2692    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2693 {
2694   switch (which_alternative)
2695     {
2696     case 0:
2697       return "vxorps\t%0, %0, %0";
2698     case 1:
2699     case 2:
2700       if (misaligned_operand (operands[0], OImode)
2701           || misaligned_operand (operands[1], OImode))
2702         return "vmovdqu\t{%1, %0|%0, %1}";
2703       else
2704         return "vmovdqa\t{%1, %0|%0, %1}";
2705     default:
2706       gcc_unreachable ();
2707     }
2708 }
2709   [(set_attr "type" "sselog1,ssemov,ssemov")
2710    (set_attr "prefix" "vex")
2711    (set_attr "mode" "OI")])
2712
2713 (define_expand "movti"
2714   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2715         (match_operand:TI 1 "nonimmediate_operand" ""))]
2716   "TARGET_SSE || TARGET_64BIT"
2717 {
2718   if (TARGET_64BIT)
2719     ix86_expand_move (TImode, operands);
2720   else if (push_operand (operands[0], TImode))
2721     ix86_expand_push (TImode, operands[1]);
2722   else
2723     ix86_expand_vector_move (TImode, operands);
2724   DONE;
2725 })
2726
2727 (define_insn "*movti_internal"
2728   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2729         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2730   "TARGET_SSE && !TARGET_64BIT
2731    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2732 {
2733   switch (which_alternative)
2734     {
2735     case 0:
2736       if (get_attr_mode (insn) == MODE_V4SF)
2737         return "%vxorps\t%0, %d0";
2738       else
2739         return "%vpxor\t%0, %d0";
2740     case 1:
2741     case 2:
2742       /* TDmode values are passed as TImode on the stack.  Moving them
2743          to stack may result in unaligned memory access.  */
2744       if (misaligned_operand (operands[0], TImode)
2745           || misaligned_operand (operands[1], TImode))
2746         {
2747           if (get_attr_mode (insn) == MODE_V4SF)
2748             return "%vmovups\t{%1, %0|%0, %1}";
2749          else
2750            return "%vmovdqu\t{%1, %0|%0, %1}";
2751         }
2752       else
2753         {
2754           if (get_attr_mode (insn) == MODE_V4SF)
2755             return "%vmovaps\t{%1, %0|%0, %1}";
2756          else
2757            return "%vmovdqa\t{%1, %0|%0, %1}";
2758         }
2759     default:
2760       gcc_unreachable ();
2761     }
2762 }
2763   [(set_attr "type" "sselog1,ssemov,ssemov")
2764    (set_attr "prefix" "maybe_vex")
2765    (set (attr "mode")
2766         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2767                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2768                  (const_string "V4SF")
2769                (and (eq_attr "alternative" "2")
2770                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2771                         (const_int 0)))
2772                  (const_string "V4SF")]
2773               (const_string "TI")))])
2774
2775 (define_insn "*movti_rex64"
2776   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2777         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2778   "TARGET_64BIT
2779    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2780 {
2781   switch (which_alternative)
2782     {
2783     case 0:
2784     case 1:
2785       return "#";
2786     case 2:
2787       if (get_attr_mode (insn) == MODE_V4SF)
2788         return "%vxorps\t%0, %d0";
2789       else
2790         return "%vpxor\t%0, %d0";
2791     case 3:
2792     case 4:
2793       /* TDmode values are passed as TImode on the stack.  Moving them
2794          to stack may result in unaligned memory access.  */
2795       if (misaligned_operand (operands[0], TImode)
2796           || misaligned_operand (operands[1], TImode))
2797         {
2798           if (get_attr_mode (insn) == MODE_V4SF)
2799             return "%vmovups\t{%1, %0|%0, %1}";
2800          else
2801            return "%vmovdqu\t{%1, %0|%0, %1}";
2802         }
2803       else
2804         {
2805           if (get_attr_mode (insn) == MODE_V4SF)
2806             return "%vmovaps\t{%1, %0|%0, %1}";
2807          else
2808            return "%vmovdqa\t{%1, %0|%0, %1}";
2809         }
2810     default:
2811       gcc_unreachable ();
2812     }
2813 }
2814   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2815    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2816    (set (attr "mode")
2817         (cond [(eq_attr "alternative" "2,3")
2818                  (if_then_else
2819                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2820                        (const_int 0))
2821                    (const_string "V4SF")
2822                    (const_string "TI"))
2823                (eq_attr "alternative" "4")
2824                  (if_then_else
2825                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2826                             (const_int 0))
2827                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2828                             (const_int 0)))
2829                    (const_string "V4SF")
2830                    (const_string "TI"))]
2831                (const_string "DI")))])
2832
2833 (define_split
2834   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2835         (match_operand:TI 1 "general_operand" ""))]
2836   "reload_completed && !SSE_REG_P (operands[0])
2837    && !SSE_REG_P (operands[1])"
2838   [(const_int 0)]
2839   "ix86_split_long_move (operands); DONE;")
2840
2841 ;; This expands to what emit_move_complex would generate if we didn't
2842 ;; have a movti pattern.  Having this avoids problems with reload on
2843 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2844 ;; to have around all the time.
2845 (define_expand "movcdi"
2846   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2847         (match_operand:CDI 1 "general_operand" ""))]
2848   ""
2849 {
2850   if (push_operand (operands[0], CDImode))
2851     emit_move_complex_push (CDImode, operands[0], operands[1]);
2852   else
2853     emit_move_complex_parts (operands[0], operands[1]);
2854   DONE;
2855 })
2856
2857 (define_expand "movsf"
2858   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2859         (match_operand:SF 1 "general_operand" ""))]
2860   ""
2861   "ix86_expand_move (SFmode, operands); DONE;")
2862
2863 (define_insn "*pushsf"
2864   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2865         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2866   "!TARGET_64BIT"
2867 {
2868   /* Anything else should be already split before reg-stack.  */
2869   gcc_assert (which_alternative == 1);
2870   return "push{l}\t%1";
2871 }
2872   [(set_attr "type" "multi,push,multi")
2873    (set_attr "unit" "i387,*,*")
2874    (set_attr "mode" "SF,SI,SF")])
2875
2876 (define_insn "*pushsf_rex64"
2877   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2878         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2879   "TARGET_64BIT"
2880 {
2881   /* Anything else should be already split before reg-stack.  */
2882   gcc_assert (which_alternative == 1);
2883   return "push{q}\t%q1";
2884 }
2885   [(set_attr "type" "multi,push,multi")
2886    (set_attr "unit" "i387,*,*")
2887    (set_attr "mode" "SF,DI,SF")])
2888
2889 (define_split
2890   [(set (match_operand:SF 0 "push_operand" "")
2891         (match_operand:SF 1 "memory_operand" ""))]
2892   "reload_completed
2893    && MEM_P (operands[1])
2894    && (operands[2] = find_constant_src (insn))"
2895   [(set (match_dup 0)
2896         (match_dup 2))])
2897
2898 ;; %%% Kill this when call knows how to work this out.
2899 (define_split
2900   [(set (match_operand:SF 0 "push_operand" "")
2901         (match_operand:SF 1 "any_fp_register_operand" ""))]
2902   "!TARGET_64BIT"
2903   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2904    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2905
2906 (define_split
2907   [(set (match_operand:SF 0 "push_operand" "")
2908         (match_operand:SF 1 "any_fp_register_operand" ""))]
2909   "TARGET_64BIT"
2910   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2911    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2912
2913 (define_insn "*movsf_1"
2914   [(set (match_operand:SF 0 "nonimmediate_operand"
2915           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2916         (match_operand:SF 1 "general_operand"
2917           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2918   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2919    && (reload_in_progress || reload_completed
2920        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2921        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2922            && standard_80387_constant_p (operands[1]))
2923        || GET_CODE (operands[1]) != CONST_DOUBLE
2924        || memory_operand (operands[0], SFmode))"
2925 {
2926   switch (which_alternative)
2927     {
2928     case 0:
2929     case 1:
2930       return output_387_reg_move (insn, operands);
2931
2932     case 2:
2933       return standard_80387_constant_opcode (operands[1]);
2934
2935     case 3:
2936     case 4:
2937       return "mov{l}\t{%1, %0|%0, %1}";
2938     case 5:
2939       if (get_attr_mode (insn) == MODE_TI)
2940         return "%vpxor\t%0, %d0";
2941       else
2942         return "%vxorps\t%0, %d0";
2943     case 6:
2944       if (get_attr_mode (insn) == MODE_V4SF)
2945         return "%vmovaps\t{%1, %0|%0, %1}";
2946       else
2947         return "%vmovss\t{%1, %d0|%d0, %1}";
2948     case 7:
2949       if (TARGET_AVX)
2950         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2951                                    : "vmovss\t{%1, %0|%0, %1}";
2952       else
2953         return "movss\t{%1, %0|%0, %1}";
2954     case 8:
2955       return "%vmovss\t{%1, %0|%0, %1}";
2956
2957     case 9: case 10: case 14: case 15:
2958       return "movd\t{%1, %0|%0, %1}";
2959     case 12: case 13:
2960       return "%vmovd\t{%1, %0|%0, %1}";
2961
2962     case 11:
2963       return "movq\t{%1, %0|%0, %1}";
2964
2965     default:
2966       gcc_unreachable ();
2967     }
2968 }
2969   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2970    (set (attr "prefix")
2971      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2972        (const_string "maybe_vex")
2973        (const_string "orig")))
2974    (set (attr "mode")
2975         (cond [(eq_attr "alternative" "3,4,9,10")
2976                  (const_string "SI")
2977                (eq_attr "alternative" "5")
2978                  (if_then_else
2979                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2980                                  (const_int 0))
2981                              (ne (symbol_ref "TARGET_SSE2")
2982                                  (const_int 0)))
2983                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2984                             (const_int 0)))
2985                    (const_string "TI")
2986                    (const_string "V4SF"))
2987                /* For architectures resolving dependencies on
2988                   whole SSE registers use APS move to break dependency
2989                   chains, otherwise use short move to avoid extra work.
2990
2991                   Do the same for architectures resolving dependencies on
2992                   the parts.  While in DF mode it is better to always handle
2993                   just register parts, the SF mode is different due to lack
2994                   of instructions to load just part of the register.  It is
2995                   better to maintain the whole registers in single format
2996                   to avoid problems on using packed logical operations.  */
2997                (eq_attr "alternative" "6")
2998                  (if_then_else
2999                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3000                             (const_int 0))
3001                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3002                             (const_int 0)))
3003                    (const_string "V4SF")
3004                    (const_string "SF"))
3005                (eq_attr "alternative" "11")
3006                  (const_string "DI")]
3007                (const_string "SF")))])
3008
3009 (define_insn "*swapsf"
3010   [(set (match_operand:SF 0 "fp_register_operand" "+f")
3011         (match_operand:SF 1 "fp_register_operand" "+f"))
3012    (set (match_dup 1)
3013         (match_dup 0))]
3014   "reload_completed || TARGET_80387"
3015 {
3016   if (STACK_TOP_P (operands[0]))
3017     return "fxch\t%1";
3018   else
3019     return "fxch\t%0";
3020 }
3021   [(set_attr "type" "fxch")
3022    (set_attr "mode" "SF")])
3023
3024 (define_expand "movdf"
3025   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3026         (match_operand:DF 1 "general_operand" ""))]
3027   ""
3028   "ix86_expand_move (DFmode, operands); DONE;")
3029
3030 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3031 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3032 ;; On the average, pushdf using integers can be still shorter.  Allow this
3033 ;; pattern for optimize_size too.
3034
3035 (define_insn "*pushdf_nointeger"
3036   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3037         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3038   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3039 {
3040   /* This insn should be already split before reg-stack.  */
3041   gcc_unreachable ();
3042 }
3043   [(set_attr "type" "multi")
3044    (set_attr "unit" "i387,*,*,*")
3045    (set_attr "mode" "DF,SI,SI,DF")])
3046
3047 (define_insn "*pushdf_integer"
3048   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3049         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3050   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3051 {
3052   /* This insn should be already split before reg-stack.  */
3053   gcc_unreachable ();
3054 }
3055   [(set_attr "type" "multi")
3056    (set_attr "unit" "i387,*,*")
3057    (set_attr "mode" "DF,SI,DF")])
3058
3059 ;; %%% Kill this when call knows how to work this out.
3060 (define_split
3061   [(set (match_operand:DF 0 "push_operand" "")
3062         (match_operand:DF 1 "any_fp_register_operand" ""))]
3063   "reload_completed"
3064   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3065    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3066   "")
3067
3068 (define_split
3069   [(set (match_operand:DF 0 "push_operand" "")
3070         (match_operand:DF 1 "general_operand" ""))]
3071   "reload_completed"
3072   [(const_int 0)]
3073   "ix86_split_long_move (operands); DONE;")
3074
3075 ;; Moving is usually shorter when only FP registers are used. This separate
3076 ;; movdf pattern avoids the use of integer registers for FP operations
3077 ;; when optimizing for size.
3078
3079 (define_insn "*movdf_nointeger"
3080   [(set (match_operand:DF 0 "nonimmediate_operand"
3081                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3082         (match_operand:DF 1 "general_operand"
3083                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3084   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3085    && ((optimize_function_for_size_p (cfun)
3086        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3087    && (reload_in_progress || reload_completed
3088        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3089        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3090            && optimize_function_for_size_p (cfun)
3091            && !memory_operand (operands[0], DFmode)
3092            && standard_80387_constant_p (operands[1]))
3093        || GET_CODE (operands[1]) != CONST_DOUBLE
3094        || ((optimize_function_for_size_p (cfun)
3095             || !TARGET_MEMORY_MISMATCH_STALL
3096             || reload_in_progress || reload_completed)
3097            && memory_operand (operands[0], DFmode)))"
3098 {
3099   switch (which_alternative)
3100     {
3101     case 0:
3102     case 1:
3103       return output_387_reg_move (insn, operands);
3104
3105     case 2:
3106       return standard_80387_constant_opcode (operands[1]);
3107
3108     case 3:
3109     case 4:
3110       return "#";
3111     case 5:
3112       switch (get_attr_mode (insn))
3113         {
3114         case MODE_V4SF:
3115           return "%vxorps\t%0, %d0";
3116         case MODE_V2DF:
3117           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3118             return "%vxorps\t%0, %d0";
3119           else
3120             return "%vxorpd\t%0, %d0";
3121         case MODE_TI:
3122           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3123             return "%vxorps\t%0, %d0";
3124           else
3125             return "%vpxor\t%0, %d0";
3126         default:
3127           gcc_unreachable ();
3128         }
3129     case 6:
3130     case 7:
3131     case 8:
3132       switch (get_attr_mode (insn))
3133         {
3134         case MODE_V4SF:
3135           return "%vmovaps\t{%1, %0|%0, %1}";
3136         case MODE_V2DF:
3137           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3138             return "%vmovaps\t{%1, %0|%0, %1}";
3139           else
3140             return "%vmovapd\t{%1, %0|%0, %1}";
3141         case MODE_TI:
3142           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3143             return "%vmovaps\t{%1, %0|%0, %1}";
3144           else
3145             return "%vmovdqa\t{%1, %0|%0, %1}";
3146         case MODE_DI:
3147           return "%vmovq\t{%1, %0|%0, %1}";
3148         case MODE_DF:
3149           if (TARGET_AVX)
3150             {
3151               if (REG_P (operands[0]) && REG_P (operands[1]))
3152                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3153               else
3154                 return "vmovsd\t{%1, %0|%0, %1}";
3155             }
3156           else
3157             return "movsd\t{%1, %0|%0, %1}";
3158         case MODE_V1DF:
3159           if (TARGET_AVX)
3160             {
3161               if (REG_P (operands[0]))
3162                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3163               else
3164                 return "vmovlpd\t{%1, %0|%0, %1}";
3165             }
3166           else
3167             return "movlpd\t{%1, %0|%0, %1}";
3168         case MODE_V2SF:
3169           if (TARGET_AVX)
3170             {
3171               if (REG_P (operands[0]))
3172                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3173               else
3174                 return "vmovlps\t{%1, %0|%0, %1}";
3175             }
3176           else
3177             return "movlps\t{%1, %0|%0, %1}";
3178         default:
3179           gcc_unreachable ();
3180         }
3181
3182     default:
3183       gcc_unreachable ();
3184     }
3185 }
3186   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3187    (set (attr "prefix")
3188      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3189        (const_string "orig")
3190        (const_string "maybe_vex")))
3191    (set (attr "prefix_data16")
3192      (if_then_else (eq_attr "mode" "V1DF")
3193        (const_string "1")
3194        (const_string "*")))
3195    (set (attr "mode")
3196         (cond [(eq_attr "alternative" "0,1,2")
3197                  (const_string "DF")
3198                (eq_attr "alternative" "3,4")
3199                  (const_string "SI")
3200
3201                /* For SSE1, we have many fewer alternatives.  */
3202                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3203                  (cond [(eq_attr "alternative" "5,6")
3204                           (const_string "V4SF")
3205                        ]
3206                    (const_string "V2SF"))
3207
3208                /* xorps is one byte shorter.  */
3209                (eq_attr "alternative" "5")
3210                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3211                             (const_int 0))
3212                           (const_string "V4SF")
3213                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3214                             (const_int 0))
3215                           (const_string "TI")
3216                        ]
3217                        (const_string "V2DF"))
3218
3219                /* For architectures resolving dependencies on
3220                   whole SSE registers use APD move to break dependency
3221                   chains, otherwise use short move to avoid extra work.
3222
3223                   movaps encodes one byte shorter.  */
3224                (eq_attr "alternative" "6")
3225                  (cond
3226                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3227                         (const_int 0))
3228                       (const_string "V4SF")
3229                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3230                         (const_int 0))
3231                       (const_string "V2DF")
3232                    ]
3233                    (const_string "DF"))
3234                /* For architectures resolving dependencies on register
3235                   parts we may avoid extra work to zero out upper part
3236                   of register.  */
3237                (eq_attr "alternative" "7")
3238                  (if_then_else
3239                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3240                        (const_int 0))
3241                    (const_string "V1DF")
3242                    (const_string "DF"))
3243               ]
3244               (const_string "DF")))])
3245
3246 (define_insn "*movdf_integer_rex64"
3247   [(set (match_operand:DF 0 "nonimmediate_operand"
3248                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3249         (match_operand:DF 1 "general_operand"
3250                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3251   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3252    && (reload_in_progress || reload_completed
3253        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3254        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3255            && optimize_function_for_size_p (cfun)
3256            && standard_80387_constant_p (operands[1]))
3257        || GET_CODE (operands[1]) != CONST_DOUBLE
3258        || memory_operand (operands[0], DFmode))"
3259 {
3260   switch (which_alternative)
3261     {
3262     case 0:
3263     case 1:
3264       return output_387_reg_move (insn, operands);
3265
3266     case 2:
3267       return standard_80387_constant_opcode (operands[1]);
3268
3269     case 3:
3270     case 4:
3271       return "#";
3272
3273     case 5:
3274       switch (get_attr_mode (insn))
3275         {
3276         case MODE_V4SF:
3277           return "%vxorps\t%0, %d0";
3278         case MODE_V2DF:
3279           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3280             return "%vxorps\t%0, %d0";
3281           else
3282             return "%vxorpd\t%0, %d0";
3283         case MODE_TI:
3284           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3285             return "%vxorps\t%0, %d0";
3286           else
3287             return "%vpxor\t%0, %d0";
3288         default:
3289           gcc_unreachable ();
3290         }
3291     case 6:
3292     case 7:
3293     case 8:
3294       switch (get_attr_mode (insn))
3295         {
3296         case MODE_V4SF:
3297           return "%vmovaps\t{%1, %0|%0, %1}";
3298         case MODE_V2DF:
3299           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3300             return "%vmovaps\t{%1, %0|%0, %1}";
3301           else
3302             return "%vmovapd\t{%1, %0|%0, %1}";
3303         case MODE_TI:
3304           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3305             return "%vmovaps\t{%1, %0|%0, %1}";
3306           else
3307             return "%vmovdqa\t{%1, %0|%0, %1}";
3308         case MODE_DI:
3309           return "%vmovq\t{%1, %0|%0, %1}";
3310         case MODE_DF:
3311           if (TARGET_AVX)
3312             {
3313               if (REG_P (operands[0]) && REG_P (operands[1]))
3314                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3315               else
3316                 return "vmovsd\t{%1, %0|%0, %1}";
3317             }
3318           else
3319             return "movsd\t{%1, %0|%0, %1}";
3320         case MODE_V1DF:
3321           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3322         case MODE_V2SF:
3323           return "%vmovlps\t{%1, %d0|%d0, %1}";
3324         default:
3325           gcc_unreachable ();
3326         }
3327
3328     case 9:
3329     case 10:
3330     return "%vmovd\t{%1, %0|%0, %1}";
3331
3332     default:
3333       gcc_unreachable();
3334     }
3335 }
3336   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3337    (set (attr "prefix")
3338      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3339        (const_string "orig")
3340        (const_string "maybe_vex")))
3341    (set (attr "prefix_data16")
3342      (if_then_else (eq_attr "mode" "V1DF")
3343        (const_string "1")
3344        (const_string "*")))
3345    (set (attr "mode")
3346         (cond [(eq_attr "alternative" "0,1,2")
3347                  (const_string "DF")
3348                (eq_attr "alternative" "3,4,9,10")
3349                  (const_string "DI")
3350
3351                /* For SSE1, we have many fewer alternatives.  */
3352                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3353                  (cond [(eq_attr "alternative" "5,6")
3354                           (const_string "V4SF")
3355                        ]
3356                    (const_string "V2SF"))
3357
3358                /* xorps is one byte shorter.  */
3359                (eq_attr "alternative" "5")
3360                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3361                             (const_int 0))
3362                           (const_string "V4SF")
3363                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3364                             (const_int 0))
3365                           (const_string "TI")
3366                        ]
3367                        (const_string "V2DF"))
3368
3369                /* For architectures resolving dependencies on
3370                   whole SSE registers use APD move to break dependency
3371                   chains, otherwise use short move to avoid extra work.
3372
3373                   movaps encodes one byte shorter.  */
3374                (eq_attr "alternative" "6")
3375                  (cond
3376                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3377                         (const_int 0))
3378                       (const_string "V4SF")
3379                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3380                         (const_int 0))
3381                       (const_string "V2DF")
3382                    ]
3383                    (const_string "DF"))
3384                /* For architectures resolving dependencies on register
3385                   parts we may avoid extra work to zero out upper part
3386                   of register.  */
3387                (eq_attr "alternative" "7")
3388                  (if_then_else
3389                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3390                        (const_int 0))
3391                    (const_string "V1DF")
3392                    (const_string "DF"))
3393               ]
3394               (const_string "DF")))])
3395
3396 (define_insn "*movdf_integer"
3397   [(set (match_operand:DF 0 "nonimmediate_operand"
3398                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3399         (match_operand:DF 1 "general_operand"
3400                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3401   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3402    && optimize_function_for_speed_p (cfun)
3403    && TARGET_INTEGER_DFMODE_MOVES
3404    && (reload_in_progress || reload_completed
3405        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3406        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3407            && optimize_function_for_size_p (cfun)
3408            && standard_80387_constant_p (operands[1]))
3409        || GET_CODE (operands[1]) != CONST_DOUBLE
3410        || memory_operand (operands[0], DFmode))"
3411 {
3412   switch (which_alternative)
3413     {
3414     case 0:
3415     case 1:
3416       return output_387_reg_move (insn, operands);
3417
3418     case 2:
3419       return standard_80387_constant_opcode (operands[1]);
3420
3421     case 3:
3422     case 4:
3423       return "#";
3424
3425     case 5:
3426       switch (get_attr_mode (insn))
3427         {
3428         case MODE_V4SF:
3429           return "xorps\t%0, %0";
3430         case MODE_V2DF:
3431           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3432             return "xorps\t%0, %0";
3433           else
3434             return "xorpd\t%0, %0";
3435         case MODE_TI:
3436           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3437             return "xorps\t%0, %0";
3438           else
3439             return "pxor\t%0, %0";
3440         default:
3441           gcc_unreachable ();
3442         }
3443     case 6:
3444     case 7:
3445     case 8:
3446       switch (get_attr_mode (insn))
3447         {
3448         case MODE_V4SF:
3449           return "movaps\t{%1, %0|%0, %1}";
3450         case MODE_V2DF:
3451           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3452             return "movaps\t{%1, %0|%0, %1}";
3453           else
3454             return "movapd\t{%1, %0|%0, %1}";
3455         case MODE_TI:
3456           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3457             return "movaps\t{%1, %0|%0, %1}";
3458           else
3459             return "movdqa\t{%1, %0|%0, %1}";
3460         case MODE_DI:
3461           return "movq\t{%1, %0|%0, %1}";
3462         case MODE_DF:
3463           return "movsd\t{%1, %0|%0, %1}";
3464         case MODE_V1DF:
3465           return "movlpd\t{%1, %0|%0, %1}";
3466         case MODE_V2SF:
3467           return "movlps\t{%1, %0|%0, %1}";
3468         default:
3469           gcc_unreachable ();
3470         }
3471
3472     default:
3473       gcc_unreachable();
3474     }
3475 }
3476   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3477    (set (attr "prefix_data16")
3478      (if_then_else (eq_attr "mode" "V1DF")
3479        (const_string "1")
3480        (const_string "*")))
3481    (set (attr "mode")
3482         (cond [(eq_attr "alternative" "0,1,2")
3483                  (const_string "DF")
3484                (eq_attr "alternative" "3,4")
3485                  (const_string "SI")
3486
3487                /* For SSE1, we have many fewer alternatives.  */
3488                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3489                  (cond [(eq_attr "alternative" "5,6")
3490                           (const_string "V4SF")
3491                        ]
3492                    (const_string "V2SF"))
3493
3494                /* xorps is one byte shorter.  */
3495                (eq_attr "alternative" "5")
3496                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3497                             (const_int 0))
3498                           (const_string "V4SF")
3499                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3500                             (const_int 0))
3501                           (const_string "TI")
3502                        ]
3503                        (const_string "V2DF"))
3504
3505                /* For architectures resolving dependencies on
3506                   whole SSE registers use APD move to break dependency
3507                   chains, otherwise use short move to avoid extra work.
3508
3509                   movaps encodes one byte shorter.  */
3510                (eq_attr "alternative" "6")
3511                  (cond
3512                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3513                         (const_int 0))
3514                       (const_string "V4SF")
3515                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3516                         (const_int 0))
3517                       (const_string "V2DF")
3518                    ]
3519                    (const_string "DF"))
3520                /* For architectures resolving dependencies on register
3521                   parts we may avoid extra work to zero out upper part
3522                   of register.  */
3523                (eq_attr "alternative" "7")
3524                  (if_then_else
3525                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3526                        (const_int 0))
3527                    (const_string "V1DF")
3528                    (const_string "DF"))
3529               ]
3530               (const_string "DF")))])
3531
3532 (define_split
3533   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3534         (match_operand:DF 1 "general_operand" ""))]
3535   "reload_completed
3536    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3537    && ! (ANY_FP_REG_P (operands[0]) ||
3538          (GET_CODE (operands[0]) == SUBREG
3539           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3540    && ! (ANY_FP_REG_P (operands[1]) ||
3541          (GET_CODE (operands[1]) == SUBREG
3542           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3543   [(const_int 0)]
3544   "ix86_split_long_move (operands); DONE;")
3545
3546 (define_insn "*swapdf"
3547   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3548         (match_operand:DF 1 "fp_register_operand" "+f"))
3549    (set (match_dup 1)
3550         (match_dup 0))]
3551   "reload_completed || TARGET_80387"
3552 {
3553   if (STACK_TOP_P (operands[0]))
3554     return "fxch\t%1";
3555   else
3556     return "fxch\t%0";
3557 }
3558   [(set_attr "type" "fxch")
3559    (set_attr "mode" "DF")])
3560
3561 (define_expand "movxf"
3562   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3563         (match_operand:XF 1 "general_operand" ""))]
3564   ""
3565   "ix86_expand_move (XFmode, operands); DONE;")
3566
3567 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3568 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3569 ;; Pushing using integer instructions is longer except for constants
3570 ;; and direct memory references.
3571 ;; (assuming that any given constant is pushed only once, but this ought to be
3572 ;;  handled elsewhere).
3573
3574 (define_insn "*pushxf_nointeger"
3575   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3576         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3577   "optimize_function_for_size_p (cfun)"
3578 {
3579   /* This insn should be already split before reg-stack.  */
3580   gcc_unreachable ();
3581 }
3582   [(set_attr "type" "multi")
3583    (set_attr "unit" "i387,*,*")
3584    (set_attr "mode" "XF,SI,SI")])
3585
3586 (define_insn "*pushxf_integer"
3587   [(set (match_operand:XF 0 "push_operand" "=<,<")
3588         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3589   "optimize_function_for_speed_p (cfun)"
3590 {
3591   /* This insn should be already split before reg-stack.  */
3592   gcc_unreachable ();
3593 }
3594   [(set_attr "type" "multi")
3595    (set_attr "unit" "i387,*")
3596    (set_attr "mode" "XF,SI")])
3597
3598 (define_split
3599   [(set (match_operand 0 "push_operand" "")
3600         (match_operand 1 "general_operand" ""))]
3601   "reload_completed
3602    && (GET_MODE (operands[0]) == XFmode
3603        || GET_MODE (operands[0]) == DFmode)
3604    && !ANY_FP_REG_P (operands[1])"
3605   [(const_int 0)]
3606   "ix86_split_long_move (operands); DONE;")
3607
3608 (define_split
3609   [(set (match_operand:XF 0 "push_operand" "")
3610         (match_operand:XF 1 "any_fp_register_operand" ""))]
3611   ""
3612   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3613    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3614   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3615
3616 ;; Do not use integer registers when optimizing for size
3617 (define_insn "*movxf_nointeger"
3618   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3619         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3620   "optimize_function_for_size_p (cfun)
3621    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3622    && (reload_in_progress || reload_completed
3623        || standard_80387_constant_p (operands[1])
3624        || GET_CODE (operands[1]) != CONST_DOUBLE
3625        || memory_operand (operands[0], XFmode))"
3626 {
3627   switch (which_alternative)
3628     {
3629     case 0:
3630     case 1:
3631       return output_387_reg_move (insn, operands);
3632
3633     case 2:
3634       return standard_80387_constant_opcode (operands[1]);
3635
3636     case 3: case 4:
3637       return "#";
3638     default:
3639       gcc_unreachable ();
3640     }
3641 }
3642   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3643    (set_attr "mode" "XF,XF,XF,SI,SI")])
3644
3645 (define_insn "*movxf_integer"
3646   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3647         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3648   "optimize_function_for_speed_p (cfun)
3649    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3650    && (reload_in_progress || reload_completed
3651        || GET_CODE (operands[1]) != CONST_DOUBLE
3652        || memory_operand (operands[0], XFmode))"
3653 {
3654   switch (which_alternative)
3655     {
3656     case 0:
3657     case 1:
3658       return output_387_reg_move (insn, operands);
3659
3660     case 2:
3661       return standard_80387_constant_opcode (operands[1]);
3662
3663     case 3: case 4:
3664       return "#";
3665
3666     default:
3667       gcc_unreachable ();
3668     }
3669 }
3670   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3671    (set_attr "mode" "XF,XF,XF,SI,SI")])
3672
3673 (define_expand "movtf"
3674   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3675         (match_operand:TF 1 "nonimmediate_operand" ""))]
3676   "TARGET_SSE2"
3677 {
3678   ix86_expand_move (TFmode, operands);
3679   DONE;
3680 })
3681
3682 (define_insn "*movtf_internal"
3683   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3684         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3685   "TARGET_SSE2
3686    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3687 {
3688   switch (which_alternative)
3689     {
3690     case 0:
3691     case 1:
3692       if (get_attr_mode (insn) == MODE_V4SF)
3693         return "%vmovaps\t{%1, %0|%0, %1}";
3694       else
3695         return "%vmovdqa\t{%1, %0|%0, %1}";
3696     case 2:
3697       if (get_attr_mode (insn) == MODE_V4SF)
3698         return "%vxorps\t%0, %d0";
3699       else
3700         return "%vpxor\t%0, %d0";
3701     case 3:
3702     case 4:
3703         return "#";
3704     default:
3705       gcc_unreachable ();
3706     }
3707 }
3708   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3709    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3710    (set (attr "mode")
3711         (cond [(eq_attr "alternative" "0,2")
3712                  (if_then_else
3713                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3714                        (const_int 0))
3715                    (const_string "V4SF")
3716                    (const_string "TI"))
3717                (eq_attr "alternative" "1")
3718                  (if_then_else
3719                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3720                             (const_int 0))
3721                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3722                             (const_int 0)))
3723                    (const_string "V4SF")
3724                    (const_string "TI"))]
3725                (const_string "DI")))])
3726
3727 (define_insn "*pushtf_sse"
3728   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3729         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3730   "TARGET_SSE2"
3731 {
3732   /* This insn should be already split before reg-stack.  */
3733   gcc_unreachable ();
3734 }
3735   [(set_attr "type" "multi")
3736    (set_attr "unit" "sse,*,*")
3737    (set_attr "mode" "TF,SI,SI")])
3738
3739 (define_split
3740   [(set (match_operand:TF 0 "push_operand" "")
3741         (match_operand:TF 1 "general_operand" ""))]
3742   "TARGET_SSE2 && reload_completed
3743    && !SSE_REG_P (operands[1])"
3744   [(const_int 0)]
3745   "ix86_split_long_move (operands); DONE;")
3746
3747 (define_split
3748   [(set (match_operand:TF 0 "push_operand" "")
3749         (match_operand:TF 1 "any_fp_register_operand" ""))]
3750   "TARGET_SSE2"
3751   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3752    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3753   "")
3754
3755 (define_split
3756   [(set (match_operand 0 "nonimmediate_operand" "")
3757         (match_operand 1 "general_operand" ""))]
3758   "reload_completed
3759    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3760    && GET_MODE (operands[0]) == XFmode
3761    && ! (ANY_FP_REG_P (operands[0]) ||
3762          (GET_CODE (operands[0]) == SUBREG
3763           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3764    && ! (ANY_FP_REG_P (operands[1]) ||
3765          (GET_CODE (operands[1]) == SUBREG
3766           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3767   [(const_int 0)]
3768   "ix86_split_long_move (operands); DONE;")
3769
3770 (define_split
3771   [(set (match_operand 0 "register_operand" "")
3772         (match_operand 1 "memory_operand" ""))]
3773   "reload_completed
3774    && MEM_P (operands[1])
3775    && (GET_MODE (operands[0]) == TFmode
3776        || GET_MODE (operands[0]) == XFmode
3777        || GET_MODE (operands[0]) == SFmode
3778        || GET_MODE (operands[0]) == DFmode)
3779    && (operands[2] = find_constant_src (insn))"
3780   [(set (match_dup 0) (match_dup 2))]
3781 {
3782   rtx c = operands[2];
3783   rtx r = operands[0];
3784
3785   if (GET_CODE (r) == SUBREG)
3786     r = SUBREG_REG (r);
3787
3788   if (SSE_REG_P (r))
3789     {
3790       if (!standard_sse_constant_p (c))
3791         FAIL;
3792     }
3793   else if (FP_REG_P (r))
3794     {
3795       if (!standard_80387_constant_p (c))
3796         FAIL;
3797     }
3798   else if (MMX_REG_P (r))
3799     FAIL;
3800 })
3801
3802 (define_split
3803   [(set (match_operand 0 "register_operand" "")
3804         (float_extend (match_operand 1 "memory_operand" "")))]
3805   "reload_completed
3806    && MEM_P (operands[1])
3807    && (GET_MODE (operands[0]) == TFmode
3808        || GET_MODE (operands[0]) == XFmode
3809        || GET_MODE (operands[0]) == SFmode
3810        || GET_MODE (operands[0]) == DFmode)
3811    && (operands[2] = find_constant_src (insn))"
3812   [(set (match_dup 0) (match_dup 2))]
3813 {
3814   rtx c = operands[2];
3815   rtx r = operands[0];
3816
3817   if (GET_CODE (r) == SUBREG)
3818     r = SUBREG_REG (r);
3819
3820   if (SSE_REG_P (r))
3821     {
3822       if (!standard_sse_constant_p (c))
3823         FAIL;
3824     }
3825   else if (FP_REG_P (r))
3826     {
3827       if (!standard_80387_constant_p (c))
3828         FAIL;
3829     }
3830   else if (MMX_REG_P (r))
3831     FAIL;
3832 })
3833
3834 (define_insn "swapxf"
3835   [(set (match_operand:XF 0 "register_operand" "+f")
3836         (match_operand:XF 1 "register_operand" "+f"))
3837    (set (match_dup 1)
3838         (match_dup 0))]
3839   "TARGET_80387"
3840 {
3841   if (STACK_TOP_P (operands[0]))
3842     return "fxch\t%1";
3843   else
3844     return "fxch\t%0";
3845 }
3846   [(set_attr "type" "fxch")
3847    (set_attr "mode" "XF")])
3848
3849 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3850 (define_split
3851   [(set (match_operand:X87MODEF 0 "register_operand" "")
3852         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3853   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3854    && (standard_80387_constant_p (operands[1]) == 8
3855        || standard_80387_constant_p (operands[1]) == 9)"
3856   [(set (match_dup 0)(match_dup 1))
3857    (set (match_dup 0)
3858         (neg:X87MODEF (match_dup 0)))]
3859 {
3860   REAL_VALUE_TYPE r;
3861
3862   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3863   if (real_isnegzero (&r))
3864     operands[1] = CONST0_RTX (<MODE>mode);
3865   else
3866     operands[1] = CONST1_RTX (<MODE>mode);
3867 })
3868
3869 (define_split
3870   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3871         (match_operand:TF 1 "general_operand" ""))]
3872   "reload_completed
3873    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3874   [(const_int 0)]
3875   "ix86_split_long_move (operands); DONE;")
3876 \f
3877 ;; Zero extension instructions
3878
3879 (define_expand "zero_extendhisi2"
3880   [(set (match_operand:SI 0 "register_operand" "")
3881      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3882   ""
3883 {
3884   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3885     {
3886       operands[1] = force_reg (HImode, operands[1]);
3887       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3888       DONE;
3889     }
3890 })
3891
3892 (define_insn "zero_extendhisi2_and"
3893   [(set (match_operand:SI 0 "register_operand" "=r")
3894      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3895    (clobber (reg:CC FLAGS_REG))]
3896   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3897   "#"
3898   [(set_attr "type" "alu1")
3899    (set_attr "mode" "SI")])
3900
3901 (define_split
3902   [(set (match_operand:SI 0 "register_operand" "")
3903         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3904    (clobber (reg:CC FLAGS_REG))]
3905   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3906    && optimize_function_for_speed_p (cfun)"
3907   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3908               (clobber (reg:CC FLAGS_REG))])]
3909   "")
3910
3911 (define_insn "*zero_extendhisi2_movzwl"
3912   [(set (match_operand:SI 0 "register_operand" "=r")
3913      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3914   "!TARGET_ZERO_EXTEND_WITH_AND
3915    || optimize_function_for_size_p (cfun)"
3916   "movz{wl|x}\t{%1, %0|%0, %1}"
3917   [(set_attr "type" "imovx")
3918    (set_attr "mode" "SI")])
3919
3920 (define_expand "zero_extendqihi2"
3921   [(parallel
3922     [(set (match_operand:HI 0 "register_operand" "")
3923        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3924      (clobber (reg:CC FLAGS_REG))])]
3925   ""
3926   "")
3927
3928 (define_insn "*zero_extendqihi2_and"
3929   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3930      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3931    (clobber (reg:CC FLAGS_REG))]
3932   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3933   "#"
3934   [(set_attr "type" "alu1")
3935    (set_attr "mode" "HI")])
3936
3937 (define_insn "*zero_extendqihi2_movzbw_and"
3938   [(set (match_operand:HI 0 "register_operand" "=r,r")
3939      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3940    (clobber (reg:CC FLAGS_REG))]
3941   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3942   "#"
3943   [(set_attr "type" "imovx,alu1")
3944    (set_attr "mode" "HI")])
3945
3946 ; zero extend to SImode here to avoid partial register stalls
3947 (define_insn "*zero_extendqihi2_movzbl"
3948   [(set (match_operand:HI 0 "register_operand" "=r")
3949      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3950   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3951    && reload_completed"
3952   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3953   [(set_attr "type" "imovx")
3954    (set_attr "mode" "SI")])
3955
3956 ;; For the movzbw case strip only the clobber
3957 (define_split
3958   [(set (match_operand:HI 0 "register_operand" "")
3959         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3960    (clobber (reg:CC FLAGS_REG))]
3961   "reload_completed
3962    && (!TARGET_ZERO_EXTEND_WITH_AND
3963        || optimize_function_for_size_p (cfun))
3964    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3965   [(set (match_operand:HI 0 "register_operand" "")
3966         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3967
3968 ;; When source and destination does not overlap, clear destination
3969 ;; first and then do the movb
3970 (define_split
3971   [(set (match_operand:HI 0 "register_operand" "")
3972         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3973    (clobber (reg:CC FLAGS_REG))]
3974   "reload_completed
3975    && ANY_QI_REG_P (operands[0])
3976    && (TARGET_ZERO_EXTEND_WITH_AND
3977        && optimize_function_for_speed_p (cfun))
3978    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3979   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3980 {
3981   operands[2] = gen_lowpart (QImode, operands[0]);
3982   ix86_expand_clear (operands[0]);
3983 })
3984
3985 ;; Rest is handled by single and.
3986 (define_split
3987   [(set (match_operand:HI 0 "register_operand" "")
3988         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3989    (clobber (reg:CC FLAGS_REG))]
3990   "reload_completed
3991    && true_regnum (operands[0]) == true_regnum (operands[1])"
3992   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3993               (clobber (reg:CC FLAGS_REG))])]
3994   "")
3995
3996 (define_expand "zero_extendqisi2"
3997   [(parallel
3998     [(set (match_operand:SI 0 "register_operand" "")
3999        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4000      (clobber (reg:CC FLAGS_REG))])]
4001   ""
4002   "")
4003
4004 (define_insn "*zero_extendqisi2_and"
4005   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4006      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4007    (clobber (reg:CC FLAGS_REG))]
4008   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4009   "#"
4010   [(set_attr "type" "alu1")
4011    (set_attr "mode" "SI")])
4012
4013 (define_insn "*zero_extendqisi2_movzbl_and"
4014   [(set (match_operand:SI 0 "register_operand" "=r,r")
4015      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4016    (clobber (reg:CC FLAGS_REG))]
4017   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4018   "#"
4019   [(set_attr "type" "imovx,alu1")
4020    (set_attr "mode" "SI")])
4021
4022 (define_insn "*zero_extendqisi2_movzbl"
4023   [(set (match_operand:SI 0 "register_operand" "=r")
4024      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4025   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4026    && reload_completed"
4027   "movz{bl|x}\t{%1, %0|%0, %1}"
4028   [(set_attr "type" "imovx")
4029    (set_attr "mode" "SI")])
4030
4031 ;; For the movzbl case strip only the clobber
4032 (define_split
4033   [(set (match_operand:SI 0 "register_operand" "")
4034         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4035    (clobber (reg:CC FLAGS_REG))]
4036   "reload_completed
4037    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4038    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4039   [(set (match_dup 0)
4040         (zero_extend:SI (match_dup 1)))])
4041
4042 ;; When source and destination does not overlap, clear destination
4043 ;; first and then do the movb
4044 (define_split
4045   [(set (match_operand:SI 0 "register_operand" "")
4046         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4047    (clobber (reg:CC FLAGS_REG))]
4048   "reload_completed
4049    && ANY_QI_REG_P (operands[0])
4050    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4051    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4052    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4053   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4054 {
4055   operands[2] = gen_lowpart (QImode, operands[0]);
4056   ix86_expand_clear (operands[0]);
4057 })
4058
4059 ;; Rest is handled by single and.
4060 (define_split
4061   [(set (match_operand:SI 0 "register_operand" "")
4062         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4063    (clobber (reg:CC FLAGS_REG))]
4064   "reload_completed
4065    && true_regnum (operands[0]) == true_regnum (operands[1])"
4066   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4067               (clobber (reg:CC FLAGS_REG))])]
4068   "")
4069
4070 ;; %%% Kill me once multi-word ops are sane.
4071 (define_expand "zero_extendsidi2"
4072   [(set (match_operand:DI 0 "register_operand" "")
4073      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4074   ""
4075 {
4076   if (!TARGET_64BIT)
4077     {
4078       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4079       DONE;
4080     }
4081 })
4082
4083 (define_insn "zero_extendsidi2_32"
4084   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4085         (zero_extend:DI
4086          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4087    (clobber (reg:CC FLAGS_REG))]
4088   "!TARGET_64BIT"
4089   "@
4090    #
4091    #
4092    #
4093    movd\t{%1, %0|%0, %1}
4094    movd\t{%1, %0|%0, %1}
4095    %vmovd\t{%1, %0|%0, %1}
4096    %vmovd\t{%1, %0|%0, %1}"
4097   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4098    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4099    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4100
4101 (define_insn "zero_extendsidi2_rex64"
4102   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4103      (zero_extend:DI
4104        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4105   "TARGET_64BIT"
4106   "@
4107    mov\t{%k1, %k0|%k0, %k1}
4108    #
4109    movd\t{%1, %0|%0, %1}
4110    movd\t{%1, %0|%0, %1}
4111    %vmovd\t{%1, %0|%0, %1}
4112    %vmovd\t{%1, %0|%0, %1}"
4113   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4114    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4115    (set_attr "prefix_0f" "0,*,*,*,*,*")
4116    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4117
4118 (define_split
4119   [(set (match_operand:DI 0 "memory_operand" "")
4120      (zero_extend:DI (match_dup 0)))]
4121   "TARGET_64BIT"
4122   [(set (match_dup 4) (const_int 0))]
4123   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4124
4125 (define_split
4126   [(set (match_operand:DI 0 "register_operand" "")
4127         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4128    (clobber (reg:CC FLAGS_REG))]
4129   "!TARGET_64BIT && reload_completed
4130    && true_regnum (operands[0]) == true_regnum (operands[1])"
4131   [(set (match_dup 4) (const_int 0))]
4132   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4133
4134 (define_split
4135   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4136         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4137    (clobber (reg:CC FLAGS_REG))]
4138   "!TARGET_64BIT && reload_completed
4139    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4140   [(set (match_dup 3) (match_dup 1))
4141    (set (match_dup 4) (const_int 0))]
4142   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4143
4144 (define_insn "zero_extendhidi2"
4145   [(set (match_operand:DI 0 "register_operand" "=r")
4146      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4147   "TARGET_64BIT"
4148   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4149   [(set_attr "type" "imovx")
4150    (set_attr "mode" "SI")])
4151
4152 (define_insn "zero_extendqidi2"
4153   [(set (match_operand:DI 0 "register_operand" "=r")
4154      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4155   "TARGET_64BIT"
4156   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4157   [(set_attr "type" "imovx")
4158    (set_attr "mode" "SI")])
4159 \f
4160 ;; Sign extension instructions
4161
4162 (define_expand "extendsidi2"
4163   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4164                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4165               (clobber (reg:CC FLAGS_REG))
4166               (clobber (match_scratch:SI 2 ""))])]
4167   ""
4168 {
4169   if (TARGET_64BIT)
4170     {
4171       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4172       DONE;
4173     }
4174 })
4175
4176 (define_insn "*extendsidi2_1"
4177   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4178         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4179    (clobber (reg:CC FLAGS_REG))
4180    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4181   "!TARGET_64BIT"
4182   "#")
4183
4184 (define_insn "extendsidi2_rex64"
4185   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4186         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4187   "TARGET_64BIT"
4188   "@
4189    {cltq|cdqe}
4190    movs{lq|x}\t{%1, %0|%0, %1}"
4191   [(set_attr "type" "imovx")
4192    (set_attr "mode" "DI")
4193    (set_attr "prefix_0f" "0")
4194    (set_attr "modrm" "0,1")])
4195
4196 (define_insn "extendhidi2"
4197   [(set (match_operand:DI 0 "register_operand" "=r")
4198         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4199   "TARGET_64BIT"
4200   "movs{wq|x}\t{%1, %0|%0, %1}"
4201   [(set_attr "type" "imovx")
4202    (set_attr "mode" "DI")])
4203
4204 (define_insn "extendqidi2"
4205   [(set (match_operand:DI 0 "register_operand" "=r")
4206         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4207   "TARGET_64BIT"
4208   "movs{bq|x}\t{%1, %0|%0, %1}"
4209    [(set_attr "type" "imovx")
4210     (set_attr "mode" "DI")])
4211
4212 ;; Extend to memory case when source register does die.
4213 (define_split
4214   [(set (match_operand:DI 0 "memory_operand" "")
4215         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4216    (clobber (reg:CC FLAGS_REG))
4217    (clobber (match_operand:SI 2 "register_operand" ""))]
4218   "(reload_completed
4219     && dead_or_set_p (insn, operands[1])
4220     && !reg_mentioned_p (operands[1], operands[0]))"
4221   [(set (match_dup 3) (match_dup 1))
4222    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4223               (clobber (reg:CC FLAGS_REG))])
4224    (set (match_dup 4) (match_dup 1))]
4225   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4226
4227 ;; Extend to memory case when source register does not die.
4228 (define_split
4229   [(set (match_operand:DI 0 "memory_operand" "")
4230         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4231    (clobber (reg:CC FLAGS_REG))
4232    (clobber (match_operand:SI 2 "register_operand" ""))]
4233   "reload_completed"
4234   [(const_int 0)]
4235 {
4236   split_di (&operands[0], 1, &operands[3], &operands[4]);
4237
4238   emit_move_insn (operands[3], operands[1]);
4239
4240   /* Generate a cltd if possible and doing so it profitable.  */
4241   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4242       && true_regnum (operands[1]) == AX_REG
4243       && true_regnum (operands[2]) == DX_REG)
4244     {
4245       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4246     }
4247   else
4248     {
4249       emit_move_insn (operands[2], operands[1]);
4250       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4251     }
4252   emit_move_insn (operands[4], operands[2]);
4253   DONE;
4254 })
4255
4256 ;; Extend to register case.  Optimize case where source and destination
4257 ;; registers match and cases where we can use cltd.
4258 (define_split
4259   [(set (match_operand:DI 0 "register_operand" "")
4260         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4261    (clobber (reg:CC FLAGS_REG))
4262    (clobber (match_scratch:SI 2 ""))]
4263   "reload_completed"
4264   [(const_int 0)]
4265 {
4266   split_di (&operands[0], 1, &operands[3], &operands[4]);
4267
4268   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4269     emit_move_insn (operands[3], operands[1]);
4270
4271   /* Generate a cltd if possible and doing so it profitable.  */
4272   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4273       && true_regnum (operands[3]) == AX_REG
4274       && true_regnum (operands[4]) == DX_REG)
4275     {
4276       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4277       DONE;
4278     }
4279
4280   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4281     emit_move_insn (operands[4], operands[1]);
4282
4283   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4284   DONE;
4285 })
4286
4287 (define_insn "extendhisi2"
4288   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4289         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4290   ""
4291 {
4292   switch (get_attr_prefix_0f (insn))
4293     {
4294     case 0:
4295       return "{cwtl|cwde}";
4296     default:
4297       return "movs{wl|x}\t{%1, %0|%0, %1}";
4298     }
4299 }
4300   [(set_attr "type" "imovx")
4301    (set_attr "mode" "SI")
4302    (set (attr "prefix_0f")
4303      ;; movsx is short decodable while cwtl is vector decoded.
4304      (if_then_else (and (eq_attr "cpu" "!k6")
4305                         (eq_attr "alternative" "0"))
4306         (const_string "0")
4307         (const_string "1")))
4308    (set (attr "modrm")
4309      (if_then_else (eq_attr "prefix_0f" "0")
4310         (const_string "0")
4311         (const_string "1")))])
4312
4313 (define_insn "*extendhisi2_zext"
4314   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4315         (zero_extend:DI
4316           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4317   "TARGET_64BIT"
4318 {
4319   switch (get_attr_prefix_0f (insn))
4320     {
4321     case 0:
4322       return "{cwtl|cwde}";
4323     default:
4324       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4325     }
4326 }
4327   [(set_attr "type" "imovx")
4328    (set_attr "mode" "SI")
4329    (set (attr "prefix_0f")
4330      ;; movsx is short decodable while cwtl is vector decoded.
4331      (if_then_else (and (eq_attr "cpu" "!k6")
4332                         (eq_attr "alternative" "0"))
4333         (const_string "0")
4334         (const_string "1")))
4335    (set (attr "modrm")
4336      (if_then_else (eq_attr "prefix_0f" "0")
4337         (const_string "0")
4338         (const_string "1")))])
4339
4340 (define_insn "extendqihi2"
4341   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4342         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4343   ""
4344 {
4345   switch (get_attr_prefix_0f (insn))
4346     {
4347     case 0:
4348       return "{cbtw|cbw}";
4349     default:
4350       return "movs{bw|x}\t{%1, %0|%0, %1}";
4351     }
4352 }
4353   [(set_attr "type" "imovx")
4354    (set_attr "mode" "HI")
4355    (set (attr "prefix_0f")
4356      ;; movsx is short decodable while cwtl is vector decoded.
4357      (if_then_else (and (eq_attr "cpu" "!k6")
4358                         (eq_attr "alternative" "0"))
4359         (const_string "0")
4360         (const_string "1")))
4361    (set (attr "modrm")
4362      (if_then_else (eq_attr "prefix_0f" "0")
4363         (const_string "0")
4364         (const_string "1")))])
4365
4366 (define_insn "extendqisi2"
4367   [(set (match_operand:SI 0 "register_operand" "=r")
4368         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4369   ""
4370   "movs{bl|x}\t{%1, %0|%0, %1}"
4371    [(set_attr "type" "imovx")
4372     (set_attr "mode" "SI")])
4373
4374 (define_insn "*extendqisi2_zext"
4375   [(set (match_operand:DI 0 "register_operand" "=r")
4376         (zero_extend:DI
4377           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4378   "TARGET_64BIT"
4379   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4380    [(set_attr "type" "imovx")
4381     (set_attr "mode" "SI")])
4382 \f
4383 ;; Conversions between float and double.
4384
4385 ;; These are all no-ops in the model used for the 80387.  So just
4386 ;; emit moves.
4387
4388 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4389 (define_insn "*dummy_extendsfdf2"
4390   [(set (match_operand:DF 0 "push_operand" "=<")
4391         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4392   "0"
4393   "#")
4394
4395 (define_split
4396   [(set (match_operand:DF 0 "push_operand" "")
4397         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4398   ""
4399   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4400    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4401
4402 (define_insn "*dummy_extendsfxf2"
4403   [(set (match_operand:XF 0 "push_operand" "=<")
4404         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4405   "0"
4406   "#")
4407
4408 (define_split
4409   [(set (match_operand:XF 0 "push_operand" "")
4410         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4411   ""
4412   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4413    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4414   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4415
4416 (define_split
4417   [(set (match_operand:XF 0 "push_operand" "")
4418         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4419   ""
4420   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4421    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4422   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4423
4424 (define_expand "extendsfdf2"
4425   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4426         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4427   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4428 {
4429   /* ??? Needed for compress_float_constant since all fp constants
4430      are LEGITIMATE_CONSTANT_P.  */
4431   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4432     {
4433       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4434           && standard_80387_constant_p (operands[1]) > 0)
4435         {
4436           operands[1] = simplify_const_unary_operation
4437             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4438           emit_move_insn_1 (operands[0], operands[1]);
4439           DONE;
4440         }
4441       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4442     }
4443 })
4444
4445 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4446    cvtss2sd:
4447       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4448       cvtps2pd xmm2,xmm1
4449    We do the conversion post reload to avoid producing of 128bit spills
4450    that might lead to ICE on 32bit target.  The sequence unlikely combine
4451    anyway.  */
4452 (define_split
4453   [(set (match_operand:DF 0 "register_operand" "")
4454         (float_extend:DF
4455           (match_operand:SF 1 "nonimmediate_operand" "")))]
4456   "TARGET_USE_VECTOR_FP_CONVERTS
4457    && optimize_insn_for_speed_p ()
4458    && reload_completed && SSE_REG_P (operands[0])"
4459    [(set (match_dup 2)
4460          (float_extend:V2DF
4461            (vec_select:V2SF
4462              (match_dup 3)
4463              (parallel [(const_int 0) (const_int 1)]))))]
4464 {
4465   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4466   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4467   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4468      Try to avoid move when unpacking can be done in source.  */
4469   if (REG_P (operands[1]))
4470     {
4471       /* If it is unsafe to overwrite upper half of source, we need
4472          to move to destination and unpack there.  */
4473       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4474            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4475           && true_regnum (operands[0]) != true_regnum (operands[1]))
4476         {
4477           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4478           emit_move_insn (tmp, operands[1]);
4479         }
4480       else
4481         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4482       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4483                                              operands[3]));
4484     }
4485   else
4486     emit_insn (gen_vec_setv4sf_0 (operands[3],
4487                                   CONST0_RTX (V4SFmode), operands[1]));
4488 })
4489
4490 (define_insn "*extendsfdf2_mixed"
4491   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4492         (float_extend:DF
4493           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4494   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4495 {
4496   switch (which_alternative)
4497     {
4498     case 0:
4499     case 1:
4500       return output_387_reg_move (insn, operands);
4501
4502     case 2:
4503       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4504
4505     default:
4506       gcc_unreachable ();
4507     }
4508 }
4509   [(set_attr "type" "fmov,fmov,ssecvt")
4510    (set_attr "prefix" "orig,orig,maybe_vex")
4511    (set_attr "mode" "SF,XF,DF")])
4512
4513 (define_insn "*extendsfdf2_sse"
4514   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4515         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4516   "TARGET_SSE2 && TARGET_SSE_MATH"
4517   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4518   [(set_attr "type" "ssecvt")
4519    (set_attr "prefix" "maybe_vex")
4520    (set_attr "mode" "DF")])
4521
4522 (define_insn "*extendsfdf2_i387"
4523   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4524         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4525   "TARGET_80387"
4526   "* return output_387_reg_move (insn, operands);"
4527   [(set_attr "type" "fmov")
4528    (set_attr "mode" "SF,XF")])
4529
4530 (define_expand "extend<mode>xf2"
4531   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4532         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4533   "TARGET_80387"
4534 {
4535   /* ??? Needed for compress_float_constant since all fp constants
4536      are LEGITIMATE_CONSTANT_P.  */
4537   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4538     {
4539       if (standard_80387_constant_p (operands[1]) > 0)
4540         {
4541           operands[1] = simplify_const_unary_operation
4542             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4543           emit_move_insn_1 (operands[0], operands[1]);
4544           DONE;
4545         }
4546       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4547     }
4548 })
4549
4550 (define_insn "*extend<mode>xf2_i387"
4551   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4552         (float_extend:XF
4553           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4554   "TARGET_80387"
4555   "* return output_387_reg_move (insn, operands);"
4556   [(set_attr "type" "fmov")
4557    (set_attr "mode" "<MODE>,XF")])
4558
4559 ;; %%% This seems bad bad news.
4560 ;; This cannot output into an f-reg because there is no way to be sure
4561 ;; of truncating in that case.  Otherwise this is just like a simple move
4562 ;; insn.  So we pretend we can output to a reg in order to get better
4563 ;; register preferencing, but we really use a stack slot.
4564
4565 ;; Conversion from DFmode to SFmode.
4566
4567 (define_expand "truncdfsf2"
4568   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4569         (float_truncate:SF
4570           (match_operand:DF 1 "nonimmediate_operand" "")))]
4571   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4572 {
4573   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4574     ;
4575   else if (flag_unsafe_math_optimizations)
4576     ;
4577   else
4578     {
4579       enum ix86_stack_slot slot = (virtuals_instantiated
4580                                    ? SLOT_TEMP
4581                                    : SLOT_VIRTUAL);
4582       rtx temp = assign_386_stack_local (SFmode, slot);
4583       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4584       DONE;
4585     }
4586 })
4587
4588 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4589    cvtsd2ss:
4590       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4591       cvtpd2ps xmm2,xmm1
4592    We do the conversion post reload to avoid producing of 128bit spills
4593    that might lead to ICE on 32bit target.  The sequence unlikely combine
4594    anyway.  */
4595 (define_split
4596   [(set (match_operand:SF 0 "register_operand" "")
4597         (float_truncate:SF
4598           (match_operand:DF 1 "nonimmediate_operand" "")))]
4599   "TARGET_USE_VECTOR_FP_CONVERTS
4600    && optimize_insn_for_speed_p ()
4601    && reload_completed && SSE_REG_P (operands[0])"
4602    [(set (match_dup 2)
4603          (vec_concat:V4SF
4604            (float_truncate:V2SF
4605              (match_dup 4))
4606            (match_dup 3)))]
4607 {
4608   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4609   operands[3] = CONST0_RTX (V2SFmode);
4610   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4611   /* Use movsd for loading from memory, unpcklpd for registers.
4612      Try to avoid move when unpacking can be done in source, or SSE3
4613      movddup is available.  */
4614   if (REG_P (operands[1]))
4615     {
4616       if (!TARGET_SSE3
4617           && true_regnum (operands[0]) != true_regnum (operands[1])
4618           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4619               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4620         {
4621           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4622           emit_move_insn (tmp, operands[1]);
4623           operands[1] = tmp;
4624         }
4625       else if (!TARGET_SSE3)
4626         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4627       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4628     }
4629   else
4630     emit_insn (gen_sse2_loadlpd (operands[4],
4631                                  CONST0_RTX (V2DFmode), operands[1]));
4632 })
4633
4634 (define_expand "truncdfsf2_with_temp"
4635   [(parallel [(set (match_operand:SF 0 "" "")
4636                    (float_truncate:SF (match_operand:DF 1 "" "")))
4637               (clobber (match_operand:SF 2 "" ""))])]
4638   "")
4639
4640 (define_insn "*truncdfsf_fast_mixed"
4641   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4642         (float_truncate:SF
4643           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4644   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4645 {
4646   switch (which_alternative)
4647     {
4648     case 0:
4649       return output_387_reg_move (insn, operands);
4650     case 1:
4651       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4652     default:
4653       gcc_unreachable ();
4654     }
4655 }
4656   [(set_attr "type" "fmov,ssecvt")
4657    (set_attr "prefix" "orig,maybe_vex")
4658    (set_attr "mode" "SF")])
4659
4660 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4661 ;; because nothing we do here is unsafe.
4662 (define_insn "*truncdfsf_fast_sse"
4663   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4664         (float_truncate:SF
4665           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4666   "TARGET_SSE2 && TARGET_SSE_MATH"
4667   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4668   [(set_attr "type" "ssecvt")
4669    (set_attr "prefix" "maybe_vex")
4670    (set_attr "mode" "SF")])
4671
4672 (define_insn "*truncdfsf_fast_i387"
4673   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4674         (float_truncate:SF
4675           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4676   "TARGET_80387 && flag_unsafe_math_optimizations"
4677   "* return output_387_reg_move (insn, operands);"
4678   [(set_attr "type" "fmov")
4679    (set_attr "mode" "SF")])
4680
4681 (define_insn "*truncdfsf_mixed"
4682   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4683         (float_truncate:SF
4684           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4685    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4686   "TARGET_MIX_SSE_I387"
4687 {
4688   switch (which_alternative)
4689     {
4690     case 0:
4691       return output_387_reg_move (insn, operands);
4692     case 1:
4693       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4694
4695     default:
4696       return "#";
4697     }
4698 }
4699   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4700    (set_attr "unit" "*,*,i387,i387,i387")
4701    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4702    (set_attr "mode" "SF")])
4703
4704 (define_insn "*truncdfsf_i387"
4705   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4706         (float_truncate:SF
4707           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4708    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4709   "TARGET_80387"
4710 {
4711   switch (which_alternative)
4712     {
4713     case 0:
4714       return output_387_reg_move (insn, operands);
4715
4716     default:
4717       return "#";
4718     }
4719 }
4720   [(set_attr "type" "fmov,multi,multi,multi")
4721    (set_attr "unit" "*,i387,i387,i387")
4722    (set_attr "mode" "SF")])
4723
4724 (define_insn "*truncdfsf2_i387_1"
4725   [(set (match_operand:SF 0 "memory_operand" "=m")
4726         (float_truncate:SF
4727           (match_operand:DF 1 "register_operand" "f")))]
4728   "TARGET_80387
4729    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4730    && !TARGET_MIX_SSE_I387"
4731   "* return output_387_reg_move (insn, operands);"
4732   [(set_attr "type" "fmov")
4733    (set_attr "mode" "SF")])
4734
4735 (define_split
4736   [(set (match_operand:SF 0 "register_operand" "")
4737         (float_truncate:SF
4738          (match_operand:DF 1 "fp_register_operand" "")))
4739    (clobber (match_operand 2 "" ""))]
4740   "reload_completed"
4741   [(set (match_dup 2) (match_dup 1))
4742    (set (match_dup 0) (match_dup 2))]
4743 {
4744   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4745 })
4746
4747 ;; Conversion from XFmode to {SF,DF}mode
4748
4749 (define_expand "truncxf<mode>2"
4750   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4751                    (float_truncate:MODEF
4752                      (match_operand:XF 1 "register_operand" "")))
4753               (clobber (match_dup 2))])]
4754   "TARGET_80387"
4755 {
4756   if (flag_unsafe_math_optimizations)
4757     {
4758       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4759       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4760       if (reg != operands[0])
4761         emit_move_insn (operands[0], reg);
4762       DONE;
4763     }
4764   else
4765     {
4766      enum ix86_stack_slot slot = (virtuals_instantiated
4767                                   ? SLOT_TEMP
4768                                   : SLOT_VIRTUAL);
4769       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4770     }
4771 })
4772
4773 (define_insn "*truncxfsf2_mixed"
4774   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4775         (float_truncate:SF
4776           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4777    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4778   "TARGET_80387"
4779 {
4780   gcc_assert (!which_alternative);
4781   return output_387_reg_move (insn, operands);
4782 }
4783   [(set_attr "type" "fmov,multi,multi,multi")
4784    (set_attr "unit" "*,i387,i387,i387")
4785    (set_attr "mode" "SF")])
4786
4787 (define_insn "*truncxfdf2_mixed"
4788   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4789         (float_truncate:DF
4790           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4791    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4792   "TARGET_80387"
4793 {
4794   gcc_assert (!which_alternative);
4795   return output_387_reg_move (insn, operands);
4796 }
4797   [(set_attr "type" "fmov,multi,multi,multi")
4798    (set_attr "unit" "*,i387,i387,i387")
4799    (set_attr "mode" "DF")])
4800
4801 (define_insn "truncxf<mode>2_i387_noop"
4802   [(set (match_operand:MODEF 0 "register_operand" "=f")
4803         (float_truncate:MODEF
4804           (match_operand:XF 1 "register_operand" "f")))]
4805   "TARGET_80387 && flag_unsafe_math_optimizations"
4806   "* return output_387_reg_move (insn, operands);"
4807   [(set_attr "type" "fmov")
4808    (set_attr "mode" "<MODE>")])
4809
4810 (define_insn "*truncxf<mode>2_i387"
4811   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4812         (float_truncate:MODEF
4813           (match_operand:XF 1 "register_operand" "f")))]
4814   "TARGET_80387"
4815   "* return output_387_reg_move (insn, operands);"
4816   [(set_attr "type" "fmov")
4817    (set_attr "mode" "<MODE>")])
4818
4819 (define_split
4820   [(set (match_operand:MODEF 0 "register_operand" "")
4821         (float_truncate:MODEF
4822           (match_operand:XF 1 "register_operand" "")))
4823    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4824   "TARGET_80387 && reload_completed"
4825   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4826    (set (match_dup 0) (match_dup 2))]
4827   "")
4828
4829 (define_split
4830   [(set (match_operand:MODEF 0 "memory_operand" "")
4831         (float_truncate:MODEF
4832           (match_operand:XF 1 "register_operand" "")))
4833    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4834   "TARGET_80387"
4835   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4836   "")
4837 \f
4838 ;; Signed conversion to DImode.
4839
4840 (define_expand "fix_truncxfdi2"
4841   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4842                    (fix:DI (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_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4849      DONE;
4850    }
4851 })
4852
4853 (define_expand "fix_trunc<mode>di2"
4854   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4855                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4856               (clobber (reg:CC FLAGS_REG))])]
4857   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4858 {
4859   if (TARGET_FISTTP
4860       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4861    {
4862      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4863      DONE;
4864    }
4865   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4866    {
4867      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4868      emit_insn (gen_fix_trunc<mode>di_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 SImode.
4876
4877 (define_expand "fix_truncxfsi2"
4878   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4879                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4880               (clobber (reg:CC FLAGS_REG))])]
4881   "TARGET_80387"
4882 {
4883   if (TARGET_FISTTP)
4884    {
4885      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4886      DONE;
4887    }
4888 })
4889
4890 (define_expand "fix_trunc<mode>si2"
4891   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4892                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4893               (clobber (reg:CC FLAGS_REG))])]
4894   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4895 {
4896   if (TARGET_FISTTP
4897       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4898    {
4899      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4900      DONE;
4901    }
4902   if (SSE_FLOAT_MODE_P (<MODE>mode))
4903    {
4904      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4905      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4906      if (out != operands[0])
4907         emit_move_insn (operands[0], out);
4908      DONE;
4909    }
4910 })
4911
4912 ;; Signed conversion to HImode.
4913
4914 (define_expand "fix_trunc<mode>hi2"
4915   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4916                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4917               (clobber (reg:CC FLAGS_REG))])]
4918   "TARGET_80387
4919    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4920 {
4921   if (TARGET_FISTTP)
4922    {
4923      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4924      DONE;
4925    }
4926 })
4927
4928 ;; Unsigned conversion to SImode.
4929
4930 (define_expand "fixuns_trunc<mode>si2"
4931   [(parallel
4932     [(set (match_operand:SI 0 "register_operand" "")
4933           (unsigned_fix:SI
4934             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4935      (use (match_dup 2))
4936      (clobber (match_scratch:<ssevecmode> 3 ""))
4937      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4938   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4939 {
4940   enum machine_mode mode = <MODE>mode;
4941   enum machine_mode vecmode = <ssevecmode>mode;
4942   REAL_VALUE_TYPE TWO31r;
4943   rtx two31;
4944
4945   if (optimize_insn_for_size_p ())
4946     FAIL;
4947
4948   real_ldexp (&TWO31r, &dconst1, 31);
4949   two31 = const_double_from_real_value (TWO31r, mode);
4950   two31 = ix86_build_const_vector (mode, true, two31);
4951   operands[2] = force_reg (vecmode, two31);
4952 })
4953
4954 (define_insn_and_split "*fixuns_trunc<mode>_1"
4955   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4956         (unsigned_fix:SI
4957           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4958    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4959    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4960    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4961   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4962    && optimize_function_for_speed_p (cfun)"
4963   "#"
4964   "&& reload_completed"
4965   [(const_int 0)]
4966 {
4967   ix86_split_convert_uns_si_sse (operands);
4968   DONE;
4969 })
4970
4971 ;; Unsigned conversion to HImode.
4972 ;; Without these patterns, we'll try the unsigned SI conversion which
4973 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4974
4975 (define_expand "fixuns_trunc<mode>hi2"
4976   [(set (match_dup 2)
4977         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4978    (set (match_operand:HI 0 "nonimmediate_operand" "")
4979         (subreg:HI (match_dup 2) 0))]
4980   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4981   "operands[2] = gen_reg_rtx (SImode);")
4982
4983 ;; When SSE is available, it is always faster to use it!
4984 (define_insn "fix_trunc<mode>di_sse"
4985   [(set (match_operand:DI 0 "register_operand" "=r,r")
4986         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4987   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4988    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4989   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4990   [(set_attr "type" "sseicvt")
4991    (set_attr "prefix" "maybe_vex")
4992    (set_attr "prefix_rex" "1")
4993    (set_attr "mode" "<MODE>")
4994    (set_attr "athlon_decode" "double,vector")
4995    (set_attr "amdfam10_decode" "double,double")])
4996
4997 (define_insn "fix_trunc<mode>si_sse"
4998   [(set (match_operand:SI 0 "register_operand" "=r,r")
4999         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5000   "SSE_FLOAT_MODE_P (<MODE>mode)
5001    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5002   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5003   [(set_attr "type" "sseicvt")
5004    (set_attr "prefix" "maybe_vex")
5005    (set_attr "mode" "<MODE>")
5006    (set_attr "athlon_decode" "double,vector")
5007    (set_attr "amdfam10_decode" "double,double")])
5008
5009 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5010 (define_peephole2
5011   [(set (match_operand:MODEF 0 "register_operand" "")
5012         (match_operand:MODEF 1 "memory_operand" ""))
5013    (set (match_operand:SSEMODEI24 2 "register_operand" "")
5014         (fix:SSEMODEI24 (match_dup 0)))]
5015   "TARGET_SHORTEN_X87_SSE
5016    && peep2_reg_dead_p (2, operands[0])"
5017   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5018   "")
5019
5020 ;; Avoid vector decoded forms of the instruction.
5021 (define_peephole2
5022   [(match_scratch:DF 2 "Y2")
5023    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5024         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5025   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5026   [(set (match_dup 2) (match_dup 1))
5027    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5028   "")
5029
5030 (define_peephole2
5031   [(match_scratch:SF 2 "x")
5032    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5033         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5034   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5035   [(set (match_dup 2) (match_dup 1))
5036    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5037   "")
5038
5039 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5040   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5041         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5042   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5043    && TARGET_FISTTP
5044    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5045          && (TARGET_64BIT || <MODE>mode != DImode))
5046         && TARGET_SSE_MATH)
5047    && can_create_pseudo_p ()"
5048   "#"
5049   "&& 1"
5050   [(const_int 0)]
5051 {
5052   if (memory_operand (operands[0], VOIDmode))
5053     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5054   else
5055     {
5056       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5057       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5058                                                             operands[1],
5059                                                             operands[2]));
5060     }
5061   DONE;
5062 }
5063   [(set_attr "type" "fisttp")
5064    (set_attr "mode" "<MODE>")])
5065
5066 (define_insn "fix_trunc<mode>_i387_fisttp"
5067   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5068         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5069    (clobber (match_scratch:XF 2 "=&1f"))]
5070   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5071    && TARGET_FISTTP
5072    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5073          && (TARGET_64BIT || <MODE>mode != DImode))
5074         && TARGET_SSE_MATH)"
5075   "* return output_fix_trunc (insn, operands, 1);"
5076   [(set_attr "type" "fisttp")
5077    (set_attr "mode" "<MODE>")])
5078
5079 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5080   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5081         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5082    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5083    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5084   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5085    && TARGET_FISTTP
5086    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5087         && (TARGET_64BIT || <MODE>mode != DImode))
5088         && TARGET_SSE_MATH)"
5089   "#"
5090   [(set_attr "type" "fisttp")
5091    (set_attr "mode" "<MODE>")])
5092
5093 (define_split
5094   [(set (match_operand:X87MODEI 0 "register_operand" "")
5095         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5096    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5097    (clobber (match_scratch 3 ""))]
5098   "reload_completed"
5099   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5100               (clobber (match_dup 3))])
5101    (set (match_dup 0) (match_dup 2))]
5102   "")
5103
5104 (define_split
5105   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5106         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5107    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5108    (clobber (match_scratch 3 ""))]
5109   "reload_completed"
5110   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5111               (clobber (match_dup 3))])]
5112   "")
5113
5114 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5115 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5116 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5117 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5118 ;; function in i386.c.
5119 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5120   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5121         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5122    (clobber (reg:CC FLAGS_REG))]
5123   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5124    && !TARGET_FISTTP
5125    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5126          && (TARGET_64BIT || <MODE>mode != DImode))
5127    && can_create_pseudo_p ()"
5128   "#"
5129   "&& 1"
5130   [(const_int 0)]
5131 {
5132   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5133
5134   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5135   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5136   if (memory_operand (operands[0], VOIDmode))
5137     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5138                                          operands[2], operands[3]));
5139   else
5140     {
5141       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5142       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5143                                                      operands[2], operands[3],
5144                                                      operands[4]));
5145     }
5146   DONE;
5147 }
5148   [(set_attr "type" "fistp")
5149    (set_attr "i387_cw" "trunc")
5150    (set_attr "mode" "<MODE>")])
5151
5152 (define_insn "fix_truncdi_i387"
5153   [(set (match_operand:DI 0 "memory_operand" "=m")
5154         (fix:DI (match_operand 1 "register_operand" "f")))
5155    (use (match_operand:HI 2 "memory_operand" "m"))
5156    (use (match_operand:HI 3 "memory_operand" "m"))
5157    (clobber (match_scratch:XF 4 "=&1f"))]
5158   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5159    && !TARGET_FISTTP
5160    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5161   "* return output_fix_trunc (insn, operands, 0);"
5162   [(set_attr "type" "fistp")
5163    (set_attr "i387_cw" "trunc")
5164    (set_attr "mode" "DI")])
5165
5166 (define_insn "fix_truncdi_i387_with_temp"
5167   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5168         (fix:DI (match_operand 1 "register_operand" "f,f")))
5169    (use (match_operand:HI 2 "memory_operand" "m,m"))
5170    (use (match_operand:HI 3 "memory_operand" "m,m"))
5171    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5172    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5173   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5174    && !TARGET_FISTTP
5175    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5176   "#"
5177   [(set_attr "type" "fistp")
5178    (set_attr "i387_cw" "trunc")
5179    (set_attr "mode" "DI")])
5180
5181 (define_split
5182   [(set (match_operand:DI 0 "register_operand" "")
5183         (fix:DI (match_operand 1 "register_operand" "")))
5184    (use (match_operand:HI 2 "memory_operand" ""))
5185    (use (match_operand:HI 3 "memory_operand" ""))
5186    (clobber (match_operand:DI 4 "memory_operand" ""))
5187    (clobber (match_scratch 5 ""))]
5188   "reload_completed"
5189   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5190               (use (match_dup 2))
5191               (use (match_dup 3))
5192               (clobber (match_dup 5))])
5193    (set (match_dup 0) (match_dup 4))]
5194   "")
5195
5196 (define_split
5197   [(set (match_operand:DI 0 "memory_operand" "")
5198         (fix:DI (match_operand 1 "register_operand" "")))
5199    (use (match_operand:HI 2 "memory_operand" ""))
5200    (use (match_operand:HI 3 "memory_operand" ""))
5201    (clobber (match_operand:DI 4 "memory_operand" ""))
5202    (clobber (match_scratch 5 ""))]
5203   "reload_completed"
5204   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5205               (use (match_dup 2))
5206               (use (match_dup 3))
5207               (clobber (match_dup 5))])]
5208   "")
5209
5210 (define_insn "fix_trunc<mode>_i387"
5211   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5212         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5213    (use (match_operand:HI 2 "memory_operand" "m"))
5214    (use (match_operand:HI 3 "memory_operand" "m"))]
5215   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5216    && !TARGET_FISTTP
5217    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5218   "* return output_fix_trunc (insn, operands, 0);"
5219   [(set_attr "type" "fistp")
5220    (set_attr "i387_cw" "trunc")
5221    (set_attr "mode" "<MODE>")])
5222
5223 (define_insn "fix_trunc<mode>_i387_with_temp"
5224   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5225         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5226    (use (match_operand:HI 2 "memory_operand" "m,m"))
5227    (use (match_operand:HI 3 "memory_operand" "m,m"))
5228    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5229   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5230    && !TARGET_FISTTP
5231    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5232   "#"
5233   [(set_attr "type" "fistp")
5234    (set_attr "i387_cw" "trunc")
5235    (set_attr "mode" "<MODE>")])
5236
5237 (define_split
5238   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5239         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5240    (use (match_operand:HI 2 "memory_operand" ""))
5241    (use (match_operand:HI 3 "memory_operand" ""))
5242    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5243   "reload_completed"
5244   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5245               (use (match_dup 2))
5246               (use (match_dup 3))])
5247    (set (match_dup 0) (match_dup 4))]
5248   "")
5249
5250 (define_split
5251   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5252         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5253    (use (match_operand:HI 2 "memory_operand" ""))
5254    (use (match_operand:HI 3 "memory_operand" ""))
5255    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5256   "reload_completed"
5257   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5258               (use (match_dup 2))
5259               (use (match_dup 3))])]
5260   "")
5261
5262 (define_insn "x86_fnstcw_1"
5263   [(set (match_operand:HI 0 "memory_operand" "=m")
5264         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5265   "TARGET_80387"
5266   "fnstcw\t%0"
5267   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5268    (set_attr "mode" "HI")
5269    (set_attr "unit" "i387")])
5270
5271 (define_insn "x86_fldcw_1"
5272   [(set (reg:HI FPCR_REG)
5273         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5274   "TARGET_80387"
5275   "fldcw\t%0"
5276   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5277    (set_attr "mode" "HI")
5278    (set_attr "unit" "i387")
5279    (set_attr "athlon_decode" "vector")
5280    (set_attr "amdfam10_decode" "vector")])
5281 \f
5282 ;; Conversion between fixed point and floating point.
5283
5284 ;; Even though we only accept memory inputs, the backend _really_
5285 ;; wants to be able to do this between registers.
5286
5287 (define_expand "floathi<mode>2"
5288   [(set (match_operand:X87MODEF 0 "register_operand" "")
5289         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5290   "TARGET_80387
5291    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5292        || TARGET_MIX_SSE_I387)"
5293   "")
5294
5295 ;; Pre-reload splitter to add memory clobber to the pattern.
5296 (define_insn_and_split "*floathi<mode>2_1"
5297   [(set (match_operand:X87MODEF 0 "register_operand" "")
5298         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5299   "TARGET_80387
5300    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5301        || TARGET_MIX_SSE_I387)
5302    && can_create_pseudo_p ()"
5303   "#"
5304   "&& 1"
5305   [(parallel [(set (match_dup 0)
5306               (float:X87MODEF (match_dup 1)))
5307    (clobber (match_dup 2))])]
5308   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5309
5310 (define_insn "*floathi<mode>2_i387_with_temp"
5311   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5312         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5313   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5314   "TARGET_80387
5315    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5316        || TARGET_MIX_SSE_I387)"
5317   "#"
5318   [(set_attr "type" "fmov,multi")
5319    (set_attr "mode" "<MODE>")
5320    (set_attr "unit" "*,i387")
5321    (set_attr "fp_int_src" "true")])
5322
5323 (define_insn "*floathi<mode>2_i387"
5324   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5325         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5326   "TARGET_80387
5327    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5328        || TARGET_MIX_SSE_I387)"
5329   "fild%Z1\t%1"
5330   [(set_attr "type" "fmov")
5331    (set_attr "mode" "<MODE>")
5332    (set_attr "fp_int_src" "true")])
5333
5334 (define_split
5335   [(set (match_operand:X87MODEF 0 "register_operand" "")
5336         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5337    (clobber (match_operand:HI 2 "memory_operand" ""))]
5338   "TARGET_80387
5339    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5340        || TARGET_MIX_SSE_I387)
5341    && reload_completed"
5342   [(set (match_dup 2) (match_dup 1))
5343    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5344   "")
5345
5346 (define_split
5347   [(set (match_operand:X87MODEF 0 "register_operand" "")
5348         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5349    (clobber (match_operand:HI 2 "memory_operand" ""))]
5350    "TARGET_80387
5351     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5352         || TARGET_MIX_SSE_I387)
5353     && reload_completed"
5354   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5355   "")
5356
5357 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5358   [(set (match_operand:X87MODEF 0 "register_operand" "")
5359         (float:X87MODEF
5360           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5361   "TARGET_80387
5362    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5363        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5364 {
5365   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5366         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5367       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5368     {
5369       rtx reg = gen_reg_rtx (XFmode);
5370       rtx insn;
5371
5372       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5373
5374       if (<X87MODEF:MODE>mode == SFmode)
5375         insn = gen_truncxfsf2 (operands[0], reg);
5376       else if (<X87MODEF:MODE>mode == DFmode)
5377         insn = gen_truncxfdf2 (operands[0], reg);
5378       else
5379         gcc_unreachable ();
5380
5381       emit_insn (insn);
5382       DONE;
5383     }
5384 })
5385
5386 ;; Pre-reload splitter to add memory clobber to the pattern.
5387 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5388   [(set (match_operand:X87MODEF 0 "register_operand" "")
5389         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5390   "((TARGET_80387
5391      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5392      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5393            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5394          || TARGET_MIX_SSE_I387))
5395     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5396         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5397         && ((<SSEMODEI24:MODE>mode == SImode
5398              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5399              && optimize_function_for_speed_p (cfun)
5400              && flag_trapping_math)
5401             || !(TARGET_INTER_UNIT_CONVERSIONS
5402                  || optimize_function_for_size_p (cfun)))))
5403    && can_create_pseudo_p ()"
5404   "#"
5405   "&& 1"
5406   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5407               (clobber (match_dup 2))])]
5408 {
5409   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5410
5411   /* Avoid store forwarding (partial memory) stall penalty
5412      by passing DImode value through XMM registers.  */
5413   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5414       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5415       && optimize_function_for_speed_p (cfun))
5416     {
5417       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5418                                                             operands[1],
5419                                                             operands[2]));
5420       DONE;
5421     }
5422 })
5423
5424 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5425   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5426         (float:MODEF
5427           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5428    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5429   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5430    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5431   "#"
5432   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5433    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5434    (set_attr "unit" "*,i387,*,*,*")
5435    (set_attr "athlon_decode" "*,*,double,direct,double")
5436    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5437    (set_attr "fp_int_src" "true")])
5438
5439 (define_insn "*floatsi<mode>2_vector_mixed"
5440   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5441         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5442   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5443    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5444   "@
5445    fild%Z1\t%1
5446    #"
5447   [(set_attr "type" "fmov,sseicvt")
5448    (set_attr "mode" "<MODE>,<ssevecmode>")
5449    (set_attr "unit" "i387,*")
5450    (set_attr "athlon_decode" "*,direct")
5451    (set_attr "amdfam10_decode" "*,double")
5452    (set_attr "fp_int_src" "true")])
5453
5454 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5455   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5456         (float:MODEF
5457           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5458   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5459   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5460    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5461   "#"
5462   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5463    (set_attr "mode" "<MODEF:MODE>")
5464    (set_attr "unit" "*,i387,*,*")
5465    (set_attr "athlon_decode" "*,*,double,direct")
5466    (set_attr "amdfam10_decode" "*,*,vector,double")
5467    (set_attr "fp_int_src" "true")])
5468
5469 (define_split
5470   [(set (match_operand:MODEF 0 "register_operand" "")
5471         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5472    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5473   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5474    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5475    && TARGET_INTER_UNIT_CONVERSIONS
5476    && reload_completed
5477    && (SSE_REG_P (operands[0])
5478        || (GET_CODE (operands[0]) == SUBREG
5479            && SSE_REG_P (operands[0])))"
5480   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5481   "")
5482
5483 (define_split
5484   [(set (match_operand:MODEF 0 "register_operand" "")
5485         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5486    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5487   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5488    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5489    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5490    && reload_completed
5491    && (SSE_REG_P (operands[0])
5492        || (GET_CODE (operands[0]) == SUBREG
5493            && SSE_REG_P (operands[0])))"
5494   [(set (match_dup 2) (match_dup 1))
5495    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5496   "")
5497
5498 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5499   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5500         (float:MODEF
5501           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5502   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5503    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5504    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5505   "@
5506    fild%Z1\t%1
5507    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5508    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5509   [(set_attr "type" "fmov,sseicvt,sseicvt")
5510    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5511    (set_attr "mode" "<MODEF:MODE>")
5512    (set (attr "prefix_rex")
5513      (if_then_else
5514        (and (eq_attr "prefix" "maybe_vex")
5515             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5516        (const_string "1")
5517        (const_string "*")))
5518    (set_attr "unit" "i387,*,*")
5519    (set_attr "athlon_decode" "*,double,direct")
5520    (set_attr "amdfam10_decode" "*,vector,double")
5521    (set_attr "fp_int_src" "true")])
5522
5523 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5524   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5525         (float:MODEF
5526           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5527   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5528    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5529    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5530   "@
5531    fild%Z1\t%1
5532    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5533   [(set_attr "type" "fmov,sseicvt")
5534    (set_attr "prefix" "orig,maybe_vex")
5535    (set_attr "mode" "<MODEF:MODE>")
5536    (set (attr "prefix_rex")
5537      (if_then_else
5538        (and (eq_attr "prefix" "maybe_vex")
5539             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5540        (const_string "1")
5541        (const_string "*")))
5542    (set_attr "athlon_decode" "*,direct")
5543    (set_attr "amdfam10_decode" "*,double")
5544    (set_attr "fp_int_src" "true")])
5545
5546 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5547   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5548         (float:MODEF
5549           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5550    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5551   "TARGET_SSE2 && TARGET_SSE_MATH
5552    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5553   "#"
5554   [(set_attr "type" "sseicvt")
5555    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5556    (set_attr "athlon_decode" "double,direct,double")
5557    (set_attr "amdfam10_decode" "vector,double,double")
5558    (set_attr "fp_int_src" "true")])
5559
5560 (define_insn "*floatsi<mode>2_vector_sse"
5561   [(set (match_operand:MODEF 0 "register_operand" "=x")
5562         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5563   "TARGET_SSE2 && TARGET_SSE_MATH
5564    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5565   "#"
5566   [(set_attr "type" "sseicvt")
5567    (set_attr "mode" "<MODE>")
5568    (set_attr "athlon_decode" "direct")
5569    (set_attr "amdfam10_decode" "double")
5570    (set_attr "fp_int_src" "true")])
5571
5572 (define_split
5573   [(set (match_operand:MODEF 0 "register_operand" "")
5574         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5575    (clobber (match_operand:SI 2 "memory_operand" ""))]
5576   "TARGET_SSE2 && TARGET_SSE_MATH
5577    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5578    && reload_completed
5579    && (SSE_REG_P (operands[0])
5580        || (GET_CODE (operands[0]) == SUBREG
5581            && SSE_REG_P (operands[0])))"
5582   [(const_int 0)]
5583 {
5584   rtx op1 = operands[1];
5585
5586   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5587                                      <MODE>mode, 0);
5588   if (GET_CODE (op1) == SUBREG)
5589     op1 = SUBREG_REG (op1);
5590
5591   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5592     {
5593       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5594       emit_insn (gen_sse2_loadld (operands[4],
5595                                   CONST0_RTX (V4SImode), operands[1]));
5596     }
5597   /* We can ignore possible trapping value in the
5598      high part of SSE register for non-trapping math. */
5599   else if (SSE_REG_P (op1) && !flag_trapping_math)
5600     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5601   else
5602     {
5603       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5604       emit_move_insn (operands[2], operands[1]);
5605       emit_insn (gen_sse2_loadld (operands[4],
5606                                   CONST0_RTX (V4SImode), operands[2]));
5607     }
5608   emit_insn
5609     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5610   DONE;
5611 })
5612
5613 (define_split
5614   [(set (match_operand:MODEF 0 "register_operand" "")
5615         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5616    (clobber (match_operand:SI 2 "memory_operand" ""))]
5617   "TARGET_SSE2 && TARGET_SSE_MATH
5618    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5619    && reload_completed
5620    && (SSE_REG_P (operands[0])
5621        || (GET_CODE (operands[0]) == SUBREG
5622            && SSE_REG_P (operands[0])))"
5623   [(const_int 0)]
5624 {
5625   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5626                                      <MODE>mode, 0);
5627   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5628
5629   emit_insn (gen_sse2_loadld (operands[4],
5630                               CONST0_RTX (V4SImode), operands[1]));
5631   emit_insn
5632     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5633   DONE;
5634 })
5635
5636 (define_split
5637   [(set (match_operand:MODEF 0 "register_operand" "")
5638         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5639   "TARGET_SSE2 && TARGET_SSE_MATH
5640    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5641    && reload_completed
5642    && (SSE_REG_P (operands[0])
5643        || (GET_CODE (operands[0]) == SUBREG
5644            && SSE_REG_P (operands[0])))"
5645   [(const_int 0)]
5646 {
5647   rtx op1 = operands[1];
5648
5649   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5650                                      <MODE>mode, 0);
5651   if (GET_CODE (op1) == SUBREG)
5652     op1 = SUBREG_REG (op1);
5653
5654   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5655     {
5656       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5657       emit_insn (gen_sse2_loadld (operands[4],
5658                                   CONST0_RTX (V4SImode), operands[1]));
5659     }
5660   /* We can ignore possible trapping value in the
5661      high part of SSE register for non-trapping math. */
5662   else if (SSE_REG_P (op1) && !flag_trapping_math)
5663     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5664   else
5665     gcc_unreachable ();
5666   emit_insn
5667     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5668   DONE;
5669 })
5670
5671 (define_split
5672   [(set (match_operand:MODEF 0 "register_operand" "")
5673         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5674   "TARGET_SSE2 && TARGET_SSE_MATH
5675    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5676    && reload_completed
5677    && (SSE_REG_P (operands[0])
5678        || (GET_CODE (operands[0]) == SUBREG
5679            && SSE_REG_P (operands[0])))"
5680   [(const_int 0)]
5681 {
5682   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5683                                      <MODE>mode, 0);
5684   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5685
5686   emit_insn (gen_sse2_loadld (operands[4],
5687                               CONST0_RTX (V4SImode), operands[1]));
5688   emit_insn
5689     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5690   DONE;
5691 })
5692
5693 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5694   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5695         (float:MODEF
5696           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5697   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5698   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5699    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5700   "#"
5701   [(set_attr "type" "sseicvt")
5702    (set_attr "mode" "<MODEF:MODE>")
5703    (set_attr "athlon_decode" "double,direct")
5704    (set_attr "amdfam10_decode" "vector,double")
5705    (set_attr "fp_int_src" "true")])
5706
5707 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5708   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5709         (float:MODEF
5710           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5711   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5712    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5713    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5714   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5715   [(set_attr "type" "sseicvt")
5716    (set_attr "prefix" "maybe_vex")
5717    (set_attr "mode" "<MODEF:MODE>")
5718    (set (attr "prefix_rex")
5719      (if_then_else
5720        (and (eq_attr "prefix" "maybe_vex")
5721             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5722        (const_string "1")
5723        (const_string "*")))
5724    (set_attr "athlon_decode" "double,direct")
5725    (set_attr "amdfam10_decode" "vector,double")
5726    (set_attr "fp_int_src" "true")])
5727
5728 (define_split
5729   [(set (match_operand:MODEF 0 "register_operand" "")
5730         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5731    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5732   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5733    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5734    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5735    && reload_completed
5736    && (SSE_REG_P (operands[0])
5737        || (GET_CODE (operands[0]) == SUBREG
5738            && SSE_REG_P (operands[0])))"
5739   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5740   "")
5741
5742 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5743   [(set (match_operand:MODEF 0 "register_operand" "=x")
5744         (float:MODEF
5745           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5746   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5747    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5748    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5749   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5750   [(set_attr "type" "sseicvt")
5751    (set_attr "prefix" "maybe_vex")
5752    (set_attr "mode" "<MODEF:MODE>")
5753    (set (attr "prefix_rex")
5754      (if_then_else
5755        (and (eq_attr "prefix" "maybe_vex")
5756             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5757        (const_string "1")
5758        (const_string "*")))
5759    (set_attr "athlon_decode" "direct")
5760    (set_attr "amdfam10_decode" "double")
5761    (set_attr "fp_int_src" "true")])
5762
5763 (define_split
5764   [(set (match_operand:MODEF 0 "register_operand" "")
5765         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5766    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5767   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5768    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5769    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5770    && reload_completed
5771    && (SSE_REG_P (operands[0])
5772        || (GET_CODE (operands[0]) == SUBREG
5773            && SSE_REG_P (operands[0])))"
5774   [(set (match_dup 2) (match_dup 1))
5775    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5776   "")
5777
5778 (define_split
5779   [(set (match_operand:MODEF 0 "register_operand" "")
5780         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5781    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5782   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5783    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5784    && reload_completed
5785    && (SSE_REG_P (operands[0])
5786        || (GET_CODE (operands[0]) == SUBREG
5787            && SSE_REG_P (operands[0])))"
5788   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5789   "")
5790
5791 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5792   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5793         (float:X87MODEF
5794           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5795   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5796   "TARGET_80387
5797    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5798   "@
5799    fild%Z1\t%1
5800    #"
5801   [(set_attr "type" "fmov,multi")
5802    (set_attr "mode" "<X87MODEF:MODE>")
5803    (set_attr "unit" "*,i387")
5804    (set_attr "fp_int_src" "true")])
5805
5806 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5807   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5808         (float:X87MODEF
5809           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5810   "TARGET_80387
5811    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5812   "fild%Z1\t%1"
5813   [(set_attr "type" "fmov")
5814    (set_attr "mode" "<X87MODEF:MODE>")
5815    (set_attr "fp_int_src" "true")])
5816
5817 (define_split
5818   [(set (match_operand:X87MODEF 0 "register_operand" "")
5819         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5820    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5821   "TARGET_80387
5822    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5823    && reload_completed
5824    && FP_REG_P (operands[0])"
5825   [(set (match_dup 2) (match_dup 1))
5826    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5827   "")
5828
5829 (define_split
5830   [(set (match_operand:X87MODEF 0 "register_operand" "")
5831         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5832    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5833   "TARGET_80387
5834    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5835    && reload_completed
5836    && FP_REG_P (operands[0])"
5837   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5838   "")
5839
5840 ;; Avoid store forwarding (partial memory) stall penalty
5841 ;; by passing DImode value through XMM registers.  */
5842
5843 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5844   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5845         (float:X87MODEF
5846           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5847    (clobber (match_scratch:V4SI 3 "=X,x"))
5848    (clobber (match_scratch:V4SI 4 "=X,x"))
5849    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5850   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5851    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5852    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5853   "#"
5854   [(set_attr "type" "multi")
5855    (set_attr "mode" "<X87MODEF:MODE>")
5856    (set_attr "unit" "i387")
5857    (set_attr "fp_int_src" "true")])
5858
5859 (define_split
5860   [(set (match_operand:X87MODEF 0 "register_operand" "")
5861         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5862    (clobber (match_scratch:V4SI 3 ""))
5863    (clobber (match_scratch:V4SI 4 ""))
5864    (clobber (match_operand:DI 2 "memory_operand" ""))]
5865   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5866    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5867    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5868    && reload_completed
5869    && FP_REG_P (operands[0])"
5870   [(set (match_dup 2) (match_dup 3))
5871    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5872 {
5873   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5874      Assemble the 64-bit DImode value in an xmm register.  */
5875   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5876                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5877   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5878                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5879   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5880                                          operands[4]));
5881
5882   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5883 })
5884
5885 (define_split
5886   [(set (match_operand:X87MODEF 0 "register_operand" "")
5887         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5888    (clobber (match_scratch:V4SI 3 ""))
5889    (clobber (match_scratch:V4SI 4 ""))
5890    (clobber (match_operand:DI 2 "memory_operand" ""))]
5891   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5892    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5893    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5894    && reload_completed
5895    && FP_REG_P (operands[0])"
5896   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5897   "")
5898
5899 ;; Avoid store forwarding (partial memory) stall penalty by extending
5900 ;; SImode value to DImode through XMM register instead of pushing two
5901 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5902 ;; targets benefit from this optimization. Also note that fild
5903 ;; loads from memory only.
5904
5905 (define_insn "*floatunssi<mode>2_1"
5906   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5907         (unsigned_float:X87MODEF
5908           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5909    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5910    (clobber (match_scratch:SI 3 "=X,x"))]
5911   "!TARGET_64BIT
5912    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5913    && TARGET_SSE"
5914   "#"
5915   [(set_attr "type" "multi")
5916    (set_attr "mode" "<MODE>")])
5917
5918 (define_split
5919   [(set (match_operand:X87MODEF 0 "register_operand" "")
5920         (unsigned_float:X87MODEF
5921           (match_operand:SI 1 "register_operand" "")))
5922    (clobber (match_operand:DI 2 "memory_operand" ""))
5923    (clobber (match_scratch:SI 3 ""))]
5924   "!TARGET_64BIT
5925    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5926    && TARGET_SSE
5927    && reload_completed"
5928   [(set (match_dup 2) (match_dup 1))
5929    (set (match_dup 0)
5930         (float:X87MODEF (match_dup 2)))]
5931   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5932
5933 (define_split
5934   [(set (match_operand:X87MODEF 0 "register_operand" "")
5935         (unsigned_float:X87MODEF
5936           (match_operand:SI 1 "memory_operand" "")))
5937    (clobber (match_operand:DI 2 "memory_operand" ""))
5938    (clobber (match_scratch:SI 3 ""))]
5939   "!TARGET_64BIT
5940    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5941    && TARGET_SSE
5942    && reload_completed"
5943   [(set (match_dup 2) (match_dup 3))
5944    (set (match_dup 0)
5945         (float:X87MODEF (match_dup 2)))]
5946 {
5947   emit_move_insn (operands[3], operands[1]);
5948   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5949 })
5950
5951 (define_expand "floatunssi<mode>2"
5952   [(parallel
5953      [(set (match_operand:X87MODEF 0 "register_operand" "")
5954            (unsigned_float:X87MODEF
5955              (match_operand:SI 1 "nonimmediate_operand" "")))
5956       (clobber (match_dup 2))
5957       (clobber (match_scratch:SI 3 ""))])]
5958   "!TARGET_64BIT
5959    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5960         && TARGET_SSE)
5961        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5962 {
5963   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5964     {
5965       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5966       DONE;
5967     }
5968   else
5969     {
5970       enum ix86_stack_slot slot = (virtuals_instantiated
5971                                    ? SLOT_TEMP
5972                                    : SLOT_VIRTUAL);
5973       operands[2] = assign_386_stack_local (DImode, slot);
5974     }
5975 })
5976
5977 (define_expand "floatunsdisf2"
5978   [(use (match_operand:SF 0 "register_operand" ""))
5979    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5980   "TARGET_64BIT && TARGET_SSE_MATH"
5981   "x86_emit_floatuns (operands); DONE;")
5982
5983 (define_expand "floatunsdidf2"
5984   [(use (match_operand:DF 0 "register_operand" ""))
5985    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5986   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5987    && TARGET_SSE2 && TARGET_SSE_MATH"
5988 {
5989   if (TARGET_64BIT)
5990     x86_emit_floatuns (operands);
5991   else
5992     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5993   DONE;
5994 })
5995 \f
5996 ;; Add instructions
5997
5998 (define_expand "add<mode>3"
5999   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6000         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6001                     (match_operand:SDWIM 2 "<general_operand>" "")))]
6002   ""
6003   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6004
6005 (define_insn_and_split "*add<dwi>3_doubleword"
6006   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6007         (plus:<DWI>
6008           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6009           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6010    (clobber (reg:CC FLAGS_REG))]
6011   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6012   "#"
6013   "reload_completed"
6014   [(parallel [(set (reg:CC FLAGS_REG)
6015                    (unspec:CC [(match_dup 1) (match_dup 2)]
6016                               UNSPEC_ADD_CARRY))
6017               (set (match_dup 0)
6018                    (plus:DWIH (match_dup 1) (match_dup 2)))])
6019    (parallel [(set (match_dup 3)
6020                    (plus:DWIH
6021                      (match_dup 4)
6022                      (plus:DWIH
6023                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6024                        (match_dup 5))))
6025               (clobber (reg:CC FLAGS_REG))])]
6026   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6027
6028 (define_insn "*add<mode>3_cc"
6029   [(set (reg:CC FLAGS_REG)
6030         (unspec:CC
6031           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6032            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
6033           UNSPEC_ADD_CARRY))
6034    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6035         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6036   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6037   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6038   [(set_attr "type" "alu")
6039    (set_attr "mode" "<MODE>")])
6040
6041 (define_insn "addqi3_cc"
6042   [(set (reg:CC FLAGS_REG)
6043         (unspec:CC
6044           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6045            (match_operand:QI 2 "general_operand" "qn,qm")]
6046           UNSPEC_ADD_CARRY))
6047    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6048         (plus:QI (match_dup 1) (match_dup 2)))]
6049   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6050   "add{b}\t{%2, %0|%0, %2}"
6051   [(set_attr "type" "alu")
6052    (set_attr "mode" "QI")])
6053
6054 (define_insn "*lea_1"
6055   [(set (match_operand:DWIH 0 "register_operand" "=r")
6056         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6057   ""
6058   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6059   [(set_attr "type" "lea")
6060    (set_attr "mode" "<MODE>")])
6061
6062 (define_insn "*lea_2"
6063   [(set (match_operand:SI 0 "register_operand" "=r")
6064         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6065   "TARGET_64BIT"
6066   "lea{l}\t{%a1, %0|%0, %a1}"
6067   [(set_attr "type" "lea")
6068    (set_attr "mode" "SI")])
6069
6070 (define_insn "*lea_2_zext"
6071   [(set (match_operand:DI 0 "register_operand" "=r")
6072         (zero_extend:DI
6073           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6074   "TARGET_64BIT"
6075   "lea{l}\t{%a1, %k0|%k0, %a1}"
6076   [(set_attr "type" "lea")
6077    (set_attr "mode" "SI")])
6078
6079 (define_insn "*add<mode>_1"
6080   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6081         (plus:SWI48
6082           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6083           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6084    (clobber (reg:CC FLAGS_REG))]
6085   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6086 {
6087   switch (get_attr_type (insn))
6088     {
6089     case TYPE_LEA:
6090       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6091       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6092
6093     case TYPE_INCDEC:
6094       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6095       if (operands[2] == const1_rtx)
6096         return "inc{<imodesuffix>}\t%0";
6097       else
6098         {
6099           gcc_assert (operands[2] == constm1_rtx);
6100           return "dec{<imodesuffix>}\t%0";
6101         }
6102
6103     default:
6104       /* Use add as much as possible to replace lea for AGU optimization. */
6105       if (which_alternative == 2 && TARGET_OPT_AGU)
6106         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6107         
6108       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6109       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6110         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6111
6112       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6113     }
6114 }
6115   [(set (attr "type")
6116      (cond [(and (eq_attr "alternative" "2") 
6117                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6118               (const_string "lea")
6119             (eq_attr "alternative" "3")
6120               (const_string "lea")
6121             (match_operand:SWI48 2 "incdec_operand" "")
6122               (const_string "incdec")
6123            ]
6124            (const_string "alu")))
6125    (set (attr "length_immediate")
6126       (if_then_else
6127         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6128         (const_string "1")
6129         (const_string "*")))
6130    (set_attr "mode" "<MODE>")])
6131
6132 ;; It may seem that nonimmediate operand is proper one for operand 1.
6133 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6134 ;; we take care in ix86_binary_operator_ok to not allow two memory
6135 ;; operands so proper swapping will be done in reload.  This allow
6136 ;; patterns constructed from addsi_1 to match.
6137
6138 (define_insn "*addsi_1_zext"
6139   [(set (match_operand:DI 0 "register_operand" "=r,r")
6140         (zero_extend:DI
6141           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6142                    (match_operand:SI 2 "general_operand" "g,li"))))
6143    (clobber (reg:CC FLAGS_REG))]
6144   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6145 {
6146   switch (get_attr_type (insn))
6147     {
6148     case TYPE_LEA:
6149       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6150       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6151
6152     case TYPE_INCDEC:
6153       if (operands[2] == const1_rtx)
6154         return "inc{l}\t%k0";
6155       else
6156         {
6157           gcc_assert (operands[2] == constm1_rtx);
6158           return "dec{l}\t%k0";
6159         }
6160
6161     default:
6162       if (x86_maybe_negate_const_int (&operands[2], SImode))
6163         return "sub{l}\t{%2, %k0|%k0, %2}";
6164
6165       return "add{l}\t{%2, %k0|%k0, %2}";
6166     }
6167 }
6168   [(set (attr "type")
6169      (cond [(eq_attr "alternative" "1")
6170               (const_string "lea")
6171             (match_operand:SI 2 "incdec_operand" "")
6172               (const_string "incdec")
6173            ]
6174            (const_string "alu")))
6175    (set (attr "length_immediate")
6176       (if_then_else
6177         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6178         (const_string "1")
6179         (const_string "*")))
6180    (set_attr "mode" "SI")])
6181
6182 (define_insn "*addhi_1"
6183   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6184         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6185                  (match_operand:HI 2 "general_operand" "rn,rm")))
6186    (clobber (reg:CC FLAGS_REG))]
6187   "TARGET_PARTIAL_REG_STALL
6188    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6189 {
6190   switch (get_attr_type (insn))
6191     {
6192     case TYPE_INCDEC:
6193       if (operands[2] == const1_rtx)
6194         return "inc{w}\t%0";
6195       else
6196         {
6197           gcc_assert (operands[2] == constm1_rtx);
6198           return "dec{w}\t%0";
6199         }
6200
6201     default:
6202       if (x86_maybe_negate_const_int (&operands[2], HImode))
6203         return "sub{w}\t{%2, %0|%0, %2}";
6204
6205       return "add{w}\t{%2, %0|%0, %2}";
6206     }
6207 }
6208   [(set (attr "type")
6209      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6210         (const_string "incdec")
6211         (const_string "alu")))
6212    (set (attr "length_immediate")
6213       (if_then_else
6214         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6215         (const_string "1")
6216         (const_string "*")))
6217    (set_attr "mode" "HI")])
6218
6219 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6220 ;; type optimizations enabled by define-splits.  This is not important
6221 ;; for PII, and in fact harmful because of partial register stalls.
6222
6223 (define_insn "*addhi_1_lea"
6224   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6225         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6226                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6227    (clobber (reg:CC FLAGS_REG))]
6228   "!TARGET_PARTIAL_REG_STALL
6229    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6230 {
6231   switch (get_attr_type (insn))
6232     {
6233     case TYPE_LEA:
6234       return "#";
6235     case TYPE_INCDEC:
6236       if (operands[2] == const1_rtx)
6237         return "inc{w}\t%0";
6238       else
6239         {
6240           gcc_assert (operands[2] == constm1_rtx);
6241           return "dec{w}\t%0";
6242         }
6243
6244     default:
6245       if (x86_maybe_negate_const_int (&operands[2], HImode))
6246         return "sub{w}\t{%2, %0|%0, %2}";
6247
6248       return "add{w}\t{%2, %0|%0, %2}";
6249     }
6250 }
6251   [(set (attr "type")
6252      (if_then_else (eq_attr "alternative" "2")
6253         (const_string "lea")
6254         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6255            (const_string "incdec")
6256            (const_string "alu"))))
6257    (set (attr "length_immediate")
6258       (if_then_else
6259         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6260         (const_string "1")
6261         (const_string "*")))
6262    (set_attr "mode" "HI,HI,SI")])
6263
6264 (define_insn "*addqi_1"
6265   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6266         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6267                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6268    (clobber (reg:CC FLAGS_REG))]
6269   "TARGET_PARTIAL_REG_STALL
6270    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6271 {
6272   int widen = (which_alternative == 2);
6273   switch (get_attr_type (insn))
6274     {
6275     case TYPE_INCDEC:
6276       if (operands[2] == const1_rtx)
6277         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6278       else
6279         {
6280           gcc_assert (operands[2] == constm1_rtx);
6281           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6282         }
6283
6284     default:
6285       if (x86_maybe_negate_const_int (&operands[2], QImode))
6286         {
6287           if (widen)
6288             return "sub{l}\t{%2, %k0|%k0, %2}";
6289           else
6290             return "sub{b}\t{%2, %0|%0, %2}";
6291         }
6292       if (widen)
6293         return "add{l}\t{%k2, %k0|%k0, %k2}";
6294       else
6295         return "add{b}\t{%2, %0|%0, %2}";
6296     }
6297 }
6298   [(set (attr "type")
6299      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6300         (const_string "incdec")
6301         (const_string "alu")))
6302    (set (attr "length_immediate")
6303       (if_then_else
6304         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6305         (const_string "1")
6306         (const_string "*")))
6307    (set_attr "mode" "QI,QI,SI")])
6308
6309 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6310 (define_insn "*addqi_1_lea"
6311   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6312         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6313                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6314    (clobber (reg:CC FLAGS_REG))]
6315   "!TARGET_PARTIAL_REG_STALL
6316    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6317 {
6318   int widen = (which_alternative == 2);
6319   switch (get_attr_type (insn))
6320     {
6321     case TYPE_LEA:
6322       return "#";
6323     case TYPE_INCDEC:
6324       if (operands[2] == const1_rtx)
6325         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6326       else
6327         {
6328           gcc_assert (operands[2] == constm1_rtx);
6329           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6330         }
6331
6332     default:
6333       if (x86_maybe_negate_const_int (&operands[2], QImode))
6334         {
6335           if (widen)
6336             return "sub{l}\t{%2, %k0|%k0, %2}";
6337           else
6338             return "sub{b}\t{%2, %0|%0, %2}";
6339         }
6340       if (widen)
6341         return "add{l}\t{%k2, %k0|%k0, %k2}";
6342       else
6343         return "add{b}\t{%2, %0|%0, %2}";
6344     }
6345 }
6346   [(set (attr "type")
6347      (if_then_else (eq_attr "alternative" "3")
6348         (const_string "lea")
6349         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6350            (const_string "incdec")
6351            (const_string "alu"))))
6352    (set (attr "length_immediate")
6353       (if_then_else
6354         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6355         (const_string "1")
6356         (const_string "*")))
6357    (set_attr "mode" "QI,QI,SI,SI")])
6358
6359 (define_insn "*addqi_1_slp"
6360   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6361         (plus:QI (match_dup 0)
6362                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6363    (clobber (reg:CC FLAGS_REG))]
6364   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6365    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6366 {
6367   switch (get_attr_type (insn))
6368     {
6369     case TYPE_INCDEC:
6370       if (operands[1] == const1_rtx)
6371         return "inc{b}\t%0";
6372       else
6373         {
6374           gcc_assert (operands[1] == constm1_rtx);
6375           return "dec{b}\t%0";
6376         }
6377
6378     default:
6379       if (x86_maybe_negate_const_int (&operands[1], QImode))
6380         return "sub{b}\t{%1, %0|%0, %1}";
6381
6382       return "add{b}\t{%1, %0|%0, %1}";
6383     }
6384 }
6385   [(set (attr "type")
6386      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6387         (const_string "incdec")
6388         (const_string "alu1")))
6389    (set (attr "memory")
6390      (if_then_else (match_operand 1 "memory_operand" "")
6391         (const_string "load")
6392         (const_string "none")))
6393    (set_attr "mode" "QI")])
6394
6395 (define_insn "*add<mode>_2"
6396   [(set (reg FLAGS_REG)
6397         (compare
6398           (plus:SWI
6399             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6400             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6401           (const_int 0)))
6402    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6403         (plus:SWI (match_dup 1) (match_dup 2)))]
6404   "ix86_match_ccmode (insn, CCGOCmode)
6405    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6406 {
6407   switch (get_attr_type (insn))
6408     {
6409     case TYPE_INCDEC:
6410       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6411       if (operands[2] == const1_rtx)
6412         return "inc{<imodesuffix>}\t%0";
6413       else
6414         {
6415           gcc_assert (operands[2] == constm1_rtx);
6416           return "dec{<imodesuffix>}\t%0";
6417         }
6418
6419     default:
6420       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6421       /* ???? In DImode, we ought to handle there the 32bit case too
6422          - do we need new constraint?  */
6423       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6424         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6425
6426       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6427     }
6428 }
6429   [(set (attr "type")
6430      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6431         (const_string "incdec")
6432         (const_string "alu")))
6433    (set (attr "length_immediate")
6434       (if_then_else
6435         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6436         (const_string "1")
6437         (const_string "*")))
6438    (set_attr "mode" "<MODE>")])
6439
6440 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6441 (define_insn "*addsi_2_zext"
6442   [(set (reg FLAGS_REG)
6443         (compare
6444           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6445                    (match_operand:SI 2 "general_operand" "g"))
6446           (const_int 0)))
6447    (set (match_operand:DI 0 "register_operand" "=r")
6448         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6449   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6450    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6451 {
6452   switch (get_attr_type (insn))
6453     {
6454     case TYPE_INCDEC:
6455       if (operands[2] == const1_rtx)
6456         return "inc{l}\t%k0";
6457       else
6458         {
6459           gcc_assert (operands[2] == constm1_rtx);
6460           return "dec{l}\t%k0";
6461         }
6462
6463     default:
6464       if (x86_maybe_negate_const_int (&operands[2], SImode))
6465         return "sub{l}\t{%2, %k0|%k0, %2}";
6466
6467       return "add{l}\t{%2, %k0|%k0, %2}";
6468     }
6469 }
6470   [(set (attr "type")
6471      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6472         (const_string "incdec")
6473         (const_string "alu")))
6474    (set (attr "length_immediate")
6475       (if_then_else
6476         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6477         (const_string "1")
6478         (const_string "*")))
6479    (set_attr "mode" "SI")])
6480
6481 (define_insn "*add<mode>_3"
6482   [(set (reg FLAGS_REG)
6483         (compare
6484           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6485           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6486    (clobber (match_scratch:SWI 0 "=<r>"))]
6487   "ix86_match_ccmode (insn, CCZmode)
6488    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6489 {
6490   switch (get_attr_type (insn))
6491     {
6492     case TYPE_INCDEC:
6493       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6494       if (operands[2] == const1_rtx)
6495         return "inc{<imodesuffix>}\t%0";
6496       else
6497         {
6498           gcc_assert (operands[2] == constm1_rtx);
6499           return "dec{<imodesuffix>}\t%0";
6500         }
6501
6502     default:
6503       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6504       /* ???? In DImode, we ought to handle there the 32bit case too
6505          - do we need new constraint?  */
6506       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6507         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6508
6509       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6510     }
6511 }
6512   [(set (attr "type")
6513      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6514         (const_string "incdec")
6515         (const_string "alu")))
6516    (set (attr "length_immediate")
6517       (if_then_else
6518         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6519         (const_string "1")
6520         (const_string "*")))
6521    (set_attr "mode" "<MODE>")])
6522
6523 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6524 (define_insn "*addsi_3_zext"
6525   [(set (reg FLAGS_REG)
6526         (compare
6527           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6528           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6529    (set (match_operand:DI 0 "register_operand" "=r")
6530         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6531   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6532    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6533 {
6534   switch (get_attr_type (insn))
6535     {
6536     case TYPE_INCDEC:
6537       if (operands[2] == const1_rtx)
6538         return "inc{l}\t%k0";
6539       else
6540         {
6541           gcc_assert (operands[2] == constm1_rtx);
6542           return "dec{l}\t%k0";
6543         }
6544
6545     default:
6546       if (x86_maybe_negate_const_int (&operands[2], SImode))
6547         return "sub{l}\t{%2, %k0|%k0, %2}";
6548
6549       return "add{l}\t{%2, %k0|%k0, %2}";
6550     }
6551 }
6552   [(set (attr "type")
6553      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6554         (const_string "incdec")
6555         (const_string "alu")))
6556    (set (attr "length_immediate")
6557       (if_then_else
6558         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6559         (const_string "1")
6560         (const_string "*")))
6561    (set_attr "mode" "SI")])
6562
6563 ; For comparisons against 1, -1 and 128, we may generate better code
6564 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6565 ; is matched then.  We can't accept general immediate, because for
6566 ; case of overflows,  the result is messed up.
6567 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6568 ; only for comparisons not depending on it.
6569
6570 (define_insn "*adddi_4"
6571   [(set (reg FLAGS_REG)
6572         (compare
6573           (match_operand:DI 1 "nonimmediate_operand" "0")
6574           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6575    (clobber (match_scratch:DI 0 "=rm"))]
6576   "TARGET_64BIT
6577    && ix86_match_ccmode (insn, CCGCmode)"
6578 {
6579   switch (get_attr_type (insn))
6580     {
6581     case TYPE_INCDEC:
6582       if (operands[2] == constm1_rtx)
6583         return "inc{q}\t%0";
6584       else
6585         {
6586           gcc_assert (operands[2] == const1_rtx);
6587           return "dec{q}\t%0";
6588         }
6589
6590     default:
6591       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6592       if (x86_maybe_negate_const_int (&operands[2], DImode))
6593         return "add{q}\t{%2, %0|%0, %2}";
6594
6595       return "sub{q}\t{%2, %0|%0, %2}";
6596     }
6597 }
6598   [(set (attr "type")
6599      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6600         (const_string "incdec")
6601         (const_string "alu")))
6602    (set (attr "length_immediate")
6603       (if_then_else
6604         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6605         (const_string "1")
6606         (const_string "*")))
6607    (set_attr "mode" "DI")])
6608
6609 ; For comparisons against 1, -1 and 128, we may generate better code
6610 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6611 ; is matched then.  We can't accept general immediate, because for
6612 ; case of overflows,  the result is messed up.
6613 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6614 ; only for comparisons not depending on it.
6615
6616 (define_insn "*add<mode>_4"
6617   [(set (reg FLAGS_REG)
6618         (compare
6619           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6620           (match_operand:SWI124 2 "const_int_operand" "n")))
6621    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6622   "ix86_match_ccmode (insn, CCGCmode)"
6623 {
6624   switch (get_attr_type (insn))
6625     {
6626     case TYPE_INCDEC:
6627       if (operands[2] == constm1_rtx)
6628         return "inc{<imodesuffix>}\t%0";
6629       else
6630         {
6631           gcc_assert (operands[2] == const1_rtx);
6632           return "dec{<imodesuffix>}\t%0";
6633         }
6634
6635     default:
6636       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6637       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6638         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6639
6640       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6641     }
6642 }
6643   [(set (attr "type")
6644      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6645         (const_string "incdec")
6646         (const_string "alu")))
6647    (set (attr "length_immediate")
6648       (if_then_else
6649         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6650         (const_string "1")
6651         (const_string "*")))
6652    (set_attr "mode" "<MODE>")])
6653
6654 (define_insn "*add<mode>_5"
6655   [(set (reg FLAGS_REG)
6656         (compare
6657           (plus:SWI
6658             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6659             (match_operand:SWI 2 "<general_operand>" "<g>"))
6660           (const_int 0)))
6661    (clobber (match_scratch:SWI 0 "=<r>"))]
6662   "ix86_match_ccmode (insn, CCGOCmode)
6663    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6664 {
6665   switch (get_attr_type (insn))
6666     {
6667     case TYPE_INCDEC:
6668       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6669       if (operands[2] == const1_rtx)
6670         return "inc{<imodesuffix>}\t%0";
6671       else
6672         {
6673           gcc_assert (operands[2] == constm1_rtx);
6674           return "dec{<imodesuffix>}\t%0";
6675         }
6676
6677     default:
6678       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6679       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6680         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6681
6682       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6683     }
6684 }
6685   [(set (attr "type")
6686      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6687         (const_string "incdec")
6688         (const_string "alu")))
6689    (set (attr "length_immediate")
6690       (if_then_else
6691         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6692         (const_string "1")
6693         (const_string "*")))
6694    (set_attr "mode" "<MODE>")])
6695
6696 (define_insn "*addqi_ext_1_rex64"
6697   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6698                          (const_int 8)
6699                          (const_int 8))
6700         (plus:SI
6701           (zero_extract:SI
6702             (match_operand 1 "ext_register_operand" "0")
6703             (const_int 8)
6704             (const_int 8))
6705           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6706    (clobber (reg:CC FLAGS_REG))]
6707   "TARGET_64BIT"
6708 {
6709   switch (get_attr_type (insn))
6710     {
6711     case TYPE_INCDEC:
6712       if (operands[2] == const1_rtx)
6713         return "inc{b}\t%h0";
6714       else
6715         {
6716           gcc_assert (operands[2] == constm1_rtx);
6717           return "dec{b}\t%h0";
6718         }
6719
6720     default:
6721       return "add{b}\t{%2, %h0|%h0, %2}";
6722     }
6723 }
6724   [(set (attr "type")
6725      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6726         (const_string "incdec")
6727         (const_string "alu")))
6728    (set_attr "modrm" "1")
6729    (set_attr "mode" "QI")])
6730
6731 (define_insn "addqi_ext_1"
6732   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6733                          (const_int 8)
6734                          (const_int 8))
6735         (plus:SI
6736           (zero_extract:SI
6737             (match_operand 1 "ext_register_operand" "0")
6738             (const_int 8)
6739             (const_int 8))
6740           (match_operand:QI 2 "general_operand" "Qmn")))
6741    (clobber (reg:CC FLAGS_REG))]
6742   "!TARGET_64BIT"
6743 {
6744   switch (get_attr_type (insn))
6745     {
6746     case TYPE_INCDEC:
6747       if (operands[2] == const1_rtx)
6748         return "inc{b}\t%h0";
6749       else
6750         {
6751           gcc_assert (operands[2] == constm1_rtx);
6752           return "dec{b}\t%h0";
6753         }
6754
6755     default:
6756       return "add{b}\t{%2, %h0|%h0, %2}";
6757     }
6758 }
6759   [(set (attr "type")
6760      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6761         (const_string "incdec")
6762         (const_string "alu")))
6763    (set_attr "modrm" "1")
6764    (set_attr "mode" "QI")])
6765
6766 (define_insn "*addqi_ext_2"
6767   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6768                          (const_int 8)
6769                          (const_int 8))
6770         (plus:SI
6771           (zero_extract:SI
6772             (match_operand 1 "ext_register_operand" "%0")
6773             (const_int 8)
6774             (const_int 8))
6775           (zero_extract:SI
6776             (match_operand 2 "ext_register_operand" "Q")
6777             (const_int 8)
6778             (const_int 8))))
6779    (clobber (reg:CC FLAGS_REG))]
6780   ""
6781   "add{b}\t{%h2, %h0|%h0, %h2}"
6782   [(set_attr "type" "alu")
6783    (set_attr "mode" "QI")])
6784
6785 ;; The lea patterns for non-Pmodes needs to be matched by
6786 ;; several insns converted to real lea by splitters.
6787
6788 (define_insn_and_split "*lea_general_1"
6789   [(set (match_operand 0 "register_operand" "=r")
6790         (plus (plus (match_operand 1 "index_register_operand" "l")
6791                     (match_operand 2 "register_operand" "r"))
6792               (match_operand 3 "immediate_operand" "i")))]
6793   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6794     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6795    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6796    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6797    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6798    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6799        || GET_MODE (operands[3]) == VOIDmode)"
6800   "#"
6801   "&& reload_completed"
6802   [(const_int 0)]
6803 {
6804   rtx pat;
6805   operands[0] = gen_lowpart (SImode, operands[0]);
6806   operands[1] = gen_lowpart (Pmode, operands[1]);
6807   operands[2] = gen_lowpart (Pmode, operands[2]);
6808   operands[3] = gen_lowpart (Pmode, operands[3]);
6809   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6810                       operands[3]);
6811   if (Pmode != SImode)
6812     pat = gen_rtx_SUBREG (SImode, pat, 0);
6813   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6814   DONE;
6815 }
6816   [(set_attr "type" "lea")
6817    (set_attr "mode" "SI")])
6818
6819 (define_insn_and_split "*lea_general_1_zext"
6820   [(set (match_operand:DI 0 "register_operand" "=r")
6821         (zero_extend:DI
6822           (plus:SI (plus:SI
6823                      (match_operand:SI 1 "index_register_operand" "l")
6824                      (match_operand:SI 2 "register_operand" "r"))
6825                    (match_operand:SI 3 "immediate_operand" "i"))))]
6826   "TARGET_64BIT"
6827   "#"
6828   "&& reload_completed"
6829   [(set (match_dup 0)
6830         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6831                                                      (match_dup 2))
6832                                             (match_dup 3)) 0)))]
6833 {
6834   operands[1] = gen_lowpart (Pmode, operands[1]);
6835   operands[2] = gen_lowpart (Pmode, operands[2]);
6836   operands[3] = gen_lowpart (Pmode, operands[3]);
6837 }
6838   [(set_attr "type" "lea")
6839    (set_attr "mode" "SI")])
6840
6841 (define_insn_and_split "*lea_general_2"
6842   [(set (match_operand 0 "register_operand" "=r")
6843         (plus (mult (match_operand 1 "index_register_operand" "l")
6844                     (match_operand 2 "const248_operand" "i"))
6845               (match_operand 3 "nonmemory_operand" "ri")))]
6846   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6847     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6848    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6849    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6850    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6851        || GET_MODE (operands[3]) == VOIDmode)"
6852   "#"
6853   "&& reload_completed"
6854   [(const_int 0)]
6855 {
6856   rtx pat;
6857   operands[0] = gen_lowpart (SImode, operands[0]);
6858   operands[1] = gen_lowpart (Pmode, operands[1]);
6859   operands[3] = gen_lowpart (Pmode, operands[3]);
6860   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6861                       operands[3]);
6862   if (Pmode != SImode)
6863     pat = gen_rtx_SUBREG (SImode, pat, 0);
6864   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6865   DONE;
6866 }
6867   [(set_attr "type" "lea")
6868    (set_attr "mode" "SI")])
6869
6870 (define_insn_and_split "*lea_general_2_zext"
6871   [(set (match_operand:DI 0 "register_operand" "=r")
6872         (zero_extend:DI
6873           (plus:SI (mult:SI
6874                      (match_operand:SI 1 "index_register_operand" "l")
6875                      (match_operand:SI 2 "const248_operand" "n"))
6876                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6877   "TARGET_64BIT"
6878   "#"
6879   "&& reload_completed"
6880   [(set (match_dup 0)
6881         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6882                                                      (match_dup 2))
6883                                             (match_dup 3)) 0)))]
6884 {
6885   operands[1] = gen_lowpart (Pmode, operands[1]);
6886   operands[3] = gen_lowpart (Pmode, operands[3]);
6887 }
6888   [(set_attr "type" "lea")
6889    (set_attr "mode" "SI")])
6890
6891 (define_insn_and_split "*lea_general_3"
6892   [(set (match_operand 0 "register_operand" "=r")
6893         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6894                           (match_operand 2 "const248_operand" "i"))
6895                     (match_operand 3 "register_operand" "r"))
6896               (match_operand 4 "immediate_operand" "i")))]
6897   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6898     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6899    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6900    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6901    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6902   "#"
6903   "&& reload_completed"
6904   [(const_int 0)]
6905 {
6906   rtx pat;
6907   operands[0] = gen_lowpart (SImode, operands[0]);
6908   operands[1] = gen_lowpart (Pmode, operands[1]);
6909   operands[3] = gen_lowpart (Pmode, operands[3]);
6910   operands[4] = gen_lowpart (Pmode, operands[4]);
6911   pat = gen_rtx_PLUS (Pmode,
6912                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6913                                                          operands[2]),
6914                                     operands[3]),
6915                       operands[4]);
6916   if (Pmode != SImode)
6917     pat = gen_rtx_SUBREG (SImode, pat, 0);
6918   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6919   DONE;
6920 }
6921   [(set_attr "type" "lea")
6922    (set_attr "mode" "SI")])
6923
6924 (define_insn_and_split "*lea_general_3_zext"
6925   [(set (match_operand:DI 0 "register_operand" "=r")
6926         (zero_extend:DI
6927           (plus:SI (plus:SI
6928                      (mult:SI
6929                        (match_operand:SI 1 "index_register_operand" "l")
6930                        (match_operand:SI 2 "const248_operand" "n"))
6931                      (match_operand:SI 3 "register_operand" "r"))
6932                    (match_operand:SI 4 "immediate_operand" "i"))))]
6933   "TARGET_64BIT"
6934   "#"
6935   "&& reload_completed"
6936   [(set (match_dup 0)
6937         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6938                                                               (match_dup 2))
6939                                                      (match_dup 3))
6940                                             (match_dup 4)) 0)))]
6941 {
6942   operands[1] = gen_lowpart (Pmode, operands[1]);
6943   operands[3] = gen_lowpart (Pmode, operands[3]);
6944   operands[4] = gen_lowpart (Pmode, operands[4]);
6945 }
6946   [(set_attr "type" "lea")
6947    (set_attr "mode" "SI")])
6948
6949 ;; Convert lea to the lea pattern to avoid flags dependency.
6950 (define_split
6951   [(set (match_operand:DI 0 "register_operand" "")
6952         (plus:DI (match_operand:DI 1 "register_operand" "")
6953                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6954    (clobber (reg:CC FLAGS_REG))]
6955   "TARGET_64BIT && reload_completed 
6956    && ix86_lea_for_add_ok (PLUS, insn, operands)"
6957   [(set (match_dup 0)
6958         (plus:DI (match_dup 1)
6959                  (match_dup 2)))]
6960   "")
6961
6962 ;; Convert lea to the lea pattern to avoid flags dependency.
6963 (define_split
6964   [(set (match_operand 0 "register_operand" "")
6965         (plus (match_operand 1 "register_operand" "")
6966               (match_operand 2 "nonmemory_operand" "")))
6967    (clobber (reg:CC FLAGS_REG))]
6968   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
6969   [(const_int 0)]
6970 {
6971   rtx pat;
6972   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6973      may confuse gen_lowpart.  */
6974   if (GET_MODE (operands[0]) != Pmode)
6975     {
6976       operands[1] = gen_lowpart (Pmode, operands[1]);
6977       operands[2] = gen_lowpart (Pmode, operands[2]);
6978     }
6979   operands[0] = gen_lowpart (SImode, operands[0]);
6980   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6981   if (Pmode != SImode)
6982     pat = gen_rtx_SUBREG (SImode, pat, 0);
6983   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6984   DONE;
6985 })
6986
6987 ;; Convert lea to the lea pattern to avoid flags dependency.
6988 (define_split
6989   [(set (match_operand:DI 0 "register_operand" "")
6990         (zero_extend:DI
6991           (plus:SI (match_operand:SI 1 "register_operand" "")
6992                    (match_operand:SI 2 "nonmemory_operand" ""))))
6993    (clobber (reg:CC FLAGS_REG))]
6994   "TARGET_64BIT && reload_completed
6995    && true_regnum (operands[0]) != true_regnum (operands[1])"
6996   [(set (match_dup 0)
6997         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6998 {
6999   operands[1] = gen_lowpart (Pmode, operands[1]);
7000   operands[2] = gen_lowpart (Pmode, operands[2]);
7001 })
7002 \f
7003 ;; Subtract instructions
7004
7005 (define_expand "sub<mode>3"
7006   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7007         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7008                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7009   ""
7010   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7011
7012 (define_insn_and_split "*sub<dwi>3_doubleword"
7013   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7014         (minus:<DWI>
7015           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7016           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7017    (clobber (reg:CC FLAGS_REG))]
7018   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7019   "#"
7020   "reload_completed"
7021   [(parallel [(set (reg:CC FLAGS_REG)
7022                    (compare:CC (match_dup 1) (match_dup 2)))
7023               (set (match_dup 0)
7024                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7025    (parallel [(set (match_dup 3)
7026                    (minus:DWIH
7027                      (match_dup 4)
7028                      (plus:DWIH
7029                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7030                        (match_dup 5))))
7031               (clobber (reg:CC FLAGS_REG))])]
7032   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7033
7034 (define_insn "*sub<mode>_1"
7035   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7036         (minus:SWI
7037           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7038           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7039    (clobber (reg:CC FLAGS_REG))]
7040   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7041   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7042   [(set_attr "type" "alu")
7043    (set_attr "mode" "<MODE>")])
7044
7045 (define_insn "*subsi_1_zext"
7046   [(set (match_operand:DI 0 "register_operand" "=r")
7047         (zero_extend:DI
7048           (minus:SI (match_operand:SI 1 "register_operand" "0")
7049                     (match_operand:SI 2 "general_operand" "g"))))
7050    (clobber (reg:CC FLAGS_REG))]
7051   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7052   "sub{l}\t{%2, %k0|%k0, %2}"
7053   [(set_attr "type" "alu")
7054    (set_attr "mode" "SI")])
7055
7056 (define_insn "*subqi_1_slp"
7057   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7058         (minus:QI (match_dup 0)
7059                   (match_operand:QI 1 "general_operand" "qn,qm")))
7060    (clobber (reg:CC FLAGS_REG))]
7061   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7062    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7063   "sub{b}\t{%1, %0|%0, %1}"
7064   [(set_attr "type" "alu1")
7065    (set_attr "mode" "QI")])
7066
7067 (define_insn "*sub<mode>_2"
7068   [(set (reg FLAGS_REG)
7069         (compare
7070           (minus:SWI
7071             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7072             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7073           (const_int 0)))
7074    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7075         (minus:SWI (match_dup 1) (match_dup 2)))]
7076   "ix86_match_ccmode (insn, CCGOCmode)
7077    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7078   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7079   [(set_attr "type" "alu")
7080    (set_attr "mode" "<MODE>")])
7081
7082 (define_insn "*subsi_2_zext"
7083   [(set (reg FLAGS_REG)
7084         (compare
7085           (minus:SI (match_operand:SI 1 "register_operand" "0")
7086                     (match_operand:SI 2 "general_operand" "g"))
7087           (const_int 0)))
7088    (set (match_operand:DI 0 "register_operand" "=r")
7089         (zero_extend:DI
7090           (minus:SI (match_dup 1)
7091                     (match_dup 2))))]
7092   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7093    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7094   "sub{l}\t{%2, %k0|%k0, %2}"
7095   [(set_attr "type" "alu")
7096    (set_attr "mode" "SI")])
7097
7098 (define_insn "*sub<mode>_3"
7099   [(set (reg FLAGS_REG)
7100         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7101                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7102    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7103         (minus:SWI (match_dup 1) (match_dup 2)))]
7104   "ix86_match_ccmode (insn, CCmode)
7105    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7106   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7107   [(set_attr "type" "alu")
7108    (set_attr "mode" "<MODE>")])
7109
7110 (define_insn "*subsi_3_zext"
7111   [(set (reg FLAGS_REG)
7112         (compare (match_operand:SI 1 "register_operand" "0")
7113                  (match_operand:SI 2 "general_operand" "g")))
7114    (set (match_operand:DI 0 "register_operand" "=r")
7115         (zero_extend:DI
7116           (minus:SI (match_dup 1)
7117                     (match_dup 2))))]
7118   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7119    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7120   "sub{l}\t{%2, %1|%1, %2}"
7121   [(set_attr "type" "alu")
7122    (set_attr "mode" "SI")])
7123 \f
7124 ;; Add with carry and subtract with borrow
7125
7126 (define_expand "<plusminus_insn><mode>3_carry"
7127   [(parallel
7128     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7129           (plusminus:SWI
7130             (match_operand:SWI 1 "nonimmediate_operand" "")
7131             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7132                        [(match_operand 3 "flags_reg_operand" "")
7133                         (const_int 0)])
7134                       (match_operand:SWI 2 "<general_operand>" ""))))
7135      (clobber (reg:CC FLAGS_REG))])]
7136   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7137   "")
7138
7139 (define_insn "*<plusminus_insn><mode>3_carry"
7140   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7141         (plusminus:SWI
7142           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7143           (plus:SWI
7144             (match_operator 3 "ix86_carry_flag_operator"
7145              [(reg FLAGS_REG) (const_int 0)])
7146             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7147    (clobber (reg:CC FLAGS_REG))]
7148   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7149   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7150   [(set_attr "type" "alu")
7151    (set_attr "use_carry" "1")
7152    (set_attr "pent_pair" "pu")
7153    (set_attr "mode" "<MODE>")])
7154
7155 (define_insn "*addsi3_carry_zext"
7156   [(set (match_operand:DI 0 "register_operand" "=r")
7157         (zero_extend:DI
7158           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7159                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7160                              [(reg FLAGS_REG) (const_int 0)])
7161                             (match_operand:SI 2 "general_operand" "g")))))
7162    (clobber (reg:CC FLAGS_REG))]
7163   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7164   "adc{l}\t{%2, %k0|%k0, %2}"
7165   [(set_attr "type" "alu")
7166    (set_attr "use_carry" "1")
7167    (set_attr "pent_pair" "pu")
7168    (set_attr "mode" "SI")])
7169
7170 (define_insn "*subsi3_carry_zext"
7171   [(set (match_operand:DI 0 "register_operand" "=r")
7172         (zero_extend:DI
7173           (minus:SI (match_operand:SI 1 "register_operand" "0")
7174                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7175                               [(reg FLAGS_REG) (const_int 0)])
7176                              (match_operand:SI 2 "general_operand" "g")))))
7177    (clobber (reg:CC FLAGS_REG))]
7178   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7179   "sbb{l}\t{%2, %k0|%k0, %2}"
7180   [(set_attr "type" "alu")
7181    (set_attr "pent_pair" "pu")
7182    (set_attr "mode" "SI")])
7183 \f
7184 ;; Overflow setting add and subtract instructions
7185
7186 (define_insn "*add<mode>3_cconly_overflow"
7187   [(set (reg:CCC FLAGS_REG)
7188         (compare:CCC
7189           (plus:SWI
7190             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7191             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7192           (match_dup 1)))
7193    (clobber (match_scratch:SWI 0 "=<r>"))]
7194   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7195   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7196   [(set_attr "type" "alu")
7197    (set_attr "mode" "<MODE>")])
7198
7199 (define_insn "*sub<mode>3_cconly_overflow"
7200   [(set (reg:CCC FLAGS_REG)
7201         (compare:CCC
7202           (minus:SWI
7203             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7204             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7205           (match_dup 0)))]
7206   ""
7207   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7208   [(set_attr "type" "icmp")
7209    (set_attr "mode" "<MODE>")])
7210
7211 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7212   [(set (reg:CCC FLAGS_REG)
7213         (compare:CCC
7214             (plusminus:SWI
7215                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7216                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7217             (match_dup 1)))
7218    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7219         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7220   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7221   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7222   [(set_attr "type" "alu")
7223    (set_attr "mode" "<MODE>")])
7224
7225 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7226   [(set (reg:CCC FLAGS_REG)
7227         (compare:CCC
7228           (plusminus:SI
7229             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7230             (match_operand:SI 2 "general_operand" "g"))
7231           (match_dup 1)))
7232    (set (match_operand:DI 0 "register_operand" "=r")
7233         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7234   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7235   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7236   [(set_attr "type" "alu")
7237    (set_attr "mode" "SI")])
7238
7239 ;; The patterns that match these are at the end of this file.
7240
7241 (define_expand "<plusminus_insn>xf3"
7242   [(set (match_operand:XF 0 "register_operand" "")
7243         (plusminus:XF
7244           (match_operand:XF 1 "register_operand" "")
7245           (match_operand:XF 2 "register_operand" "")))]
7246   "TARGET_80387"
7247   "")
7248
7249 (define_expand "<plusminus_insn><mode>3"
7250   [(set (match_operand:MODEF 0 "register_operand" "")
7251         (plusminus:MODEF
7252           (match_operand:MODEF 1 "register_operand" "")
7253           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7254   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7255     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7256   "")
7257 \f
7258 ;; Multiply instructions
7259
7260 (define_expand "mul<mode>3"
7261   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7262                    (mult:SWIM248
7263                      (match_operand:SWIM248 1 "register_operand" "")
7264                      (match_operand:SWIM248 2 "<general_operand>" "")))
7265               (clobber (reg:CC FLAGS_REG))])]
7266   ""
7267   "")
7268
7269 (define_expand "mulqi3"
7270   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7271                    (mult:QI
7272                      (match_operand:QI 1 "register_operand" "")
7273                      (match_operand:QI 2 "nonimmediate_operand" "")))
7274               (clobber (reg:CC FLAGS_REG))])]
7275   "TARGET_QIMODE_MATH"
7276   "")
7277
7278 ;; On AMDFAM10
7279 ;; IMUL reg32/64, reg32/64, imm8        Direct
7280 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7281 ;; IMUL reg32/64, reg32/64, imm32       Direct
7282 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7283 ;; IMUL reg32/64, reg32/64              Direct
7284 ;; IMUL reg32/64, mem32/64              Direct
7285
7286 (define_insn "*mul<mode>3_1"
7287   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7288         (mult:SWI48
7289           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7290           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7291    (clobber (reg:CC FLAGS_REG))]
7292   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7293   "@
7294    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7295    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7296    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7297   [(set_attr "type" "imul")
7298    (set_attr "prefix_0f" "0,0,1")
7299    (set (attr "athlon_decode")
7300         (cond [(eq_attr "cpu" "athlon")
7301                   (const_string "vector")
7302                (eq_attr "alternative" "1")
7303                   (const_string "vector")
7304                (and (eq_attr "alternative" "2")
7305                     (match_operand 1 "memory_operand" ""))
7306                   (const_string "vector")]
7307               (const_string "direct")))
7308    (set (attr "amdfam10_decode")
7309         (cond [(and (eq_attr "alternative" "0,1")
7310                     (match_operand 1 "memory_operand" ""))
7311                   (const_string "vector")]
7312               (const_string "direct")))
7313    (set_attr "mode" "<MODE>")])
7314
7315 (define_insn "*mulsi3_1_zext"
7316   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7317         (zero_extend:DI
7318           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7319                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7320    (clobber (reg:CC FLAGS_REG))]
7321   "TARGET_64BIT
7322    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7323   "@
7324    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7325    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7326    imul{l}\t{%2, %k0|%k0, %2}"
7327   [(set_attr "type" "imul")
7328    (set_attr "prefix_0f" "0,0,1")
7329    (set (attr "athlon_decode")
7330         (cond [(eq_attr "cpu" "athlon")
7331                   (const_string "vector")
7332                (eq_attr "alternative" "1")
7333                   (const_string "vector")
7334                (and (eq_attr "alternative" "2")
7335                     (match_operand 1 "memory_operand" ""))
7336                   (const_string "vector")]
7337               (const_string "direct")))
7338    (set (attr "amdfam10_decode")
7339         (cond [(and (eq_attr "alternative" "0,1")
7340                     (match_operand 1 "memory_operand" ""))
7341                   (const_string "vector")]
7342               (const_string "direct")))
7343    (set_attr "mode" "SI")])
7344
7345 ;; On AMDFAM10
7346 ;; IMUL reg16, reg16, imm8      VectorPath
7347 ;; IMUL reg16, mem16, imm8      VectorPath
7348 ;; IMUL reg16, reg16, imm16     VectorPath
7349 ;; IMUL reg16, mem16, imm16     VectorPath
7350 ;; IMUL reg16, reg16            Direct
7351 ;; IMUL reg16, mem16            Direct
7352
7353 (define_insn "*mulhi3_1"
7354   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7355         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7356                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7357    (clobber (reg:CC FLAGS_REG))]
7358   "TARGET_HIMODE_MATH
7359    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7360   "@
7361    imul{w}\t{%2, %1, %0|%0, %1, %2}
7362    imul{w}\t{%2, %1, %0|%0, %1, %2}
7363    imul{w}\t{%2, %0|%0, %2}"
7364   [(set_attr "type" "imul")
7365    (set_attr "prefix_0f" "0,0,1")
7366    (set (attr "athlon_decode")
7367         (cond [(eq_attr "cpu" "athlon")
7368                   (const_string "vector")
7369                (eq_attr "alternative" "1,2")
7370                   (const_string "vector")]
7371               (const_string "direct")))
7372    (set (attr "amdfam10_decode")
7373         (cond [(eq_attr "alternative" "0,1")
7374                   (const_string "vector")]
7375               (const_string "direct")))
7376    (set_attr "mode" "HI")])
7377
7378 ;;On AMDFAM10
7379 ;; MUL reg8     Direct
7380 ;; MUL mem8     Direct
7381
7382 (define_insn "*mulqi3_1"
7383   [(set (match_operand:QI 0 "register_operand" "=a")
7384         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7385                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7386    (clobber (reg:CC FLAGS_REG))]
7387   "TARGET_QIMODE_MATH
7388    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7389   "mul{b}\t%2"
7390   [(set_attr "type" "imul")
7391    (set_attr "length_immediate" "0")
7392    (set (attr "athlon_decode")
7393      (if_then_else (eq_attr "cpu" "athlon")
7394         (const_string "vector")
7395         (const_string "direct")))
7396    (set_attr "amdfam10_decode" "direct")
7397    (set_attr "mode" "QI")])
7398
7399 (define_expand "<u>mul<mode><dwi>3"
7400   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7401                    (mult:<DWI>
7402                      (any_extend:<DWI>
7403                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7404                      (any_extend:<DWI>
7405                        (match_operand:DWIH 2 "register_operand" ""))))
7406               (clobber (reg:CC FLAGS_REG))])]
7407   ""
7408   "")
7409
7410 (define_expand "<u>mulqihi3"
7411   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7412                    (mult:HI
7413                      (any_extend:HI
7414                        (match_operand:QI 1 "nonimmediate_operand" ""))
7415                      (any_extend:HI
7416                        (match_operand:QI 2 "register_operand" ""))))
7417               (clobber (reg:CC FLAGS_REG))])]
7418   "TARGET_QIMODE_MATH"
7419   "")
7420
7421 (define_insn "*<u>mul<mode><dwi>3_1"
7422   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7423         (mult:<DWI>
7424           (any_extend:<DWI>
7425             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7426           (any_extend:<DWI>
7427             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7428    (clobber (reg:CC FLAGS_REG))]
7429   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7430   "<sgnprefix>mul{<imodesuffix>}\t%2"
7431   [(set_attr "type" "imul")
7432    (set_attr "length_immediate" "0")
7433    (set (attr "athlon_decode")
7434      (if_then_else (eq_attr "cpu" "athlon")
7435         (const_string "vector")
7436         (const_string "double")))
7437    (set_attr "amdfam10_decode" "double")
7438    (set_attr "mode" "<MODE>")])
7439
7440 (define_insn "*<u>mulqihi3_1"
7441   [(set (match_operand:HI 0 "register_operand" "=a")
7442         (mult:HI
7443           (any_extend:HI
7444             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7445           (any_extend:HI
7446             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7447    (clobber (reg:CC FLAGS_REG))]
7448   "TARGET_QIMODE_MATH
7449    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7450   "<sgnprefix>mul{b}\t%2"
7451   [(set_attr "type" "imul")
7452    (set_attr "length_immediate" "0")
7453    (set (attr "athlon_decode")
7454      (if_then_else (eq_attr "cpu" "athlon")
7455         (const_string "vector")
7456         (const_string "direct")))
7457    (set_attr "amdfam10_decode" "direct")
7458    (set_attr "mode" "QI")])
7459
7460 (define_expand "<s>mul<mode>3_highpart"
7461   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7462                    (truncate:SWI48
7463                      (lshiftrt:<DWI>
7464                        (mult:<DWI>
7465                          (any_extend:<DWI>
7466                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7467                          (any_extend:<DWI>
7468                            (match_operand:SWI48 2 "register_operand" "")))
7469                        (match_dup 4))))
7470               (clobber (match_scratch:SWI48 3 ""))
7471               (clobber (reg:CC FLAGS_REG))])]
7472   ""
7473   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7474
7475 (define_insn "*<s>muldi3_highpart_1"
7476   [(set (match_operand:DI 0 "register_operand" "=d")
7477         (truncate:DI
7478           (lshiftrt:TI
7479             (mult:TI
7480               (any_extend:TI
7481                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7482               (any_extend:TI
7483                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7484             (const_int 64))))
7485    (clobber (match_scratch:DI 3 "=1"))
7486    (clobber (reg:CC FLAGS_REG))]
7487   "TARGET_64BIT
7488    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7489   "<sgnprefix>mul{q}\t%2"
7490   [(set_attr "type" "imul")
7491    (set_attr "length_immediate" "0")
7492    (set (attr "athlon_decode")
7493      (if_then_else (eq_attr "cpu" "athlon")
7494         (const_string "vector")
7495         (const_string "double")))
7496    (set_attr "amdfam10_decode" "double")
7497    (set_attr "mode" "DI")])
7498
7499 (define_insn "*<s>mulsi3_highpart_1"
7500   [(set (match_operand:SI 0 "register_operand" "=d")
7501         (truncate:SI
7502           (lshiftrt:DI
7503             (mult:DI
7504               (any_extend:DI
7505                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7506               (any_extend:DI
7507                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7508             (const_int 32))))
7509    (clobber (match_scratch:SI 3 "=1"))
7510    (clobber (reg:CC FLAGS_REG))]
7511   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7512   "<sgnprefix>mul{l}\t%2"
7513   [(set_attr "type" "imul")
7514    (set_attr "length_immediate" "0")
7515    (set (attr "athlon_decode")
7516      (if_then_else (eq_attr "cpu" "athlon")
7517         (const_string "vector")
7518         (const_string "double")))
7519    (set_attr "amdfam10_decode" "double")
7520    (set_attr "mode" "SI")])
7521
7522 (define_insn "*<s>mulsi3_highpart_zext"
7523   [(set (match_operand:DI 0 "register_operand" "=d")
7524         (zero_extend:DI (truncate:SI
7525           (lshiftrt:DI
7526             (mult:DI (any_extend:DI
7527                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7528                      (any_extend:DI
7529                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7530             (const_int 32)))))
7531    (clobber (match_scratch:SI 3 "=1"))
7532    (clobber (reg:CC FLAGS_REG))]
7533   "TARGET_64BIT
7534    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7535   "<sgnprefix>mul{l}\t%2"
7536   [(set_attr "type" "imul")
7537    (set_attr "length_immediate" "0")
7538    (set (attr "athlon_decode")
7539      (if_then_else (eq_attr "cpu" "athlon")
7540         (const_string "vector")
7541         (const_string "double")))
7542    (set_attr "amdfam10_decode" "double")
7543    (set_attr "mode" "SI")])
7544
7545 ;; The patterns that match these are at the end of this file.
7546
7547 (define_expand "mulxf3"
7548   [(set (match_operand:XF 0 "register_operand" "")
7549         (mult:XF (match_operand:XF 1 "register_operand" "")
7550                  (match_operand:XF 2 "register_operand" "")))]
7551   "TARGET_80387"
7552   "")
7553
7554 (define_expand "mul<mode>3"
7555   [(set (match_operand:MODEF 0 "register_operand" "")
7556         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7557                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7558   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7559     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7560   "")
7561 \f
7562 ;; Divide instructions
7563
7564 (define_insn "<u>divqi3"
7565   [(set (match_operand:QI 0 "register_operand" "=a")
7566         (any_div:QI
7567           (match_operand:HI 1 "register_operand" "0")
7568           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7569    (clobber (reg:CC FLAGS_REG))]
7570   "TARGET_QIMODE_MATH"
7571   "<sgnprefix>div{b}\t%2"
7572   [(set_attr "type" "idiv")
7573    (set_attr "mode" "QI")])
7574
7575 ;; The patterns that match these are at the end of this file.
7576
7577 (define_expand "divxf3"
7578   [(set (match_operand:XF 0 "register_operand" "")
7579         (div:XF (match_operand:XF 1 "register_operand" "")
7580                 (match_operand:XF 2 "register_operand" "")))]
7581   "TARGET_80387"
7582   "")
7583
7584 (define_expand "divdf3"
7585   [(set (match_operand:DF 0 "register_operand" "")
7586         (div:DF (match_operand:DF 1 "register_operand" "")
7587                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7588    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7589     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7590    "")
7591
7592 (define_expand "divsf3"
7593   [(set (match_operand:SF 0 "register_operand" "")
7594         (div:SF (match_operand:SF 1 "register_operand" "")
7595                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7596   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7597     || TARGET_SSE_MATH"
7598 {
7599   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7600       && flag_finite_math_only && !flag_trapping_math
7601       && flag_unsafe_math_optimizations)
7602     {
7603       ix86_emit_swdivsf (operands[0], operands[1],
7604                          operands[2], SFmode);
7605       DONE;
7606     }
7607 })
7608 \f
7609 ;; Divmod instructions.
7610
7611 (define_expand "divmod<mode>4"
7612   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7613                    (div:SWIM248
7614                      (match_operand:SWIM248 1 "register_operand" "")
7615                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7616               (set (match_operand:SWIM248 3 "register_operand" "")
7617                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7618               (clobber (reg:CC FLAGS_REG))])]
7619   ""
7620   "")
7621
7622 (define_insn_and_split "*divmod<mode>4"
7623   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7624         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7625                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7626    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7627         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7628    (clobber (reg:CC FLAGS_REG))]
7629   ""
7630   "#"
7631   "reload_completed"
7632   [(parallel [(set (match_dup 1)
7633                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7634               (clobber (reg:CC FLAGS_REG))])
7635    (parallel [(set (match_dup 0)
7636                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7637               (set (match_dup 1)
7638                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7639               (use (match_dup 1))
7640               (clobber (reg:CC FLAGS_REG))])]
7641 {
7642   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7643
7644   if (<MODE>mode != HImode
7645       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7646     operands[4] = operands[2];
7647   else
7648     {
7649       /* Avoid use of cltd in favor of a mov+shift.  */
7650       emit_move_insn (operands[1], operands[2]);
7651       operands[4] = operands[1];
7652     }
7653 }
7654   [(set_attr "type" "multi")
7655    (set_attr "mode" "<MODE>")])
7656
7657 (define_insn "*divmod<mode>4_noext"
7658   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7659         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7660                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7661    (set (match_operand:SWIM248 1 "register_operand" "=d")
7662         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7663    (use (match_operand:SWIM248 4 "register_operand" "1"))
7664    (clobber (reg:CC FLAGS_REG))]
7665   ""
7666   "idiv{<imodesuffix>}\t%3"
7667   [(set_attr "type" "idiv")
7668    (set_attr "mode" "<MODE>")])
7669
7670 (define_expand "udivmod<mode>4"
7671   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7672                    (udiv:SWIM248
7673                      (match_operand:SWIM248 1 "register_operand" "")
7674                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7675               (set (match_operand:SWIM248 3 "register_operand" "")
7676                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7677               (clobber (reg:CC FLAGS_REG))])]
7678   ""
7679   "")
7680
7681 (define_insn_and_split "*udivmod<mode>4"
7682   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7683         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7684                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7685    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7686         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7687    (clobber (reg:CC FLAGS_REG))]
7688   ""
7689   "#"
7690   "reload_completed"
7691   [(set (match_dup 1) (const_int 0))
7692    (parallel [(set (match_dup 0)
7693                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7694               (set (match_dup 1)
7695                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7696               (use (match_dup 1))
7697               (clobber (reg:CC FLAGS_REG))])]
7698   ""
7699   [(set_attr "type" "multi")
7700    (set_attr "mode" "<MODE>")])
7701
7702 (define_insn "*udivmod<mode>4_noext"
7703   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7704         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7705                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7706    (set (match_operand:SWIM248 1 "register_operand" "=d")
7707         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7708    (use (match_operand:SWIM248 4 "register_operand" "1"))
7709    (clobber (reg:CC FLAGS_REG))]
7710   ""
7711   "div{<imodesuffix>}\t%3"
7712   [(set_attr "type" "idiv")
7713    (set_attr "mode" "<MODE>")])
7714
7715 ;; We cannot use div/idiv for double division, because it causes
7716 ;; "division by zero" on the overflow and that's not what we expect
7717 ;; from truncate.  Because true (non truncating) double division is
7718 ;; never generated, we can't create this insn anyway.
7719 ;
7720 ;(define_insn ""
7721 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7722 ;       (truncate:SI
7723 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7724 ;                  (zero_extend:DI
7725 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7726 ;   (set (match_operand:SI 3 "register_operand" "=d")
7727 ;       (truncate:SI
7728 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7729 ;   (clobber (reg:CC FLAGS_REG))]
7730 ;  ""
7731 ;  "div{l}\t{%2, %0|%0, %2}"
7732 ;  [(set_attr "type" "idiv")])
7733 \f
7734 ;;- Logical AND instructions
7735
7736 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7737 ;; Note that this excludes ah.
7738
7739 (define_expand "testsi_ccno_1"
7740   [(set (reg:CCNO FLAGS_REG)
7741         (compare:CCNO
7742           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7743                   (match_operand:SI 1 "nonmemory_operand" ""))
7744           (const_int 0)))]
7745   ""
7746   "")
7747
7748 (define_expand "testqi_ccz_1"
7749   [(set (reg:CCZ FLAGS_REG)
7750         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7751                              (match_operand:QI 1 "nonmemory_operand" ""))
7752                  (const_int 0)))]
7753   ""
7754   "")
7755
7756 (define_insn "*testdi_1"
7757   [(set (reg FLAGS_REG)
7758         (compare
7759          (and:DI
7760           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7761           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7762          (const_int 0)))]
7763   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7764    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7765   "@
7766    test{l}\t{%k1, %k0|%k0, %k1}
7767    test{l}\t{%k1, %k0|%k0, %k1}
7768    test{q}\t{%1, %0|%0, %1}
7769    test{q}\t{%1, %0|%0, %1}
7770    test{q}\t{%1, %0|%0, %1}"
7771   [(set_attr "type" "test")
7772    (set_attr "modrm" "0,1,0,1,1")
7773    (set_attr "mode" "SI,SI,DI,DI,DI")])
7774
7775 (define_insn "*testqi_1_maybe_si"
7776   [(set (reg FLAGS_REG)
7777         (compare
7778           (and:QI
7779             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7780             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7781           (const_int 0)))]
7782    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7783     && ix86_match_ccmode (insn,
7784                          CONST_INT_P (operands[1])
7785                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7786 {
7787   if (which_alternative == 3)
7788     {
7789       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7790         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7791       return "test{l}\t{%1, %k0|%k0, %1}";
7792     }
7793   return "test{b}\t{%1, %0|%0, %1}";
7794 }
7795   [(set_attr "type" "test")
7796    (set_attr "modrm" "0,1,1,1")
7797    (set_attr "mode" "QI,QI,QI,SI")
7798    (set_attr "pent_pair" "uv,np,uv,np")])
7799
7800 (define_insn "*test<mode>_1"
7801   [(set (reg FLAGS_REG)
7802         (compare
7803          (and:SWI124
7804           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7805           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7806          (const_int 0)))]
7807   "ix86_match_ccmode (insn, CCNOmode)
7808    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7809   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7810   [(set_attr "type" "test")
7811    (set_attr "modrm" "0,1,1")
7812    (set_attr "mode" "<MODE>")
7813    (set_attr "pent_pair" "uv,np,uv")])
7814
7815 (define_expand "testqi_ext_ccno_0"
7816   [(set (reg:CCNO FLAGS_REG)
7817         (compare:CCNO
7818           (and:SI
7819             (zero_extract:SI
7820               (match_operand 0 "ext_register_operand" "")
7821               (const_int 8)
7822               (const_int 8))
7823             (match_operand 1 "const_int_operand" ""))
7824           (const_int 0)))]
7825   ""
7826   "")
7827
7828 (define_insn "*testqi_ext_0"
7829   [(set (reg FLAGS_REG)
7830         (compare
7831           (and:SI
7832             (zero_extract:SI
7833               (match_operand 0 "ext_register_operand" "Q")
7834               (const_int 8)
7835               (const_int 8))
7836             (match_operand 1 "const_int_operand" "n"))
7837           (const_int 0)))]
7838   "ix86_match_ccmode (insn, CCNOmode)"
7839   "test{b}\t{%1, %h0|%h0, %1}"
7840   [(set_attr "type" "test")
7841    (set_attr "mode" "QI")
7842    (set_attr "length_immediate" "1")
7843    (set_attr "modrm" "1")
7844    (set_attr "pent_pair" "np")])
7845
7846 (define_insn "*testqi_ext_1_rex64"
7847   [(set (reg FLAGS_REG)
7848         (compare
7849           (and:SI
7850             (zero_extract:SI
7851               (match_operand 0 "ext_register_operand" "Q")
7852               (const_int 8)
7853               (const_int 8))
7854             (zero_extend:SI
7855               (match_operand:QI 1 "register_operand" "Q")))
7856           (const_int 0)))]
7857   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7858   "test{b}\t{%1, %h0|%h0, %1}"
7859   [(set_attr "type" "test")
7860    (set_attr "mode" "QI")])
7861
7862 (define_insn "*testqi_ext_1"
7863   [(set (reg FLAGS_REG)
7864         (compare
7865           (and:SI
7866             (zero_extract:SI
7867               (match_operand 0 "ext_register_operand" "Q")
7868               (const_int 8)
7869               (const_int 8))
7870             (zero_extend:SI
7871               (match_operand:QI 1 "general_operand" "Qm")))
7872           (const_int 0)))]
7873   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7874   "test{b}\t{%1, %h0|%h0, %1}"
7875   [(set_attr "type" "test")
7876    (set_attr "mode" "QI")])
7877
7878 (define_insn "*testqi_ext_2"
7879   [(set (reg FLAGS_REG)
7880         (compare
7881           (and:SI
7882             (zero_extract:SI
7883               (match_operand 0 "ext_register_operand" "Q")
7884               (const_int 8)
7885               (const_int 8))
7886             (zero_extract:SI
7887               (match_operand 1 "ext_register_operand" "Q")
7888               (const_int 8)
7889               (const_int 8)))
7890           (const_int 0)))]
7891   "ix86_match_ccmode (insn, CCNOmode)"
7892   "test{b}\t{%h1, %h0|%h0, %h1}"
7893   [(set_attr "type" "test")
7894    (set_attr "mode" "QI")])
7895
7896 (define_insn "*testqi_ext_3_rex64"
7897   [(set (reg FLAGS_REG)
7898         (compare (zero_extract:DI
7899                    (match_operand 0 "nonimmediate_operand" "rm")
7900                    (match_operand:DI 1 "const_int_operand" "")
7901                    (match_operand:DI 2 "const_int_operand" ""))
7902                  (const_int 0)))]
7903   "TARGET_64BIT
7904    && ix86_match_ccmode (insn, CCNOmode)
7905    && INTVAL (operands[1]) > 0
7906    && INTVAL (operands[2]) >= 0
7907    /* Ensure that resulting mask is zero or sign extended operand.  */
7908    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7909        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7910            && INTVAL (operands[1]) > 32))
7911    && (GET_MODE (operands[0]) == SImode
7912        || GET_MODE (operands[0]) == DImode
7913        || GET_MODE (operands[0]) == HImode
7914        || GET_MODE (operands[0]) == QImode)"
7915   "#")
7916
7917 ;; Combine likes to form bit extractions for some tests.  Humor it.
7918 (define_insn "*testqi_ext_3"
7919   [(set (reg FLAGS_REG)
7920         (compare (zero_extract:SI
7921                    (match_operand 0 "nonimmediate_operand" "rm")
7922                    (match_operand:SI 1 "const_int_operand" "")
7923                    (match_operand:SI 2 "const_int_operand" ""))
7924                  (const_int 0)))]
7925   "ix86_match_ccmode (insn, CCNOmode)
7926    && INTVAL (operands[1]) > 0
7927    && INTVAL (operands[2]) >= 0
7928    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7929    && (GET_MODE (operands[0]) == SImode
7930        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7931        || GET_MODE (operands[0]) == HImode
7932        || GET_MODE (operands[0]) == QImode)"
7933   "#")
7934
7935 (define_split
7936   [(set (match_operand 0 "flags_reg_operand" "")
7937         (match_operator 1 "compare_operator"
7938           [(zero_extract
7939              (match_operand 2 "nonimmediate_operand" "")
7940              (match_operand 3 "const_int_operand" "")
7941              (match_operand 4 "const_int_operand" ""))
7942            (const_int 0)]))]
7943   "ix86_match_ccmode (insn, CCNOmode)"
7944   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7945 {
7946   rtx val = operands[2];
7947   HOST_WIDE_INT len = INTVAL (operands[3]);
7948   HOST_WIDE_INT pos = INTVAL (operands[4]);
7949   HOST_WIDE_INT mask;
7950   enum machine_mode mode, submode;
7951
7952   mode = GET_MODE (val);
7953   if (MEM_P (val))
7954     {
7955       /* ??? Combine likes to put non-volatile mem extractions in QImode
7956          no matter the size of the test.  So find a mode that works.  */
7957       if (! MEM_VOLATILE_P (val))
7958         {
7959           mode = smallest_mode_for_size (pos + len, MODE_INT);
7960           val = adjust_address (val, mode, 0);
7961         }
7962     }
7963   else if (GET_CODE (val) == SUBREG
7964            && (submode = GET_MODE (SUBREG_REG (val)),
7965                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7966            && pos + len <= GET_MODE_BITSIZE (submode)
7967            && GET_MODE_CLASS (submode) == MODE_INT)
7968     {
7969       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7970       mode = submode;
7971       val = SUBREG_REG (val);
7972     }
7973   else if (mode == HImode && pos + len <= 8)
7974     {
7975       /* Small HImode tests can be converted to QImode.  */
7976       mode = QImode;
7977       val = gen_lowpart (QImode, val);
7978     }
7979
7980   if (len == HOST_BITS_PER_WIDE_INT)
7981     mask = -1;
7982   else
7983     mask = ((HOST_WIDE_INT)1 << len) - 1;
7984   mask <<= pos;
7985
7986   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7987 })
7988
7989 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7990 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7991 ;; this is relatively important trick.
7992 ;; Do the conversion only post-reload to avoid limiting of the register class
7993 ;; to QI regs.
7994 (define_split
7995   [(set (match_operand 0 "flags_reg_operand" "")
7996         (match_operator 1 "compare_operator"
7997           [(and (match_operand 2 "register_operand" "")
7998                 (match_operand 3 "const_int_operand" ""))
7999            (const_int 0)]))]
8000    "reload_completed
8001     && QI_REG_P (operands[2])
8002     && GET_MODE (operands[2]) != QImode
8003     && ((ix86_match_ccmode (insn, CCZmode)
8004          && !(INTVAL (operands[3]) & ~(255 << 8)))
8005         || (ix86_match_ccmode (insn, CCNOmode)
8006             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8007   [(set (match_dup 0)
8008         (match_op_dup 1
8009           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8010                    (match_dup 3))
8011            (const_int 0)]))]
8012   "operands[2] = gen_lowpart (SImode, operands[2]);
8013    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8014
8015 (define_split
8016   [(set (match_operand 0 "flags_reg_operand" "")
8017         (match_operator 1 "compare_operator"
8018           [(and (match_operand 2 "nonimmediate_operand" "")
8019                 (match_operand 3 "const_int_operand" ""))
8020            (const_int 0)]))]
8021    "reload_completed
8022     && GET_MODE (operands[2]) != QImode
8023     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8024     && ((ix86_match_ccmode (insn, CCZmode)
8025          && !(INTVAL (operands[3]) & ~255))
8026         || (ix86_match_ccmode (insn, CCNOmode)
8027             && !(INTVAL (operands[3]) & ~127)))"
8028   [(set (match_dup 0)
8029         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8030                          (const_int 0)]))]
8031   "operands[2] = gen_lowpart (QImode, operands[2]);
8032    operands[3] = gen_lowpart (QImode, operands[3]);")
8033
8034 ;; %%% This used to optimize known byte-wide and operations to memory,
8035 ;; and sometimes to QImode registers.  If this is considered useful,
8036 ;; it should be done with splitters.
8037
8038 (define_expand "and<mode>3"
8039   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8040         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8041                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8042   ""
8043   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8044
8045 (define_insn "*anddi_1"
8046   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8047         (and:DI
8048          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8049          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8050    (clobber (reg:CC FLAGS_REG))]
8051   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8052 {
8053   switch (get_attr_type (insn))
8054     {
8055     case TYPE_IMOVX:
8056       {
8057         enum machine_mode mode;
8058
8059         gcc_assert (CONST_INT_P (operands[2]));
8060         if (INTVAL (operands[2]) == 0xff)
8061           mode = QImode;
8062         else
8063           {
8064             gcc_assert (INTVAL (operands[2]) == 0xffff);
8065             mode = HImode;
8066           }
8067
8068         operands[1] = gen_lowpart (mode, operands[1]);
8069         if (mode == QImode)
8070           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8071         else
8072           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8073       }
8074
8075     default:
8076       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8077       if (get_attr_mode (insn) == MODE_SI)
8078         return "and{l}\t{%k2, %k0|%k0, %k2}";
8079       else
8080         return "and{q}\t{%2, %0|%0, %2}";
8081     }
8082 }
8083   [(set_attr "type" "alu,alu,alu,imovx")
8084    (set_attr "length_immediate" "*,*,*,0")
8085    (set (attr "prefix_rex")
8086      (if_then_else
8087        (and (eq_attr "type" "imovx")
8088             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8089                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8090        (const_string "1")
8091        (const_string "*")))
8092    (set_attr "mode" "SI,DI,DI,SI")])
8093
8094 (define_insn "*andsi_1"
8095   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8096         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8097                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8098    (clobber (reg:CC FLAGS_REG))]
8099   "ix86_binary_operator_ok (AND, SImode, operands)"
8100 {
8101   switch (get_attr_type (insn))
8102     {
8103     case TYPE_IMOVX:
8104       {
8105         enum machine_mode mode;
8106
8107         gcc_assert (CONST_INT_P (operands[2]));
8108         if (INTVAL (operands[2]) == 0xff)
8109           mode = QImode;
8110         else
8111           {
8112             gcc_assert (INTVAL (operands[2]) == 0xffff);
8113             mode = HImode;
8114           }
8115
8116         operands[1] = gen_lowpart (mode, operands[1]);
8117         if (mode == QImode)
8118           return "movz{bl|x}\t{%1, %0|%0, %1}";
8119         else
8120           return "movz{wl|x}\t{%1, %0|%0, %1}";
8121       }
8122
8123     default:
8124       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8125       return "and{l}\t{%2, %0|%0, %2}";
8126     }
8127 }
8128   [(set_attr "type" "alu,alu,imovx")
8129    (set (attr "prefix_rex")
8130      (if_then_else
8131        (and (eq_attr "type" "imovx")
8132             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8133                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8134        (const_string "1")
8135        (const_string "*")))
8136    (set_attr "length_immediate" "*,*,0")
8137    (set_attr "mode" "SI")])
8138
8139 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8140 (define_insn "*andsi_1_zext"
8141   [(set (match_operand:DI 0 "register_operand" "=r")
8142         (zero_extend:DI
8143           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8144                   (match_operand:SI 2 "general_operand" "g"))))
8145    (clobber (reg:CC FLAGS_REG))]
8146   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8147   "and{l}\t{%2, %k0|%k0, %2}"
8148   [(set_attr "type" "alu")
8149    (set_attr "mode" "SI")])
8150
8151 (define_insn "*andhi_1"
8152   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8153         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8154                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8155    (clobber (reg:CC FLAGS_REG))]
8156   "ix86_binary_operator_ok (AND, HImode, operands)"
8157 {
8158   switch (get_attr_type (insn))
8159     {
8160     case TYPE_IMOVX:
8161       gcc_assert (CONST_INT_P (operands[2]));
8162       gcc_assert (INTVAL (operands[2]) == 0xff);
8163       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8164
8165     default:
8166       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8167
8168       return "and{w}\t{%2, %0|%0, %2}";
8169     }
8170 }
8171   [(set_attr "type" "alu,alu,imovx")
8172    (set_attr "length_immediate" "*,*,0")
8173    (set (attr "prefix_rex")
8174      (if_then_else
8175        (and (eq_attr "type" "imovx")
8176             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8177        (const_string "1")
8178        (const_string "*")))
8179    (set_attr "mode" "HI,HI,SI")])
8180
8181 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8182 (define_insn "*andqi_1"
8183   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8184         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8185                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8186    (clobber (reg:CC FLAGS_REG))]
8187   "ix86_binary_operator_ok (AND, QImode, operands)"
8188   "@
8189    and{b}\t{%2, %0|%0, %2}
8190    and{b}\t{%2, %0|%0, %2}
8191    and{l}\t{%k2, %k0|%k0, %k2}"
8192   [(set_attr "type" "alu")
8193    (set_attr "mode" "QI,QI,SI")])
8194
8195 (define_insn "*andqi_1_slp"
8196   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8197         (and:QI (match_dup 0)
8198                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8199    (clobber (reg:CC FLAGS_REG))]
8200   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8201    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8202   "and{b}\t{%1, %0|%0, %1}"
8203   [(set_attr "type" "alu1")
8204    (set_attr "mode" "QI")])
8205
8206 (define_split
8207   [(set (match_operand 0 "register_operand" "")
8208         (and (match_dup 0)
8209              (const_int -65536)))
8210    (clobber (reg:CC FLAGS_REG))]
8211   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8212     || optimize_function_for_size_p (cfun)"
8213   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8214   "operands[1] = gen_lowpart (HImode, operands[0]);")
8215
8216 (define_split
8217   [(set (match_operand 0 "ext_register_operand" "")
8218         (and (match_dup 0)
8219              (const_int -256)))
8220    (clobber (reg:CC FLAGS_REG))]
8221   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8222    && reload_completed"
8223   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8224   "operands[1] = gen_lowpart (QImode, operands[0]);")
8225
8226 (define_split
8227   [(set (match_operand 0 "ext_register_operand" "")
8228         (and (match_dup 0)
8229              (const_int -65281)))
8230    (clobber (reg:CC FLAGS_REG))]
8231   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8232    && reload_completed"
8233   [(parallel [(set (zero_extract:SI (match_dup 0)
8234                                     (const_int 8)
8235                                     (const_int 8))
8236                    (xor:SI
8237                      (zero_extract:SI (match_dup 0)
8238                                       (const_int 8)
8239                                       (const_int 8))
8240                      (zero_extract:SI (match_dup 0)
8241                                       (const_int 8)
8242                                       (const_int 8))))
8243               (clobber (reg:CC FLAGS_REG))])]
8244   "operands[0] = gen_lowpart (SImode, operands[0]);")
8245
8246 (define_insn "*anddi_2"
8247   [(set (reg FLAGS_REG)
8248         (compare
8249          (and:DI
8250           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8251           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8252          (const_int 0)))
8253    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8254         (and:DI (match_dup 1) (match_dup 2)))]
8255   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8256    && ix86_binary_operator_ok (AND, DImode, operands)"
8257   "@
8258    and{l}\t{%k2, %k0|%k0, %k2}
8259    and{q}\t{%2, %0|%0, %2}
8260    and{q}\t{%2, %0|%0, %2}"
8261   [(set_attr "type" "alu")
8262    (set_attr "mode" "SI,DI,DI")])
8263
8264 (define_insn "*andqi_2_maybe_si"
8265   [(set (reg FLAGS_REG)
8266         (compare (and:QI
8267                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8268                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8269                  (const_int 0)))
8270    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8271         (and:QI (match_dup 1) (match_dup 2)))]
8272   "ix86_binary_operator_ok (AND, QImode, operands)
8273    && ix86_match_ccmode (insn,
8274                          CONST_INT_P (operands[2])
8275                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8276 {
8277   if (which_alternative == 2)
8278     {
8279       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8280         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8281       return "and{l}\t{%2, %k0|%k0, %2}";
8282     }
8283   return "and{b}\t{%2, %0|%0, %2}";
8284 }
8285   [(set_attr "type" "alu")
8286    (set_attr "mode" "QI,QI,SI")])
8287
8288 (define_insn "*and<mode>_2"
8289   [(set (reg FLAGS_REG)
8290         (compare (and:SWI124
8291                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8292                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8293                  (const_int 0)))
8294    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8295         (and:SWI124 (match_dup 1) (match_dup 2)))]
8296   "ix86_match_ccmode (insn, CCNOmode)
8297    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8298   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8299   [(set_attr "type" "alu")
8300    (set_attr "mode" "<MODE>")])
8301
8302 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8303 (define_insn "*andsi_2_zext"
8304   [(set (reg FLAGS_REG)
8305         (compare (and:SI
8306                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8307                   (match_operand:SI 2 "general_operand" "g"))
8308                  (const_int 0)))
8309    (set (match_operand:DI 0 "register_operand" "=r")
8310         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8311   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8312    && ix86_binary_operator_ok (AND, SImode, operands)"
8313   "and{l}\t{%2, %k0|%k0, %2}"
8314   [(set_attr "type" "alu")
8315    (set_attr "mode" "SI")])
8316
8317 (define_insn "*andqi_2_slp"
8318   [(set (reg FLAGS_REG)
8319         (compare (and:QI
8320                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8321                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8322                  (const_int 0)))
8323    (set (strict_low_part (match_dup 0))
8324         (and:QI (match_dup 0) (match_dup 1)))]
8325   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8326    && ix86_match_ccmode (insn, CCNOmode)
8327    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8328   "and{b}\t{%1, %0|%0, %1}"
8329   [(set_attr "type" "alu1")
8330    (set_attr "mode" "QI")])
8331
8332 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8333 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8334 ;; for a QImode operand, which of course failed.
8335 (define_insn "andqi_ext_0"
8336   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8337                          (const_int 8)
8338                          (const_int 8))
8339         (and:SI
8340           (zero_extract:SI
8341             (match_operand 1 "ext_register_operand" "0")
8342             (const_int 8)
8343             (const_int 8))
8344           (match_operand 2 "const_int_operand" "n")))
8345    (clobber (reg:CC FLAGS_REG))]
8346   ""
8347   "and{b}\t{%2, %h0|%h0, %2}"
8348   [(set_attr "type" "alu")
8349    (set_attr "length_immediate" "1")
8350    (set_attr "modrm" "1")
8351    (set_attr "mode" "QI")])
8352
8353 ;; Generated by peephole translating test to and.  This shows up
8354 ;; often in fp comparisons.
8355 (define_insn "*andqi_ext_0_cc"
8356   [(set (reg FLAGS_REG)
8357         (compare
8358           (and:SI
8359             (zero_extract:SI
8360               (match_operand 1 "ext_register_operand" "0")
8361               (const_int 8)
8362               (const_int 8))
8363             (match_operand 2 "const_int_operand" "n"))
8364           (const_int 0)))
8365    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8366                          (const_int 8)
8367                          (const_int 8))
8368         (and:SI
8369           (zero_extract:SI
8370             (match_dup 1)
8371             (const_int 8)
8372             (const_int 8))
8373           (match_dup 2)))]
8374   "ix86_match_ccmode (insn, CCNOmode)"
8375   "and{b}\t{%2, %h0|%h0, %2}"
8376   [(set_attr "type" "alu")
8377    (set_attr "length_immediate" "1")
8378    (set_attr "modrm" "1")
8379    (set_attr "mode" "QI")])
8380
8381 (define_insn "*andqi_ext_1_rex64"
8382   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8383                          (const_int 8)
8384                          (const_int 8))
8385         (and:SI
8386           (zero_extract:SI
8387             (match_operand 1 "ext_register_operand" "0")
8388             (const_int 8)
8389             (const_int 8))
8390           (zero_extend:SI
8391             (match_operand 2 "ext_register_operand" "Q"))))
8392    (clobber (reg:CC FLAGS_REG))]
8393   "TARGET_64BIT"
8394   "and{b}\t{%2, %h0|%h0, %2}"
8395   [(set_attr "type" "alu")
8396    (set_attr "length_immediate" "0")
8397    (set_attr "mode" "QI")])
8398
8399 (define_insn "*andqi_ext_1"
8400   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8401                          (const_int 8)
8402                          (const_int 8))
8403         (and:SI
8404           (zero_extract:SI
8405             (match_operand 1 "ext_register_operand" "0")
8406             (const_int 8)
8407             (const_int 8))
8408           (zero_extend:SI
8409             (match_operand:QI 2 "general_operand" "Qm"))))
8410    (clobber (reg:CC FLAGS_REG))]
8411   "!TARGET_64BIT"
8412   "and{b}\t{%2, %h0|%h0, %2}"
8413   [(set_attr "type" "alu")
8414    (set_attr "length_immediate" "0")
8415    (set_attr "mode" "QI")])
8416
8417 (define_insn "*andqi_ext_2"
8418   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8419                          (const_int 8)
8420                          (const_int 8))
8421         (and:SI
8422           (zero_extract:SI
8423             (match_operand 1 "ext_register_operand" "%0")
8424             (const_int 8)
8425             (const_int 8))
8426           (zero_extract:SI
8427             (match_operand 2 "ext_register_operand" "Q")
8428             (const_int 8)
8429             (const_int 8))))
8430    (clobber (reg:CC FLAGS_REG))]
8431   ""
8432   "and{b}\t{%h2, %h0|%h0, %h2}"
8433   [(set_attr "type" "alu")
8434    (set_attr "length_immediate" "0")
8435    (set_attr "mode" "QI")])
8436
8437 ;; Convert wide AND instructions with immediate operand to shorter QImode
8438 ;; equivalents when possible.
8439 ;; Don't do the splitting with memory operands, since it introduces risk
8440 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8441 ;; for size, but that can (should?) be handled by generic code instead.
8442 (define_split
8443   [(set (match_operand 0 "register_operand" "")
8444         (and (match_operand 1 "register_operand" "")
8445              (match_operand 2 "const_int_operand" "")))
8446    (clobber (reg:CC FLAGS_REG))]
8447    "reload_completed
8448     && QI_REG_P (operands[0])
8449     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8450     && !(~INTVAL (operands[2]) & ~(255 << 8))
8451     && GET_MODE (operands[0]) != QImode"
8452   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8453                    (and:SI (zero_extract:SI (match_dup 1)
8454                                             (const_int 8) (const_int 8))
8455                            (match_dup 2)))
8456               (clobber (reg:CC FLAGS_REG))])]
8457   "operands[0] = gen_lowpart (SImode, operands[0]);
8458    operands[1] = gen_lowpart (SImode, operands[1]);
8459    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8460
8461 ;; Since AND can be encoded with sign extended immediate, this is only
8462 ;; profitable when 7th bit is not set.
8463 (define_split
8464   [(set (match_operand 0 "register_operand" "")
8465         (and (match_operand 1 "general_operand" "")
8466              (match_operand 2 "const_int_operand" "")))
8467    (clobber (reg:CC FLAGS_REG))]
8468    "reload_completed
8469     && ANY_QI_REG_P (operands[0])
8470     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8471     && !(~INTVAL (operands[2]) & ~255)
8472     && !(INTVAL (operands[2]) & 128)
8473     && GET_MODE (operands[0]) != QImode"
8474   [(parallel [(set (strict_low_part (match_dup 0))
8475                    (and:QI (match_dup 1)
8476                            (match_dup 2)))
8477               (clobber (reg:CC FLAGS_REG))])]
8478   "operands[0] = gen_lowpart (QImode, operands[0]);
8479    operands[1] = gen_lowpart (QImode, operands[1]);
8480    operands[2] = gen_lowpart (QImode, operands[2]);")
8481 \f
8482 ;; Logical inclusive and exclusive OR instructions
8483
8484 ;; %%% This used to optimize known byte-wide and operations to memory.
8485 ;; If this is considered useful, it should be done with splitters.
8486
8487 (define_expand "<code><mode>3"
8488   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8489         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8490                      (match_operand:SWIM 2 "<general_operand>" "")))]
8491   ""
8492   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8493
8494 (define_insn "*<code><mode>_1"
8495   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8496         (any_or:SWI248
8497          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8498          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8499    (clobber (reg:CC FLAGS_REG))]
8500   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8501   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8502   [(set_attr "type" "alu")
8503    (set_attr "mode" "<MODE>")])
8504
8505 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8506 (define_insn "*<code>qi_1"
8507   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8508         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8509                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8510    (clobber (reg:CC FLAGS_REG))]
8511   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8512   "@
8513    <logic>{b}\t{%2, %0|%0, %2}
8514    <logic>{b}\t{%2, %0|%0, %2}
8515    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8516   [(set_attr "type" "alu")
8517    (set_attr "mode" "QI,QI,SI")])
8518
8519 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8520 (define_insn "*<code>si_1_zext"
8521   [(set (match_operand:DI 0 "register_operand" "=r")
8522         (zero_extend:DI
8523          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8524                     (match_operand:SI 2 "general_operand" "g"))))
8525    (clobber (reg:CC FLAGS_REG))]
8526   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8527   "<logic>{l}\t{%2, %k0|%k0, %2}"
8528   [(set_attr "type" "alu")
8529    (set_attr "mode" "SI")])
8530
8531 (define_insn "*<code>si_1_zext_imm"
8532   [(set (match_operand:DI 0 "register_operand" "=r")
8533         (any_or:DI
8534          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8535          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8536    (clobber (reg:CC FLAGS_REG))]
8537   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8538   "<logic>{l}\t{%2, %k0|%k0, %2}"
8539   [(set_attr "type" "alu")
8540    (set_attr "mode" "SI")])
8541
8542 (define_insn "*<code>qi_1_slp"
8543   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8544         (any_or:QI (match_dup 0)
8545                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8546    (clobber (reg:CC FLAGS_REG))]
8547   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8548    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8549   "<logic>{b}\t{%1, %0|%0, %1}"
8550   [(set_attr "type" "alu1")
8551    (set_attr "mode" "QI")])
8552
8553 (define_insn "*<code><mode>_2"
8554   [(set (reg FLAGS_REG)
8555         (compare (any_or:SWI
8556                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8557                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8558                  (const_int 0)))
8559    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8560         (any_or:SWI (match_dup 1) (match_dup 2)))]
8561   "ix86_match_ccmode (insn, CCNOmode)
8562    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8563   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8564   [(set_attr "type" "alu")
8565    (set_attr "mode" "<MODE>")])
8566
8567 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8568 ;; ??? Special case for immediate operand is missing - it is tricky.
8569 (define_insn "*<code>si_2_zext"
8570   [(set (reg FLAGS_REG)
8571         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8572                             (match_operand:SI 2 "general_operand" "g"))
8573                  (const_int 0)))
8574    (set (match_operand:DI 0 "register_operand" "=r")
8575         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8576   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8577    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8578   "<logic>{l}\t{%2, %k0|%k0, %2}"
8579   [(set_attr "type" "alu")
8580    (set_attr "mode" "SI")])
8581
8582 (define_insn "*<code>si_2_zext_imm"
8583   [(set (reg FLAGS_REG)
8584         (compare (any_or:SI
8585                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8586                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8587                  (const_int 0)))
8588    (set (match_operand:DI 0 "register_operand" "=r")
8589         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8590   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8591    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8592   "<logic>{l}\t{%2, %k0|%k0, %2}"
8593   [(set_attr "type" "alu")
8594    (set_attr "mode" "SI")])
8595
8596 (define_insn "*<code>qi_2_slp"
8597   [(set (reg FLAGS_REG)
8598         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8599                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8600                  (const_int 0)))
8601    (set (strict_low_part (match_dup 0))
8602         (any_or:QI (match_dup 0) (match_dup 1)))]
8603   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8604    && ix86_match_ccmode (insn, CCNOmode)
8605    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8606   "<logic>{b}\t{%1, %0|%0, %1}"
8607   [(set_attr "type" "alu1")
8608    (set_attr "mode" "QI")])
8609
8610 (define_insn "*<code><mode>_3"
8611   [(set (reg FLAGS_REG)
8612         (compare (any_or:SWI
8613                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8614                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8615                  (const_int 0)))
8616    (clobber (match_scratch:SWI 0 "=<r>"))]
8617   "ix86_match_ccmode (insn, CCNOmode)
8618    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8619   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8620   [(set_attr "type" "alu")
8621    (set_attr "mode" "<MODE>")])
8622
8623 (define_insn "*<code>qi_ext_0"
8624   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8625                          (const_int 8)
8626                          (const_int 8))
8627         (any_or:SI
8628           (zero_extract:SI
8629             (match_operand 1 "ext_register_operand" "0")
8630             (const_int 8)
8631             (const_int 8))
8632           (match_operand 2 "const_int_operand" "n")))
8633    (clobber (reg:CC FLAGS_REG))]
8634   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8635   "<logic>{b}\t{%2, %h0|%h0, %2}"
8636   [(set_attr "type" "alu")
8637    (set_attr "length_immediate" "1")
8638    (set_attr "modrm" "1")
8639    (set_attr "mode" "QI")])
8640
8641 (define_insn "*<code>qi_ext_1_rex64"
8642   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8643                          (const_int 8)
8644                          (const_int 8))
8645         (any_or:SI
8646           (zero_extract:SI
8647             (match_operand 1 "ext_register_operand" "0")
8648             (const_int 8)
8649             (const_int 8))
8650           (zero_extend:SI
8651             (match_operand 2 "ext_register_operand" "Q"))))
8652    (clobber (reg:CC FLAGS_REG))]
8653   "TARGET_64BIT
8654    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8655   "<logic>{b}\t{%2, %h0|%h0, %2}"
8656   [(set_attr "type" "alu")
8657    (set_attr "length_immediate" "0")
8658    (set_attr "mode" "QI")])
8659
8660 (define_insn "*<code>qi_ext_1"
8661   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8662                          (const_int 8)
8663                          (const_int 8))
8664         (any_or:SI
8665           (zero_extract:SI
8666             (match_operand 1 "ext_register_operand" "0")
8667             (const_int 8)
8668             (const_int 8))
8669           (zero_extend:SI
8670             (match_operand:QI 2 "general_operand" "Qm"))))
8671    (clobber (reg:CC FLAGS_REG))]
8672   "!TARGET_64BIT
8673    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8674   "<logic>{b}\t{%2, %h0|%h0, %2}"
8675   [(set_attr "type" "alu")
8676    (set_attr "length_immediate" "0")
8677    (set_attr "mode" "QI")])
8678
8679 (define_insn "*<code>qi_ext_2"
8680   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8681                          (const_int 8)
8682                          (const_int 8))
8683         (any_or:SI
8684           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8685                            (const_int 8)
8686                            (const_int 8))
8687           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8688                            (const_int 8)
8689                            (const_int 8))))
8690    (clobber (reg:CC FLAGS_REG))]
8691   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8692   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8693   [(set_attr "type" "alu")
8694    (set_attr "length_immediate" "0")
8695    (set_attr "mode" "QI")])
8696
8697 (define_split
8698   [(set (match_operand 0 "register_operand" "")
8699         (any_or (match_operand 1 "register_operand" "")
8700                 (match_operand 2 "const_int_operand" "")))
8701    (clobber (reg:CC FLAGS_REG))]
8702    "reload_completed
8703     && QI_REG_P (operands[0])
8704     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8705     && !(INTVAL (operands[2]) & ~(255 << 8))
8706     && GET_MODE (operands[0]) != QImode"
8707   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8708                    (any_or:SI (zero_extract:SI (match_dup 1)
8709                                                (const_int 8) (const_int 8))
8710                               (match_dup 2)))
8711               (clobber (reg:CC FLAGS_REG))])]
8712   "operands[0] = gen_lowpart (SImode, operands[0]);
8713    operands[1] = gen_lowpart (SImode, operands[1]);
8714    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8715
8716 ;; Since OR can be encoded with sign extended immediate, this is only
8717 ;; profitable when 7th bit is set.
8718 (define_split
8719   [(set (match_operand 0 "register_operand" "")
8720         (any_or (match_operand 1 "general_operand" "")
8721                 (match_operand 2 "const_int_operand" "")))
8722    (clobber (reg:CC FLAGS_REG))]
8723    "reload_completed
8724     && ANY_QI_REG_P (operands[0])
8725     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8726     && !(INTVAL (operands[2]) & ~255)
8727     && (INTVAL (operands[2]) & 128)
8728     && GET_MODE (operands[0]) != QImode"
8729   [(parallel [(set (strict_low_part (match_dup 0))
8730                    (any_or:QI (match_dup 1)
8731                               (match_dup 2)))
8732               (clobber (reg:CC FLAGS_REG))])]
8733   "operands[0] = gen_lowpart (QImode, operands[0]);
8734    operands[1] = gen_lowpart (QImode, operands[1]);
8735    operands[2] = gen_lowpart (QImode, operands[2]);")
8736
8737 (define_expand "xorqi_cc_ext_1"
8738   [(parallel [
8739      (set (reg:CCNO FLAGS_REG)
8740           (compare:CCNO
8741             (xor:SI
8742               (zero_extract:SI
8743                 (match_operand 1 "ext_register_operand" "")
8744                 (const_int 8)
8745                 (const_int 8))
8746               (match_operand:QI 2 "general_operand" ""))
8747             (const_int 0)))
8748      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8749                            (const_int 8)
8750                            (const_int 8))
8751           (xor:SI
8752             (zero_extract:SI
8753              (match_dup 1)
8754              (const_int 8)
8755              (const_int 8))
8756             (match_dup 2)))])]
8757   ""
8758   "")
8759
8760 (define_insn "*xorqi_cc_ext_1_rex64"
8761   [(set (reg FLAGS_REG)
8762         (compare
8763           (xor:SI
8764             (zero_extract:SI
8765               (match_operand 1 "ext_register_operand" "0")
8766               (const_int 8)
8767               (const_int 8))
8768             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8769           (const_int 0)))
8770    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8771                          (const_int 8)
8772                          (const_int 8))
8773         (xor:SI
8774           (zero_extract:SI
8775            (match_dup 1)
8776            (const_int 8)
8777            (const_int 8))
8778           (match_dup 2)))]
8779   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8780   "xor{b}\t{%2, %h0|%h0, %2}"
8781   [(set_attr "type" "alu")
8782    (set_attr "modrm" "1")
8783    (set_attr "mode" "QI")])
8784
8785 (define_insn "*xorqi_cc_ext_1"
8786   [(set (reg FLAGS_REG)
8787         (compare
8788           (xor:SI
8789             (zero_extract:SI
8790               (match_operand 1 "ext_register_operand" "0")
8791               (const_int 8)
8792               (const_int 8))
8793             (match_operand:QI 2 "general_operand" "qmn"))
8794           (const_int 0)))
8795    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8796                          (const_int 8)
8797                          (const_int 8))
8798         (xor:SI
8799           (zero_extract:SI
8800            (match_dup 1)
8801            (const_int 8)
8802            (const_int 8))
8803           (match_dup 2)))]
8804   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8805   "xor{b}\t{%2, %h0|%h0, %2}"
8806   [(set_attr "type" "alu")
8807    (set_attr "modrm" "1")
8808    (set_attr "mode" "QI")])
8809 \f
8810 ;; Negation instructions
8811
8812 (define_expand "neg<mode>2"
8813   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8814         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8815   ""
8816   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8817
8818 (define_insn_and_split "*neg<dwi>2_doubleword"
8819   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8820         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8821    (clobber (reg:CC FLAGS_REG))]
8822   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8823   "#"
8824   "reload_completed"
8825   [(parallel
8826     [(set (reg:CCZ FLAGS_REG)
8827           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8828      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8829    (parallel
8830     [(set (match_dup 2)
8831           (plus:DWIH (match_dup 3)
8832                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8833                                 (const_int 0))))
8834      (clobber (reg:CC FLAGS_REG))])
8835    (parallel
8836     [(set (match_dup 2)
8837           (neg:DWIH (match_dup 2)))
8838      (clobber (reg:CC FLAGS_REG))])]
8839   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8840
8841 (define_insn "*neg<mode>2_1"
8842   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8843         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8844    (clobber (reg:CC FLAGS_REG))]
8845   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8846   "neg{<imodesuffix>}\t%0"
8847   [(set_attr "type" "negnot")
8848    (set_attr "mode" "<MODE>")])
8849
8850 ;; Combine is quite creative about this pattern.
8851 (define_insn "*negsi2_1_zext"
8852   [(set (match_operand:DI 0 "register_operand" "=r")
8853         (lshiftrt:DI
8854           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8855                              (const_int 32)))
8856         (const_int 32)))
8857    (clobber (reg:CC FLAGS_REG))]
8858   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8859   "neg{l}\t%k0"
8860   [(set_attr "type" "negnot")
8861    (set_attr "mode" "SI")])
8862
8863 ;; The problem with neg is that it does not perform (compare x 0),
8864 ;; it really performs (compare 0 x), which leaves us with the zero
8865 ;; flag being the only useful item.
8866
8867 (define_insn "*neg<mode>2_cmpz"
8868   [(set (reg:CCZ FLAGS_REG)
8869         (compare:CCZ
8870           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8871                    (const_int 0)))
8872    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8873         (neg:SWI (match_dup 1)))]
8874   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8875   "neg{<imodesuffix>}\t%0"
8876   [(set_attr "type" "negnot")
8877    (set_attr "mode" "<MODE>")])
8878
8879 (define_insn "*negsi2_cmpz_zext"
8880   [(set (reg:CCZ FLAGS_REG)
8881         (compare:CCZ
8882           (lshiftrt:DI
8883             (neg:DI (ashift:DI
8884                       (match_operand:DI 1 "register_operand" "0")
8885                       (const_int 32)))
8886             (const_int 32))
8887           (const_int 0)))
8888    (set (match_operand:DI 0 "register_operand" "=r")
8889         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8890                                         (const_int 32)))
8891                      (const_int 32)))]
8892   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8893   "neg{l}\t%k0"
8894   [(set_attr "type" "negnot")
8895    (set_attr "mode" "SI")])
8896
8897 ;; Changing of sign for FP values is doable using integer unit too.
8898
8899 (define_expand "<code><mode>2"
8900   [(set (match_operand:X87MODEF 0 "register_operand" "")
8901         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8902   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8903   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8904
8905 (define_insn "*absneg<mode>2_mixed"
8906   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8907         (match_operator:MODEF 3 "absneg_operator"
8908           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8909    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8910    (clobber (reg:CC FLAGS_REG))]
8911   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8912   "#")
8913
8914 (define_insn "*absneg<mode>2_sse"
8915   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8916         (match_operator:MODEF 3 "absneg_operator"
8917           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8918    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8919    (clobber (reg:CC FLAGS_REG))]
8920   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8921   "#")
8922
8923 (define_insn "*absneg<mode>2_i387"
8924   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8925         (match_operator:X87MODEF 3 "absneg_operator"
8926           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8927    (use (match_operand 2 "" ""))
8928    (clobber (reg:CC FLAGS_REG))]
8929   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8930   "#")
8931
8932 (define_expand "<code>tf2"
8933   [(set (match_operand:TF 0 "register_operand" "")
8934         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8935   "TARGET_SSE2"
8936   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8937
8938 (define_insn "*absnegtf2_sse"
8939   [(set (match_operand:TF 0 "register_operand" "=x,x")
8940         (match_operator:TF 3 "absneg_operator"
8941           [(match_operand:TF 1 "register_operand" "0,x")]))
8942    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8943    (clobber (reg:CC FLAGS_REG))]
8944   "TARGET_SSE2"
8945   "#")
8946
8947 ;; Splitters for fp abs and neg.
8948
8949 (define_split
8950   [(set (match_operand 0 "fp_register_operand" "")
8951         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8952    (use (match_operand 2 "" ""))
8953    (clobber (reg:CC FLAGS_REG))]
8954   "reload_completed"
8955   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8956
8957 (define_split
8958   [(set (match_operand 0 "register_operand" "")
8959         (match_operator 3 "absneg_operator"
8960           [(match_operand 1 "register_operand" "")]))
8961    (use (match_operand 2 "nonimmediate_operand" ""))
8962    (clobber (reg:CC FLAGS_REG))]
8963   "reload_completed && SSE_REG_P (operands[0])"
8964   [(set (match_dup 0) (match_dup 3))]
8965 {
8966   enum machine_mode mode = GET_MODE (operands[0]);
8967   enum machine_mode vmode = GET_MODE (operands[2]);
8968   rtx tmp;
8969
8970   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8971   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8972   if (operands_match_p (operands[0], operands[2]))
8973     {
8974       tmp = operands[1];
8975       operands[1] = operands[2];
8976       operands[2] = tmp;
8977     }
8978   if (GET_CODE (operands[3]) == ABS)
8979     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8980   else
8981     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8982   operands[3] = tmp;
8983 })
8984
8985 (define_split
8986   [(set (match_operand:SF 0 "register_operand" "")
8987         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8988    (use (match_operand:V4SF 2 "" ""))
8989    (clobber (reg:CC FLAGS_REG))]
8990   "reload_completed"
8991   [(parallel [(set (match_dup 0) (match_dup 1))
8992               (clobber (reg:CC FLAGS_REG))])]
8993 {
8994   rtx tmp;
8995   operands[0] = gen_lowpart (SImode, operands[0]);
8996   if (GET_CODE (operands[1]) == ABS)
8997     {
8998       tmp = gen_int_mode (0x7fffffff, SImode);
8999       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9000     }
9001   else
9002     {
9003       tmp = gen_int_mode (0x80000000, SImode);
9004       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9005     }
9006   operands[1] = tmp;
9007 })
9008
9009 (define_split
9010   [(set (match_operand:DF 0 "register_operand" "")
9011         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9012    (use (match_operand 2 "" ""))
9013    (clobber (reg:CC FLAGS_REG))]
9014   "reload_completed"
9015   [(parallel [(set (match_dup 0) (match_dup 1))
9016               (clobber (reg:CC FLAGS_REG))])]
9017 {
9018   rtx tmp;
9019   if (TARGET_64BIT)
9020     {
9021       tmp = gen_lowpart (DImode, operands[0]);
9022       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9023       operands[0] = tmp;
9024
9025       if (GET_CODE (operands[1]) == ABS)
9026         tmp = const0_rtx;
9027       else
9028         tmp = gen_rtx_NOT (DImode, tmp);
9029     }
9030   else
9031     {
9032       operands[0] = gen_highpart (SImode, operands[0]);
9033       if (GET_CODE (operands[1]) == ABS)
9034         {
9035           tmp = gen_int_mode (0x7fffffff, SImode);
9036           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9037         }
9038       else
9039         {
9040           tmp = gen_int_mode (0x80000000, SImode);
9041           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9042         }
9043     }
9044   operands[1] = tmp;
9045 })
9046
9047 (define_split
9048   [(set (match_operand:XF 0 "register_operand" "")
9049         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9050    (use (match_operand 2 "" ""))
9051    (clobber (reg:CC FLAGS_REG))]
9052   "reload_completed"
9053   [(parallel [(set (match_dup 0) (match_dup 1))
9054               (clobber (reg:CC FLAGS_REG))])]
9055 {
9056   rtx tmp;
9057   operands[0] = gen_rtx_REG (SImode,
9058                              true_regnum (operands[0])
9059                              + (TARGET_64BIT ? 1 : 2));
9060   if (GET_CODE (operands[1]) == ABS)
9061     {
9062       tmp = GEN_INT (0x7fff);
9063       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9064     }
9065   else
9066     {
9067       tmp = GEN_INT (0x8000);
9068       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9069     }
9070   operands[1] = tmp;
9071 })
9072
9073 ;; Conditionalize these after reload. If they match before reload, we
9074 ;; lose the clobber and ability to use integer instructions.
9075
9076 (define_insn "*<code><mode>2_1"
9077   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9078         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9079   "TARGET_80387
9080    && (reload_completed
9081        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9082   "f<absneg_mnemonic>"
9083   [(set_attr "type" "fsgn")
9084    (set_attr "mode" "<MODE>")])
9085
9086 (define_insn "*<code>extendsfdf2"
9087   [(set (match_operand:DF 0 "register_operand" "=f")
9088         (absneg:DF (float_extend:DF
9089                      (match_operand:SF 1 "register_operand" "0"))))]
9090   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9091   "f<absneg_mnemonic>"
9092   [(set_attr "type" "fsgn")
9093    (set_attr "mode" "DF")])
9094
9095 (define_insn "*<code>extendsfxf2"
9096   [(set (match_operand:XF 0 "register_operand" "=f")
9097         (absneg:XF (float_extend:XF
9098                      (match_operand:SF 1 "register_operand" "0"))))]
9099   "TARGET_80387"
9100   "f<absneg_mnemonic>"
9101   [(set_attr "type" "fsgn")
9102    (set_attr "mode" "XF")])
9103
9104 (define_insn "*<code>extenddfxf2"
9105   [(set (match_operand:XF 0 "register_operand" "=f")
9106         (absneg:XF (float_extend:XF
9107                      (match_operand:DF 1 "register_operand" "0"))))]
9108   "TARGET_80387"
9109   "f<absneg_mnemonic>"
9110   [(set_attr "type" "fsgn")
9111    (set_attr "mode" "XF")])
9112
9113 ;; Copysign instructions
9114
9115 (define_mode_iterator CSGNMODE [SF DF TF])
9116 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9117
9118 (define_expand "copysign<mode>3"
9119   [(match_operand:CSGNMODE 0 "register_operand" "")
9120    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9121    (match_operand:CSGNMODE 2 "register_operand" "")]
9122   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9123    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9124 {
9125   ix86_expand_copysign (operands);
9126   DONE;
9127 })
9128
9129 (define_insn_and_split "copysign<mode>3_const"
9130   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9131         (unspec:CSGNMODE
9132           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9133            (match_operand:CSGNMODE 2 "register_operand" "0")
9134            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9135           UNSPEC_COPYSIGN))]
9136   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9137    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9138   "#"
9139   "&& reload_completed"
9140   [(const_int 0)]
9141 {
9142   ix86_split_copysign_const (operands);
9143   DONE;
9144 })
9145
9146 (define_insn "copysign<mode>3_var"
9147   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9148         (unspec:CSGNMODE
9149           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9150            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9151            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9152            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9153           UNSPEC_COPYSIGN))
9154    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9155   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9156    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9157   "#")
9158
9159 (define_split
9160   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9161         (unspec:CSGNMODE
9162           [(match_operand:CSGNMODE 2 "register_operand" "")
9163            (match_operand:CSGNMODE 3 "register_operand" "")
9164            (match_operand:<CSGNVMODE> 4 "" "")
9165            (match_operand:<CSGNVMODE> 5 "" "")]
9166           UNSPEC_COPYSIGN))
9167    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9168   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9169     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9170    && reload_completed"
9171   [(const_int 0)]
9172 {
9173   ix86_split_copysign_var (operands);
9174   DONE;
9175 })
9176 \f
9177 ;; One complement instructions
9178
9179 (define_expand "one_cmpl<mode>2"
9180   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9181         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9182   ""
9183   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9184
9185 (define_insn "*one_cmpl<mode>2_1"
9186   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9187         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9188   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9189   "not{<imodesuffix>}\t%0"
9190   [(set_attr "type" "negnot")
9191    (set_attr "mode" "<MODE>")])
9192
9193 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9194 (define_insn "*one_cmplqi2_1"
9195   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9196         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9197   "ix86_unary_operator_ok (NOT, QImode, operands)"
9198   "@
9199    not{b}\t%0
9200    not{l}\t%k0"
9201   [(set_attr "type" "negnot")
9202    (set_attr "mode" "QI,SI")])
9203
9204 ;; ??? Currently never generated - xor is used instead.
9205 (define_insn "*one_cmplsi2_1_zext"
9206   [(set (match_operand:DI 0 "register_operand" "=r")
9207         (zero_extend:DI
9208           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9209   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9210   "not{l}\t%k0"
9211   [(set_attr "type" "negnot")
9212    (set_attr "mode" "SI")])
9213
9214 (define_insn "*one_cmpl<mode>2_2"
9215   [(set (reg FLAGS_REG)
9216         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9217                  (const_int 0)))
9218    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9219         (not:SWI (match_dup 1)))]
9220   "ix86_match_ccmode (insn, CCNOmode)
9221    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9222   "#"
9223   [(set_attr "type" "alu1")
9224    (set_attr "mode" "<MODE>")])
9225
9226 (define_split
9227   [(set (match_operand 0 "flags_reg_operand" "")
9228         (match_operator 2 "compare_operator"
9229           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9230            (const_int 0)]))
9231    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9232         (not:SWI (match_dup 3)))]
9233   "ix86_match_ccmode (insn, CCNOmode)"
9234   [(parallel [(set (match_dup 0)
9235                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9236                                     (const_int 0)]))
9237               (set (match_dup 1)
9238                    (xor:SWI (match_dup 3) (const_int -1)))])]
9239   "")
9240
9241 ;; ??? Currently never generated - xor is used instead.
9242 (define_insn "*one_cmplsi2_2_zext"
9243   [(set (reg FLAGS_REG)
9244         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9245                  (const_int 0)))
9246    (set (match_operand:DI 0 "register_operand" "=r")
9247         (zero_extend:DI (not:SI (match_dup 1))))]
9248   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9249    && ix86_unary_operator_ok (NOT, SImode, operands)"
9250   "#"
9251   [(set_attr "type" "alu1")
9252    (set_attr "mode" "SI")])
9253
9254 (define_split
9255   [(set (match_operand 0 "flags_reg_operand" "")
9256         (match_operator 2 "compare_operator"
9257           [(not:SI (match_operand:SI 3 "register_operand" ""))
9258            (const_int 0)]))
9259    (set (match_operand:DI 1 "register_operand" "")
9260         (zero_extend:DI (not:SI (match_dup 3))))]
9261   "ix86_match_ccmode (insn, CCNOmode)"
9262   [(parallel [(set (match_dup 0)
9263                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9264                                     (const_int 0)]))
9265               (set (match_dup 1)
9266                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9267   "")
9268 \f
9269 ;; Shift instructions
9270
9271 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9272 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9273 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9274 ;; from the assembler input.
9275 ;;
9276 ;; This instruction shifts the target reg/mem as usual, but instead of
9277 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9278 ;; is a left shift double, bits are taken from the high order bits of
9279 ;; reg, else if the insn is a shift right double, bits are taken from the
9280 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9281 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9282 ;;
9283 ;; Since sh[lr]d does not change the `reg' operand, that is done
9284 ;; separately, making all shifts emit pairs of shift double and normal
9285 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9286 ;; support a 63 bit shift, each shift where the count is in a reg expands
9287 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9288 ;;
9289 ;; If the shift count is a constant, we need never emit more than one
9290 ;; shift pair, instead using moves and sign extension for counts greater
9291 ;; than 31.
9292
9293 (define_expand "ashl<mode>3"
9294   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9295         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9296                       (match_operand:QI 2 "nonmemory_operand" "")))]
9297   ""
9298   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9299
9300 (define_insn "*ashl<mode>3_doubleword"
9301   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9302         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9303                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9304    (clobber (reg:CC FLAGS_REG))]
9305   ""
9306   "#"
9307   [(set_attr "type" "multi")])
9308
9309 (define_split
9310   [(set (match_operand:DWI 0 "register_operand" "")
9311         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9312                     (match_operand:QI 2 "nonmemory_operand" "")))
9313    (clobber (reg:CC FLAGS_REG))]
9314   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9315   [(const_int 0)]
9316   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9317
9318 ;; By default we don't ask for a scratch register, because when DWImode
9319 ;; values are manipulated, registers are already at a premium.  But if
9320 ;; we have one handy, we won't turn it away.
9321
9322 (define_peephole2
9323   [(match_scratch:DWIH 3 "r")
9324    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9325                    (ashift:<DWI>
9326                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9327                      (match_operand:QI 2 "nonmemory_operand" "")))
9328               (clobber (reg:CC FLAGS_REG))])
9329    (match_dup 3)]
9330   "TARGET_CMOVE"
9331   [(const_int 0)]
9332   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9333
9334 (define_insn "x86_64_shld"
9335   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9336         (ior:DI (ashift:DI (match_dup 0)
9337                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9338                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9339                   (minus:QI (const_int 64) (match_dup 2)))))
9340    (clobber (reg:CC FLAGS_REG))]
9341   "TARGET_64BIT"
9342   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9343   [(set_attr "type" "ishift")
9344    (set_attr "prefix_0f" "1")
9345    (set_attr "mode" "DI")
9346    (set_attr "athlon_decode" "vector")
9347    (set_attr "amdfam10_decode" "vector")])
9348
9349 (define_insn "x86_shld"
9350   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9351         (ior:SI (ashift:SI (match_dup 0)
9352                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9353                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9354                   (minus:QI (const_int 32) (match_dup 2)))))
9355    (clobber (reg:CC FLAGS_REG))]
9356   ""
9357   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9358   [(set_attr "type" "ishift")
9359    (set_attr "prefix_0f" "1")
9360    (set_attr "mode" "SI")
9361    (set_attr "pent_pair" "np")
9362    (set_attr "athlon_decode" "vector")
9363    (set_attr "amdfam10_decode" "vector")])
9364
9365 (define_expand "x86_shift<mode>_adj_1"
9366   [(set (reg:CCZ FLAGS_REG)
9367         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9368                              (match_dup 4))
9369                      (const_int 0)))
9370    (set (match_operand:SWI48 0 "register_operand" "")
9371         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9372                             (match_operand:SWI48 1 "register_operand" "")
9373                             (match_dup 0)))
9374    (set (match_dup 1)
9375         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9376                             (match_operand:SWI48 3 "register_operand" "r")
9377                             (match_dup 1)))]
9378   "TARGET_CMOVE"
9379   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9380
9381 (define_expand "x86_shift<mode>_adj_2"
9382   [(use (match_operand:SWI48 0 "register_operand" ""))
9383    (use (match_operand:SWI48 1 "register_operand" ""))
9384    (use (match_operand:QI 2 "register_operand" ""))]
9385   ""
9386 {
9387   rtx label = gen_label_rtx ();
9388   rtx tmp;
9389
9390   emit_insn (gen_testqi_ccz_1 (operands[2],
9391                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9392
9393   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9394   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9395   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9396                               gen_rtx_LABEL_REF (VOIDmode, label),
9397                               pc_rtx);
9398   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9399   JUMP_LABEL (tmp) = label;
9400
9401   emit_move_insn (operands[0], operands[1]);
9402   ix86_expand_clear (operands[1]);
9403
9404   emit_label (label);
9405   LABEL_NUSES (label) = 1;
9406
9407   DONE;
9408 })
9409
9410 (define_insn "*ashl<mode>3_1"
9411   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9412         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9413                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9414    (clobber (reg:CC FLAGS_REG))]
9415   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9416 {
9417   switch (get_attr_type (insn))
9418     {
9419     case TYPE_LEA:
9420       return "#";
9421
9422     case TYPE_ALU:
9423       gcc_assert (operands[2] == const1_rtx);
9424       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9425       return "add{<imodesuffix>}\t%0, %0";
9426
9427     default:
9428       if (operands[2] == const1_rtx
9429           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9430         return "sal{<imodesuffix>}\t%0";
9431       else
9432         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9433     }
9434 }
9435   [(set (attr "type")
9436      (cond [(eq_attr "alternative" "1")
9437               (const_string "lea")
9438             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9439                           (const_int 0))
9440                       (match_operand 0 "register_operand" ""))
9441                  (match_operand 2 "const1_operand" ""))
9442               (const_string "alu")
9443            ]
9444            (const_string "ishift")))
9445    (set (attr "length_immediate")
9446      (if_then_else
9447        (ior (eq_attr "type" "alu")
9448             (and (eq_attr "type" "ishift")
9449                  (and (match_operand 2 "const1_operand" "")
9450                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9451                           (const_int 0)))))
9452        (const_string "0")
9453        (const_string "*")))
9454    (set_attr "mode" "<MODE>")])
9455
9456 (define_insn "*ashlsi3_1_zext"
9457   [(set (match_operand:DI 0 "register_operand" "=r,r")
9458         (zero_extend:DI
9459           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9460                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9461    (clobber (reg:CC FLAGS_REG))]
9462   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9463 {
9464   switch (get_attr_type (insn))
9465     {
9466     case TYPE_LEA:
9467       return "#";
9468
9469     case TYPE_ALU:
9470       gcc_assert (operands[2] == const1_rtx);
9471       return "add{l}\t%k0, %k0";
9472
9473     default:
9474       if (operands[2] == const1_rtx
9475           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9476         return "sal{l}\t%k0";
9477       else
9478         return "sal{l}\t{%2, %k0|%k0, %2}";
9479     }
9480 }
9481   [(set (attr "type")
9482      (cond [(eq_attr "alternative" "1")
9483               (const_string "lea")
9484             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9485                      (const_int 0))
9486                  (match_operand 2 "const1_operand" ""))
9487               (const_string "alu")
9488            ]
9489            (const_string "ishift")))
9490    (set (attr "length_immediate")
9491      (if_then_else
9492        (ior (eq_attr "type" "alu")
9493             (and (eq_attr "type" "ishift")
9494                  (and (match_operand 2 "const1_operand" "")
9495                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9496                           (const_int 0)))))
9497        (const_string "0")
9498        (const_string "*")))
9499    (set_attr "mode" "SI")])
9500
9501 (define_insn "*ashlhi3_1"
9502   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9503         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9504                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9505    (clobber (reg:CC FLAGS_REG))]
9506   "TARGET_PARTIAL_REG_STALL
9507    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9508 {
9509   switch (get_attr_type (insn))
9510     {
9511     case TYPE_ALU:
9512       gcc_assert (operands[2] == const1_rtx);
9513       return "add{w}\t%0, %0";
9514
9515     default:
9516       if (operands[2] == const1_rtx
9517           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9518         return "sal{w}\t%0";
9519       else
9520         return "sal{w}\t{%2, %0|%0, %2}";
9521     }
9522 }
9523   [(set (attr "type")
9524      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9525                           (const_int 0))
9526                       (match_operand 0 "register_operand" ""))
9527                  (match_operand 2 "const1_operand" ""))
9528               (const_string "alu")
9529            ]
9530            (const_string "ishift")))
9531    (set (attr "length_immediate")
9532      (if_then_else
9533        (ior (eq_attr "type" "alu")
9534             (and (eq_attr "type" "ishift")
9535                  (and (match_operand 2 "const1_operand" "")
9536                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9537                           (const_int 0)))))
9538        (const_string "0")
9539        (const_string "*")))
9540    (set_attr "mode" "HI")])
9541
9542 (define_insn "*ashlhi3_1_lea"
9543   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9544         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9545                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9546    (clobber (reg:CC FLAGS_REG))]
9547   "!TARGET_PARTIAL_REG_STALL
9548    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9549 {
9550   switch (get_attr_type (insn))
9551     {
9552     case TYPE_LEA:
9553       return "#";
9554
9555     case TYPE_ALU:
9556       gcc_assert (operands[2] == const1_rtx);
9557       return "add{w}\t%0, %0";
9558
9559     default:
9560       if (operands[2] == const1_rtx
9561           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9562         return "sal{w}\t%0";
9563       else
9564         return "sal{w}\t{%2, %0|%0, %2}";
9565     }
9566 }
9567   [(set (attr "type")
9568      (cond [(eq_attr "alternative" "1")
9569               (const_string "lea")
9570             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9571                           (const_int 0))
9572                       (match_operand 0 "register_operand" ""))
9573                  (match_operand 2 "const1_operand" ""))
9574               (const_string "alu")
9575            ]
9576            (const_string "ishift")))
9577    (set (attr "length_immediate")
9578      (if_then_else
9579        (ior (eq_attr "type" "alu")
9580             (and (eq_attr "type" "ishift")
9581                  (and (match_operand 2 "const1_operand" "")
9582                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9583                           (const_int 0)))))
9584        (const_string "0")
9585        (const_string "*")))
9586    (set_attr "mode" "HI,SI")])
9587
9588 (define_insn "*ashlqi3_1"
9589   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9590         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9591                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9592    (clobber (reg:CC FLAGS_REG))]
9593   "TARGET_PARTIAL_REG_STALL
9594    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9595 {
9596   switch (get_attr_type (insn))
9597     {
9598     case TYPE_ALU:
9599       gcc_assert (operands[2] == const1_rtx);
9600       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9601         return "add{l}\t%k0, %k0";
9602       else
9603         return "add{b}\t%0, %0";
9604
9605     default:
9606       if (operands[2] == const1_rtx
9607           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9608         {
9609           if (get_attr_mode (insn) == MODE_SI)
9610             return "sal{l}\t%k0";
9611           else
9612             return "sal{b}\t%0";
9613         }
9614       else
9615         {
9616           if (get_attr_mode (insn) == MODE_SI)
9617             return "sal{l}\t{%2, %k0|%k0, %2}";
9618           else
9619             return "sal{b}\t{%2, %0|%0, %2}";
9620         }
9621     }
9622 }
9623   [(set (attr "type")
9624      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9625                           (const_int 0))
9626                       (match_operand 0 "register_operand" ""))
9627                  (match_operand 2 "const1_operand" ""))
9628               (const_string "alu")
9629            ]
9630            (const_string "ishift")))
9631    (set (attr "length_immediate")
9632      (if_then_else
9633        (ior (eq_attr "type" "alu")
9634             (and (eq_attr "type" "ishift")
9635                  (and (match_operand 2 "const1_operand" "")
9636                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9637                           (const_int 0)))))
9638        (const_string "0")
9639        (const_string "*")))
9640    (set_attr "mode" "QI,SI")])
9641
9642 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9643 (define_insn "*ashlqi3_1_lea"
9644   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9645         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9646                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9647    (clobber (reg:CC FLAGS_REG))]
9648   "!TARGET_PARTIAL_REG_STALL
9649    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9650 {
9651   switch (get_attr_type (insn))
9652     {
9653     case TYPE_LEA:
9654       return "#";
9655
9656     case TYPE_ALU:
9657       gcc_assert (operands[2] == const1_rtx);
9658       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9659         return "add{l}\t%k0, %k0";
9660       else
9661         return "add{b}\t%0, %0";
9662
9663     default:
9664       if (operands[2] == const1_rtx
9665           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9666         {
9667           if (get_attr_mode (insn) == MODE_SI)
9668             return "sal{l}\t%k0";
9669           else
9670             return "sal{b}\t%0";
9671         }
9672       else
9673         {
9674           if (get_attr_mode (insn) == MODE_SI)
9675             return "sal{l}\t{%2, %k0|%k0, %2}";
9676           else
9677             return "sal{b}\t{%2, %0|%0, %2}";
9678         }
9679     }
9680 }
9681   [(set (attr "type")
9682      (cond [(eq_attr "alternative" "2")
9683               (const_string "lea")
9684             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9685                           (const_int 0))
9686                       (match_operand 0 "register_operand" ""))
9687                  (match_operand 2 "const1_operand" ""))
9688               (const_string "alu")
9689            ]
9690            (const_string "ishift")))
9691    (set (attr "length_immediate")
9692      (if_then_else
9693        (ior (eq_attr "type" "alu")
9694             (and (eq_attr "type" "ishift")
9695                  (and (match_operand 2 "const1_operand" "")
9696                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9697                           (const_int 0)))))
9698        (const_string "0")
9699        (const_string "*")))
9700    (set_attr "mode" "QI,SI,SI")])
9701
9702 (define_insn "*ashlqi3_1_slp"
9703   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9704         (ashift:QI (match_dup 0)
9705                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9706    (clobber (reg:CC FLAGS_REG))]
9707   "(optimize_function_for_size_p (cfun)
9708     || !TARGET_PARTIAL_FLAG_REG_STALL
9709     || (operands[1] == const1_rtx
9710         && (TARGET_SHIFT1
9711             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9712 {
9713   switch (get_attr_type (insn))
9714     {
9715     case TYPE_ALU:
9716       gcc_assert (operands[1] == const1_rtx);
9717       return "add{b}\t%0, %0";
9718
9719     default:
9720       if (operands[1] == const1_rtx
9721           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9722         return "sal{b}\t%0";
9723       else
9724         return "sal{b}\t{%1, %0|%0, %1}";
9725     }
9726 }
9727   [(set (attr "type")
9728      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9729                           (const_int 0))
9730                       (match_operand 0 "register_operand" ""))
9731                  (match_operand 1 "const1_operand" ""))
9732               (const_string "alu")
9733            ]
9734            (const_string "ishift1")))
9735    (set (attr "length_immediate")
9736      (if_then_else
9737        (ior (eq_attr "type" "alu")
9738             (and (eq_attr "type" "ishift1")
9739                  (and (match_operand 1 "const1_operand" "")
9740                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9741                           (const_int 0)))))
9742        (const_string "0")
9743        (const_string "*")))
9744    (set_attr "mode" "QI")])
9745
9746 ;; Convert lea to the lea pattern to avoid flags dependency.
9747 (define_split
9748   [(set (match_operand:DI 0 "register_operand" "")
9749         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9750                    (match_operand:QI 2 "const_int_operand" "")))
9751    (clobber (reg:CC FLAGS_REG))]
9752   "TARGET_64BIT && reload_completed
9753    && true_regnum (operands[0]) != true_regnum (operands[1])"
9754   [(set (match_dup 0)
9755         (mult:DI (match_dup 1)
9756                  (match_dup 2)))]
9757   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9758
9759 ;; Convert lea to the lea pattern to avoid flags dependency.
9760 (define_split
9761   [(set (match_operand 0 "register_operand" "")
9762         (ashift (match_operand 1 "index_register_operand" "")
9763                 (match_operand:QI 2 "const_int_operand" "")))
9764    (clobber (reg:CC FLAGS_REG))]
9765   "reload_completed
9766    && true_regnum (operands[0]) != true_regnum (operands[1])
9767    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9768   [(const_int 0)]
9769 {
9770   rtx pat;
9771   enum machine_mode mode = GET_MODE (operands[0]);
9772
9773   if (GET_MODE_SIZE (mode) < 4)
9774     operands[0] = gen_lowpart (SImode, operands[0]);
9775   if (mode != Pmode)
9776     operands[1] = gen_lowpart (Pmode, operands[1]);
9777   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9778
9779   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9780   if (Pmode != SImode)
9781     pat = gen_rtx_SUBREG (SImode, pat, 0);
9782   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9783   DONE;
9784 })
9785
9786 ;; Rare case of shifting RSP is handled by generating move and shift
9787 (define_split
9788   [(set (match_operand 0 "register_operand" "")
9789         (ashift (match_operand 1 "register_operand" "")
9790                 (match_operand:QI 2 "const_int_operand" "")))
9791    (clobber (reg:CC FLAGS_REG))]
9792   "reload_completed
9793    && true_regnum (operands[0]) != true_regnum (operands[1])"
9794   [(const_int 0)]
9795 {
9796   rtx pat, clob;
9797   emit_move_insn (operands[0], operands[1]);
9798   pat = gen_rtx_SET (VOIDmode, operands[0],
9799                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
9800                                      operands[0], operands[2]));
9801   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9802   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9803   DONE;
9804 })
9805
9806 ;; Convert lea to the lea pattern to avoid flags dependency.
9807 (define_split
9808   [(set (match_operand:DI 0 "register_operand" "")
9809         (zero_extend:DI
9810           (ashift:SI (match_operand:SI 1 "register_operand" "")
9811                      (match_operand:QI 2 "const_int_operand" ""))))
9812    (clobber (reg:CC FLAGS_REG))]
9813   "TARGET_64BIT && reload_completed
9814    && true_regnum (operands[0]) != true_regnum (operands[1])"
9815   [(set (match_dup 0)
9816         (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
9817 {
9818   operands[1] = gen_lowpart (Pmode, operands[1]);
9819   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9820 })
9821
9822 ;; This pattern can't accept a variable shift count, since shifts by
9823 ;; zero don't affect the flags.  We assume that shifts by constant
9824 ;; zero are optimized away.
9825 (define_insn "*ashl<mode>3_cmp"
9826   [(set (reg FLAGS_REG)
9827         (compare
9828           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9829                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9830           (const_int 0)))
9831    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9832         (ashift:SWI (match_dup 1) (match_dup 2)))]
9833   "(optimize_function_for_size_p (cfun)
9834     || !TARGET_PARTIAL_FLAG_REG_STALL
9835     || (operands[2] == const1_rtx
9836         && (TARGET_SHIFT1
9837             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9838    && ix86_match_ccmode (insn, CCGOCmode)
9839    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9840 {
9841   switch (get_attr_type (insn))
9842     {
9843     case TYPE_ALU:
9844       gcc_assert (operands[2] == const1_rtx);
9845       return "add{<imodesuffix>}\t%0, %0";
9846
9847     default:
9848       if (operands[2] == const1_rtx
9849           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9850         return "sal{<imodesuffix>}\t%0";
9851       else
9852         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9853     }
9854 }
9855   [(set (attr "type")
9856      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9857                           (const_int 0))
9858                       (match_operand 0 "register_operand" ""))
9859                  (match_operand 2 "const1_operand" ""))
9860               (const_string "alu")
9861            ]
9862            (const_string "ishift")))
9863    (set (attr "length_immediate")
9864      (if_then_else
9865        (ior (eq_attr "type" "alu")
9866             (and (eq_attr "type" "ishift")
9867                  (and (match_operand 2 "const1_operand" "")
9868                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9869                           (const_int 0)))))
9870        (const_string "0")
9871        (const_string "*")))
9872    (set_attr "mode" "<MODE>")])
9873
9874 (define_insn "*ashlsi3_cmp_zext"
9875   [(set (reg FLAGS_REG)
9876         (compare
9877           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9878                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9879           (const_int 0)))
9880    (set (match_operand:DI 0 "register_operand" "=r")
9881         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9882   "TARGET_64BIT
9883    && (optimize_function_for_size_p (cfun)
9884        || !TARGET_PARTIAL_FLAG_REG_STALL
9885        || (operands[2] == const1_rtx
9886            && (TARGET_SHIFT1
9887                || TARGET_DOUBLE_WITH_ADD)))
9888    && ix86_match_ccmode (insn, CCGOCmode)
9889    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9890 {
9891   switch (get_attr_type (insn))
9892     {
9893     case TYPE_ALU:
9894       gcc_assert (operands[2] == const1_rtx);
9895       return "add{l}\t%k0, %k0";
9896
9897     default:
9898       if (operands[2] == const1_rtx
9899           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9900         return "sal{l}\t%k0";
9901       else
9902         return "sal{l}\t{%2, %k0|%k0, %2}";
9903     }
9904 }
9905   [(set (attr "type")
9906      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9907                      (const_int 0))
9908                  (match_operand 2 "const1_operand" ""))
9909               (const_string "alu")
9910            ]
9911            (const_string "ishift")))
9912    (set (attr "length_immediate")
9913      (if_then_else
9914        (ior (eq_attr "type" "alu")
9915             (and (eq_attr "type" "ishift")
9916                  (and (match_operand 2 "const1_operand" "")
9917                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9918                           (const_int 0)))))
9919        (const_string "0")
9920        (const_string "*")))
9921    (set_attr "mode" "SI")])
9922
9923 (define_insn "*ashl<mode>3_cconly"
9924   [(set (reg FLAGS_REG)
9925         (compare
9926           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9927                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9928           (const_int 0)))
9929    (clobber (match_scratch:SWI 0 "=<r>"))]
9930   "(optimize_function_for_size_p (cfun)
9931     || !TARGET_PARTIAL_FLAG_REG_STALL
9932     || (operands[2] == const1_rtx
9933         && (TARGET_SHIFT1
9934             || TARGET_DOUBLE_WITH_ADD)))
9935    && ix86_match_ccmode (insn, CCGOCmode)
9936    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9937 {
9938   switch (get_attr_type (insn))
9939     {
9940     case TYPE_ALU:
9941       gcc_assert (operands[2] == const1_rtx);
9942       return "add{<imodesuffix>}\t%0, %0";
9943
9944     default:
9945       if (operands[2] == const1_rtx
9946           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9947         return "sal{<imodesuffix>}\t%0";
9948       else
9949         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9950     }
9951 }
9952   [(set (attr "type")
9953      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9954                           (const_int 0))
9955                       (match_operand 0 "register_operand" ""))
9956                  (match_operand 2 "const1_operand" ""))
9957               (const_string "alu")
9958            ]
9959            (const_string "ishift")))
9960    (set (attr "length_immediate")
9961      (if_then_else
9962        (ior (eq_attr "type" "alu")
9963             (and (eq_attr "type" "ishift")
9964                  (and (match_operand 2 "const1_operand" "")
9965                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9966                           (const_int 0)))))
9967        (const_string "0")
9968        (const_string "*")))
9969    (set_attr "mode" "<MODE>")])
9970
9971 ;; See comment above `ashl<mode>3' about how this works.
9972
9973 (define_expand "<shiftrt_insn><mode>3"
9974   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9975         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9976                            (match_operand:QI 2 "nonmemory_operand" "")))]
9977   ""
9978   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9979
9980 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9981   [(set (match_operand:DWI 0 "register_operand" "=r")
9982         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9983                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9984    (clobber (reg:CC FLAGS_REG))]
9985   ""
9986   "#"
9987   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9988   [(const_int 0)]
9989   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9990   [(set_attr "type" "multi")])
9991
9992 ;; By default we don't ask for a scratch register, because when DWImode
9993 ;; values are manipulated, registers are already at a premium.  But if
9994 ;; we have one handy, we won't turn it away.
9995
9996 (define_peephole2
9997   [(match_scratch:DWIH 3 "r")
9998    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9999                    (any_shiftrt:<DWI>
10000                      (match_operand:<DWI> 1 "register_operand" "")
10001                      (match_operand:QI 2 "nonmemory_operand" "")))
10002               (clobber (reg:CC FLAGS_REG))])
10003    (match_dup 3)]
10004   "TARGET_CMOVE"
10005   [(const_int 0)]
10006   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10007
10008 (define_insn "x86_64_shrd"
10009   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10010         (ior:DI (ashiftrt:DI (match_dup 0)
10011                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10012                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10013                   (minus:QI (const_int 64) (match_dup 2)))))
10014    (clobber (reg:CC FLAGS_REG))]
10015   "TARGET_64BIT"
10016   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10017   [(set_attr "type" "ishift")
10018    (set_attr "prefix_0f" "1")
10019    (set_attr "mode" "DI")
10020    (set_attr "athlon_decode" "vector")
10021    (set_attr "amdfam10_decode" "vector")])
10022
10023 (define_insn "x86_shrd"
10024   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10025         (ior:SI (ashiftrt:SI (match_dup 0)
10026                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10027                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10028                   (minus:QI (const_int 32) (match_dup 2)))))
10029    (clobber (reg:CC FLAGS_REG))]
10030   ""
10031   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10032   [(set_attr "type" "ishift")
10033    (set_attr "prefix_0f" "1")
10034    (set_attr "mode" "SI")
10035    (set_attr "pent_pair" "np")
10036    (set_attr "athlon_decode" "vector")
10037    (set_attr "amdfam10_decode" "vector")])
10038
10039 (define_insn "ashrdi3_cvt"
10040   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10041         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10042                      (match_operand:QI 2 "const_int_operand" "")))
10043    (clobber (reg:CC FLAGS_REG))]
10044   "TARGET_64BIT && INTVAL (operands[2]) == 63
10045    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10046    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10047   "@
10048    {cqto|cqo}
10049    sar{q}\t{%2, %0|%0, %2}"
10050   [(set_attr "type" "imovx,ishift")
10051    (set_attr "prefix_0f" "0,*")
10052    (set_attr "length_immediate" "0,*")
10053    (set_attr "modrm" "0,1")
10054    (set_attr "mode" "DI")])
10055
10056 (define_insn "ashrsi3_cvt"
10057   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10058         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10059                      (match_operand:QI 2 "const_int_operand" "")))
10060    (clobber (reg:CC FLAGS_REG))]
10061   "INTVAL (operands[2]) == 31
10062    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10063    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10064   "@
10065    {cltd|cdq}
10066    sar{l}\t{%2, %0|%0, %2}"
10067   [(set_attr "type" "imovx,ishift")
10068    (set_attr "prefix_0f" "0,*")
10069    (set_attr "length_immediate" "0,*")
10070    (set_attr "modrm" "0,1")
10071    (set_attr "mode" "SI")])
10072
10073 (define_insn "*ashrsi3_cvt_zext"
10074   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10075         (zero_extend:DI
10076           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10077                        (match_operand:QI 2 "const_int_operand" ""))))
10078    (clobber (reg:CC FLAGS_REG))]
10079   "TARGET_64BIT && INTVAL (operands[2]) == 31
10080    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10081    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10082   "@
10083    {cltd|cdq}
10084    sar{l}\t{%2, %k0|%k0, %2}"
10085   [(set_attr "type" "imovx,ishift")
10086    (set_attr "prefix_0f" "0,*")
10087    (set_attr "length_immediate" "0,*")
10088    (set_attr "modrm" "0,1")
10089    (set_attr "mode" "SI")])
10090
10091 (define_expand "x86_shift<mode>_adj_3"
10092   [(use (match_operand:SWI48 0 "register_operand" ""))
10093    (use (match_operand:SWI48 1 "register_operand" ""))
10094    (use (match_operand:QI 2 "register_operand" ""))]
10095   ""
10096 {
10097   rtx label = gen_label_rtx ();
10098   rtx tmp;
10099
10100   emit_insn (gen_testqi_ccz_1 (operands[2],
10101                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10102
10103   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10104   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10105   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10106                               gen_rtx_LABEL_REF (VOIDmode, label),
10107                               pc_rtx);
10108   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10109   JUMP_LABEL (tmp) = label;
10110
10111   emit_move_insn (operands[0], operands[1]);
10112   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10113                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10114   emit_label (label);
10115   LABEL_NUSES (label) = 1;
10116
10117   DONE;
10118 })
10119
10120 (define_insn "*<shiftrt_insn><mode>3_1"
10121   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10122         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10123                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10124    (clobber (reg:CC FLAGS_REG))]
10125   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10126 {
10127   if (operands[2] == const1_rtx
10128       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10129     return "<shiftrt>{<imodesuffix>}\t%0";
10130   else
10131     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10132 }
10133   [(set_attr "type" "ishift")
10134    (set (attr "length_immediate")
10135      (if_then_else
10136        (and (match_operand 2 "const1_operand" "")
10137             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10138                 (const_int 0)))
10139        (const_string "0")
10140        (const_string "*")))
10141    (set_attr "mode" "<MODE>")])
10142
10143 (define_insn "*<shiftrt_insn>si3_1_zext"
10144   [(set (match_operand:DI 0 "register_operand" "=r")
10145         (zero_extend:DI
10146           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10147                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
10148    (clobber (reg:CC FLAGS_REG))]
10149   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10150 {
10151   if (operands[2] == const1_rtx
10152       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10153     return "<shiftrt>{l}\t%k0";
10154   else
10155     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10156 }
10157   [(set_attr "type" "ishift")
10158    (set (attr "length_immediate")
10159      (if_then_else
10160        (and (match_operand 2 "const1_operand" "")
10161             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10162                 (const_int 0)))
10163        (const_string "0")
10164        (const_string "*")))
10165    (set_attr "mode" "SI")])
10166
10167 (define_insn "*<shiftrt_insn>qi3_1_slp"
10168   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10169         (any_shiftrt:QI (match_dup 0)
10170                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10171    (clobber (reg:CC FLAGS_REG))]
10172   "(optimize_function_for_size_p (cfun)
10173     || !TARGET_PARTIAL_REG_STALL
10174     || (operands[1] == const1_rtx
10175         && TARGET_SHIFT1))"
10176 {
10177   if (operands[1] == const1_rtx
10178       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10179     return "<shiftrt>{b}\t%0";
10180   else
10181     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10182 }
10183   [(set_attr "type" "ishift1")
10184    (set (attr "length_immediate")
10185      (if_then_else
10186        (and (match_operand 1 "const1_operand" "")
10187             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10188                 (const_int 0)))
10189        (const_string "0")
10190        (const_string "*")))
10191    (set_attr "mode" "QI")])
10192
10193 ;; This pattern can't accept a variable shift count, since shifts by
10194 ;; zero don't affect the flags.  We assume that shifts by constant
10195 ;; zero are optimized away.
10196 (define_insn "*<shiftrt_insn><mode>3_cmp"
10197   [(set (reg FLAGS_REG)
10198         (compare
10199           (any_shiftrt:SWI
10200             (match_operand:SWI 1 "nonimmediate_operand" "0")
10201             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10202           (const_int 0)))
10203    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10204         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10205   "(optimize_function_for_size_p (cfun)
10206     || !TARGET_PARTIAL_FLAG_REG_STALL
10207     || (operands[2] == const1_rtx
10208         && TARGET_SHIFT1))
10209    && ix86_match_ccmode (insn, CCGOCmode)
10210    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10211 {
10212   if (operands[2] == const1_rtx
10213       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10214     return "<shiftrt>{<imodesuffix>}\t%0";
10215   else
10216     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10217 }
10218   [(set_attr "type" "ishift")
10219    (set (attr "length_immediate")
10220      (if_then_else
10221        (and (match_operand 2 "const1_operand" "")
10222             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10223                 (const_int 0)))
10224        (const_string "0")
10225        (const_string "*")))
10226    (set_attr "mode" "<MODE>")])
10227
10228 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10229   [(set (reg FLAGS_REG)
10230         (compare
10231           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10232                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10233           (const_int 0)))
10234    (set (match_operand:DI 0 "register_operand" "=r")
10235         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10236   "TARGET_64BIT
10237    && (optimize_function_for_size_p (cfun)
10238        || !TARGET_PARTIAL_FLAG_REG_STALL
10239        || (operands[2] == const1_rtx
10240            && TARGET_SHIFT1))
10241    && ix86_match_ccmode (insn, CCGOCmode)
10242    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10243 {
10244   if (operands[2] == const1_rtx
10245       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10246     return "<shiftrt>{l}\t%k0";
10247   else
10248     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10249 }
10250   [(set_attr "type" "ishift")
10251    (set (attr "length_immediate")
10252      (if_then_else
10253        (and (match_operand 2 "const1_operand" "")
10254             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10255                 (const_int 0)))
10256        (const_string "0")
10257        (const_string "*")))
10258    (set_attr "mode" "SI")])
10259
10260 (define_insn "*<shiftrt_insn><mode>3_cconly"
10261   [(set (reg FLAGS_REG)
10262         (compare
10263           (any_shiftrt:SWI
10264             (match_operand:SWI 1 "nonimmediate_operand" "0")
10265             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10266           (const_int 0)))
10267    (clobber (match_scratch:SWI 0 "=<r>"))]
10268   "(optimize_function_for_size_p (cfun)
10269     || !TARGET_PARTIAL_FLAG_REG_STALL
10270     || (operands[2] == const1_rtx
10271         && TARGET_SHIFT1))
10272    && ix86_match_ccmode (insn, CCGOCmode)
10273    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10274 {
10275   if (operands[2] == const1_rtx
10276       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10277     return "<shiftrt>{<imodesuffix>}\t%0";
10278   else
10279     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10280 }
10281   [(set_attr "type" "ishift")
10282    (set (attr "length_immediate")
10283      (if_then_else
10284        (and (match_operand 2 "const1_operand" "")
10285             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10286                 (const_int 0)))
10287        (const_string "0")
10288        (const_string "*")))
10289    (set_attr "mode" "<MODE>")])
10290 \f
10291 ;; Rotate instructions
10292
10293 (define_expand "<rotate_insn>ti3"
10294   [(set (match_operand:TI 0 "register_operand" "")
10295         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10296                        (match_operand:QI 2 "nonmemory_operand" "")))]
10297   "TARGET_64BIT"
10298 {
10299   if (const_1_to_63_operand (operands[2], VOIDmode))
10300     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10301                 (operands[0], operands[1], operands[2]));
10302   else
10303     FAIL;
10304
10305   DONE;
10306 })
10307
10308 (define_expand "<rotate_insn>di3"
10309   [(set (match_operand:DI 0 "shiftdi_operand" "")
10310         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10311                        (match_operand:QI 2 "nonmemory_operand" "")))]
10312  ""
10313 {
10314   if (TARGET_64BIT)
10315     ix86_expand_binary_operator (<CODE>, DImode, operands);
10316   else if (const_1_to_31_operand (operands[2], VOIDmode))
10317     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10318                 (operands[0], operands[1], operands[2]));
10319   else
10320     FAIL;
10321
10322   DONE;
10323 })
10324
10325 (define_expand "<rotate_insn><mode>3"
10326   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10327         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10328                             (match_operand:QI 2 "nonmemory_operand" "")))]
10329   ""
10330   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10331
10332 ;; Implement rotation using two double-precision
10333 ;; shift instructions and a scratch register.
10334
10335 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10336  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10337        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10338                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10339   (clobber (reg:CC FLAGS_REG))
10340   (clobber (match_scratch:DWIH 3 "=&r"))]
10341  ""
10342  "#"
10343  "reload_completed"
10344  [(set (match_dup 3) (match_dup 4))
10345   (parallel
10346    [(set (match_dup 4)
10347          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10348                    (lshiftrt:DWIH (match_dup 5)
10349                                   (minus:QI (match_dup 6) (match_dup 2)))))
10350     (clobber (reg:CC FLAGS_REG))])
10351   (parallel
10352    [(set (match_dup 5)
10353          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10354                    (lshiftrt:DWIH (match_dup 3)
10355                                   (minus:QI (match_dup 6) (match_dup 2)))))
10356     (clobber (reg:CC FLAGS_REG))])]
10357 {
10358   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10359
10360   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10361 })
10362
10363 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10364  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10365        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10366                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10367   (clobber (reg:CC FLAGS_REG))
10368   (clobber (match_scratch:DWIH 3 "=&r"))]
10369  ""
10370  "#"
10371  "reload_completed"
10372  [(set (match_dup 3) (match_dup 4))
10373   (parallel
10374    [(set (match_dup 4)
10375          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10376                    (ashift:DWIH (match_dup 5)
10377                                 (minus:QI (match_dup 6) (match_dup 2)))))
10378     (clobber (reg:CC FLAGS_REG))])
10379   (parallel
10380    [(set (match_dup 5)
10381          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10382                    (ashift:DWIH (match_dup 3)
10383                                 (minus:QI (match_dup 6) (match_dup 2)))))
10384     (clobber (reg:CC FLAGS_REG))])]
10385 {
10386   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10387
10388   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10389 })
10390
10391 (define_insn "*<rotate_insn><mode>3_1"
10392   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10393         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10394                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10395    (clobber (reg:CC FLAGS_REG))]
10396   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10397 {
10398   if (operands[2] == const1_rtx
10399       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10400     return "<rotate>{<imodesuffix>}\t%0";
10401   else
10402     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10403 }
10404   [(set_attr "type" "rotate")
10405    (set (attr "length_immediate")
10406      (if_then_else
10407        (and (match_operand 2 "const1_operand" "")
10408             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10409                 (const_int 0)))
10410        (const_string "0")
10411        (const_string "*")))
10412    (set_attr "mode" "<MODE>")])
10413
10414 (define_insn "*<rotate_insn>si3_1_zext"
10415   [(set (match_operand:DI 0 "register_operand" "=r")
10416         (zero_extend:DI
10417           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10418                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10419    (clobber (reg:CC FLAGS_REG))]
10420   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10421 {
10422     if (operands[2] == const1_rtx
10423         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10424     return "<rotate>{l}\t%k0";
10425   else
10426     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10427 }
10428   [(set_attr "type" "rotate")
10429    (set (attr "length_immediate")
10430      (if_then_else
10431        (and (match_operand 2 "const1_operand" "")
10432             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10433                 (const_int 0)))
10434        (const_string "0")
10435        (const_string "*")))
10436    (set_attr "mode" "SI")])
10437
10438 (define_insn "*<rotate_insn>qi3_1_slp"
10439   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10440         (any_rotate:QI (match_dup 0)
10441                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10442    (clobber (reg:CC FLAGS_REG))]
10443   "(optimize_function_for_size_p (cfun)
10444     || !TARGET_PARTIAL_REG_STALL
10445     || (operands[1] == const1_rtx
10446         && TARGET_SHIFT1))"
10447 {
10448   if (operands[1] == const1_rtx
10449       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10450     return "<rotate>{b}\t%0";
10451   else
10452     return "<rotate>{b}\t{%1, %0|%0, %1}";
10453 }
10454   [(set_attr "type" "rotate1")
10455    (set (attr "length_immediate")
10456      (if_then_else
10457        (and (match_operand 1 "const1_operand" "")
10458             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10459                 (const_int 0)))
10460        (const_string "0")
10461        (const_string "*")))
10462    (set_attr "mode" "QI")])
10463
10464 (define_split
10465  [(set (match_operand:HI 0 "register_operand" "")
10466        (any_rotate:HI (match_dup 0) (const_int 8)))
10467   (clobber (reg:CC FLAGS_REG))]
10468  "reload_completed
10469   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10470  [(parallel [(set (strict_low_part (match_dup 0))
10471                   (bswap:HI (match_dup 0)))
10472              (clobber (reg:CC FLAGS_REG))])]
10473  "")
10474 \f
10475 ;; Bit set / bit test instructions
10476
10477 (define_expand "extv"
10478   [(set (match_operand:SI 0 "register_operand" "")
10479         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10480                          (match_operand:SI 2 "const8_operand" "")
10481                          (match_operand:SI 3 "const8_operand" "")))]
10482   ""
10483 {
10484   /* Handle extractions from %ah et al.  */
10485   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10486     FAIL;
10487
10488   /* From mips.md: extract_bit_field doesn't verify that our source
10489      matches the predicate, so check it again here.  */
10490   if (! ext_register_operand (operands[1], VOIDmode))
10491     FAIL;
10492 })
10493
10494 (define_expand "extzv"
10495   [(set (match_operand:SI 0 "register_operand" "")
10496         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10497                          (match_operand:SI 2 "const8_operand" "")
10498                          (match_operand:SI 3 "const8_operand" "")))]
10499   ""
10500 {
10501   /* Handle extractions from %ah et al.  */
10502   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10503     FAIL;
10504
10505   /* From mips.md: extract_bit_field doesn't verify that our source
10506      matches the predicate, so check it again here.  */
10507   if (! ext_register_operand (operands[1], VOIDmode))
10508     FAIL;
10509 })
10510
10511 (define_expand "insv"
10512   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10513                       (match_operand 1 "const8_operand" "")
10514                       (match_operand 2 "const8_operand" ""))
10515         (match_operand 3 "register_operand" ""))]
10516   ""
10517 {
10518   /* Handle insertions to %ah et al.  */
10519   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10520     FAIL;
10521
10522   /* From mips.md: insert_bit_field doesn't verify that our source
10523      matches the predicate, so check it again here.  */
10524   if (! ext_register_operand (operands[0], VOIDmode))
10525     FAIL;
10526
10527   if (TARGET_64BIT)
10528     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10529   else
10530     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10531
10532   DONE;
10533 })
10534
10535 ;; %%% bts, btr, btc, bt.
10536 ;; In general these instructions are *slow* when applied to memory,
10537 ;; since they enforce atomic operation.  When applied to registers,
10538 ;; it depends on the cpu implementation.  They're never faster than
10539 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10540 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10541 ;; within the instruction itself, so operating on bits in the high
10542 ;; 32-bits of a register becomes easier.
10543 ;;
10544 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10545 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10546 ;; negdf respectively, so they can never be disabled entirely.
10547
10548 (define_insn "*btsq"
10549   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10550                          (const_int 1)
10551                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10552         (const_int 1))
10553    (clobber (reg:CC FLAGS_REG))]
10554   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10555   "bts{q}\t{%1, %0|%0, %1}"
10556   [(set_attr "type" "alu1")
10557    (set_attr "prefix_0f" "1")
10558    (set_attr "mode" "DI")])
10559
10560 (define_insn "*btrq"
10561   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10562                          (const_int 1)
10563                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10564         (const_int 0))
10565    (clobber (reg:CC FLAGS_REG))]
10566   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10567   "btr{q}\t{%1, %0|%0, %1}"
10568   [(set_attr "type" "alu1")
10569    (set_attr "prefix_0f" "1")
10570    (set_attr "mode" "DI")])
10571
10572 (define_insn "*btcq"
10573   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10574                          (const_int 1)
10575                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10576         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10577    (clobber (reg:CC FLAGS_REG))]
10578   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10579   "btc{q}\t{%1, %0|%0, %1}"
10580   [(set_attr "type" "alu1")
10581    (set_attr "prefix_0f" "1")
10582    (set_attr "mode" "DI")])
10583
10584 ;; Allow Nocona to avoid these instructions if a register is available.
10585
10586 (define_peephole2
10587   [(match_scratch:DI 2 "r")
10588    (parallel [(set (zero_extract:DI
10589                      (match_operand:DI 0 "register_operand" "")
10590                      (const_int 1)
10591                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10592                    (const_int 1))
10593               (clobber (reg:CC FLAGS_REG))])]
10594   "TARGET_64BIT && !TARGET_USE_BT"
10595   [(const_int 0)]
10596 {
10597   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10598   rtx op1;
10599
10600   if (HOST_BITS_PER_WIDE_INT >= 64)
10601     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10602   else if (i < HOST_BITS_PER_WIDE_INT)
10603     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10604   else
10605     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10606
10607   op1 = immed_double_const (lo, hi, DImode);
10608   if (i >= 31)
10609     {
10610       emit_move_insn (operands[2], op1);
10611       op1 = operands[2];
10612     }
10613
10614   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10615   DONE;
10616 })
10617
10618 (define_peephole2
10619   [(match_scratch:DI 2 "r")
10620    (parallel [(set (zero_extract:DI
10621                      (match_operand:DI 0 "register_operand" "")
10622                      (const_int 1)
10623                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10624                    (const_int 0))
10625               (clobber (reg:CC FLAGS_REG))])]
10626   "TARGET_64BIT && !TARGET_USE_BT"
10627   [(const_int 0)]
10628 {
10629   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10630   rtx op1;
10631
10632   if (HOST_BITS_PER_WIDE_INT >= 64)
10633     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10634   else if (i < HOST_BITS_PER_WIDE_INT)
10635     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10636   else
10637     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10638
10639   op1 = immed_double_const (~lo, ~hi, DImode);
10640   if (i >= 32)
10641     {
10642       emit_move_insn (operands[2], op1);
10643       op1 = operands[2];
10644     }
10645
10646   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10647   DONE;
10648 })
10649
10650 (define_peephole2
10651   [(match_scratch:DI 2 "r")
10652    (parallel [(set (zero_extract:DI
10653                      (match_operand:DI 0 "register_operand" "")
10654                      (const_int 1)
10655                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10656               (not:DI (zero_extract:DI
10657                         (match_dup 0) (const_int 1) (match_dup 1))))
10658               (clobber (reg:CC FLAGS_REG))])]
10659   "TARGET_64BIT && !TARGET_USE_BT"
10660   [(const_int 0)]
10661 {
10662   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10663   rtx op1;
10664
10665   if (HOST_BITS_PER_WIDE_INT >= 64)
10666     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10667   else if (i < HOST_BITS_PER_WIDE_INT)
10668     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10669   else
10670     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10671
10672   op1 = immed_double_const (lo, hi, DImode);
10673   if (i >= 31)
10674     {
10675       emit_move_insn (operands[2], op1);
10676       op1 = operands[2];
10677     }
10678
10679   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10680   DONE;
10681 })
10682
10683 (define_insn "*bt<mode>"
10684   [(set (reg:CCC FLAGS_REG)
10685         (compare:CCC
10686           (zero_extract:SWI48
10687             (match_operand:SWI48 0 "register_operand" "r")
10688             (const_int 1)
10689             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10690           (const_int 0)))]
10691   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10692   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10693   [(set_attr "type" "alu1")
10694    (set_attr "prefix_0f" "1")
10695    (set_attr "mode" "<MODE>")])
10696 \f
10697 ;; Store-flag instructions.
10698
10699 ;; For all sCOND expanders, also expand the compare or test insn that
10700 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10701
10702 (define_insn_and_split "*setcc_di_1"
10703   [(set (match_operand:DI 0 "register_operand" "=q")
10704         (match_operator:DI 1 "ix86_comparison_operator"
10705           [(reg FLAGS_REG) (const_int 0)]))]
10706   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10707   "#"
10708   "&& reload_completed"
10709   [(set (match_dup 2) (match_dup 1))
10710    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10711 {
10712   PUT_MODE (operands[1], QImode);
10713   operands[2] = gen_lowpart (QImode, operands[0]);
10714 })
10715
10716 (define_insn_and_split "*setcc_si_1_and"
10717   [(set (match_operand:SI 0 "register_operand" "=q")
10718         (match_operator:SI 1 "ix86_comparison_operator"
10719           [(reg FLAGS_REG) (const_int 0)]))
10720    (clobber (reg:CC FLAGS_REG))]
10721   "!TARGET_PARTIAL_REG_STALL
10722    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10723   "#"
10724   "&& reload_completed"
10725   [(set (match_dup 2) (match_dup 1))
10726    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10727               (clobber (reg:CC FLAGS_REG))])]
10728 {
10729   PUT_MODE (operands[1], QImode);
10730   operands[2] = gen_lowpart (QImode, operands[0]);
10731 })
10732
10733 (define_insn_and_split "*setcc_si_1_movzbl"
10734   [(set (match_operand:SI 0 "register_operand" "=q")
10735         (match_operator:SI 1 "ix86_comparison_operator"
10736           [(reg FLAGS_REG) (const_int 0)]))]
10737   "!TARGET_PARTIAL_REG_STALL
10738    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10739   "#"
10740   "&& reload_completed"
10741   [(set (match_dup 2) (match_dup 1))
10742    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10743 {
10744   PUT_MODE (operands[1], QImode);
10745   operands[2] = gen_lowpart (QImode, operands[0]);
10746 })
10747
10748 (define_insn "*setcc_qi"
10749   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10750         (match_operator:QI 1 "ix86_comparison_operator"
10751           [(reg FLAGS_REG) (const_int 0)]))]
10752   ""
10753   "set%C1\t%0"
10754   [(set_attr "type" "setcc")
10755    (set_attr "mode" "QI")])
10756
10757 (define_insn "*setcc_qi_slp"
10758   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10759         (match_operator:QI 1 "ix86_comparison_operator"
10760           [(reg FLAGS_REG) (const_int 0)]))]
10761   ""
10762   "set%C1\t%0"
10763   [(set_attr "type" "setcc")
10764    (set_attr "mode" "QI")])
10765
10766 ;; In general it is not safe to assume too much about CCmode registers,
10767 ;; so simplify-rtx stops when it sees a second one.  Under certain
10768 ;; conditions this is safe on x86, so help combine not create
10769 ;;
10770 ;;      seta    %al
10771 ;;      testb   %al, %al
10772 ;;      sete    %al
10773
10774 (define_split
10775   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10776         (ne:QI (match_operator 1 "ix86_comparison_operator"
10777                  [(reg FLAGS_REG) (const_int 0)])
10778             (const_int 0)))]
10779   ""
10780   [(set (match_dup 0) (match_dup 1))]
10781 {
10782   PUT_MODE (operands[1], QImode);
10783 })
10784
10785 (define_split
10786   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10787         (ne:QI (match_operator 1 "ix86_comparison_operator"
10788                  [(reg FLAGS_REG) (const_int 0)])
10789             (const_int 0)))]
10790   ""
10791   [(set (match_dup 0) (match_dup 1))]
10792 {
10793   PUT_MODE (operands[1], QImode);
10794 })
10795
10796 (define_split
10797   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10798         (eq:QI (match_operator 1 "ix86_comparison_operator"
10799                  [(reg FLAGS_REG) (const_int 0)])
10800             (const_int 0)))]
10801   ""
10802   [(set (match_dup 0) (match_dup 1))]
10803 {
10804   rtx new_op1 = copy_rtx (operands[1]);
10805   operands[1] = new_op1;
10806   PUT_MODE (new_op1, QImode);
10807   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10808                                              GET_MODE (XEXP (new_op1, 0))));
10809
10810   /* Make sure that (a) the CCmode we have for the flags is strong
10811      enough for the reversed compare or (b) we have a valid FP compare.  */
10812   if (! ix86_comparison_operator (new_op1, VOIDmode))
10813     FAIL;
10814 })
10815
10816 (define_split
10817   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10818         (eq:QI (match_operator 1 "ix86_comparison_operator"
10819                  [(reg FLAGS_REG) (const_int 0)])
10820             (const_int 0)))]
10821   ""
10822   [(set (match_dup 0) (match_dup 1))]
10823 {
10824   rtx new_op1 = copy_rtx (operands[1]);
10825   operands[1] = new_op1;
10826   PUT_MODE (new_op1, QImode);
10827   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10828                                              GET_MODE (XEXP (new_op1, 0))));
10829
10830   /* Make sure that (a) the CCmode we have for the flags is strong
10831      enough for the reversed compare or (b) we have a valid FP compare.  */
10832   if (! ix86_comparison_operator (new_op1, VOIDmode))
10833     FAIL;
10834 })
10835
10836 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10837 ;; subsequent logical operations are used to imitate conditional moves.
10838 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10839 ;; it directly.
10840
10841 (define_insn "*avx_setcc<mode>"
10842   [(set (match_operand:MODEF 0 "register_operand" "=x")
10843         (match_operator:MODEF 1 "avx_comparison_float_operator"
10844           [(match_operand:MODEF 2 "register_operand" "x")
10845            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10846   "TARGET_AVX"
10847   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10848   [(set_attr "type" "ssecmp")
10849    (set_attr "prefix" "vex")
10850    (set_attr "length_immediate" "1")
10851    (set_attr "mode" "<MODE>")])
10852
10853 (define_insn "*sse_setcc<mode>"
10854   [(set (match_operand:MODEF 0 "register_operand" "=x")
10855         (match_operator:MODEF 1 "sse_comparison_operator"
10856           [(match_operand:MODEF 2 "register_operand" "0")
10857            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10858   "SSE_FLOAT_MODE_P (<MODE>mode)"
10859   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10860   [(set_attr "type" "ssecmp")
10861    (set_attr "length_immediate" "1")
10862    (set_attr "mode" "<MODE>")])
10863 \f
10864 ;; Basic conditional jump instructions.
10865 ;; We ignore the overflow flag for signed branch instructions.
10866
10867 (define_insn "*jcc_1"
10868   [(set (pc)
10869         (if_then_else (match_operator 1 "ix86_comparison_operator"
10870                                       [(reg FLAGS_REG) (const_int 0)])
10871                       (label_ref (match_operand 0 "" ""))
10872                       (pc)))]
10873   ""
10874   "%+j%C1\t%l0"
10875   [(set_attr "type" "ibr")
10876    (set_attr "modrm" "0")
10877    (set (attr "length")
10878            (if_then_else (and (ge (minus (match_dup 0) (pc))
10879                                   (const_int -126))
10880                               (lt (minus (match_dup 0) (pc))
10881                                   (const_int 128)))
10882              (const_int 2)
10883              (const_int 6)))])
10884
10885 (define_insn "*jcc_2"
10886   [(set (pc)
10887         (if_then_else (match_operator 1 "ix86_comparison_operator"
10888                                       [(reg FLAGS_REG) (const_int 0)])
10889                       (pc)
10890                       (label_ref (match_operand 0 "" ""))))]
10891   ""
10892   "%+j%c1\t%l0"
10893   [(set_attr "type" "ibr")
10894    (set_attr "modrm" "0")
10895    (set (attr "length")
10896            (if_then_else (and (ge (minus (match_dup 0) (pc))
10897                                   (const_int -126))
10898                               (lt (minus (match_dup 0) (pc))
10899                                   (const_int 128)))
10900              (const_int 2)
10901              (const_int 6)))])
10902
10903 ;; In general it is not safe to assume too much about CCmode registers,
10904 ;; so simplify-rtx stops when it sees a second one.  Under certain
10905 ;; conditions this is safe on x86, so help combine not create
10906 ;;
10907 ;;      seta    %al
10908 ;;      testb   %al, %al
10909 ;;      je      Lfoo
10910
10911 (define_split
10912   [(set (pc)
10913         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10914                                       [(reg FLAGS_REG) (const_int 0)])
10915                           (const_int 0))
10916                       (label_ref (match_operand 1 "" ""))
10917                       (pc)))]
10918   ""
10919   [(set (pc)
10920         (if_then_else (match_dup 0)
10921                       (label_ref (match_dup 1))
10922                       (pc)))]
10923 {
10924   PUT_MODE (operands[0], VOIDmode);
10925 })
10926
10927 (define_split
10928   [(set (pc)
10929         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10930                                       [(reg FLAGS_REG) (const_int 0)])
10931                           (const_int 0))
10932                       (label_ref (match_operand 1 "" ""))
10933                       (pc)))]
10934   ""
10935   [(set (pc)
10936         (if_then_else (match_dup 0)
10937                       (label_ref (match_dup 1))
10938                       (pc)))]
10939 {
10940   rtx new_op0 = copy_rtx (operands[0]);
10941   operands[0] = new_op0;
10942   PUT_MODE (new_op0, VOIDmode);
10943   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10944                                              GET_MODE (XEXP (new_op0, 0))));
10945
10946   /* Make sure that (a) the CCmode we have for the flags is strong
10947      enough for the reversed compare or (b) we have a valid FP compare.  */
10948   if (! ix86_comparison_operator (new_op0, VOIDmode))
10949     FAIL;
10950 })
10951
10952 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10953 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10954 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10955 ;; appropriate modulo of the bit offset value.
10956
10957 (define_insn_and_split "*jcc_bt<mode>"
10958   [(set (pc)
10959         (if_then_else (match_operator 0 "bt_comparison_operator"
10960                         [(zero_extract:SWI48
10961                            (match_operand:SWI48 1 "register_operand" "r")
10962                            (const_int 1)
10963                            (zero_extend:SI
10964                              (match_operand:QI 2 "register_operand" "r")))
10965                          (const_int 0)])
10966                       (label_ref (match_operand 3 "" ""))
10967                       (pc)))
10968    (clobber (reg:CC FLAGS_REG))]
10969   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10970   "#"
10971   "&& 1"
10972   [(set (reg:CCC FLAGS_REG)
10973         (compare:CCC
10974           (zero_extract:SWI48
10975             (match_dup 1)
10976             (const_int 1)
10977             (match_dup 2))
10978           (const_int 0)))
10979    (set (pc)
10980         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10981                       (label_ref (match_dup 3))
10982                       (pc)))]
10983 {
10984   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10985
10986   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10987 })
10988
10989 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10990 ;; also for DImode, this is what combine produces.
10991 (define_insn_and_split "*jcc_bt<mode>_mask"
10992   [(set (pc)
10993         (if_then_else (match_operator 0 "bt_comparison_operator"
10994                         [(zero_extract:SWI48
10995                            (match_operand:SWI48 1 "register_operand" "r")
10996                            (const_int 1)
10997                            (and:SI
10998                              (match_operand:SI 2 "register_operand" "r")
10999                              (match_operand:SI 3 "const_int_operand" "n")))])
11000                       (label_ref (match_operand 4 "" ""))
11001                       (pc)))
11002    (clobber (reg:CC FLAGS_REG))]
11003   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11004    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11005       == GET_MODE_BITSIZE (<MODE>mode)-1"
11006   "#"
11007   "&& 1"
11008   [(set (reg:CCC FLAGS_REG)
11009         (compare:CCC
11010           (zero_extract:SWI48
11011             (match_dup 1)
11012             (const_int 1)
11013             (match_dup 2))
11014           (const_int 0)))
11015    (set (pc)
11016         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11017                       (label_ref (match_dup 4))
11018                       (pc)))]
11019 {
11020   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11021
11022   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11023 })
11024
11025 (define_insn_and_split "*jcc_btsi_1"
11026   [(set (pc)
11027         (if_then_else (match_operator 0 "bt_comparison_operator"
11028                         [(and:SI
11029                            (lshiftrt:SI
11030                              (match_operand:SI 1 "register_operand" "r")
11031                              (match_operand:QI 2 "register_operand" "r"))
11032                            (const_int 1))
11033                          (const_int 0)])
11034                       (label_ref (match_operand 3 "" ""))
11035                       (pc)))
11036    (clobber (reg:CC FLAGS_REG))]
11037   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11038   "#"
11039   "&& 1"
11040   [(set (reg:CCC FLAGS_REG)
11041         (compare:CCC
11042           (zero_extract:SI
11043             (match_dup 1)
11044             (const_int 1)
11045             (match_dup 2))
11046           (const_int 0)))
11047    (set (pc)
11048         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11049                       (label_ref (match_dup 3))
11050                       (pc)))]
11051 {
11052   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11053
11054   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11055 })
11056
11057 ;; avoid useless masking of bit offset operand
11058 (define_insn_and_split "*jcc_btsi_mask_1"
11059   [(set (pc)
11060         (if_then_else
11061           (match_operator 0 "bt_comparison_operator"
11062             [(and:SI
11063                (lshiftrt:SI
11064                  (match_operand:SI 1 "register_operand" "r")
11065                  (subreg:QI
11066                    (and:SI
11067                      (match_operand:SI 2 "register_operand" "r")
11068                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11069                (const_int 1))
11070              (const_int 0)])
11071           (label_ref (match_operand 4 "" ""))
11072           (pc)))
11073    (clobber (reg:CC FLAGS_REG))]
11074   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11075    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11076   "#"
11077   "&& 1"
11078   [(set (reg:CCC FLAGS_REG)
11079         (compare:CCC
11080           (zero_extract:SI
11081             (match_dup 1)
11082             (const_int 1)
11083             (match_dup 2))
11084           (const_int 0)))
11085    (set (pc)
11086         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11087                       (label_ref (match_dup 4))
11088                       (pc)))]
11089   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11090
11091 ;; Define combination compare-and-branch fp compare instructions to help
11092 ;; combine.
11093
11094 (define_insn "*fp_jcc_3_387"
11095   [(set (pc)
11096         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11097                         [(match_operand 1 "register_operand" "f")
11098                          (match_operand 2 "nonimmediate_operand" "fm")])
11099           (label_ref (match_operand 3 "" ""))
11100           (pc)))
11101    (clobber (reg:CCFP FPSR_REG))
11102    (clobber (reg:CCFP FLAGS_REG))
11103    (clobber (match_scratch:HI 4 "=a"))]
11104   "TARGET_80387
11105    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11106    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11107    && SELECT_CC_MODE (GET_CODE (operands[0]),
11108                       operands[1], operands[2]) == CCFPmode
11109    && !TARGET_CMOVE"
11110   "#")
11111
11112 (define_insn "*fp_jcc_4_387"
11113   [(set (pc)
11114         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11115                         [(match_operand 1 "register_operand" "f")
11116                          (match_operand 2 "nonimmediate_operand" "fm")])
11117           (pc)
11118           (label_ref (match_operand 3 "" ""))))
11119    (clobber (reg:CCFP FPSR_REG))
11120    (clobber (reg:CCFP FLAGS_REG))
11121    (clobber (match_scratch:HI 4 "=a"))]
11122   "TARGET_80387
11123    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11124    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11125    && SELECT_CC_MODE (GET_CODE (operands[0]),
11126                       operands[1], operands[2]) == CCFPmode
11127    && !TARGET_CMOVE"
11128   "#")
11129
11130 (define_insn "*fp_jcc_5_387"
11131   [(set (pc)
11132         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11133                         [(match_operand 1 "register_operand" "f")
11134                          (match_operand 2 "register_operand" "f")])
11135           (label_ref (match_operand 3 "" ""))
11136           (pc)))
11137    (clobber (reg:CCFP FPSR_REG))
11138    (clobber (reg:CCFP FLAGS_REG))
11139    (clobber (match_scratch:HI 4 "=a"))]
11140   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11141    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11142    && !TARGET_CMOVE"
11143   "#")
11144
11145 (define_insn "*fp_jcc_6_387"
11146   [(set (pc)
11147         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11148                         [(match_operand 1 "register_operand" "f")
11149                          (match_operand 2 "register_operand" "f")])
11150           (pc)
11151           (label_ref (match_operand 3 "" ""))))
11152    (clobber (reg:CCFP FPSR_REG))
11153    (clobber (reg:CCFP FLAGS_REG))
11154    (clobber (match_scratch:HI 4 "=a"))]
11155   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11156    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11157    && !TARGET_CMOVE"
11158   "#")
11159
11160 (define_insn "*fp_jcc_7_387"
11161   [(set (pc)
11162         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11163                         [(match_operand 1 "register_operand" "f")
11164                          (match_operand 2 "const0_operand" "")])
11165           (label_ref (match_operand 3 "" ""))
11166           (pc)))
11167    (clobber (reg:CCFP FPSR_REG))
11168    (clobber (reg:CCFP FLAGS_REG))
11169    (clobber (match_scratch:HI 4 "=a"))]
11170   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11171    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11172    && SELECT_CC_MODE (GET_CODE (operands[0]),
11173                       operands[1], operands[2]) == CCFPmode
11174    && !TARGET_CMOVE"
11175   "#")
11176
11177 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11178 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11179 ;; with a precedence over other operators and is always put in the first
11180 ;; place. Swap condition and operands to match ficom instruction.
11181
11182 (define_insn "*fp_jcc_8<mode>_387"
11183   [(set (pc)
11184         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11185                         [(match_operator 1 "float_operator"
11186                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11187                            (match_operand 3 "register_operand" "f,f")])
11188           (label_ref (match_operand 4 "" ""))
11189           (pc)))
11190    (clobber (reg:CCFP FPSR_REG))
11191    (clobber (reg:CCFP FLAGS_REG))
11192    (clobber (match_scratch:HI 5 "=a,a"))]
11193   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11194    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11195    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11196    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11197    && !TARGET_CMOVE"
11198   "#")
11199
11200 (define_split
11201   [(set (pc)
11202         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11203                         [(match_operand 1 "register_operand" "")
11204                          (match_operand 2 "nonimmediate_operand" "")])
11205           (match_operand 3 "" "")
11206           (match_operand 4 "" "")))
11207    (clobber (reg:CCFP FPSR_REG))
11208    (clobber (reg:CCFP FLAGS_REG))]
11209   "reload_completed"
11210   [(const_int 0)]
11211 {
11212   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11213                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11214   DONE;
11215 })
11216
11217 (define_split
11218   [(set (pc)
11219         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11220                         [(match_operand 1 "register_operand" "")
11221                          (match_operand 2 "general_operand" "")])
11222           (match_operand 3 "" "")
11223           (match_operand 4 "" "")))
11224    (clobber (reg:CCFP FPSR_REG))
11225    (clobber (reg:CCFP FLAGS_REG))
11226    (clobber (match_scratch:HI 5 "=a"))]
11227   "reload_completed"
11228   [(const_int 0)]
11229 {
11230   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11231                         operands[3], operands[4], operands[5], NULL_RTX);
11232   DONE;
11233 })
11234
11235 (define_split
11236   [(set (pc)
11237         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11238                         [(match_operator 1 "float_operator"
11239                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
11240                            (match_operand 3 "register_operand" "")])
11241           (match_operand 4 "" "")
11242           (match_operand 5 "" "")))
11243    (clobber (reg:CCFP FPSR_REG))
11244    (clobber (reg:CCFP FLAGS_REG))
11245    (clobber (match_scratch:HI 6 "=a"))]
11246   "reload_completed"
11247   [(const_int 0)]
11248 {
11249   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11250
11251   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11252                         operands[3], operands[7],
11253                         operands[4], operands[5], operands[6], NULL_RTX);
11254   DONE;
11255 })
11256
11257 ;; %%% Kill this when reload knows how to do it.
11258 (define_split
11259   [(set (pc)
11260         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11261                         [(match_operator 1 "float_operator"
11262                            [(match_operand:X87MODEI12 2 "register_operand" "")])
11263                            (match_operand 3 "register_operand" "")])
11264           (match_operand 4 "" "")
11265           (match_operand 5 "" "")))
11266    (clobber (reg:CCFP FPSR_REG))
11267    (clobber (reg:CCFP FLAGS_REG))
11268    (clobber (match_scratch:HI 6 "=a"))]
11269   "reload_completed"
11270   [(const_int 0)]
11271 {
11272   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11273   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11274
11275   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11276                         operands[3], operands[7],
11277                         operands[4], operands[5], operands[6], operands[2]);
11278   DONE;
11279 })
11280 \f
11281 ;; Unconditional and other jump instructions
11282
11283 (define_insn "jump"
11284   [(set (pc)
11285         (label_ref (match_operand 0 "" "")))]
11286   ""
11287   "jmp\t%l0"
11288   [(set_attr "type" "ibr")
11289    (set (attr "length")
11290            (if_then_else (and (ge (minus (match_dup 0) (pc))
11291                                   (const_int -126))
11292                               (lt (minus (match_dup 0) (pc))
11293                                   (const_int 128)))
11294              (const_int 2)
11295              (const_int 5)))
11296    (set_attr "modrm" "0")])
11297
11298 (define_expand "indirect_jump"
11299   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11300   ""
11301   "")
11302
11303 (define_insn "*indirect_jump"
11304   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11305   ""
11306   "jmp\t%A0"
11307   [(set_attr "type" "ibr")
11308    (set_attr "length_immediate" "0")])
11309
11310 (define_expand "tablejump"
11311   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11312               (use (label_ref (match_operand 1 "" "")))])]
11313   ""
11314 {
11315   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11316      relative.  Convert the relative address to an absolute address.  */
11317   if (flag_pic)
11318     {
11319       rtx op0, op1;
11320       enum rtx_code code;
11321
11322       /* We can't use @GOTOFF for text labels on VxWorks;
11323          see gotoff_operand.  */
11324       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11325         {
11326           code = PLUS;
11327           op0 = operands[0];
11328           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11329         }
11330       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11331         {
11332           code = PLUS;
11333           op0 = operands[0];
11334           op1 = pic_offset_table_rtx;
11335         }
11336       else
11337         {
11338           code = MINUS;
11339           op0 = pic_offset_table_rtx;
11340           op1 = operands[0];
11341         }
11342
11343       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11344                                          OPTAB_DIRECT);
11345     }
11346 })
11347
11348 (define_insn "*tablejump_1"
11349   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11350    (use (label_ref (match_operand 1 "" "")))]
11351   ""
11352   "jmp\t%A0"
11353   [(set_attr "type" "ibr")
11354    (set_attr "length_immediate" "0")])
11355 \f
11356 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11357
11358 (define_peephole2
11359   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11360    (set (match_operand:QI 1 "register_operand" "")
11361         (match_operator:QI 2 "ix86_comparison_operator"
11362           [(reg FLAGS_REG) (const_int 0)]))
11363    (set (match_operand 3 "q_regs_operand" "")
11364         (zero_extend (match_dup 1)))]
11365   "(peep2_reg_dead_p (3, operands[1])
11366     || operands_match_p (operands[1], operands[3]))
11367    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11368   [(set (match_dup 4) (match_dup 0))
11369    (set (strict_low_part (match_dup 5))
11370         (match_dup 2))]
11371 {
11372   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11373   operands[5] = gen_lowpart (QImode, operands[3]);
11374   ix86_expand_clear (operands[3]);
11375 })
11376
11377 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11378
11379 (define_peephole2
11380   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11381    (set (match_operand:QI 1 "register_operand" "")
11382         (match_operator:QI 2 "ix86_comparison_operator"
11383           [(reg FLAGS_REG) (const_int 0)]))
11384    (parallel [(set (match_operand 3 "q_regs_operand" "")
11385                    (zero_extend (match_dup 1)))
11386               (clobber (reg:CC FLAGS_REG))])]
11387   "(peep2_reg_dead_p (3, operands[1])
11388     || operands_match_p (operands[1], operands[3]))
11389    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11390   [(set (match_dup 4) (match_dup 0))
11391    (set (strict_low_part (match_dup 5))
11392         (match_dup 2))]
11393 {
11394   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11395   operands[5] = gen_lowpart (QImode, operands[3]);
11396   ix86_expand_clear (operands[3]);
11397 })
11398 \f
11399 ;; Call instructions.
11400
11401 ;; The predicates normally associated with named expanders are not properly
11402 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11403 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11404
11405 ;; P6 processors will jump to the address after the decrement when %esp
11406 ;; is used as a call operand, so they will execute return address as a code.
11407 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11408  
11409 ;; Call subroutine returning no value.
11410
11411 (define_expand "call_pop"
11412   [(parallel [(call (match_operand:QI 0 "" "")
11413                     (match_operand:SI 1 "" ""))
11414               (set (reg:SI SP_REG)
11415                    (plus:SI (reg:SI SP_REG)
11416                             (match_operand:SI 3 "" "")))])]
11417   "!TARGET_64BIT"
11418 {
11419   ix86_expand_call (NULL, operands[0], operands[1],
11420                     operands[2], operands[3], 0);
11421   DONE;
11422 })
11423
11424 (define_insn "*call_pop_0"
11425   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11426          (match_operand:SI 1 "" ""))
11427    (set (reg:SI SP_REG)
11428         (plus:SI (reg:SI SP_REG)
11429                  (match_operand:SI 2 "immediate_operand" "")))]
11430   "!TARGET_64BIT"
11431 {
11432   if (SIBLING_CALL_P (insn))
11433     return "jmp\t%P0";
11434   else
11435     return "call\t%P0";
11436 }
11437   [(set_attr "type" "call")])
11438
11439 (define_insn "*call_pop_1"
11440   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11441          (match_operand:SI 1 "" ""))
11442    (set (reg:SI SP_REG)
11443         (plus:SI (reg:SI SP_REG)
11444                  (match_operand:SI 2 "immediate_operand" "i")))]
11445   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11446 {
11447   if (constant_call_address_operand (operands[0], Pmode))
11448     return "call\t%P0";
11449   return "call\t%A0";
11450 }
11451   [(set_attr "type" "call")])
11452
11453 (define_insn "*sibcall_pop_1"
11454   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11455          (match_operand:SI 1 "" ""))
11456    (set (reg:SI SP_REG)
11457         (plus:SI (reg:SI SP_REG)
11458                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11459   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11460   "@
11461    jmp\t%P0
11462    jmp\t%A0"
11463   [(set_attr "type" "call")])
11464
11465 (define_expand "call"
11466   [(call (match_operand:QI 0 "" "")
11467          (match_operand 1 "" ""))
11468    (use (match_operand 2 "" ""))]
11469   ""
11470 {
11471   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11472   DONE;
11473 })
11474
11475 (define_expand "sibcall"
11476   [(call (match_operand:QI 0 "" "")
11477          (match_operand 1 "" ""))
11478    (use (match_operand 2 "" ""))]
11479   ""
11480 {
11481   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11482   DONE;
11483 })
11484
11485 (define_insn "*call_0"
11486   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11487          (match_operand 1 "" ""))]
11488   ""
11489 {
11490   if (SIBLING_CALL_P (insn))
11491     return "jmp\t%P0";
11492   else
11493     return "call\t%P0";
11494 }
11495   [(set_attr "type" "call")])
11496
11497 (define_insn "*call_1"
11498   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11499          (match_operand 1 "" ""))]
11500   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11501 {
11502   if (constant_call_address_operand (operands[0], Pmode))
11503     return "call\t%P0";
11504   return "call\t%A0";
11505 }
11506   [(set_attr "type" "call")])
11507
11508 (define_insn "*sibcall_1"
11509   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11510          (match_operand 1 "" ""))]
11511   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11512   "@
11513    jmp\t%P0
11514    jmp\t%A0"
11515   [(set_attr "type" "call")])
11516
11517 (define_insn "*call_1_rex64"
11518   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11519          (match_operand 1 "" ""))]
11520   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11521    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11522 {
11523   if (constant_call_address_operand (operands[0], Pmode))
11524     return "call\t%P0";
11525   return "call\t%A0";
11526 }
11527   [(set_attr "type" "call")])
11528
11529 (define_insn "*call_1_rex64_ms_sysv"
11530   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11531          (match_operand 1 "" ""))
11532    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11533    (clobber (reg:TI XMM6_REG))
11534    (clobber (reg:TI XMM7_REG))
11535    (clobber (reg:TI XMM8_REG))
11536    (clobber (reg:TI XMM9_REG))
11537    (clobber (reg:TI XMM10_REG))
11538    (clobber (reg:TI XMM11_REG))
11539    (clobber (reg:TI XMM12_REG))
11540    (clobber (reg:TI XMM13_REG))
11541    (clobber (reg:TI XMM14_REG))
11542    (clobber (reg:TI XMM15_REG))
11543    (clobber (reg:DI SI_REG))
11544    (clobber (reg:DI DI_REG))]
11545   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11546 {
11547   if (constant_call_address_operand (operands[0], Pmode))
11548     return "call\t%P0";
11549   return "call\t%A0";
11550 }
11551   [(set_attr "type" "call")])
11552
11553 (define_insn "*call_1_rex64_large"
11554   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11555          (match_operand 1 "" ""))]
11556   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11557   "call\t%A0"
11558   [(set_attr "type" "call")])
11559
11560 (define_insn "*sibcall_1_rex64"
11561   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11562          (match_operand 1 "" ""))]
11563   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11564   "@
11565    jmp\t%P0
11566    jmp\t%A0"
11567   [(set_attr "type" "call")])
11568
11569 ;; Call subroutine, returning value in operand 0
11570 (define_expand "call_value_pop"
11571   [(parallel [(set (match_operand 0 "" "")
11572                    (call (match_operand:QI 1 "" "")
11573                          (match_operand:SI 2 "" "")))
11574               (set (reg:SI SP_REG)
11575                    (plus:SI (reg:SI SP_REG)
11576                             (match_operand:SI 4 "" "")))])]
11577   "!TARGET_64BIT"
11578 {
11579   ix86_expand_call (operands[0], operands[1], operands[2],
11580                     operands[3], operands[4], 0);
11581   DONE;
11582 })
11583
11584 (define_expand "call_value"
11585   [(set (match_operand 0 "" "")
11586         (call (match_operand:QI 1 "" "")
11587               (match_operand:SI 2 "" "")))
11588    (use (match_operand:SI 3 "" ""))]
11589   ;; Operand 3 is not used on the i386.
11590   ""
11591 {
11592   ix86_expand_call (operands[0], operands[1], operands[2],
11593                     operands[3], NULL, 0);
11594   DONE;
11595 })
11596
11597 (define_expand "sibcall_value"
11598   [(set (match_operand 0 "" "")
11599         (call (match_operand:QI 1 "" "")
11600               (match_operand:SI 2 "" "")))
11601    (use (match_operand:SI 3 "" ""))]
11602   ;; Operand 3 is not used on the i386.
11603   ""
11604 {
11605   ix86_expand_call (operands[0], operands[1], operands[2],
11606                     operands[3], NULL, 1);
11607   DONE;
11608 })
11609
11610 ;; Call subroutine returning any type.
11611
11612 (define_expand "untyped_call"
11613   [(parallel [(call (match_operand 0 "" "")
11614                     (const_int 0))
11615               (match_operand 1 "" "")
11616               (match_operand 2 "" "")])]
11617   ""
11618 {
11619   int i;
11620
11621   /* In order to give reg-stack an easier job in validating two
11622      coprocessor registers as containing a possible return value,
11623      simply pretend the untyped call returns a complex long double
11624      value. 
11625
11626      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11627      and should have the default ABI.  */
11628
11629   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11630                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11631                     operands[0], const0_rtx,
11632                     GEN_INT ((TARGET_64BIT
11633                               ? (ix86_abi == SYSV_ABI
11634                                  ? X86_64_SSE_REGPARM_MAX
11635                                  : X86_64_MS_SSE_REGPARM_MAX)
11636                               : X86_32_SSE_REGPARM_MAX)
11637                              - 1),
11638                     NULL, 0);
11639
11640   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11641     {
11642       rtx set = XVECEXP (operands[2], 0, i);
11643       emit_move_insn (SET_DEST (set), SET_SRC (set));
11644     }
11645
11646   /* The optimizer does not know that the call sets the function value
11647      registers we stored in the result block.  We avoid problems by
11648      claiming that all hard registers are used and clobbered at this
11649      point.  */
11650   emit_insn (gen_blockage ());
11651
11652   DONE;
11653 })
11654 \f
11655 ;; Prologue and epilogue instructions
11656
11657 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11658 ;; all of memory.  This blocks insns from being moved across this point.
11659
11660 (define_insn "blockage"
11661   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11662   ""
11663   ""
11664   [(set_attr "length" "0")])
11665
11666 ;; Do not schedule instructions accessing memory across this point.
11667
11668 (define_expand "memory_blockage"
11669   [(set (match_dup 0)
11670         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11671   ""
11672 {
11673   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11674   MEM_VOLATILE_P (operands[0]) = 1;
11675 })
11676
11677 (define_insn "*memory_blockage"
11678   [(set (match_operand:BLK 0 "" "")
11679         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11680   ""
11681   ""
11682   [(set_attr "length" "0")])
11683
11684 ;; As USE insns aren't meaningful after reload, this is used instead
11685 ;; to prevent deleting instructions setting registers for PIC code
11686 (define_insn "prologue_use"
11687   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11688   ""
11689   ""
11690   [(set_attr "length" "0")])
11691
11692 ;; Insn emitted into the body of a function to return from a function.
11693 ;; This is only done if the function's epilogue is known to be simple.
11694 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11695
11696 (define_expand "return"
11697   [(return)]
11698   "ix86_can_use_return_insn_p ()"
11699 {
11700   if (crtl->args.pops_args)
11701     {
11702       rtx popc = GEN_INT (crtl->args.pops_args);
11703       emit_jump_insn (gen_return_pop_internal (popc));
11704       DONE;
11705     }
11706 })
11707
11708 (define_insn "return_internal"
11709   [(return)]
11710   "reload_completed"
11711   "ret"
11712   [(set_attr "length" "1")
11713    (set_attr "atom_unit" "jeu")
11714    (set_attr "length_immediate" "0")
11715    (set_attr "modrm" "0")])
11716
11717 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11718 ;; instruction Athlon and K8 have.
11719
11720 (define_insn "return_internal_long"
11721   [(return)
11722    (unspec [(const_int 0)] UNSPEC_REP)]
11723   "reload_completed"
11724   "rep\;ret"
11725   [(set_attr "length" "2")
11726    (set_attr "atom_unit" "jeu")
11727    (set_attr "length_immediate" "0")
11728    (set_attr "prefix_rep" "1")
11729    (set_attr "modrm" "0")])
11730
11731 (define_insn "return_pop_internal"
11732   [(return)
11733    (use (match_operand:SI 0 "const_int_operand" ""))]
11734   "reload_completed"
11735   "ret\t%0"
11736   [(set_attr "length" "3")
11737    (set_attr "atom_unit" "jeu")
11738    (set_attr "length_immediate" "2")
11739    (set_attr "modrm" "0")])
11740
11741 (define_insn "return_indirect_internal"
11742   [(return)
11743    (use (match_operand:SI 0 "register_operand" "r"))]
11744   "reload_completed"
11745   "jmp\t%A0"
11746   [(set_attr "type" "ibr")
11747    (set_attr "length_immediate" "0")])
11748
11749 (define_insn "nop"
11750   [(const_int 0)]
11751   ""
11752   "nop"
11753   [(set_attr "length" "1")
11754    (set_attr "length_immediate" "0")
11755    (set_attr "modrm" "0")])
11756
11757 (define_insn "vswapmov"
11758   [(set (match_operand:SI 0 "register_operand" "=r")
11759         (match_operand:SI 1 "register_operand" "r"))
11760    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
11761   ""
11762   "movl.s\t{%1, %0|%0, %1}"
11763   [(set_attr "length" "2")
11764    (set_attr "length_immediate" "0")
11765    (set_attr "modrm" "0")])
11766
11767 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11768 ;; branch prediction penalty for the third jump in a 16-byte
11769 ;; block on K8.
11770
11771 (define_insn "pad"
11772   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11773   ""
11774 {
11775 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11776   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11777 #else
11778   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11779      The align insn is used to avoid 3 jump instructions in the row to improve
11780      branch prediction and the benefits hardly outweigh the cost of extra 8
11781      nops on the average inserted by full alignment pseudo operation.  */
11782 #endif
11783   return "";
11784 }
11785   [(set_attr "length" "16")])
11786
11787 (define_expand "prologue"
11788   [(const_int 0)]
11789   ""
11790   "ix86_expand_prologue (); DONE;")
11791
11792 (define_insn "set_got"
11793   [(set (match_operand:SI 0 "register_operand" "=r")
11794         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11795    (clobber (reg:CC FLAGS_REG))]
11796   "!TARGET_64BIT"
11797   { return output_set_got (operands[0], NULL_RTX); }
11798   [(set_attr "type" "multi")
11799    (set_attr "length" "12")])
11800
11801 (define_insn "set_got_labelled"
11802   [(set (match_operand:SI 0 "register_operand" "=r")
11803         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11804          UNSPEC_SET_GOT))
11805    (clobber (reg:CC FLAGS_REG))]
11806   "!TARGET_64BIT"
11807   { return output_set_got (operands[0], operands[1]); }
11808   [(set_attr "type" "multi")
11809    (set_attr "length" "12")])
11810
11811 (define_insn "set_got_rex64"
11812   [(set (match_operand:DI 0 "register_operand" "=r")
11813         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11814   "TARGET_64BIT"
11815   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11816   [(set_attr "type" "lea")
11817    (set_attr "length_address" "4")
11818    (set_attr "mode" "DI")])
11819
11820 (define_insn "set_rip_rex64"
11821   [(set (match_operand:DI 0 "register_operand" "=r")
11822         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11823   "TARGET_64BIT"
11824   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11825   [(set_attr "type" "lea")
11826    (set_attr "length_address" "4")
11827    (set_attr "mode" "DI")])
11828
11829 (define_insn "set_got_offset_rex64"
11830   [(set (match_operand:DI 0 "register_operand" "=r")
11831         (unspec:DI
11832           [(label_ref (match_operand 1 "" ""))]
11833           UNSPEC_SET_GOT_OFFSET))]
11834   "TARGET_64BIT"
11835   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11836   [(set_attr "type" "imov")
11837    (set_attr "length_immediate" "0")
11838    (set_attr "length_address" "8")
11839    (set_attr "mode" "DI")])
11840
11841 (define_expand "epilogue"
11842   [(const_int 0)]
11843   ""
11844   "ix86_expand_epilogue (1); DONE;")
11845
11846 (define_expand "sibcall_epilogue"
11847   [(const_int 0)]
11848   ""
11849   "ix86_expand_epilogue (0); DONE;")
11850
11851 (define_expand "eh_return"
11852   [(use (match_operand 0 "register_operand" ""))]
11853   ""
11854 {
11855   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11856
11857   /* Tricky bit: we write the address of the handler to which we will
11858      be returning into someone else's stack frame, one word below the
11859      stack address we wish to restore.  */
11860   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11861   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11862   tmp = gen_rtx_MEM (Pmode, tmp);
11863   emit_move_insn (tmp, ra);
11864
11865   emit_jump_insn (gen_eh_return_internal ());
11866   emit_barrier ();
11867   DONE;
11868 })
11869
11870 (define_insn_and_split "eh_return_internal"
11871   [(eh_return)]
11872   ""
11873   "#"
11874   "epilogue_completed"
11875   [(const_int 0)]
11876   "ix86_expand_epilogue (2); DONE;")
11877
11878 (define_insn "leave"
11879   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11880    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11881    (clobber (mem:BLK (scratch)))]
11882   "!TARGET_64BIT"
11883   "leave"
11884   [(set_attr "type" "leave")])
11885
11886 (define_insn "leave_rex64"
11887   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11888    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11889    (clobber (mem:BLK (scratch)))]
11890   "TARGET_64BIT"
11891   "leave"
11892   [(set_attr "type" "leave")])
11893 \f
11894 ;; Bit manipulation instructions.
11895
11896 (define_expand "ffs<mode>2"
11897   [(set (match_dup 2) (const_int -1))
11898    (parallel [(set (reg:CCZ FLAGS_REG)
11899                    (compare:CCZ
11900                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11901                      (const_int 0)))
11902               (set (match_operand:SWI48 0 "register_operand" "")
11903                    (ctz:SWI48 (match_dup 1)))])
11904    (set (match_dup 0) (if_then_else:SWI48
11905                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11906                         (match_dup 2)
11907                         (match_dup 0)))
11908    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11909               (clobber (reg:CC FLAGS_REG))])]
11910   ""
11911 {
11912   if (<MODE>mode == SImode && !TARGET_CMOVE)
11913     {
11914       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11915       DONE;
11916     }
11917   operands[2] = gen_reg_rtx (<MODE>mode);
11918 })
11919
11920 (define_insn_and_split "ffssi2_no_cmove"
11921   [(set (match_operand:SI 0 "register_operand" "=r")
11922         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11923    (clobber (match_scratch:SI 2 "=&q"))
11924    (clobber (reg:CC FLAGS_REG))]
11925   "!TARGET_CMOVE"
11926   "#"
11927   "&& reload_completed"
11928   [(parallel [(set (reg:CCZ FLAGS_REG)
11929                    (compare:CCZ (match_dup 1) (const_int 0)))
11930               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11931    (set (strict_low_part (match_dup 3))
11932         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11933    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11934               (clobber (reg:CC FLAGS_REG))])
11935    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11936               (clobber (reg:CC FLAGS_REG))])
11937    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11938               (clobber (reg:CC FLAGS_REG))])]
11939 {
11940   operands[3] = gen_lowpart (QImode, operands[2]);
11941   ix86_expand_clear (operands[2]);
11942 })
11943
11944 (define_insn "*ffs<mode>_1"
11945   [(set (reg:CCZ FLAGS_REG)
11946         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11947                      (const_int 0)))
11948    (set (match_operand:SWI48 0 "register_operand" "=r")
11949         (ctz:SWI48 (match_dup 1)))]
11950   ""
11951   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11952   [(set_attr "type" "alu1")
11953    (set_attr "prefix_0f" "1")
11954    (set_attr "mode" "<MODE>")])
11955
11956 (define_insn "ctz<mode>2"
11957   [(set (match_operand:SWI48 0 "register_operand" "=r")
11958         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11959    (clobber (reg:CC FLAGS_REG))]
11960   ""
11961   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11962   [(set_attr "type" "alu1")
11963    (set_attr "prefix_0f" "1")
11964    (set_attr "mode" "<MODE>")])
11965
11966 (define_expand "clz<mode>2"
11967   [(parallel
11968      [(set (match_operand:SWI248 0 "register_operand" "")
11969            (minus:SWI248
11970              (match_dup 2)
11971              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11972       (clobber (reg:CC FLAGS_REG))])
11973    (parallel
11974      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11975       (clobber (reg:CC FLAGS_REG))])]
11976   ""
11977 {
11978   if (TARGET_ABM)
11979     {
11980       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11981       DONE;
11982     }
11983   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11984 })
11985
11986 (define_insn "clz<mode>2_abm"
11987   [(set (match_operand:SWI248 0 "register_operand" "=r")
11988         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11989    (clobber (reg:CC FLAGS_REG))]
11990   "TARGET_ABM"
11991   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11992   [(set_attr "prefix_rep" "1")
11993    (set_attr "type" "bitmanip")
11994    (set_attr "mode" "<MODE>")])
11995
11996 (define_insn "bsr_rex64"
11997   [(set (match_operand:DI 0 "register_operand" "=r")
11998         (minus:DI (const_int 63)
11999                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12000    (clobber (reg:CC FLAGS_REG))]
12001   "TARGET_64BIT"
12002   "bsr{q}\t{%1, %0|%0, %1}"
12003   [(set_attr "type" "alu1")
12004    (set_attr "prefix_0f" "1")
12005    (set_attr "mode" "DI")])
12006
12007 (define_insn "bsr"
12008   [(set (match_operand:SI 0 "register_operand" "=r")
12009         (minus:SI (const_int 31)
12010                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12011    (clobber (reg:CC FLAGS_REG))]
12012   ""
12013   "bsr{l}\t{%1, %0|%0, %1}"
12014   [(set_attr "type" "alu1")
12015    (set_attr "prefix_0f" "1")
12016    (set_attr "mode" "SI")])
12017
12018 (define_insn "*bsrhi"
12019   [(set (match_operand:HI 0 "register_operand" "=r")
12020         (minus:HI (const_int 15)
12021                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12022    (clobber (reg:CC FLAGS_REG))]
12023   ""
12024   "bsr{w}\t{%1, %0|%0, %1}"
12025   [(set_attr "type" "alu1")
12026    (set_attr "prefix_0f" "1")
12027    (set_attr "mode" "HI")])
12028
12029 (define_insn "popcount<mode>2"
12030   [(set (match_operand:SWI248 0 "register_operand" "=r")
12031         (popcount:SWI248
12032           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12033    (clobber (reg:CC FLAGS_REG))]
12034   "TARGET_POPCNT"
12035 {
12036 #if TARGET_MACHO
12037   return "popcnt\t{%1, %0|%0, %1}";
12038 #else
12039   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12040 #endif
12041 }
12042   [(set_attr "prefix_rep" "1")
12043    (set_attr "type" "bitmanip")
12044    (set_attr "mode" "<MODE>")])
12045
12046 (define_insn "*popcount<mode>2_cmp"
12047   [(set (reg FLAGS_REG)
12048         (compare
12049           (popcount:SWI248
12050             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12051           (const_int 0)))
12052    (set (match_operand:SWI248 0 "register_operand" "=r")
12053         (popcount:SWI248 (match_dup 1)))]
12054   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12055 {
12056 #if TARGET_MACHO
12057   return "popcnt\t{%1, %0|%0, %1}";
12058 #else
12059   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12060 #endif
12061 }
12062   [(set_attr "prefix_rep" "1")
12063    (set_attr "type" "bitmanip")
12064    (set_attr "mode" "<MODE>")])
12065
12066 (define_insn "*popcountsi2_cmp_zext"
12067   [(set (reg FLAGS_REG)
12068         (compare
12069           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12070           (const_int 0)))
12071    (set (match_operand:DI 0 "register_operand" "=r")
12072         (zero_extend:DI(popcount:SI (match_dup 1))))]
12073   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12074 {
12075 #if TARGET_MACHO
12076   return "popcnt\t{%1, %0|%0, %1}";
12077 #else
12078   return "popcnt{l}\t{%1, %0|%0, %1}";
12079 #endif
12080 }
12081   [(set_attr "prefix_rep" "1")
12082    (set_attr "type" "bitmanip")
12083    (set_attr "mode" "SI")])
12084
12085 (define_expand "bswap<mode>2"
12086   [(set (match_operand:SWI48 0 "register_operand" "")
12087         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12088   ""
12089 {
12090   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12091     {
12092       rtx x = operands[0];
12093
12094       emit_move_insn (x, operands[1]);
12095       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12096       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12097       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12098       DONE;
12099     }
12100 })
12101
12102 (define_insn "*bswap<mode>2_movbe"
12103   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12104         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12105   "TARGET_MOVBE
12106    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12107   "@
12108     bswap\t%0
12109     movbe\t{%1, %0|%0, %1}
12110     movbe\t{%1, %0|%0, %1}"
12111   [(set_attr "type" "bitmanip,imov,imov")
12112    (set_attr "modrm" "0,1,1")
12113    (set_attr "prefix_0f" "*,1,1")
12114    (set_attr "prefix_extra" "*,1,1")
12115    (set_attr "mode" "<MODE>")])
12116
12117 (define_insn "*bswap<mode>2_1"
12118   [(set (match_operand:SWI48 0 "register_operand" "=r")
12119         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12120   "TARGET_BSWAP"
12121   "bswap\t%0"
12122   [(set_attr "type" "bitmanip")
12123    (set_attr "modrm" "0")
12124    (set_attr "mode" "<MODE>")])
12125
12126 (define_insn "*bswaphi_lowpart_1"
12127   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12128         (bswap:HI (match_dup 0)))
12129    (clobber (reg:CC FLAGS_REG))]
12130   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12131   "@
12132     xchg{b}\t{%h0, %b0|%b0, %h0}
12133     rol{w}\t{$8, %0|%0, 8}"
12134   [(set_attr "length" "2,4")
12135    (set_attr "mode" "QI,HI")])
12136
12137 (define_insn "bswaphi_lowpart"
12138   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12139         (bswap:HI (match_dup 0)))
12140    (clobber (reg:CC FLAGS_REG))]
12141   ""
12142   "rol{w}\t{$8, %0|%0, 8}"
12143   [(set_attr "length" "4")
12144    (set_attr "mode" "HI")])
12145
12146 (define_expand "paritydi2"
12147   [(set (match_operand:DI 0 "register_operand" "")
12148         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12149   "! TARGET_POPCNT"
12150 {
12151   rtx scratch = gen_reg_rtx (QImode);
12152   rtx cond;
12153
12154   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12155                                 NULL_RTX, operands[1]));
12156
12157   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12158                          gen_rtx_REG (CCmode, FLAGS_REG),
12159                          const0_rtx);
12160   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12161
12162   if (TARGET_64BIT)
12163     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12164   else
12165     {
12166       rtx tmp = gen_reg_rtx (SImode);
12167
12168       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12169       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12170     }
12171   DONE;
12172 })
12173
12174 (define_expand "paritysi2"
12175   [(set (match_operand:SI 0 "register_operand" "")
12176         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12177   "! TARGET_POPCNT"
12178 {
12179   rtx scratch = gen_reg_rtx (QImode);
12180   rtx cond;
12181
12182   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12183
12184   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12185                          gen_rtx_REG (CCmode, FLAGS_REG),
12186                          const0_rtx);
12187   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12188
12189   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12190   DONE;
12191 })
12192
12193 (define_insn_and_split "paritydi2_cmp"
12194   [(set (reg:CC FLAGS_REG)
12195         (parity:CC (match_operand:DI 3 "register_operand" "0")))
12196    (clobber (match_scratch:DI 0 "=r"))
12197    (clobber (match_scratch:SI 1 "=&r"))
12198    (clobber (match_scratch:HI 2 "=Q"))]
12199   "! TARGET_POPCNT"
12200   "#"
12201   "&& reload_completed"
12202   [(parallel
12203      [(set (match_dup 1)
12204            (xor:SI (match_dup 1) (match_dup 4)))
12205       (clobber (reg:CC FLAGS_REG))])
12206    (parallel
12207      [(set (reg:CC FLAGS_REG)
12208            (parity:CC (match_dup 1)))
12209       (clobber (match_dup 1))
12210       (clobber (match_dup 2))])]
12211 {
12212   operands[4] = gen_lowpart (SImode, operands[3]);
12213
12214   if (TARGET_64BIT)
12215     {
12216       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12217       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12218     }
12219   else
12220     operands[1] = gen_highpart (SImode, operands[3]);
12221 })
12222
12223 (define_insn_and_split "paritysi2_cmp"
12224   [(set (reg:CC FLAGS_REG)
12225         (parity:CC (match_operand:SI 2 "register_operand" "0")))
12226    (clobber (match_scratch:SI 0 "=r"))
12227    (clobber (match_scratch:HI 1 "=&Q"))]
12228   "! TARGET_POPCNT"
12229   "#"
12230   "&& reload_completed"
12231   [(parallel
12232      [(set (match_dup 1)
12233            (xor:HI (match_dup 1) (match_dup 3)))
12234       (clobber (reg:CC FLAGS_REG))])
12235    (parallel
12236      [(set (reg:CC FLAGS_REG)
12237            (parity:CC (match_dup 1)))
12238       (clobber (match_dup 1))])]
12239 {
12240   operands[3] = gen_lowpart (HImode, operands[2]);
12241
12242   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12243   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12244 })
12245
12246 (define_insn "*parityhi2_cmp"
12247   [(set (reg:CC FLAGS_REG)
12248         (parity:CC (match_operand:HI 1 "register_operand" "0")))
12249    (clobber (match_scratch:HI 0 "=Q"))]
12250   "! TARGET_POPCNT"
12251   "xor{b}\t{%h0, %b0|%b0, %h0}"
12252   [(set_attr "length" "2")
12253    (set_attr "mode" "HI")])
12254
12255 (define_insn "*parityqi2_cmp"
12256   [(set (reg:CC FLAGS_REG)
12257         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12258   "! TARGET_POPCNT"
12259   "test{b}\t%0, %0"
12260   [(set_attr "length" "2")
12261    (set_attr "mode" "QI")])
12262 \f
12263 ;; Thread-local storage patterns for ELF.
12264 ;;
12265 ;; Note that these code sequences must appear exactly as shown
12266 ;; in order to allow linker relaxation.
12267
12268 (define_insn "*tls_global_dynamic_32_gnu"
12269   [(set (match_operand:SI 0 "register_operand" "=a")
12270         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12271                     (match_operand:SI 2 "tls_symbolic_operand" "")
12272                     (match_operand:SI 3 "call_insn_operand" "")]
12273                     UNSPEC_TLS_GD))
12274    (clobber (match_scratch:SI 4 "=d"))
12275    (clobber (match_scratch:SI 5 "=c"))
12276    (clobber (reg:CC FLAGS_REG))]
12277   "!TARGET_64BIT && TARGET_GNU_TLS"
12278   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12279   [(set_attr "type" "multi")
12280    (set_attr "length" "12")])
12281
12282 (define_expand "tls_global_dynamic_32"
12283   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12284                    (unspec:SI
12285                     [(match_dup 2)
12286                      (match_operand:SI 1 "tls_symbolic_operand" "")
12287                      (match_dup 3)]
12288                     UNSPEC_TLS_GD))
12289               (clobber (match_scratch:SI 4 ""))
12290               (clobber (match_scratch:SI 5 ""))
12291               (clobber (reg:CC FLAGS_REG))])]
12292   ""
12293 {
12294   if (flag_pic)
12295     operands[2] = pic_offset_table_rtx;
12296   else
12297     {
12298       operands[2] = gen_reg_rtx (Pmode);
12299       emit_insn (gen_set_got (operands[2]));
12300     }
12301   if (TARGET_GNU2_TLS)
12302     {
12303        emit_insn (gen_tls_dynamic_gnu2_32
12304                   (operands[0], operands[1], operands[2]));
12305        DONE;
12306     }
12307   operands[3] = ix86_tls_get_addr ();
12308 })
12309
12310 (define_insn "*tls_global_dynamic_64"
12311   [(set (match_operand:DI 0 "register_operand" "=a")
12312         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12313                  (match_operand:DI 3 "" "")))
12314    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12315               UNSPEC_TLS_GD)]
12316   "TARGET_64BIT"
12317   { 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"; }
12318   [(set_attr "type" "multi")
12319    (set_attr "length" "16")])
12320
12321 (define_expand "tls_global_dynamic_64"
12322   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12323                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12324               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12325                          UNSPEC_TLS_GD)])]
12326   ""
12327 {
12328   if (TARGET_GNU2_TLS)
12329     {
12330        emit_insn (gen_tls_dynamic_gnu2_64
12331                   (operands[0], operands[1]));
12332        DONE;
12333     }
12334   operands[2] = ix86_tls_get_addr ();
12335 })
12336
12337 (define_insn "*tls_local_dynamic_base_32_gnu"
12338   [(set (match_operand:SI 0 "register_operand" "=a")
12339         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12340                     (match_operand:SI 2 "call_insn_operand" "")]
12341                    UNSPEC_TLS_LD_BASE))
12342    (clobber (match_scratch:SI 3 "=d"))
12343    (clobber (match_scratch:SI 4 "=c"))
12344    (clobber (reg:CC FLAGS_REG))]
12345   "!TARGET_64BIT && TARGET_GNU_TLS"
12346   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12347   [(set_attr "type" "multi")
12348    (set_attr "length" "11")])
12349
12350 (define_expand "tls_local_dynamic_base_32"
12351   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12352                    (unspec:SI [(match_dup 1) (match_dup 2)]
12353                               UNSPEC_TLS_LD_BASE))
12354               (clobber (match_scratch:SI 3 ""))
12355               (clobber (match_scratch:SI 4 ""))
12356               (clobber (reg:CC FLAGS_REG))])]
12357   ""
12358 {
12359   if (flag_pic)
12360     operands[1] = pic_offset_table_rtx;
12361   else
12362     {
12363       operands[1] = gen_reg_rtx (Pmode);
12364       emit_insn (gen_set_got (operands[1]));
12365     }
12366   if (TARGET_GNU2_TLS)
12367     {
12368        emit_insn (gen_tls_dynamic_gnu2_32
12369                   (operands[0], ix86_tls_module_base (), operands[1]));
12370        DONE;
12371     }
12372   operands[2] = ix86_tls_get_addr ();
12373 })
12374
12375 (define_insn "*tls_local_dynamic_base_64"
12376   [(set (match_operand:DI 0 "register_operand" "=a")
12377         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12378                  (match_operand:DI 2 "" "")))
12379    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12380   "TARGET_64BIT"
12381   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12382   [(set_attr "type" "multi")
12383    (set_attr "length" "12")])
12384
12385 (define_expand "tls_local_dynamic_base_64"
12386   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12387                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12388               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12389   ""
12390 {
12391   if (TARGET_GNU2_TLS)
12392     {
12393        emit_insn (gen_tls_dynamic_gnu2_64
12394                   (operands[0], ix86_tls_module_base ()));
12395        DONE;
12396     }
12397   operands[1] = ix86_tls_get_addr ();
12398 })
12399
12400 ;; Local dynamic of a single variable is a lose.  Show combine how
12401 ;; to convert that back to global dynamic.
12402
12403 (define_insn_and_split "*tls_local_dynamic_32_once"
12404   [(set (match_operand:SI 0 "register_operand" "=a")
12405         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12406                              (match_operand:SI 2 "call_insn_operand" "")]
12407                             UNSPEC_TLS_LD_BASE)
12408                  (const:SI (unspec:SI
12409                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12410                             UNSPEC_DTPOFF))))
12411    (clobber (match_scratch:SI 4 "=d"))
12412    (clobber (match_scratch:SI 5 "=c"))
12413    (clobber (reg:CC FLAGS_REG))]
12414   ""
12415   "#"
12416   ""
12417   [(parallel [(set (match_dup 0)
12418                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12419                               UNSPEC_TLS_GD))
12420               (clobber (match_dup 4))
12421               (clobber (match_dup 5))
12422               (clobber (reg:CC FLAGS_REG))])]
12423   "")
12424
12425 ;; Load and add the thread base pointer from %gs:0.
12426
12427 (define_insn "*load_tp_si"
12428   [(set (match_operand:SI 0 "register_operand" "=r")
12429         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12430   "!TARGET_64BIT"
12431   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12432   [(set_attr "type" "imov")
12433    (set_attr "modrm" "0")
12434    (set_attr "length" "7")
12435    (set_attr "memory" "load")
12436    (set_attr "imm_disp" "false")])
12437
12438 (define_insn "*add_tp_si"
12439   [(set (match_operand:SI 0 "register_operand" "=r")
12440         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12441                  (match_operand:SI 1 "register_operand" "0")))
12442    (clobber (reg:CC FLAGS_REG))]
12443   "!TARGET_64BIT"
12444   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12445   [(set_attr "type" "alu")
12446    (set_attr "modrm" "0")
12447    (set_attr "length" "7")
12448    (set_attr "memory" "load")
12449    (set_attr "imm_disp" "false")])
12450
12451 (define_insn "*load_tp_di"
12452   [(set (match_operand:DI 0 "register_operand" "=r")
12453         (unspec:DI [(const_int 0)] UNSPEC_TP))]
12454   "TARGET_64BIT"
12455   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12456   [(set_attr "type" "imov")
12457    (set_attr "modrm" "0")
12458    (set_attr "length" "7")
12459    (set_attr "memory" "load")
12460    (set_attr "imm_disp" "false")])
12461
12462 (define_insn "*add_tp_di"
12463   [(set (match_operand:DI 0 "register_operand" "=r")
12464         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12465                  (match_operand:DI 1 "register_operand" "0")))
12466    (clobber (reg:CC FLAGS_REG))]
12467   "TARGET_64BIT"
12468   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12469   [(set_attr "type" "alu")
12470    (set_attr "modrm" "0")
12471    (set_attr "length" "7")
12472    (set_attr "memory" "load")
12473    (set_attr "imm_disp" "false")])
12474
12475 ;; GNU2 TLS patterns can be split.
12476
12477 (define_expand "tls_dynamic_gnu2_32"
12478   [(set (match_dup 3)
12479         (plus:SI (match_operand:SI 2 "register_operand" "")
12480                  (const:SI
12481                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12482                              UNSPEC_TLSDESC))))
12483    (parallel
12484     [(set (match_operand:SI 0 "register_operand" "")
12485           (unspec:SI [(match_dup 1) (match_dup 3)
12486                       (match_dup 2) (reg:SI SP_REG)]
12487                       UNSPEC_TLSDESC))
12488      (clobber (reg:CC FLAGS_REG))])]
12489   "!TARGET_64BIT && TARGET_GNU2_TLS"
12490 {
12491   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12492   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12493 })
12494
12495 (define_insn "*tls_dynamic_lea_32"
12496   [(set (match_operand:SI 0 "register_operand" "=r")
12497         (plus:SI (match_operand:SI 1 "register_operand" "b")
12498                  (const:SI
12499                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12500                               UNSPEC_TLSDESC))))]
12501   "!TARGET_64BIT && TARGET_GNU2_TLS"
12502   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12503   [(set_attr "type" "lea")
12504    (set_attr "mode" "SI")
12505    (set_attr "length" "6")
12506    (set_attr "length_address" "4")])
12507
12508 (define_insn "*tls_dynamic_call_32"
12509   [(set (match_operand:SI 0 "register_operand" "=a")
12510         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12511                     (match_operand:SI 2 "register_operand" "0")
12512                     ;; we have to make sure %ebx still points to the GOT
12513                     (match_operand:SI 3 "register_operand" "b")
12514                     (reg:SI SP_REG)]
12515                    UNSPEC_TLSDESC))
12516    (clobber (reg:CC FLAGS_REG))]
12517   "!TARGET_64BIT && TARGET_GNU2_TLS"
12518   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12519   [(set_attr "type" "call")
12520    (set_attr "length" "2")
12521    (set_attr "length_address" "0")])
12522
12523 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12524   [(set (match_operand:SI 0 "register_operand" "=&a")
12525         (plus:SI
12526          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12527                      (match_operand:SI 4 "" "")
12528                      (match_operand:SI 2 "register_operand" "b")
12529                      (reg:SI SP_REG)]
12530                     UNSPEC_TLSDESC)
12531          (const:SI (unspec:SI
12532                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12533                     UNSPEC_DTPOFF))))
12534    (clobber (reg:CC FLAGS_REG))]
12535   "!TARGET_64BIT && TARGET_GNU2_TLS"
12536   "#"
12537   ""
12538   [(set (match_dup 0) (match_dup 5))]
12539 {
12540   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12541   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12542 })
12543
12544 (define_expand "tls_dynamic_gnu2_64"
12545   [(set (match_dup 2)
12546         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12547                    UNSPEC_TLSDESC))
12548    (parallel
12549     [(set (match_operand:DI 0 "register_operand" "")
12550           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12551                      UNSPEC_TLSDESC))
12552      (clobber (reg:CC FLAGS_REG))])]
12553   "TARGET_64BIT && TARGET_GNU2_TLS"
12554 {
12555   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12556   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12557 })
12558
12559 (define_insn "*tls_dynamic_lea_64"
12560   [(set (match_operand:DI 0 "register_operand" "=r")
12561         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12562                    UNSPEC_TLSDESC))]
12563   "TARGET_64BIT && TARGET_GNU2_TLS"
12564   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12565   [(set_attr "type" "lea")
12566    (set_attr "mode" "DI")
12567    (set_attr "length" "7")
12568    (set_attr "length_address" "4")])
12569
12570 (define_insn "*tls_dynamic_call_64"
12571   [(set (match_operand:DI 0 "register_operand" "=a")
12572         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12573                     (match_operand:DI 2 "register_operand" "0")
12574                     (reg:DI SP_REG)]
12575                    UNSPEC_TLSDESC))
12576    (clobber (reg:CC FLAGS_REG))]
12577   "TARGET_64BIT && TARGET_GNU2_TLS"
12578   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12579   [(set_attr "type" "call")
12580    (set_attr "length" "2")
12581    (set_attr "length_address" "0")])
12582
12583 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12584   [(set (match_operand:DI 0 "register_operand" "=&a")
12585         (plus:DI
12586          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12587                      (match_operand:DI 3 "" "")
12588                      (reg:DI SP_REG)]
12589                     UNSPEC_TLSDESC)
12590          (const:DI (unspec:DI
12591                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12592                     UNSPEC_DTPOFF))))
12593    (clobber (reg:CC FLAGS_REG))]
12594   "TARGET_64BIT && TARGET_GNU2_TLS"
12595   "#"
12596   ""
12597   [(set (match_dup 0) (match_dup 4))]
12598 {
12599   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12600   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12601 })
12602
12603 ;;
12604 \f
12605 ;; These patterns match the binary 387 instructions for addM3, subM3,
12606 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12607 ;; SFmode.  The first is the normal insn, the second the same insn but
12608 ;; with one operand a conversion, and the third the same insn but with
12609 ;; the other operand a conversion.  The conversion may be SFmode or
12610 ;; SImode if the target mode DFmode, but only SImode if the target mode
12611 ;; is SFmode.
12612
12613 ;; Gcc is slightly more smart about handling normal two address instructions
12614 ;; so use special patterns for add and mull.
12615
12616 (define_insn "*fop_<mode>_comm_mixed_avx"
12617   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12618         (match_operator:MODEF 3 "binary_fp_operator"
12619           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12620            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12621   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12622    && COMMUTATIVE_ARITH_P (operands[3])
12623    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12624   "* return output_387_binary_op (insn, operands);"
12625   [(set (attr "type")
12626         (if_then_else (eq_attr "alternative" "1")
12627            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12628               (const_string "ssemul")
12629               (const_string "sseadd"))
12630            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12631               (const_string "fmul")
12632               (const_string "fop"))))
12633    (set_attr "prefix" "orig,maybe_vex")
12634    (set_attr "mode" "<MODE>")])
12635
12636 (define_insn "*fop_<mode>_comm_mixed"
12637   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12638         (match_operator:MODEF 3 "binary_fp_operator"
12639           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12640            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12641   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12642    && COMMUTATIVE_ARITH_P (operands[3])
12643    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12644   "* return output_387_binary_op (insn, operands);"
12645   [(set (attr "type")
12646         (if_then_else (eq_attr "alternative" "1")
12647            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12648               (const_string "ssemul")
12649               (const_string "sseadd"))
12650            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12651               (const_string "fmul")
12652               (const_string "fop"))))
12653    (set_attr "mode" "<MODE>")])
12654
12655 (define_insn "*fop_<mode>_comm_avx"
12656   [(set (match_operand:MODEF 0 "register_operand" "=x")
12657         (match_operator:MODEF 3 "binary_fp_operator"
12658           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12659            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12660   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12661    && COMMUTATIVE_ARITH_P (operands[3])
12662    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12663   "* return output_387_binary_op (insn, operands);"
12664   [(set (attr "type")
12665         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12666            (const_string "ssemul")
12667            (const_string "sseadd")))
12668    (set_attr "prefix" "vex")
12669    (set_attr "mode" "<MODE>")])
12670
12671 (define_insn "*fop_<mode>_comm_sse"
12672   [(set (match_operand:MODEF 0 "register_operand" "=x")
12673         (match_operator:MODEF 3 "binary_fp_operator"
12674           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12675            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12676   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12677    && COMMUTATIVE_ARITH_P (operands[3])
12678    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12679   "* return output_387_binary_op (insn, operands);"
12680   [(set (attr "type")
12681         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12682            (const_string "ssemul")
12683            (const_string "sseadd")))
12684    (set_attr "mode" "<MODE>")])
12685
12686 (define_insn "*fop_<mode>_comm_i387"
12687   [(set (match_operand:MODEF 0 "register_operand" "=f")
12688         (match_operator:MODEF 3 "binary_fp_operator"
12689           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12690            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12691   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12692    && COMMUTATIVE_ARITH_P (operands[3])
12693    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12694   "* return output_387_binary_op (insn, operands);"
12695   [(set (attr "type")
12696         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12697            (const_string "fmul")
12698            (const_string "fop")))
12699    (set_attr "mode" "<MODE>")])
12700
12701 (define_insn "*fop_<mode>_1_mixed_avx"
12702   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12703         (match_operator:MODEF 3 "binary_fp_operator"
12704           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12705            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12706   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12707    && !COMMUTATIVE_ARITH_P (operands[3])
12708    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12709   "* return output_387_binary_op (insn, operands);"
12710   [(set (attr "type")
12711         (cond [(and (eq_attr "alternative" "2")
12712                     (match_operand:MODEF 3 "mult_operator" ""))
12713                  (const_string "ssemul")
12714                (and (eq_attr "alternative" "2")
12715                     (match_operand:MODEF 3 "div_operator" ""))
12716                  (const_string "ssediv")
12717                (eq_attr "alternative" "2")
12718                  (const_string "sseadd")
12719                (match_operand:MODEF 3 "mult_operator" "")
12720                  (const_string "fmul")
12721                (match_operand:MODEF 3 "div_operator" "")
12722                  (const_string "fdiv")
12723               ]
12724               (const_string "fop")))
12725    (set_attr "prefix" "orig,orig,maybe_vex")
12726    (set_attr "mode" "<MODE>")])
12727
12728 (define_insn "*fop_<mode>_1_mixed"
12729   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12730         (match_operator:MODEF 3 "binary_fp_operator"
12731           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12732            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12733   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12734    && !COMMUTATIVE_ARITH_P (operands[3])
12735    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12736   "* return output_387_binary_op (insn, operands);"
12737   [(set (attr "type")
12738         (cond [(and (eq_attr "alternative" "2")
12739                     (match_operand:MODEF 3 "mult_operator" ""))
12740                  (const_string "ssemul")
12741                (and (eq_attr "alternative" "2")
12742                     (match_operand:MODEF 3 "div_operator" ""))
12743                  (const_string "ssediv")
12744                (eq_attr "alternative" "2")
12745                  (const_string "sseadd")
12746                (match_operand:MODEF 3 "mult_operator" "")
12747                  (const_string "fmul")
12748                (match_operand:MODEF 3 "div_operator" "")
12749                  (const_string "fdiv")
12750               ]
12751               (const_string "fop")))
12752    (set_attr "mode" "<MODE>")])
12753
12754 (define_insn "*rcpsf2_sse"
12755   [(set (match_operand:SF 0 "register_operand" "=x")
12756         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12757                    UNSPEC_RCP))]
12758   "TARGET_SSE_MATH"
12759   "%vrcpss\t{%1, %d0|%d0, %1}"
12760   [(set_attr "type" "sse")
12761    (set_attr "atom_sse_attr" "rcp")
12762    (set_attr "prefix" "maybe_vex")
12763    (set_attr "mode" "SF")])
12764
12765 (define_insn "*fop_<mode>_1_avx"
12766   [(set (match_operand:MODEF 0 "register_operand" "=x")
12767         (match_operator:MODEF 3 "binary_fp_operator"
12768           [(match_operand:MODEF 1 "register_operand" "x")
12769            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12770   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12771    && !COMMUTATIVE_ARITH_P (operands[3])"
12772   "* return output_387_binary_op (insn, operands);"
12773   [(set (attr "type")
12774         (cond [(match_operand:MODEF 3 "mult_operator" "")
12775                  (const_string "ssemul")
12776                (match_operand:MODEF 3 "div_operator" "")
12777                  (const_string "ssediv")
12778               ]
12779               (const_string "sseadd")))
12780    (set_attr "prefix" "vex")
12781    (set_attr "mode" "<MODE>")])
12782
12783 (define_insn "*fop_<mode>_1_sse"
12784   [(set (match_operand:MODEF 0 "register_operand" "=x")
12785         (match_operator:MODEF 3 "binary_fp_operator"
12786           [(match_operand:MODEF 1 "register_operand" "0")
12787            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12788   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12789    && !COMMUTATIVE_ARITH_P (operands[3])"
12790   "* return output_387_binary_op (insn, operands);"
12791   [(set (attr "type")
12792         (cond [(match_operand:MODEF 3 "mult_operator" "")
12793                  (const_string "ssemul")
12794                (match_operand:MODEF 3 "div_operator" "")
12795                  (const_string "ssediv")
12796               ]
12797               (const_string "sseadd")))
12798    (set_attr "mode" "<MODE>")])
12799
12800 ;; This pattern is not fully shadowed by the pattern above.
12801 (define_insn "*fop_<mode>_1_i387"
12802   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12803         (match_operator:MODEF 3 "binary_fp_operator"
12804           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12805            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12806   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12807    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12808    && !COMMUTATIVE_ARITH_P (operands[3])
12809    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12810   "* return output_387_binary_op (insn, operands);"
12811   [(set (attr "type")
12812         (cond [(match_operand:MODEF 3 "mult_operator" "")
12813                  (const_string "fmul")
12814                (match_operand:MODEF 3 "div_operator" "")
12815                  (const_string "fdiv")
12816               ]
12817               (const_string "fop")))
12818    (set_attr "mode" "<MODE>")])
12819
12820 ;; ??? Add SSE splitters for these!
12821 (define_insn "*fop_<MODEF:mode>_2_i387"
12822   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12823         (match_operator:MODEF 3 "binary_fp_operator"
12824           [(float:MODEF
12825              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12826            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12827   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12828    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12829    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12830   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12831   [(set (attr "type")
12832         (cond [(match_operand:MODEF 3 "mult_operator" "")
12833                  (const_string "fmul")
12834                (match_operand:MODEF 3 "div_operator" "")
12835                  (const_string "fdiv")
12836               ]
12837               (const_string "fop")))
12838    (set_attr "fp_int_src" "true")
12839    (set_attr "mode" "<X87MODEI12:MODE>")])
12840
12841 (define_insn "*fop_<MODEF:mode>_3_i387"
12842   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12843         (match_operator:MODEF 3 "binary_fp_operator"
12844           [(match_operand:MODEF 1 "register_operand" "0,0")
12845            (float:MODEF
12846              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12847   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12848    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12849    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12850   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12851   [(set (attr "type")
12852         (cond [(match_operand:MODEF 3 "mult_operator" "")
12853                  (const_string "fmul")
12854                (match_operand:MODEF 3 "div_operator" "")
12855                  (const_string "fdiv")
12856               ]
12857               (const_string "fop")))
12858    (set_attr "fp_int_src" "true")
12859    (set_attr "mode" "<MODE>")])
12860
12861 (define_insn "*fop_df_4_i387"
12862   [(set (match_operand:DF 0 "register_operand" "=f,f")
12863         (match_operator:DF 3 "binary_fp_operator"
12864            [(float_extend:DF
12865              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12866             (match_operand:DF 2 "register_operand" "0,f")]))]
12867   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12868    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12869    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12870   "* return output_387_binary_op (insn, operands);"
12871   [(set (attr "type")
12872         (cond [(match_operand:DF 3 "mult_operator" "")
12873                  (const_string "fmul")
12874                (match_operand:DF 3 "div_operator" "")
12875                  (const_string "fdiv")
12876               ]
12877               (const_string "fop")))
12878    (set_attr "mode" "SF")])
12879
12880 (define_insn "*fop_df_5_i387"
12881   [(set (match_operand:DF 0 "register_operand" "=f,f")
12882         (match_operator:DF 3 "binary_fp_operator"
12883           [(match_operand:DF 1 "register_operand" "0,f")
12884            (float_extend:DF
12885             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12886   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12887    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12888   "* return output_387_binary_op (insn, operands);"
12889   [(set (attr "type")
12890         (cond [(match_operand:DF 3 "mult_operator" "")
12891                  (const_string "fmul")
12892                (match_operand:DF 3 "div_operator" "")
12893                  (const_string "fdiv")
12894               ]
12895               (const_string "fop")))
12896    (set_attr "mode" "SF")])
12897
12898 (define_insn "*fop_df_6_i387"
12899   [(set (match_operand:DF 0 "register_operand" "=f,f")
12900         (match_operator:DF 3 "binary_fp_operator"
12901           [(float_extend:DF
12902             (match_operand:SF 1 "register_operand" "0,f"))
12903            (float_extend:DF
12904             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12905   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12906    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12907   "* return output_387_binary_op (insn, operands);"
12908   [(set (attr "type")
12909         (cond [(match_operand:DF 3 "mult_operator" "")
12910                  (const_string "fmul")
12911                (match_operand:DF 3 "div_operator" "")
12912                  (const_string "fdiv")
12913               ]
12914               (const_string "fop")))
12915    (set_attr "mode" "SF")])
12916
12917 (define_insn "*fop_xf_comm_i387"
12918   [(set (match_operand:XF 0 "register_operand" "=f")
12919         (match_operator:XF 3 "binary_fp_operator"
12920                         [(match_operand:XF 1 "register_operand" "%0")
12921                          (match_operand:XF 2 "register_operand" "f")]))]
12922   "TARGET_80387
12923    && COMMUTATIVE_ARITH_P (operands[3])"
12924   "* return output_387_binary_op (insn, operands);"
12925   [(set (attr "type")
12926         (if_then_else (match_operand:XF 3 "mult_operator" "")
12927            (const_string "fmul")
12928            (const_string "fop")))
12929    (set_attr "mode" "XF")])
12930
12931 (define_insn "*fop_xf_1_i387"
12932   [(set (match_operand:XF 0 "register_operand" "=f,f")
12933         (match_operator:XF 3 "binary_fp_operator"
12934                         [(match_operand:XF 1 "register_operand" "0,f")
12935                          (match_operand:XF 2 "register_operand" "f,0")]))]
12936   "TARGET_80387
12937    && !COMMUTATIVE_ARITH_P (operands[3])"
12938   "* return output_387_binary_op (insn, operands);"
12939   [(set (attr "type")
12940         (cond [(match_operand:XF 3 "mult_operator" "")
12941                  (const_string "fmul")
12942                (match_operand:XF 3 "div_operator" "")
12943                  (const_string "fdiv")
12944               ]
12945               (const_string "fop")))
12946    (set_attr "mode" "XF")])
12947
12948 (define_insn "*fop_xf_2_i387"
12949   [(set (match_operand:XF 0 "register_operand" "=f,f")
12950         (match_operator:XF 3 "binary_fp_operator"
12951           [(float:XF
12952              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12953            (match_operand:XF 2 "register_operand" "0,0")]))]
12954   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12955   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12956   [(set (attr "type")
12957         (cond [(match_operand:XF 3 "mult_operator" "")
12958                  (const_string "fmul")
12959                (match_operand:XF 3 "div_operator" "")
12960                  (const_string "fdiv")
12961               ]
12962               (const_string "fop")))
12963    (set_attr "fp_int_src" "true")
12964    (set_attr "mode" "<MODE>")])
12965
12966 (define_insn "*fop_xf_3_i387"
12967   [(set (match_operand:XF 0 "register_operand" "=f,f")
12968         (match_operator:XF 3 "binary_fp_operator"
12969           [(match_operand:XF 1 "register_operand" "0,0")
12970            (float:XF
12971              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12972   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12973   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12974   [(set (attr "type")
12975         (cond [(match_operand:XF 3 "mult_operator" "")
12976                  (const_string "fmul")
12977                (match_operand:XF 3 "div_operator" "")
12978                  (const_string "fdiv")
12979               ]
12980               (const_string "fop")))
12981    (set_attr "fp_int_src" "true")
12982    (set_attr "mode" "<MODE>")])
12983
12984 (define_insn "*fop_xf_4_i387"
12985   [(set (match_operand:XF 0 "register_operand" "=f,f")
12986         (match_operator:XF 3 "binary_fp_operator"
12987            [(float_extend:XF
12988               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12989             (match_operand:XF 2 "register_operand" "0,f")]))]
12990   "TARGET_80387"
12991   "* return output_387_binary_op (insn, operands);"
12992   [(set (attr "type")
12993         (cond [(match_operand:XF 3 "mult_operator" "")
12994                  (const_string "fmul")
12995                (match_operand:XF 3 "div_operator" "")
12996                  (const_string "fdiv")
12997               ]
12998               (const_string "fop")))
12999    (set_attr "mode" "<MODE>")])
13000
13001 (define_insn "*fop_xf_5_i387"
13002   [(set (match_operand:XF 0 "register_operand" "=f,f")
13003         (match_operator:XF 3 "binary_fp_operator"
13004           [(match_operand:XF 1 "register_operand" "0,f")
13005            (float_extend:XF
13006              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13007   "TARGET_80387"
13008   "* return output_387_binary_op (insn, operands);"
13009   [(set (attr "type")
13010         (cond [(match_operand:XF 3 "mult_operator" "")
13011                  (const_string "fmul")
13012                (match_operand:XF 3 "div_operator" "")
13013                  (const_string "fdiv")
13014               ]
13015               (const_string "fop")))
13016    (set_attr "mode" "<MODE>")])
13017
13018 (define_insn "*fop_xf_6_i387"
13019   [(set (match_operand:XF 0 "register_operand" "=f,f")
13020         (match_operator:XF 3 "binary_fp_operator"
13021           [(float_extend:XF
13022              (match_operand:MODEF 1 "register_operand" "0,f"))
13023            (float_extend:XF
13024              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13025   "TARGET_80387"
13026   "* return output_387_binary_op (insn, operands);"
13027   [(set (attr "type")
13028         (cond [(match_operand:XF 3 "mult_operator" "")
13029                  (const_string "fmul")
13030                (match_operand:XF 3 "div_operator" "")
13031                  (const_string "fdiv")
13032               ]
13033               (const_string "fop")))
13034    (set_attr "mode" "<MODE>")])
13035
13036 (define_split
13037   [(set (match_operand 0 "register_operand" "")
13038         (match_operator 3 "binary_fp_operator"
13039            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13040             (match_operand 2 "register_operand" "")]))]
13041   "reload_completed
13042    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13043    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13044   [(const_int 0)]
13045 {
13046   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13047   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13048   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13049                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13050                                           GET_MODE (operands[3]),
13051                                           operands[4],
13052                                           operands[2])));
13053   ix86_free_from_memory (GET_MODE (operands[1]));
13054   DONE;
13055 })
13056
13057 (define_split
13058   [(set (match_operand 0 "register_operand" "")
13059         (match_operator 3 "binary_fp_operator"
13060            [(match_operand 1 "register_operand" "")
13061             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13062   "reload_completed
13063    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13064    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13065   [(const_int 0)]
13066 {
13067   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13068   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13069   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13070                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13071                                           GET_MODE (operands[3]),
13072                                           operands[1],
13073                                           operands[4])));
13074   ix86_free_from_memory (GET_MODE (operands[2]));
13075   DONE;
13076 })
13077 \f
13078 ;; FPU special functions.
13079
13080 ;; This pattern implements a no-op XFmode truncation for
13081 ;; all fancy i386 XFmode math functions.
13082
13083 (define_insn "truncxf<mode>2_i387_noop_unspec"
13084   [(set (match_operand:MODEF 0 "register_operand" "=f")
13085         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13086         UNSPEC_TRUNC_NOOP))]
13087   "TARGET_USE_FANCY_MATH_387"
13088   "* return output_387_reg_move (insn, operands);"
13089   [(set_attr "type" "fmov")
13090    (set_attr "mode" "<MODE>")])
13091
13092 (define_insn "sqrtxf2"
13093   [(set (match_operand:XF 0 "register_operand" "=f")
13094         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13095   "TARGET_USE_FANCY_MATH_387"
13096   "fsqrt"
13097   [(set_attr "type" "fpspc")
13098    (set_attr "mode" "XF")
13099    (set_attr "athlon_decode" "direct")
13100    (set_attr "amdfam10_decode" "direct")])
13101
13102 (define_insn "sqrt_extend<mode>xf2_i387"
13103   [(set (match_operand:XF 0 "register_operand" "=f")
13104         (sqrt:XF
13105           (float_extend:XF
13106             (match_operand:MODEF 1 "register_operand" "0"))))]
13107   "TARGET_USE_FANCY_MATH_387"
13108   "fsqrt"
13109   [(set_attr "type" "fpspc")
13110    (set_attr "mode" "XF")
13111    (set_attr "athlon_decode" "direct")
13112    (set_attr "amdfam10_decode" "direct")])
13113
13114 (define_insn "*rsqrtsf2_sse"
13115   [(set (match_operand:SF 0 "register_operand" "=x")
13116         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13117                    UNSPEC_RSQRT))]
13118   "TARGET_SSE_MATH"
13119   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13120   [(set_attr "type" "sse")
13121    (set_attr "atom_sse_attr" "rcp")
13122    (set_attr "prefix" "maybe_vex")
13123    (set_attr "mode" "SF")])
13124
13125 (define_expand "rsqrtsf2"
13126   [(set (match_operand:SF 0 "register_operand" "")
13127         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13128                    UNSPEC_RSQRT))]
13129   "TARGET_SSE_MATH"
13130 {
13131   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13132   DONE;
13133 })
13134
13135 (define_insn "*sqrt<mode>2_sse"
13136   [(set (match_operand:MODEF 0 "register_operand" "=x")
13137         (sqrt:MODEF
13138           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13139   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13140   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13141   [(set_attr "type" "sse")
13142    (set_attr "atom_sse_attr" "sqrt")
13143    (set_attr "prefix" "maybe_vex")
13144    (set_attr "mode" "<MODE>")
13145    (set_attr "athlon_decode" "*")
13146    (set_attr "amdfam10_decode" "*")])
13147
13148 (define_expand "sqrt<mode>2"
13149   [(set (match_operand:MODEF 0 "register_operand" "")
13150         (sqrt:MODEF
13151           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13152   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13153    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13154 {
13155   if (<MODE>mode == SFmode
13156       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13157       && flag_finite_math_only && !flag_trapping_math
13158       && flag_unsafe_math_optimizations)
13159     {
13160       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13161       DONE;
13162     }
13163
13164   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13165     {
13166       rtx op0 = gen_reg_rtx (XFmode);
13167       rtx op1 = force_reg (<MODE>mode, operands[1]);
13168
13169       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13170       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13171       DONE;
13172    }
13173 })
13174
13175 (define_insn "fpremxf4_i387"
13176   [(set (match_operand:XF 0 "register_operand" "=f")
13177         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13178                     (match_operand:XF 3 "register_operand" "1")]
13179                    UNSPEC_FPREM_F))
13180    (set (match_operand:XF 1 "register_operand" "=u")
13181         (unspec:XF [(match_dup 2) (match_dup 3)]
13182                    UNSPEC_FPREM_U))
13183    (set (reg:CCFP FPSR_REG)
13184         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13185                      UNSPEC_C2_FLAG))]
13186   "TARGET_USE_FANCY_MATH_387"
13187   "fprem"
13188   [(set_attr "type" "fpspc")
13189    (set_attr "mode" "XF")])
13190
13191 (define_expand "fmodxf3"
13192   [(use (match_operand:XF 0 "register_operand" ""))
13193    (use (match_operand:XF 1 "general_operand" ""))
13194    (use (match_operand:XF 2 "general_operand" ""))]
13195   "TARGET_USE_FANCY_MATH_387"
13196 {
13197   rtx label = gen_label_rtx ();
13198
13199   rtx op1 = gen_reg_rtx (XFmode);
13200   rtx op2 = gen_reg_rtx (XFmode);
13201
13202   emit_move_insn (op2, operands[2]);
13203   emit_move_insn (op1, operands[1]);
13204
13205   emit_label (label);
13206   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13207   ix86_emit_fp_unordered_jump (label);
13208   LABEL_NUSES (label) = 1;
13209
13210   emit_move_insn (operands[0], op1);
13211   DONE;
13212 })
13213
13214 (define_expand "fmod<mode>3"
13215   [(use (match_operand:MODEF 0 "register_operand" ""))
13216    (use (match_operand:MODEF 1 "general_operand" ""))
13217    (use (match_operand:MODEF 2 "general_operand" ""))]
13218   "TARGET_USE_FANCY_MATH_387"
13219 {
13220   rtx label = gen_label_rtx ();
13221
13222   rtx op1 = gen_reg_rtx (XFmode);
13223   rtx op2 = gen_reg_rtx (XFmode);
13224
13225   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13226   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13227
13228   emit_label (label);
13229   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13230   ix86_emit_fp_unordered_jump (label);
13231   LABEL_NUSES (label) = 1;
13232
13233   /* Truncate the result properly for strict SSE math.  */
13234   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13235       && !TARGET_MIX_SSE_I387)
13236     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13237   else
13238     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13239
13240   DONE;
13241 })
13242
13243 (define_insn "fprem1xf4_i387"
13244   [(set (match_operand:XF 0 "register_operand" "=f")
13245         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13246                     (match_operand:XF 3 "register_operand" "1")]
13247                    UNSPEC_FPREM1_F))
13248    (set (match_operand:XF 1 "register_operand" "=u")
13249         (unspec:XF [(match_dup 2) (match_dup 3)]
13250                    UNSPEC_FPREM1_U))
13251    (set (reg:CCFP FPSR_REG)
13252         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13253                      UNSPEC_C2_FLAG))]
13254   "TARGET_USE_FANCY_MATH_387"
13255   "fprem1"
13256   [(set_attr "type" "fpspc")
13257    (set_attr "mode" "XF")])
13258
13259 (define_expand "remainderxf3"
13260   [(use (match_operand:XF 0 "register_operand" ""))
13261    (use (match_operand:XF 1 "general_operand" ""))
13262    (use (match_operand:XF 2 "general_operand" ""))]
13263   "TARGET_USE_FANCY_MATH_387"
13264 {
13265   rtx label = gen_label_rtx ();
13266
13267   rtx op1 = gen_reg_rtx (XFmode);
13268   rtx op2 = gen_reg_rtx (XFmode);
13269
13270   emit_move_insn (op2, operands[2]);
13271   emit_move_insn (op1, operands[1]);
13272
13273   emit_label (label);
13274   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13275   ix86_emit_fp_unordered_jump (label);
13276   LABEL_NUSES (label) = 1;
13277
13278   emit_move_insn (operands[0], op1);
13279   DONE;
13280 })
13281
13282 (define_expand "remainder<mode>3"
13283   [(use (match_operand:MODEF 0 "register_operand" ""))
13284    (use (match_operand:MODEF 1 "general_operand" ""))
13285    (use (match_operand:MODEF 2 "general_operand" ""))]
13286   "TARGET_USE_FANCY_MATH_387"
13287 {
13288   rtx label = gen_label_rtx ();
13289
13290   rtx op1 = gen_reg_rtx (XFmode);
13291   rtx op2 = gen_reg_rtx (XFmode);
13292
13293   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13294   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13295
13296   emit_label (label);
13297
13298   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13299   ix86_emit_fp_unordered_jump (label);
13300   LABEL_NUSES (label) = 1;
13301
13302   /* Truncate the result properly for strict SSE math.  */
13303   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13304       && !TARGET_MIX_SSE_I387)
13305     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13306   else
13307     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13308
13309   DONE;
13310 })
13311
13312 (define_insn "*sinxf2_i387"
13313   [(set (match_operand:XF 0 "register_operand" "=f")
13314         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13315   "TARGET_USE_FANCY_MATH_387
13316    && flag_unsafe_math_optimizations"
13317   "fsin"
13318   [(set_attr "type" "fpspc")
13319    (set_attr "mode" "XF")])
13320
13321 (define_insn "*sin_extend<mode>xf2_i387"
13322   [(set (match_operand:XF 0 "register_operand" "=f")
13323         (unspec:XF [(float_extend:XF
13324                       (match_operand:MODEF 1 "register_operand" "0"))]
13325                    UNSPEC_SIN))]
13326   "TARGET_USE_FANCY_MATH_387
13327    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13328        || TARGET_MIX_SSE_I387)
13329    && flag_unsafe_math_optimizations"
13330   "fsin"
13331   [(set_attr "type" "fpspc")
13332    (set_attr "mode" "XF")])
13333
13334 (define_insn "*cosxf2_i387"
13335   [(set (match_operand:XF 0 "register_operand" "=f")
13336         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13337   "TARGET_USE_FANCY_MATH_387
13338    && flag_unsafe_math_optimizations"
13339   "fcos"
13340   [(set_attr "type" "fpspc")
13341    (set_attr "mode" "XF")])
13342
13343 (define_insn "*cos_extend<mode>xf2_i387"
13344   [(set (match_operand:XF 0 "register_operand" "=f")
13345         (unspec:XF [(float_extend:XF
13346                       (match_operand:MODEF 1 "register_operand" "0"))]
13347                    UNSPEC_COS))]
13348   "TARGET_USE_FANCY_MATH_387
13349    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13350        || TARGET_MIX_SSE_I387)
13351    && flag_unsafe_math_optimizations"
13352   "fcos"
13353   [(set_attr "type" "fpspc")
13354    (set_attr "mode" "XF")])
13355
13356 ;; When sincos pattern is defined, sin and cos builtin functions will be
13357 ;; expanded to sincos pattern with one of its outputs left unused.
13358 ;; CSE pass will figure out if two sincos patterns can be combined,
13359 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13360 ;; depending on the unused output.
13361
13362 (define_insn "sincosxf3"
13363   [(set (match_operand:XF 0 "register_operand" "=f")
13364         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13365                    UNSPEC_SINCOS_COS))
13366    (set (match_operand:XF 1 "register_operand" "=u")
13367         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13368   "TARGET_USE_FANCY_MATH_387
13369    && flag_unsafe_math_optimizations"
13370   "fsincos"
13371   [(set_attr "type" "fpspc")
13372    (set_attr "mode" "XF")])
13373
13374 (define_split
13375   [(set (match_operand:XF 0 "register_operand" "")
13376         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13377                    UNSPEC_SINCOS_COS))
13378    (set (match_operand:XF 1 "register_operand" "")
13379         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13380   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13381    && !(reload_completed || reload_in_progress)"
13382   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13383   "")
13384
13385 (define_split
13386   [(set (match_operand:XF 0 "register_operand" "")
13387         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13388                    UNSPEC_SINCOS_COS))
13389    (set (match_operand:XF 1 "register_operand" "")
13390         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13391   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13392    && !(reload_completed || reload_in_progress)"
13393   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13394   "")
13395
13396 (define_insn "sincos_extend<mode>xf3_i387"
13397   [(set (match_operand:XF 0 "register_operand" "=f")
13398         (unspec:XF [(float_extend:XF
13399                       (match_operand:MODEF 2 "register_operand" "0"))]
13400                    UNSPEC_SINCOS_COS))
13401    (set (match_operand:XF 1 "register_operand" "=u")
13402         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13403   "TARGET_USE_FANCY_MATH_387
13404    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13405        || TARGET_MIX_SSE_I387)
13406    && flag_unsafe_math_optimizations"
13407   "fsincos"
13408   [(set_attr "type" "fpspc")
13409    (set_attr "mode" "XF")])
13410
13411 (define_split
13412   [(set (match_operand:XF 0 "register_operand" "")
13413         (unspec:XF [(float_extend:XF
13414                       (match_operand:MODEF 2 "register_operand" ""))]
13415                    UNSPEC_SINCOS_COS))
13416    (set (match_operand:XF 1 "register_operand" "")
13417         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13418   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13419    && !(reload_completed || reload_in_progress)"
13420   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13421   "")
13422
13423 (define_split
13424   [(set (match_operand:XF 0 "register_operand" "")
13425         (unspec:XF [(float_extend:XF
13426                       (match_operand:MODEF 2 "register_operand" ""))]
13427                    UNSPEC_SINCOS_COS))
13428    (set (match_operand:XF 1 "register_operand" "")
13429         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13430   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13431    && !(reload_completed || reload_in_progress)"
13432   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13433   "")
13434
13435 (define_expand "sincos<mode>3"
13436   [(use (match_operand:MODEF 0 "register_operand" ""))
13437    (use (match_operand:MODEF 1 "register_operand" ""))
13438    (use (match_operand:MODEF 2 "register_operand" ""))]
13439   "TARGET_USE_FANCY_MATH_387
13440    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13441        || TARGET_MIX_SSE_I387)
13442    && flag_unsafe_math_optimizations"
13443 {
13444   rtx op0 = gen_reg_rtx (XFmode);
13445   rtx op1 = gen_reg_rtx (XFmode);
13446
13447   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13448   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13449   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13450   DONE;
13451 })
13452
13453 (define_insn "fptanxf4_i387"
13454   [(set (match_operand:XF 0 "register_operand" "=f")
13455         (match_operand:XF 3 "const_double_operand" "F"))
13456    (set (match_operand:XF 1 "register_operand" "=u")
13457         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13458                    UNSPEC_TAN))]
13459   "TARGET_USE_FANCY_MATH_387
13460    && flag_unsafe_math_optimizations
13461    && standard_80387_constant_p (operands[3]) == 2"
13462   "fptan"
13463   [(set_attr "type" "fpspc")
13464    (set_attr "mode" "XF")])
13465
13466 (define_insn "fptan_extend<mode>xf4_i387"
13467   [(set (match_operand:MODEF 0 "register_operand" "=f")
13468         (match_operand:MODEF 3 "const_double_operand" "F"))
13469    (set (match_operand:XF 1 "register_operand" "=u")
13470         (unspec:XF [(float_extend:XF
13471                       (match_operand:MODEF 2 "register_operand" "0"))]
13472                    UNSPEC_TAN))]
13473   "TARGET_USE_FANCY_MATH_387
13474    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13475        || TARGET_MIX_SSE_I387)
13476    && flag_unsafe_math_optimizations
13477    && standard_80387_constant_p (operands[3]) == 2"
13478   "fptan"
13479   [(set_attr "type" "fpspc")
13480    (set_attr "mode" "XF")])
13481
13482 (define_expand "tanxf2"
13483   [(use (match_operand:XF 0 "register_operand" ""))
13484    (use (match_operand:XF 1 "register_operand" ""))]
13485   "TARGET_USE_FANCY_MATH_387
13486    && flag_unsafe_math_optimizations"
13487 {
13488   rtx one = gen_reg_rtx (XFmode);
13489   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13490
13491   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13492   DONE;
13493 })
13494
13495 (define_expand "tan<mode>2"
13496   [(use (match_operand:MODEF 0 "register_operand" ""))
13497    (use (match_operand:MODEF 1 "register_operand" ""))]
13498   "TARGET_USE_FANCY_MATH_387
13499    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13500        || TARGET_MIX_SSE_I387)
13501    && flag_unsafe_math_optimizations"
13502 {
13503   rtx op0 = gen_reg_rtx (XFmode);
13504
13505   rtx one = gen_reg_rtx (<MODE>mode);
13506   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13507
13508   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13509                                              operands[1], op2));
13510   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13511   DONE;
13512 })
13513
13514 (define_insn "*fpatanxf3_i387"
13515   [(set (match_operand:XF 0 "register_operand" "=f")
13516         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13517                     (match_operand:XF 2 "register_operand" "u")]
13518                    UNSPEC_FPATAN))
13519    (clobber (match_scratch:XF 3 "=2"))]
13520   "TARGET_USE_FANCY_MATH_387
13521    && flag_unsafe_math_optimizations"
13522   "fpatan"
13523   [(set_attr "type" "fpspc")
13524    (set_attr "mode" "XF")])
13525
13526 (define_insn "fpatan_extend<mode>xf3_i387"
13527   [(set (match_operand:XF 0 "register_operand" "=f")
13528         (unspec:XF [(float_extend:XF
13529                       (match_operand:MODEF 1 "register_operand" "0"))
13530                     (float_extend:XF
13531                       (match_operand:MODEF 2 "register_operand" "u"))]
13532                    UNSPEC_FPATAN))
13533    (clobber (match_scratch:XF 3 "=2"))]
13534   "TARGET_USE_FANCY_MATH_387
13535    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13536        || TARGET_MIX_SSE_I387)
13537    && flag_unsafe_math_optimizations"
13538   "fpatan"
13539   [(set_attr "type" "fpspc")
13540    (set_attr "mode" "XF")])
13541
13542 (define_expand "atan2xf3"
13543   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13544                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13545                                (match_operand:XF 1 "register_operand" "")]
13546                               UNSPEC_FPATAN))
13547               (clobber (match_scratch:XF 3 ""))])]
13548   "TARGET_USE_FANCY_MATH_387
13549    && flag_unsafe_math_optimizations"
13550   "")
13551
13552 (define_expand "atan2<mode>3"
13553   [(use (match_operand:MODEF 0 "register_operand" ""))
13554    (use (match_operand:MODEF 1 "register_operand" ""))
13555    (use (match_operand:MODEF 2 "register_operand" ""))]
13556   "TARGET_USE_FANCY_MATH_387
13557    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13558        || TARGET_MIX_SSE_I387)
13559    && flag_unsafe_math_optimizations"
13560 {
13561   rtx op0 = gen_reg_rtx (XFmode);
13562
13563   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13564   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13565   DONE;
13566 })
13567
13568 (define_expand "atanxf2"
13569   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13570                    (unspec:XF [(match_dup 2)
13571                                (match_operand:XF 1 "register_operand" "")]
13572                               UNSPEC_FPATAN))
13573               (clobber (match_scratch:XF 3 ""))])]
13574   "TARGET_USE_FANCY_MATH_387
13575    && flag_unsafe_math_optimizations"
13576 {
13577   operands[2] = gen_reg_rtx (XFmode);
13578   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13579 })
13580
13581 (define_expand "atan<mode>2"
13582   [(use (match_operand:MODEF 0 "register_operand" ""))
13583    (use (match_operand:MODEF 1 "register_operand" ""))]
13584   "TARGET_USE_FANCY_MATH_387
13585    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13586        || TARGET_MIX_SSE_I387)
13587    && flag_unsafe_math_optimizations"
13588 {
13589   rtx op0 = gen_reg_rtx (XFmode);
13590
13591   rtx op2 = gen_reg_rtx (<MODE>mode);
13592   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13593
13594   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13595   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13596   DONE;
13597 })
13598
13599 (define_expand "asinxf2"
13600   [(set (match_dup 2)
13601         (mult:XF (match_operand:XF 1 "register_operand" "")
13602                  (match_dup 1)))
13603    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13604    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13605    (parallel [(set (match_operand:XF 0 "register_operand" "")
13606                    (unspec:XF [(match_dup 5) (match_dup 1)]
13607                               UNSPEC_FPATAN))
13608               (clobber (match_scratch:XF 6 ""))])]
13609   "TARGET_USE_FANCY_MATH_387
13610    && flag_unsafe_math_optimizations"
13611 {
13612   int i;
13613
13614   if (optimize_insn_for_size_p ())
13615     FAIL;
13616
13617   for (i = 2; i < 6; i++)
13618     operands[i] = gen_reg_rtx (XFmode);
13619
13620   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13621 })
13622
13623 (define_expand "asin<mode>2"
13624   [(use (match_operand:MODEF 0 "register_operand" ""))
13625    (use (match_operand:MODEF 1 "general_operand" ""))]
13626  "TARGET_USE_FANCY_MATH_387
13627    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13628        || TARGET_MIX_SSE_I387)
13629    && flag_unsafe_math_optimizations"
13630 {
13631   rtx op0 = gen_reg_rtx (XFmode);
13632   rtx op1 = gen_reg_rtx (XFmode);
13633
13634   if (optimize_insn_for_size_p ())
13635     FAIL;
13636
13637   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13638   emit_insn (gen_asinxf2 (op0, op1));
13639   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13640   DONE;
13641 })
13642
13643 (define_expand "acosxf2"
13644   [(set (match_dup 2)
13645         (mult:XF (match_operand:XF 1 "register_operand" "")
13646                  (match_dup 1)))
13647    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13648    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13649    (parallel [(set (match_operand:XF 0 "register_operand" "")
13650                    (unspec:XF [(match_dup 1) (match_dup 5)]
13651                               UNSPEC_FPATAN))
13652               (clobber (match_scratch:XF 6 ""))])]
13653   "TARGET_USE_FANCY_MATH_387
13654    && flag_unsafe_math_optimizations"
13655 {
13656   int i;
13657
13658   if (optimize_insn_for_size_p ())
13659     FAIL;
13660
13661   for (i = 2; i < 6; i++)
13662     operands[i] = gen_reg_rtx (XFmode);
13663
13664   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13665 })
13666
13667 (define_expand "acos<mode>2"
13668   [(use (match_operand:MODEF 0 "register_operand" ""))
13669    (use (match_operand:MODEF 1 "general_operand" ""))]
13670  "TARGET_USE_FANCY_MATH_387
13671    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13672        || TARGET_MIX_SSE_I387)
13673    && flag_unsafe_math_optimizations"
13674 {
13675   rtx op0 = gen_reg_rtx (XFmode);
13676   rtx op1 = gen_reg_rtx (XFmode);
13677
13678   if (optimize_insn_for_size_p ())
13679     FAIL;
13680
13681   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13682   emit_insn (gen_acosxf2 (op0, op1));
13683   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13684   DONE;
13685 })
13686
13687 (define_insn "fyl2xxf3_i387"
13688   [(set (match_operand:XF 0 "register_operand" "=f")
13689         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13690                     (match_operand:XF 2 "register_operand" "u")]
13691                    UNSPEC_FYL2X))
13692    (clobber (match_scratch:XF 3 "=2"))]
13693   "TARGET_USE_FANCY_MATH_387
13694    && flag_unsafe_math_optimizations"
13695   "fyl2x"
13696   [(set_attr "type" "fpspc")
13697    (set_attr "mode" "XF")])
13698
13699 (define_insn "fyl2x_extend<mode>xf3_i387"
13700   [(set (match_operand:XF 0 "register_operand" "=f")
13701         (unspec:XF [(float_extend:XF
13702                       (match_operand:MODEF 1 "register_operand" "0"))
13703                     (match_operand:XF 2 "register_operand" "u")]
13704                    UNSPEC_FYL2X))
13705    (clobber (match_scratch:XF 3 "=2"))]
13706   "TARGET_USE_FANCY_MATH_387
13707    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13708        || TARGET_MIX_SSE_I387)
13709    && flag_unsafe_math_optimizations"
13710   "fyl2x"
13711   [(set_attr "type" "fpspc")
13712    (set_attr "mode" "XF")])
13713
13714 (define_expand "logxf2"
13715   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13716                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13717                                (match_dup 2)] UNSPEC_FYL2X))
13718               (clobber (match_scratch:XF 3 ""))])]
13719   "TARGET_USE_FANCY_MATH_387
13720    && flag_unsafe_math_optimizations"
13721 {
13722   operands[2] = gen_reg_rtx (XFmode);
13723   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13724 })
13725
13726 (define_expand "log<mode>2"
13727   [(use (match_operand:MODEF 0 "register_operand" ""))
13728    (use (match_operand:MODEF 1 "register_operand" ""))]
13729   "TARGET_USE_FANCY_MATH_387
13730    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13731        || TARGET_MIX_SSE_I387)
13732    && flag_unsafe_math_optimizations"
13733 {
13734   rtx op0 = gen_reg_rtx (XFmode);
13735
13736   rtx op2 = gen_reg_rtx (XFmode);
13737   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13738
13739   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13740   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13741   DONE;
13742 })
13743
13744 (define_expand "log10xf2"
13745   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13746                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13747                                (match_dup 2)] UNSPEC_FYL2X))
13748               (clobber (match_scratch:XF 3 ""))])]
13749   "TARGET_USE_FANCY_MATH_387
13750    && flag_unsafe_math_optimizations"
13751 {
13752   operands[2] = gen_reg_rtx (XFmode);
13753   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13754 })
13755
13756 (define_expand "log10<mode>2"
13757   [(use (match_operand:MODEF 0 "register_operand" ""))
13758    (use (match_operand:MODEF 1 "register_operand" ""))]
13759   "TARGET_USE_FANCY_MATH_387
13760    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13761        || TARGET_MIX_SSE_I387)
13762    && flag_unsafe_math_optimizations"
13763 {
13764   rtx op0 = gen_reg_rtx (XFmode);
13765
13766   rtx op2 = gen_reg_rtx (XFmode);
13767   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13768
13769   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13770   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13771   DONE;
13772 })
13773
13774 (define_expand "log2xf2"
13775   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13776                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13777                                (match_dup 2)] UNSPEC_FYL2X))
13778               (clobber (match_scratch:XF 3 ""))])]
13779   "TARGET_USE_FANCY_MATH_387
13780    && flag_unsafe_math_optimizations"
13781 {
13782   operands[2] = gen_reg_rtx (XFmode);
13783   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13784 })
13785
13786 (define_expand "log2<mode>2"
13787   [(use (match_operand:MODEF 0 "register_operand" ""))
13788    (use (match_operand:MODEF 1 "register_operand" ""))]
13789   "TARGET_USE_FANCY_MATH_387
13790    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13791        || TARGET_MIX_SSE_I387)
13792    && flag_unsafe_math_optimizations"
13793 {
13794   rtx op0 = gen_reg_rtx (XFmode);
13795
13796   rtx op2 = gen_reg_rtx (XFmode);
13797   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13798
13799   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13800   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13801   DONE;
13802 })
13803
13804 (define_insn "fyl2xp1xf3_i387"
13805   [(set (match_operand:XF 0 "register_operand" "=f")
13806         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13807                     (match_operand:XF 2 "register_operand" "u")]
13808                    UNSPEC_FYL2XP1))
13809    (clobber (match_scratch:XF 3 "=2"))]
13810   "TARGET_USE_FANCY_MATH_387
13811    && flag_unsafe_math_optimizations"
13812   "fyl2xp1"
13813   [(set_attr "type" "fpspc")
13814    (set_attr "mode" "XF")])
13815
13816 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13817   [(set (match_operand:XF 0 "register_operand" "=f")
13818         (unspec:XF [(float_extend:XF
13819                       (match_operand:MODEF 1 "register_operand" "0"))
13820                     (match_operand:XF 2 "register_operand" "u")]
13821                    UNSPEC_FYL2XP1))
13822    (clobber (match_scratch:XF 3 "=2"))]
13823   "TARGET_USE_FANCY_MATH_387
13824    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13825        || TARGET_MIX_SSE_I387)
13826    && flag_unsafe_math_optimizations"
13827   "fyl2xp1"
13828   [(set_attr "type" "fpspc")
13829    (set_attr "mode" "XF")])
13830
13831 (define_expand "log1pxf2"
13832   [(use (match_operand:XF 0 "register_operand" ""))
13833    (use (match_operand:XF 1 "register_operand" ""))]
13834   "TARGET_USE_FANCY_MATH_387
13835    && flag_unsafe_math_optimizations"
13836 {
13837   if (optimize_insn_for_size_p ())
13838     FAIL;
13839
13840   ix86_emit_i387_log1p (operands[0], operands[1]);
13841   DONE;
13842 })
13843
13844 (define_expand "log1p<mode>2"
13845   [(use (match_operand:MODEF 0 "register_operand" ""))
13846    (use (match_operand:MODEF 1 "register_operand" ""))]
13847   "TARGET_USE_FANCY_MATH_387
13848    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13849        || TARGET_MIX_SSE_I387)
13850    && flag_unsafe_math_optimizations"
13851 {
13852   rtx op0;
13853
13854   if (optimize_insn_for_size_p ())
13855     FAIL;
13856
13857   op0 = gen_reg_rtx (XFmode);
13858
13859   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13860
13861   ix86_emit_i387_log1p (op0, operands[1]);
13862   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13863   DONE;
13864 })
13865
13866 (define_insn "fxtractxf3_i387"
13867   [(set (match_operand:XF 0 "register_operand" "=f")
13868         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13869                    UNSPEC_XTRACT_FRACT))
13870    (set (match_operand:XF 1 "register_operand" "=u")
13871         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13872   "TARGET_USE_FANCY_MATH_387
13873    && flag_unsafe_math_optimizations"
13874   "fxtract"
13875   [(set_attr "type" "fpspc")
13876    (set_attr "mode" "XF")])
13877
13878 (define_insn "fxtract_extend<mode>xf3_i387"
13879   [(set (match_operand:XF 0 "register_operand" "=f")
13880         (unspec:XF [(float_extend:XF
13881                       (match_operand:MODEF 2 "register_operand" "0"))]
13882                    UNSPEC_XTRACT_FRACT))
13883    (set (match_operand:XF 1 "register_operand" "=u")
13884         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13885   "TARGET_USE_FANCY_MATH_387
13886    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13887        || TARGET_MIX_SSE_I387)
13888    && flag_unsafe_math_optimizations"
13889   "fxtract"
13890   [(set_attr "type" "fpspc")
13891    (set_attr "mode" "XF")])
13892
13893 (define_expand "logbxf2"
13894   [(parallel [(set (match_dup 2)
13895                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13896                               UNSPEC_XTRACT_FRACT))
13897               (set (match_operand:XF 0 "register_operand" "")
13898                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13899   "TARGET_USE_FANCY_MATH_387
13900    && flag_unsafe_math_optimizations"
13901 {
13902   operands[2] = gen_reg_rtx (XFmode);
13903 })
13904
13905 (define_expand "logb<mode>2"
13906   [(use (match_operand:MODEF 0 "register_operand" ""))
13907    (use (match_operand:MODEF 1 "register_operand" ""))]
13908   "TARGET_USE_FANCY_MATH_387
13909    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13910        || TARGET_MIX_SSE_I387)
13911    && flag_unsafe_math_optimizations"
13912 {
13913   rtx op0 = gen_reg_rtx (XFmode);
13914   rtx op1 = gen_reg_rtx (XFmode);
13915
13916   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13917   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13918   DONE;
13919 })
13920
13921 (define_expand "ilogbxf2"
13922   [(use (match_operand:SI 0 "register_operand" ""))
13923    (use (match_operand:XF 1 "register_operand" ""))]
13924   "TARGET_USE_FANCY_MATH_387
13925    && flag_unsafe_math_optimizations"
13926 {
13927   rtx op0, op1;
13928
13929   if (optimize_insn_for_size_p ())
13930     FAIL;
13931
13932   op0 = gen_reg_rtx (XFmode);
13933   op1 = gen_reg_rtx (XFmode);
13934
13935   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13936   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13937   DONE;
13938 })
13939
13940 (define_expand "ilogb<mode>2"
13941   [(use (match_operand:SI 0 "register_operand" ""))
13942    (use (match_operand:MODEF 1 "register_operand" ""))]
13943   "TARGET_USE_FANCY_MATH_387
13944    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13945        || TARGET_MIX_SSE_I387)
13946    && flag_unsafe_math_optimizations"
13947 {
13948   rtx op0, op1;
13949
13950   if (optimize_insn_for_size_p ())
13951     FAIL;
13952
13953   op0 = gen_reg_rtx (XFmode);
13954   op1 = gen_reg_rtx (XFmode);
13955
13956   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13957   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13958   DONE;
13959 })
13960
13961 (define_insn "*f2xm1xf2_i387"
13962   [(set (match_operand:XF 0 "register_operand" "=f")
13963         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13964                    UNSPEC_F2XM1))]
13965   "TARGET_USE_FANCY_MATH_387
13966    && flag_unsafe_math_optimizations"
13967   "f2xm1"
13968   [(set_attr "type" "fpspc")
13969    (set_attr "mode" "XF")])
13970
13971 (define_insn "*fscalexf4_i387"
13972   [(set (match_operand:XF 0 "register_operand" "=f")
13973         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13974                     (match_operand:XF 3 "register_operand" "1")]
13975                    UNSPEC_FSCALE_FRACT))
13976    (set (match_operand:XF 1 "register_operand" "=u")
13977         (unspec:XF [(match_dup 2) (match_dup 3)]
13978                    UNSPEC_FSCALE_EXP))]
13979   "TARGET_USE_FANCY_MATH_387
13980    && flag_unsafe_math_optimizations"
13981   "fscale"
13982   [(set_attr "type" "fpspc")
13983    (set_attr "mode" "XF")])
13984
13985 (define_expand "expNcorexf3"
13986   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13987                                (match_operand:XF 2 "register_operand" "")))
13988    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13989    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13990    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13991    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13992    (parallel [(set (match_operand:XF 0 "register_operand" "")
13993                    (unspec:XF [(match_dup 8) (match_dup 4)]
13994                               UNSPEC_FSCALE_FRACT))
13995               (set (match_dup 9)
13996                    (unspec:XF [(match_dup 8) (match_dup 4)]
13997                               UNSPEC_FSCALE_EXP))])]
13998   "TARGET_USE_FANCY_MATH_387
13999    && flag_unsafe_math_optimizations"
14000 {
14001   int i;
14002
14003   if (optimize_insn_for_size_p ())
14004     FAIL;
14005
14006   for (i = 3; i < 10; i++)
14007     operands[i] = gen_reg_rtx (XFmode);
14008
14009   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14010 })
14011
14012 (define_expand "expxf2"
14013   [(use (match_operand:XF 0 "register_operand" ""))
14014    (use (match_operand:XF 1 "register_operand" ""))]
14015   "TARGET_USE_FANCY_MATH_387
14016    && flag_unsafe_math_optimizations"
14017 {
14018   rtx op2;
14019
14020   if (optimize_insn_for_size_p ())
14021     FAIL;
14022
14023   op2 = gen_reg_rtx (XFmode);
14024   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14025
14026   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14027   DONE;
14028 })
14029
14030 (define_expand "exp<mode>2"
14031   [(use (match_operand:MODEF 0 "register_operand" ""))
14032    (use (match_operand:MODEF 1 "general_operand" ""))]
14033  "TARGET_USE_FANCY_MATH_387
14034    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14035        || TARGET_MIX_SSE_I387)
14036    && flag_unsafe_math_optimizations"
14037 {
14038   rtx op0, op1;
14039
14040   if (optimize_insn_for_size_p ())
14041     FAIL;
14042
14043   op0 = gen_reg_rtx (XFmode);
14044   op1 = gen_reg_rtx (XFmode);
14045
14046   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14047   emit_insn (gen_expxf2 (op0, op1));
14048   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14049   DONE;
14050 })
14051
14052 (define_expand "exp10xf2"
14053   [(use (match_operand:XF 0 "register_operand" ""))
14054    (use (match_operand:XF 1 "register_operand" ""))]
14055   "TARGET_USE_FANCY_MATH_387
14056    && flag_unsafe_math_optimizations"
14057 {
14058   rtx op2;
14059
14060   if (optimize_insn_for_size_p ())
14061     FAIL;
14062
14063   op2 = gen_reg_rtx (XFmode);
14064   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14065
14066   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14067   DONE;
14068 })
14069
14070 (define_expand "exp10<mode>2"
14071   [(use (match_operand:MODEF 0 "register_operand" ""))
14072    (use (match_operand:MODEF 1 "general_operand" ""))]
14073  "TARGET_USE_FANCY_MATH_387
14074    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14075        || TARGET_MIX_SSE_I387)
14076    && flag_unsafe_math_optimizations"
14077 {
14078   rtx op0, op1;
14079
14080   if (optimize_insn_for_size_p ())
14081     FAIL;
14082
14083   op0 = gen_reg_rtx (XFmode);
14084   op1 = gen_reg_rtx (XFmode);
14085
14086   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14087   emit_insn (gen_exp10xf2 (op0, op1));
14088   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14089   DONE;
14090 })
14091
14092 (define_expand "exp2xf2"
14093   [(use (match_operand:XF 0 "register_operand" ""))
14094    (use (match_operand:XF 1 "register_operand" ""))]
14095   "TARGET_USE_FANCY_MATH_387
14096    && flag_unsafe_math_optimizations"
14097 {
14098   rtx op2;
14099
14100   if (optimize_insn_for_size_p ())
14101     FAIL;
14102
14103   op2 = gen_reg_rtx (XFmode);
14104   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14105
14106   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14107   DONE;
14108 })
14109
14110 (define_expand "exp2<mode>2"
14111   [(use (match_operand:MODEF 0 "register_operand" ""))
14112    (use (match_operand:MODEF 1 "general_operand" ""))]
14113  "TARGET_USE_FANCY_MATH_387
14114    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14115        || TARGET_MIX_SSE_I387)
14116    && flag_unsafe_math_optimizations"
14117 {
14118   rtx op0, op1;
14119
14120   if (optimize_insn_for_size_p ())
14121     FAIL;
14122
14123   op0 = gen_reg_rtx (XFmode);
14124   op1 = gen_reg_rtx (XFmode);
14125
14126   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14127   emit_insn (gen_exp2xf2 (op0, op1));
14128   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14129   DONE;
14130 })
14131
14132 (define_expand "expm1xf2"
14133   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14134                                (match_dup 2)))
14135    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14136    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14137    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14138    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14139    (parallel [(set (match_dup 7)
14140                    (unspec:XF [(match_dup 6) (match_dup 4)]
14141                               UNSPEC_FSCALE_FRACT))
14142               (set (match_dup 8)
14143                    (unspec:XF [(match_dup 6) (match_dup 4)]
14144                               UNSPEC_FSCALE_EXP))])
14145    (parallel [(set (match_dup 10)
14146                    (unspec:XF [(match_dup 9) (match_dup 8)]
14147                               UNSPEC_FSCALE_FRACT))
14148               (set (match_dup 11)
14149                    (unspec:XF [(match_dup 9) (match_dup 8)]
14150                               UNSPEC_FSCALE_EXP))])
14151    (set (match_dup 12) (minus:XF (match_dup 10)
14152                                  (float_extend:XF (match_dup 13))))
14153    (set (match_operand:XF 0 "register_operand" "")
14154         (plus:XF (match_dup 12) (match_dup 7)))]
14155   "TARGET_USE_FANCY_MATH_387
14156    && flag_unsafe_math_optimizations"
14157 {
14158   int i;
14159
14160   if (optimize_insn_for_size_p ())
14161     FAIL;
14162
14163   for (i = 2; i < 13; i++)
14164     operands[i] = gen_reg_rtx (XFmode);
14165
14166   operands[13]
14167     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14168
14169   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14170 })
14171
14172 (define_expand "expm1<mode>2"
14173   [(use (match_operand:MODEF 0 "register_operand" ""))
14174    (use (match_operand:MODEF 1 "general_operand" ""))]
14175  "TARGET_USE_FANCY_MATH_387
14176    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14177        || TARGET_MIX_SSE_I387)
14178    && flag_unsafe_math_optimizations"
14179 {
14180   rtx op0, op1;
14181
14182   if (optimize_insn_for_size_p ())
14183     FAIL;
14184
14185   op0 = gen_reg_rtx (XFmode);
14186   op1 = gen_reg_rtx (XFmode);
14187
14188   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14189   emit_insn (gen_expm1xf2 (op0, op1));
14190   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14191   DONE;
14192 })
14193
14194 (define_expand "ldexpxf3"
14195   [(set (match_dup 3)
14196         (float:XF (match_operand:SI 2 "register_operand" "")))
14197    (parallel [(set (match_operand:XF 0 " register_operand" "")
14198                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14199                                (match_dup 3)]
14200                               UNSPEC_FSCALE_FRACT))
14201               (set (match_dup 4)
14202                    (unspec:XF [(match_dup 1) (match_dup 3)]
14203                               UNSPEC_FSCALE_EXP))])]
14204   "TARGET_USE_FANCY_MATH_387
14205    && flag_unsafe_math_optimizations"
14206 {
14207   if (optimize_insn_for_size_p ())
14208     FAIL;
14209
14210   operands[3] = gen_reg_rtx (XFmode);
14211   operands[4] = gen_reg_rtx (XFmode);
14212 })
14213
14214 (define_expand "ldexp<mode>3"
14215   [(use (match_operand:MODEF 0 "register_operand" ""))
14216    (use (match_operand:MODEF 1 "general_operand" ""))
14217    (use (match_operand:SI 2 "register_operand" ""))]
14218  "TARGET_USE_FANCY_MATH_387
14219    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14220        || TARGET_MIX_SSE_I387)
14221    && flag_unsafe_math_optimizations"
14222 {
14223   rtx op0, op1;
14224
14225   if (optimize_insn_for_size_p ())
14226     FAIL;
14227
14228   op0 = gen_reg_rtx (XFmode);
14229   op1 = gen_reg_rtx (XFmode);
14230
14231   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14232   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14233   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14234   DONE;
14235 })
14236
14237 (define_expand "scalbxf3"
14238   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14239                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14240                                (match_operand:XF 2 "register_operand" "")]
14241                               UNSPEC_FSCALE_FRACT))
14242               (set (match_dup 3)
14243                    (unspec:XF [(match_dup 1) (match_dup 2)]
14244                               UNSPEC_FSCALE_EXP))])]
14245   "TARGET_USE_FANCY_MATH_387
14246    && flag_unsafe_math_optimizations"
14247 {
14248   if (optimize_insn_for_size_p ())
14249     FAIL;
14250
14251   operands[3] = gen_reg_rtx (XFmode);
14252 })
14253
14254 (define_expand "scalb<mode>3"
14255   [(use (match_operand:MODEF 0 "register_operand" ""))
14256    (use (match_operand:MODEF 1 "general_operand" ""))
14257    (use (match_operand:MODEF 2 "general_operand" ""))]
14258  "TARGET_USE_FANCY_MATH_387
14259    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14260        || TARGET_MIX_SSE_I387)
14261    && flag_unsafe_math_optimizations"
14262 {
14263   rtx op0, op1, op2;
14264
14265   if (optimize_insn_for_size_p ())
14266     FAIL;
14267
14268   op0 = gen_reg_rtx (XFmode);
14269   op1 = gen_reg_rtx (XFmode);
14270   op2 = gen_reg_rtx (XFmode);
14271
14272   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14273   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14274   emit_insn (gen_scalbxf3 (op0, op1, op2));
14275   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14276   DONE;
14277 })
14278
14279 (define_expand "significandxf2"
14280   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14281                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14282                               UNSPEC_XTRACT_FRACT))
14283               (set (match_dup 2)
14284                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14285   "TARGET_USE_FANCY_MATH_387
14286    && flag_unsafe_math_optimizations"
14287 {
14288   operands[2] = gen_reg_rtx (XFmode);
14289 })
14290
14291 (define_expand "significand<mode>2"
14292   [(use (match_operand:MODEF 0 "register_operand" ""))
14293    (use (match_operand:MODEF 1 "register_operand" ""))]
14294   "TARGET_USE_FANCY_MATH_387
14295    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296        || TARGET_MIX_SSE_I387)
14297    && flag_unsafe_math_optimizations"
14298 {
14299   rtx op0 = gen_reg_rtx (XFmode);
14300   rtx op1 = gen_reg_rtx (XFmode);
14301
14302   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14303   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14304   DONE;
14305 })
14306 \f
14307
14308 (define_insn "sse4_1_round<mode>2"
14309   [(set (match_operand:MODEF 0 "register_operand" "=x")
14310         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14311                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14312                       UNSPEC_ROUND))]
14313   "TARGET_ROUND"
14314   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14315   [(set_attr "type" "ssecvt")
14316    (set_attr "prefix_extra" "1")
14317    (set_attr "prefix" "maybe_vex")
14318    (set_attr "mode" "<MODE>")])
14319
14320 (define_insn "rintxf2"
14321   [(set (match_operand:XF 0 "register_operand" "=f")
14322         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14323                    UNSPEC_FRNDINT))]
14324   "TARGET_USE_FANCY_MATH_387
14325    && flag_unsafe_math_optimizations"
14326   "frndint"
14327   [(set_attr "type" "fpspc")
14328    (set_attr "mode" "XF")])
14329
14330 (define_expand "rint<mode>2"
14331   [(use (match_operand:MODEF 0 "register_operand" ""))
14332    (use (match_operand:MODEF 1 "register_operand" ""))]
14333   "(TARGET_USE_FANCY_MATH_387
14334     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14335         || TARGET_MIX_SSE_I387)
14336     && flag_unsafe_math_optimizations)
14337    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14338        && !flag_trapping_math)"
14339 {
14340   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14341       && !flag_trapping_math)
14342     {
14343       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14344         FAIL;
14345       if (TARGET_ROUND)
14346         emit_insn (gen_sse4_1_round<mode>2
14347                    (operands[0], operands[1], GEN_INT (0x04)));
14348       else
14349         ix86_expand_rint (operand0, operand1);
14350     }
14351   else
14352     {
14353       rtx op0 = gen_reg_rtx (XFmode);
14354       rtx op1 = gen_reg_rtx (XFmode);
14355
14356       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14357       emit_insn (gen_rintxf2 (op0, op1));
14358
14359       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14360     }
14361   DONE;
14362 })
14363
14364 (define_expand "round<mode>2"
14365   [(match_operand:MODEF 0 "register_operand" "")
14366    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14367   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14368    && !flag_trapping_math && !flag_rounding_math"
14369 {
14370   if (optimize_insn_for_size_p ())
14371     FAIL;
14372   if (TARGET_64BIT || (<MODE>mode != DFmode))
14373     ix86_expand_round (operand0, operand1);
14374   else
14375     ix86_expand_rounddf_32 (operand0, operand1);
14376   DONE;
14377 })
14378
14379 (define_insn_and_split "*fistdi2_1"
14380   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14381         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14382                    UNSPEC_FIST))]
14383   "TARGET_USE_FANCY_MATH_387
14384    && can_create_pseudo_p ()"
14385   "#"
14386   "&& 1"
14387   [(const_int 0)]
14388 {
14389   if (memory_operand (operands[0], VOIDmode))
14390     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14391   else
14392     {
14393       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14394       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14395                                          operands[2]));
14396     }
14397   DONE;
14398 }
14399   [(set_attr "type" "fpspc")
14400    (set_attr "mode" "DI")])
14401
14402 (define_insn "fistdi2"
14403   [(set (match_operand:DI 0 "memory_operand" "=m")
14404         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14405                    UNSPEC_FIST))
14406    (clobber (match_scratch:XF 2 "=&1f"))]
14407   "TARGET_USE_FANCY_MATH_387"
14408   "* return output_fix_trunc (insn, operands, 0);"
14409   [(set_attr "type" "fpspc")
14410    (set_attr "mode" "DI")])
14411
14412 (define_insn "fistdi2_with_temp"
14413   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14414         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14415                    UNSPEC_FIST))
14416    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14417    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14418   "TARGET_USE_FANCY_MATH_387"
14419   "#"
14420   [(set_attr "type" "fpspc")
14421    (set_attr "mode" "DI")])
14422
14423 (define_split
14424   [(set (match_operand:DI 0 "register_operand" "")
14425         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14426                    UNSPEC_FIST))
14427    (clobber (match_operand:DI 2 "memory_operand" ""))
14428    (clobber (match_scratch 3 ""))]
14429   "reload_completed"
14430   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14431               (clobber (match_dup 3))])
14432    (set (match_dup 0) (match_dup 2))]
14433   "")
14434
14435 (define_split
14436   [(set (match_operand:DI 0 "memory_operand" "")
14437         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14438                    UNSPEC_FIST))
14439    (clobber (match_operand:DI 2 "memory_operand" ""))
14440    (clobber (match_scratch 3 ""))]
14441   "reload_completed"
14442   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14443               (clobber (match_dup 3))])]
14444   "")
14445
14446 (define_insn_and_split "*fist<mode>2_1"
14447   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14448         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14449                            UNSPEC_FIST))]
14450   "TARGET_USE_FANCY_MATH_387
14451    && can_create_pseudo_p ()"
14452   "#"
14453   "&& 1"
14454   [(const_int 0)]
14455 {
14456   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14457   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14458                                         operands[2]));
14459   DONE;
14460 }
14461   [(set_attr "type" "fpspc")
14462    (set_attr "mode" "<MODE>")])
14463
14464 (define_insn "fist<mode>2"
14465   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14466         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14467                            UNSPEC_FIST))]
14468   "TARGET_USE_FANCY_MATH_387"
14469   "* return output_fix_trunc (insn, operands, 0);"
14470   [(set_attr "type" "fpspc")
14471    (set_attr "mode" "<MODE>")])
14472
14473 (define_insn "fist<mode>2_with_temp"
14474   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14475         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14476                            UNSPEC_FIST))
14477    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14478   "TARGET_USE_FANCY_MATH_387"
14479   "#"
14480   [(set_attr "type" "fpspc")
14481    (set_attr "mode" "<MODE>")])
14482
14483 (define_split
14484   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14485         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14486                            UNSPEC_FIST))
14487    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14488   "reload_completed"
14489   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14490    (set (match_dup 0) (match_dup 2))]
14491   "")
14492
14493 (define_split
14494   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14495         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14496                            UNSPEC_FIST))
14497    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14498   "reload_completed"
14499   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14500   "")
14501
14502 (define_expand "lrintxf<mode>2"
14503   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14504      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14505                       UNSPEC_FIST))]
14506   "TARGET_USE_FANCY_MATH_387"
14507   "")
14508
14509 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14510   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14511      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14512                         UNSPEC_FIX_NOTRUNC))]
14513   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14514    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14515   "")
14516
14517 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14518   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14519    (match_operand:MODEF 1 "register_operand" "")]
14520   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14521    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14522    && !flag_trapping_math && !flag_rounding_math"
14523 {
14524   if (optimize_insn_for_size_p ())
14525     FAIL;
14526   ix86_expand_lround (operand0, operand1);
14527   DONE;
14528 })
14529
14530 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14531 (define_insn_and_split "frndintxf2_floor"
14532   [(set (match_operand:XF 0 "register_operand" "")
14533         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14534          UNSPEC_FRNDINT_FLOOR))
14535    (clobber (reg:CC FLAGS_REG))]
14536   "TARGET_USE_FANCY_MATH_387
14537    && flag_unsafe_math_optimizations
14538    && can_create_pseudo_p ()"
14539   "#"
14540   "&& 1"
14541   [(const_int 0)]
14542 {
14543   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14544
14545   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14546   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14547
14548   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14549                                         operands[2], operands[3]));
14550   DONE;
14551 }
14552   [(set_attr "type" "frndint")
14553    (set_attr "i387_cw" "floor")
14554    (set_attr "mode" "XF")])
14555
14556 (define_insn "frndintxf2_floor_i387"
14557   [(set (match_operand:XF 0 "register_operand" "=f")
14558         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14559          UNSPEC_FRNDINT_FLOOR))
14560    (use (match_operand:HI 2 "memory_operand" "m"))
14561    (use (match_operand:HI 3 "memory_operand" "m"))]
14562   "TARGET_USE_FANCY_MATH_387
14563    && flag_unsafe_math_optimizations"
14564   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14565   [(set_attr "type" "frndint")
14566    (set_attr "i387_cw" "floor")
14567    (set_attr "mode" "XF")])
14568
14569 (define_expand "floorxf2"
14570   [(use (match_operand:XF 0 "register_operand" ""))
14571    (use (match_operand:XF 1 "register_operand" ""))]
14572   "TARGET_USE_FANCY_MATH_387
14573    && flag_unsafe_math_optimizations"
14574 {
14575   if (optimize_insn_for_size_p ())
14576     FAIL;
14577   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14578   DONE;
14579 })
14580
14581 (define_expand "floor<mode>2"
14582   [(use (match_operand:MODEF 0 "register_operand" ""))
14583    (use (match_operand:MODEF 1 "register_operand" ""))]
14584   "(TARGET_USE_FANCY_MATH_387
14585     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586         || TARGET_MIX_SSE_I387)
14587     && flag_unsafe_math_optimizations)
14588    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14589        && !flag_trapping_math)"
14590 {
14591   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14592       && !flag_trapping_math
14593       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14594     {
14595       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14596         FAIL;
14597       if (TARGET_ROUND)
14598         emit_insn (gen_sse4_1_round<mode>2
14599                    (operands[0], operands[1], GEN_INT (0x01)));
14600       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14601         ix86_expand_floorceil (operand0, operand1, true);
14602       else
14603         ix86_expand_floorceildf_32 (operand0, operand1, true);
14604     }
14605   else
14606     {
14607       rtx op0, op1;
14608
14609       if (optimize_insn_for_size_p ())
14610         FAIL;
14611
14612       op0 = gen_reg_rtx (XFmode);
14613       op1 = gen_reg_rtx (XFmode);
14614       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14615       emit_insn (gen_frndintxf2_floor (op0, op1));
14616
14617       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14618     }
14619   DONE;
14620 })
14621
14622 (define_insn_and_split "*fist<mode>2_floor_1"
14623   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14624         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14625          UNSPEC_FIST_FLOOR))
14626    (clobber (reg:CC FLAGS_REG))]
14627   "TARGET_USE_FANCY_MATH_387
14628    && flag_unsafe_math_optimizations
14629    && can_create_pseudo_p ()"
14630   "#"
14631   "&& 1"
14632   [(const_int 0)]
14633 {
14634   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14635
14636   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14637   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14638   if (memory_operand (operands[0], VOIDmode))
14639     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14640                                       operands[2], operands[3]));
14641   else
14642     {
14643       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14644       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14645                                                   operands[2], operands[3],
14646                                                   operands[4]));
14647     }
14648   DONE;
14649 }
14650   [(set_attr "type" "fistp")
14651    (set_attr "i387_cw" "floor")
14652    (set_attr "mode" "<MODE>")])
14653
14654 (define_insn "fistdi2_floor"
14655   [(set (match_operand:DI 0 "memory_operand" "=m")
14656         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14657          UNSPEC_FIST_FLOOR))
14658    (use (match_operand:HI 2 "memory_operand" "m"))
14659    (use (match_operand:HI 3 "memory_operand" "m"))
14660    (clobber (match_scratch:XF 4 "=&1f"))]
14661   "TARGET_USE_FANCY_MATH_387
14662    && flag_unsafe_math_optimizations"
14663   "* return output_fix_trunc (insn, operands, 0);"
14664   [(set_attr "type" "fistp")
14665    (set_attr "i387_cw" "floor")
14666    (set_attr "mode" "DI")])
14667
14668 (define_insn "fistdi2_floor_with_temp"
14669   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14670         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14671          UNSPEC_FIST_FLOOR))
14672    (use (match_operand:HI 2 "memory_operand" "m,m"))
14673    (use (match_operand:HI 3 "memory_operand" "m,m"))
14674    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14675    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14676   "TARGET_USE_FANCY_MATH_387
14677    && flag_unsafe_math_optimizations"
14678   "#"
14679   [(set_attr "type" "fistp")
14680    (set_attr "i387_cw" "floor")
14681    (set_attr "mode" "DI")])
14682
14683 (define_split
14684   [(set (match_operand:DI 0 "register_operand" "")
14685         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14686          UNSPEC_FIST_FLOOR))
14687    (use (match_operand:HI 2 "memory_operand" ""))
14688    (use (match_operand:HI 3 "memory_operand" ""))
14689    (clobber (match_operand:DI 4 "memory_operand" ""))
14690    (clobber (match_scratch 5 ""))]
14691   "reload_completed"
14692   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14693               (use (match_dup 2))
14694               (use (match_dup 3))
14695               (clobber (match_dup 5))])
14696    (set (match_dup 0) (match_dup 4))]
14697   "")
14698
14699 (define_split
14700   [(set (match_operand:DI 0 "memory_operand" "")
14701         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14702          UNSPEC_FIST_FLOOR))
14703    (use (match_operand:HI 2 "memory_operand" ""))
14704    (use (match_operand:HI 3 "memory_operand" ""))
14705    (clobber (match_operand:DI 4 "memory_operand" ""))
14706    (clobber (match_scratch 5 ""))]
14707   "reload_completed"
14708   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14709               (use (match_dup 2))
14710               (use (match_dup 3))
14711               (clobber (match_dup 5))])]
14712   "")
14713
14714 (define_insn "fist<mode>2_floor"
14715   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14716         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14717          UNSPEC_FIST_FLOOR))
14718    (use (match_operand:HI 2 "memory_operand" "m"))
14719    (use (match_operand:HI 3 "memory_operand" "m"))]
14720   "TARGET_USE_FANCY_MATH_387
14721    && flag_unsafe_math_optimizations"
14722   "* return output_fix_trunc (insn, operands, 0);"
14723   [(set_attr "type" "fistp")
14724    (set_attr "i387_cw" "floor")
14725    (set_attr "mode" "<MODE>")])
14726
14727 (define_insn "fist<mode>2_floor_with_temp"
14728   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14729         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14730          UNSPEC_FIST_FLOOR))
14731    (use (match_operand:HI 2 "memory_operand" "m,m"))
14732    (use (match_operand:HI 3 "memory_operand" "m,m"))
14733    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14734   "TARGET_USE_FANCY_MATH_387
14735    && flag_unsafe_math_optimizations"
14736   "#"
14737   [(set_attr "type" "fistp")
14738    (set_attr "i387_cw" "floor")
14739    (set_attr "mode" "<MODE>")])
14740
14741 (define_split
14742   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14743         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14744          UNSPEC_FIST_FLOOR))
14745    (use (match_operand:HI 2 "memory_operand" ""))
14746    (use (match_operand:HI 3 "memory_operand" ""))
14747    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14748   "reload_completed"
14749   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14750                                   UNSPEC_FIST_FLOOR))
14751               (use (match_dup 2))
14752               (use (match_dup 3))])
14753    (set (match_dup 0) (match_dup 4))]
14754   "")
14755
14756 (define_split
14757   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14758         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14759          UNSPEC_FIST_FLOOR))
14760    (use (match_operand:HI 2 "memory_operand" ""))
14761    (use (match_operand:HI 3 "memory_operand" ""))
14762    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14763   "reload_completed"
14764   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14765                                   UNSPEC_FIST_FLOOR))
14766               (use (match_dup 2))
14767               (use (match_dup 3))])]
14768   "")
14769
14770 (define_expand "lfloorxf<mode>2"
14771   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14772                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14773                     UNSPEC_FIST_FLOOR))
14774               (clobber (reg:CC FLAGS_REG))])]
14775   "TARGET_USE_FANCY_MATH_387
14776    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14777    && flag_unsafe_math_optimizations"
14778   "")
14779
14780 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14781   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14782    (match_operand:MODEF 1 "register_operand" "")]
14783   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14784    && !flag_trapping_math"
14785 {
14786   if (TARGET_64BIT && optimize_insn_for_size_p ())
14787     FAIL;
14788   ix86_expand_lfloorceil (operand0, operand1, true);
14789   DONE;
14790 })
14791
14792 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14793 (define_insn_and_split "frndintxf2_ceil"
14794   [(set (match_operand:XF 0 "register_operand" "")
14795         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14796          UNSPEC_FRNDINT_CEIL))
14797    (clobber (reg:CC FLAGS_REG))]
14798   "TARGET_USE_FANCY_MATH_387
14799    && flag_unsafe_math_optimizations
14800    && can_create_pseudo_p ()"
14801   "#"
14802   "&& 1"
14803   [(const_int 0)]
14804 {
14805   ix86_optimize_mode_switching[I387_CEIL] = 1;
14806
14807   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14808   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14809
14810   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14811                                        operands[2], operands[3]));
14812   DONE;
14813 }
14814   [(set_attr "type" "frndint")
14815    (set_attr "i387_cw" "ceil")
14816    (set_attr "mode" "XF")])
14817
14818 (define_insn "frndintxf2_ceil_i387"
14819   [(set (match_operand:XF 0 "register_operand" "=f")
14820         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14821          UNSPEC_FRNDINT_CEIL))
14822    (use (match_operand:HI 2 "memory_operand" "m"))
14823    (use (match_operand:HI 3 "memory_operand" "m"))]
14824   "TARGET_USE_FANCY_MATH_387
14825    && flag_unsafe_math_optimizations"
14826   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14827   [(set_attr "type" "frndint")
14828    (set_attr "i387_cw" "ceil")
14829    (set_attr "mode" "XF")])
14830
14831 (define_expand "ceilxf2"
14832   [(use (match_operand:XF 0 "register_operand" ""))
14833    (use (match_operand:XF 1 "register_operand" ""))]
14834   "TARGET_USE_FANCY_MATH_387
14835    && flag_unsafe_math_optimizations"
14836 {
14837   if (optimize_insn_for_size_p ())
14838     FAIL;
14839   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14840   DONE;
14841 })
14842
14843 (define_expand "ceil<mode>2"
14844   [(use (match_operand:MODEF 0 "register_operand" ""))
14845    (use (match_operand:MODEF 1 "register_operand" ""))]
14846   "(TARGET_USE_FANCY_MATH_387
14847     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14848         || TARGET_MIX_SSE_I387)
14849     && flag_unsafe_math_optimizations)
14850    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14851        && !flag_trapping_math)"
14852 {
14853   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14854       && !flag_trapping_math
14855       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14856     {
14857       if (TARGET_ROUND)
14858         emit_insn (gen_sse4_1_round<mode>2
14859                    (operands[0], operands[1], GEN_INT (0x02)));
14860       else if (optimize_insn_for_size_p ())
14861         FAIL;
14862       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14863         ix86_expand_floorceil (operand0, operand1, false);
14864       else
14865         ix86_expand_floorceildf_32 (operand0, operand1, false);
14866     }
14867   else
14868     {
14869       rtx op0, op1;
14870
14871       if (optimize_insn_for_size_p ())
14872         FAIL;
14873
14874       op0 = gen_reg_rtx (XFmode);
14875       op1 = gen_reg_rtx (XFmode);
14876       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14877       emit_insn (gen_frndintxf2_ceil (op0, op1));
14878
14879       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14880     }
14881   DONE;
14882 })
14883
14884 (define_insn_and_split "*fist<mode>2_ceil_1"
14885   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14886         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14887          UNSPEC_FIST_CEIL))
14888    (clobber (reg:CC FLAGS_REG))]
14889   "TARGET_USE_FANCY_MATH_387
14890    && flag_unsafe_math_optimizations
14891    && can_create_pseudo_p ()"
14892   "#"
14893   "&& 1"
14894   [(const_int 0)]
14895 {
14896   ix86_optimize_mode_switching[I387_CEIL] = 1;
14897
14898   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14899   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14900   if (memory_operand (operands[0], VOIDmode))
14901     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14902                                      operands[2], operands[3]));
14903   else
14904     {
14905       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14906       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14907                                                  operands[2], operands[3],
14908                                                  operands[4]));
14909     }
14910   DONE;
14911 }
14912   [(set_attr "type" "fistp")
14913    (set_attr "i387_cw" "ceil")
14914    (set_attr "mode" "<MODE>")])
14915
14916 (define_insn "fistdi2_ceil"
14917   [(set (match_operand:DI 0 "memory_operand" "=m")
14918         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14919          UNSPEC_FIST_CEIL))
14920    (use (match_operand:HI 2 "memory_operand" "m"))
14921    (use (match_operand:HI 3 "memory_operand" "m"))
14922    (clobber (match_scratch:XF 4 "=&1f"))]
14923   "TARGET_USE_FANCY_MATH_387
14924    && flag_unsafe_math_optimizations"
14925   "* return output_fix_trunc (insn, operands, 0);"
14926   [(set_attr "type" "fistp")
14927    (set_attr "i387_cw" "ceil")
14928    (set_attr "mode" "DI")])
14929
14930 (define_insn "fistdi2_ceil_with_temp"
14931   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14932         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14933          UNSPEC_FIST_CEIL))
14934    (use (match_operand:HI 2 "memory_operand" "m,m"))
14935    (use (match_operand:HI 3 "memory_operand" "m,m"))
14936    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14937    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14938   "TARGET_USE_FANCY_MATH_387
14939    && flag_unsafe_math_optimizations"
14940   "#"
14941   [(set_attr "type" "fistp")
14942    (set_attr "i387_cw" "ceil")
14943    (set_attr "mode" "DI")])
14944
14945 (define_split
14946   [(set (match_operand:DI 0 "register_operand" "")
14947         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14948          UNSPEC_FIST_CEIL))
14949    (use (match_operand:HI 2 "memory_operand" ""))
14950    (use (match_operand:HI 3 "memory_operand" ""))
14951    (clobber (match_operand:DI 4 "memory_operand" ""))
14952    (clobber (match_scratch 5 ""))]
14953   "reload_completed"
14954   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14955               (use (match_dup 2))
14956               (use (match_dup 3))
14957               (clobber (match_dup 5))])
14958    (set (match_dup 0) (match_dup 4))]
14959   "")
14960
14961 (define_split
14962   [(set (match_operand:DI 0 "memory_operand" "")
14963         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14964          UNSPEC_FIST_CEIL))
14965    (use (match_operand:HI 2 "memory_operand" ""))
14966    (use (match_operand:HI 3 "memory_operand" ""))
14967    (clobber (match_operand:DI 4 "memory_operand" ""))
14968    (clobber (match_scratch 5 ""))]
14969   "reload_completed"
14970   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14971               (use (match_dup 2))
14972               (use (match_dup 3))
14973               (clobber (match_dup 5))])]
14974   "")
14975
14976 (define_insn "fist<mode>2_ceil"
14977   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14978         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14979          UNSPEC_FIST_CEIL))
14980    (use (match_operand:HI 2 "memory_operand" "m"))
14981    (use (match_operand:HI 3 "memory_operand" "m"))]
14982   "TARGET_USE_FANCY_MATH_387
14983    && flag_unsafe_math_optimizations"
14984   "* return output_fix_trunc (insn, operands, 0);"
14985   [(set_attr "type" "fistp")
14986    (set_attr "i387_cw" "ceil")
14987    (set_attr "mode" "<MODE>")])
14988
14989 (define_insn "fist<mode>2_ceil_with_temp"
14990   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14991         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14992          UNSPEC_FIST_CEIL))
14993    (use (match_operand:HI 2 "memory_operand" "m,m"))
14994    (use (match_operand:HI 3 "memory_operand" "m,m"))
14995    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14996   "TARGET_USE_FANCY_MATH_387
14997    && flag_unsafe_math_optimizations"
14998   "#"
14999   [(set_attr "type" "fistp")
15000    (set_attr "i387_cw" "ceil")
15001    (set_attr "mode" "<MODE>")])
15002
15003 (define_split
15004   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15005         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15006          UNSPEC_FIST_CEIL))
15007    (use (match_operand:HI 2 "memory_operand" ""))
15008    (use (match_operand:HI 3 "memory_operand" ""))
15009    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15010   "reload_completed"
15011   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15012                                   UNSPEC_FIST_CEIL))
15013               (use (match_dup 2))
15014               (use (match_dup 3))])
15015    (set (match_dup 0) (match_dup 4))]
15016   "")
15017
15018 (define_split
15019   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15020         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15021          UNSPEC_FIST_CEIL))
15022    (use (match_operand:HI 2 "memory_operand" ""))
15023    (use (match_operand:HI 3 "memory_operand" ""))
15024    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15025   "reload_completed"
15026   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15027                                   UNSPEC_FIST_CEIL))
15028               (use (match_dup 2))
15029               (use (match_dup 3))])]
15030   "")
15031
15032 (define_expand "lceilxf<mode>2"
15033   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15034                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15035                     UNSPEC_FIST_CEIL))
15036               (clobber (reg:CC FLAGS_REG))])]
15037   "TARGET_USE_FANCY_MATH_387
15038    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15039    && flag_unsafe_math_optimizations"
15040   "")
15041
15042 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15043   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15044    (match_operand:MODEF 1 "register_operand" "")]
15045   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15046    && !flag_trapping_math"
15047 {
15048   ix86_expand_lfloorceil (operand0, operand1, false);
15049   DONE;
15050 })
15051
15052 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15053 (define_insn_and_split "frndintxf2_trunc"
15054   [(set (match_operand:XF 0 "register_operand" "")
15055         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15056          UNSPEC_FRNDINT_TRUNC))
15057    (clobber (reg:CC FLAGS_REG))]
15058   "TARGET_USE_FANCY_MATH_387
15059    && flag_unsafe_math_optimizations
15060    && can_create_pseudo_p ()"
15061   "#"
15062   "&& 1"
15063   [(const_int 0)]
15064 {
15065   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15066
15067   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15068   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15069
15070   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15071                                         operands[2], operands[3]));
15072   DONE;
15073 }
15074   [(set_attr "type" "frndint")
15075    (set_attr "i387_cw" "trunc")
15076    (set_attr "mode" "XF")])
15077
15078 (define_insn "frndintxf2_trunc_i387"
15079   [(set (match_operand:XF 0 "register_operand" "=f")
15080         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15081          UNSPEC_FRNDINT_TRUNC))
15082    (use (match_operand:HI 2 "memory_operand" "m"))
15083    (use (match_operand:HI 3 "memory_operand" "m"))]
15084   "TARGET_USE_FANCY_MATH_387
15085    && flag_unsafe_math_optimizations"
15086   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15087   [(set_attr "type" "frndint")
15088    (set_attr "i387_cw" "trunc")
15089    (set_attr "mode" "XF")])
15090
15091 (define_expand "btruncxf2"
15092   [(use (match_operand:XF 0 "register_operand" ""))
15093    (use (match_operand:XF 1 "register_operand" ""))]
15094   "TARGET_USE_FANCY_MATH_387
15095    && flag_unsafe_math_optimizations"
15096 {
15097   if (optimize_insn_for_size_p ())
15098     FAIL;
15099   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15100   DONE;
15101 })
15102
15103 (define_expand "btrunc<mode>2"
15104   [(use (match_operand:MODEF 0 "register_operand" ""))
15105    (use (match_operand:MODEF 1 "register_operand" ""))]
15106   "(TARGET_USE_FANCY_MATH_387
15107     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15108         || TARGET_MIX_SSE_I387)
15109     && flag_unsafe_math_optimizations)
15110    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15111        && !flag_trapping_math)"
15112 {
15113   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15114       && !flag_trapping_math
15115       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15116     {
15117       if (TARGET_ROUND)
15118         emit_insn (gen_sse4_1_round<mode>2
15119                    (operands[0], operands[1], GEN_INT (0x03)));
15120       else if (optimize_insn_for_size_p ())
15121         FAIL;
15122       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15123         ix86_expand_trunc (operand0, operand1);
15124       else
15125         ix86_expand_truncdf_32 (operand0, operand1);
15126     }
15127   else
15128     {
15129       rtx op0, op1;
15130
15131       if (optimize_insn_for_size_p ())
15132         FAIL;
15133
15134       op0 = gen_reg_rtx (XFmode);
15135       op1 = gen_reg_rtx (XFmode);
15136       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15137       emit_insn (gen_frndintxf2_trunc (op0, op1));
15138
15139       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15140     }
15141   DONE;
15142 })
15143
15144 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15145 (define_insn_and_split "frndintxf2_mask_pm"
15146   [(set (match_operand:XF 0 "register_operand" "")
15147         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15148          UNSPEC_FRNDINT_MASK_PM))
15149    (clobber (reg:CC FLAGS_REG))]
15150   "TARGET_USE_FANCY_MATH_387
15151    && flag_unsafe_math_optimizations
15152    && can_create_pseudo_p ()"
15153   "#"
15154   "&& 1"
15155   [(const_int 0)]
15156 {
15157   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15158
15159   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15160   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15161
15162   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15163                                           operands[2], operands[3]));
15164   DONE;
15165 }
15166   [(set_attr "type" "frndint")
15167    (set_attr "i387_cw" "mask_pm")
15168    (set_attr "mode" "XF")])
15169
15170 (define_insn "frndintxf2_mask_pm_i387"
15171   [(set (match_operand:XF 0 "register_operand" "=f")
15172         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15173          UNSPEC_FRNDINT_MASK_PM))
15174    (use (match_operand:HI 2 "memory_operand" "m"))
15175    (use (match_operand:HI 3 "memory_operand" "m"))]
15176   "TARGET_USE_FANCY_MATH_387
15177    && flag_unsafe_math_optimizations"
15178   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15179   [(set_attr "type" "frndint")
15180    (set_attr "i387_cw" "mask_pm")
15181    (set_attr "mode" "XF")])
15182
15183 (define_expand "nearbyintxf2"
15184   [(use (match_operand:XF 0 "register_operand" ""))
15185    (use (match_operand:XF 1 "register_operand" ""))]
15186   "TARGET_USE_FANCY_MATH_387
15187    && flag_unsafe_math_optimizations"
15188 {
15189   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15190
15191   DONE;
15192 })
15193
15194 (define_expand "nearbyint<mode>2"
15195   [(use (match_operand:MODEF 0 "register_operand" ""))
15196    (use (match_operand:MODEF 1 "register_operand" ""))]
15197   "TARGET_USE_FANCY_MATH_387
15198    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15199        || TARGET_MIX_SSE_I387)
15200    && flag_unsafe_math_optimizations"
15201 {
15202   rtx op0 = gen_reg_rtx (XFmode);
15203   rtx op1 = gen_reg_rtx (XFmode);
15204
15205   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15206   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15207
15208   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15209   DONE;
15210 })
15211
15212 (define_insn "fxam<mode>2_i387"
15213   [(set (match_operand:HI 0 "register_operand" "=a")
15214         (unspec:HI
15215           [(match_operand:X87MODEF 1 "register_operand" "f")]
15216           UNSPEC_FXAM))]
15217   "TARGET_USE_FANCY_MATH_387"
15218   "fxam\n\tfnstsw\t%0"
15219   [(set_attr "type" "multi")
15220    (set_attr "length" "4")
15221    (set_attr "unit" "i387")
15222    (set_attr "mode" "<MODE>")])
15223
15224 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15225   [(set (match_operand:HI 0 "register_operand" "")
15226         (unspec:HI
15227           [(match_operand:MODEF 1 "memory_operand" "")]
15228           UNSPEC_FXAM_MEM))]
15229   "TARGET_USE_FANCY_MATH_387
15230    && can_create_pseudo_p ()"
15231   "#"
15232   "&& 1"
15233   [(set (match_dup 2)(match_dup 1))
15234    (set (match_dup 0)
15235         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15236 {
15237   operands[2] = gen_reg_rtx (<MODE>mode);
15238
15239   MEM_VOLATILE_P (operands[1]) = 1;
15240 }
15241   [(set_attr "type" "multi")
15242    (set_attr "unit" "i387")
15243    (set_attr "mode" "<MODE>")])
15244
15245 (define_expand "isinfxf2"
15246   [(use (match_operand:SI 0 "register_operand" ""))
15247    (use (match_operand:XF 1 "register_operand" ""))]
15248   "TARGET_USE_FANCY_MATH_387
15249    && TARGET_C99_FUNCTIONS"
15250 {
15251   rtx mask = GEN_INT (0x45);
15252   rtx val = GEN_INT (0x05);
15253
15254   rtx cond;
15255
15256   rtx scratch = gen_reg_rtx (HImode);
15257   rtx res = gen_reg_rtx (QImode);
15258
15259   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15260
15261   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15262   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15263   cond = gen_rtx_fmt_ee (EQ, QImode,
15264                          gen_rtx_REG (CCmode, FLAGS_REG),
15265                          const0_rtx);
15266   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15267   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15268   DONE;
15269 })
15270
15271 (define_expand "isinf<mode>2"
15272   [(use (match_operand:SI 0 "register_operand" ""))
15273    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15274   "TARGET_USE_FANCY_MATH_387
15275    && TARGET_C99_FUNCTIONS
15276    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15277 {
15278   rtx mask = GEN_INT (0x45);
15279   rtx val = GEN_INT (0x05);
15280
15281   rtx cond;
15282
15283   rtx scratch = gen_reg_rtx (HImode);
15284   rtx res = gen_reg_rtx (QImode);
15285
15286   /* Remove excess precision by forcing value through memory. */
15287   if (memory_operand (operands[1], VOIDmode))
15288     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15289   else
15290     {
15291       enum ix86_stack_slot slot = (virtuals_instantiated
15292                                    ? SLOT_TEMP
15293                                    : SLOT_VIRTUAL);
15294       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15295
15296       emit_move_insn (temp, operands[1]);
15297       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15298     }
15299
15300   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15301   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15302   cond = gen_rtx_fmt_ee (EQ, QImode,
15303                          gen_rtx_REG (CCmode, FLAGS_REG),
15304                          const0_rtx);
15305   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15306   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15307   DONE;
15308 })
15309
15310 (define_expand "signbit<mode>2"
15311   [(use (match_operand:SI 0 "register_operand" ""))
15312    (use (match_operand:X87MODEF 1 "register_operand" ""))]
15313   "TARGET_USE_FANCY_MATH_387
15314    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15315 {
15316   rtx mask = GEN_INT (0x0200);
15317
15318   rtx scratch = gen_reg_rtx (HImode);
15319
15320   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15321   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15322   DONE;
15323 })
15324 \f
15325 ;; Block operation instructions
15326
15327 (define_insn "cld"
15328   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15329   ""
15330   "cld"
15331   [(set_attr "length" "1")
15332    (set_attr "length_immediate" "0")
15333    (set_attr "modrm" "0")])
15334
15335 (define_expand "movmemsi"
15336   [(use (match_operand:BLK 0 "memory_operand" ""))
15337    (use (match_operand:BLK 1 "memory_operand" ""))
15338    (use (match_operand:SI 2 "nonmemory_operand" ""))
15339    (use (match_operand:SI 3 "const_int_operand" ""))
15340    (use (match_operand:SI 4 "const_int_operand" ""))
15341    (use (match_operand:SI 5 "const_int_operand" ""))]
15342   ""
15343 {
15344  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15345                          operands[4], operands[5]))
15346    DONE;
15347  else
15348    FAIL;
15349 })
15350
15351 (define_expand "movmemdi"
15352   [(use (match_operand:BLK 0 "memory_operand" ""))
15353    (use (match_operand:BLK 1 "memory_operand" ""))
15354    (use (match_operand:DI 2 "nonmemory_operand" ""))
15355    (use (match_operand:DI 3 "const_int_operand" ""))
15356    (use (match_operand:SI 4 "const_int_operand" ""))
15357    (use (match_operand:SI 5 "const_int_operand" ""))]
15358   "TARGET_64BIT"
15359 {
15360  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15361                          operands[4], operands[5]))
15362    DONE;
15363  else
15364    FAIL;
15365 })
15366
15367 ;; Most CPUs don't like single string operations
15368 ;; Handle this case here to simplify previous expander.
15369
15370 (define_expand "strmov"
15371   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15372    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15373    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15374               (clobber (reg:CC FLAGS_REG))])
15375    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15376               (clobber (reg:CC FLAGS_REG))])]
15377   ""
15378 {
15379   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15380
15381   /* If .md ever supports :P for Pmode, these can be directly
15382      in the pattern above.  */
15383   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15384   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15385
15386   /* Can't use this if the user has appropriated esi or edi.  */
15387   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15388       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15389     {
15390       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15391                                       operands[2], operands[3],
15392                                       operands[5], operands[6]));
15393       DONE;
15394     }
15395
15396   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15397 })
15398
15399 (define_expand "strmov_singleop"
15400   [(parallel [(set (match_operand 1 "memory_operand" "")
15401                    (match_operand 3 "memory_operand" ""))
15402               (set (match_operand 0 "register_operand" "")
15403                    (match_operand 4 "" ""))
15404               (set (match_operand 2 "register_operand" "")
15405                    (match_operand 5 "" ""))])]
15406   ""
15407   "ix86_current_function_needs_cld = 1;")
15408
15409 (define_insn "*strmovdi_rex_1"
15410   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15411         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15412    (set (match_operand:DI 0 "register_operand" "=D")
15413         (plus:DI (match_dup 2)
15414                  (const_int 8)))
15415    (set (match_operand:DI 1 "register_operand" "=S")
15416         (plus:DI (match_dup 3)
15417                  (const_int 8)))]
15418   "TARGET_64BIT"
15419   "movsq"
15420   [(set_attr "type" "str")
15421    (set_attr "mode" "DI")
15422    (set_attr "memory" "both")])
15423
15424 (define_insn "*strmovsi_1"
15425   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15426         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15427    (set (match_operand:SI 0 "register_operand" "=D")
15428         (plus:SI (match_dup 2)
15429                  (const_int 4)))
15430    (set (match_operand:SI 1 "register_operand" "=S")
15431         (plus:SI (match_dup 3)
15432                  (const_int 4)))]
15433   "!TARGET_64BIT"
15434   "movs{l|d}"
15435   [(set_attr "type" "str")
15436    (set_attr "mode" "SI")
15437    (set_attr "memory" "both")])
15438
15439 (define_insn "*strmovsi_rex_1"
15440   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15441         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15442    (set (match_operand:DI 0 "register_operand" "=D")
15443         (plus:DI (match_dup 2)
15444                  (const_int 4)))
15445    (set (match_operand:DI 1 "register_operand" "=S")
15446         (plus:DI (match_dup 3)
15447                  (const_int 4)))]
15448   "TARGET_64BIT"
15449   "movs{l|d}"
15450   [(set_attr "type" "str")
15451    (set_attr "mode" "SI")
15452    (set_attr "memory" "both")])
15453
15454 (define_insn "*strmovhi_1"
15455   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15456         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15457    (set (match_operand:SI 0 "register_operand" "=D")
15458         (plus:SI (match_dup 2)
15459                  (const_int 2)))
15460    (set (match_operand:SI 1 "register_operand" "=S")
15461         (plus:SI (match_dup 3)
15462                  (const_int 2)))]
15463   "!TARGET_64BIT"
15464   "movsw"
15465   [(set_attr "type" "str")
15466    (set_attr "memory" "both")
15467    (set_attr "mode" "HI")])
15468
15469 (define_insn "*strmovhi_rex_1"
15470   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15471         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15472    (set (match_operand:DI 0 "register_operand" "=D")
15473         (plus:DI (match_dup 2)
15474                  (const_int 2)))
15475    (set (match_operand:DI 1 "register_operand" "=S")
15476         (plus:DI (match_dup 3)
15477                  (const_int 2)))]
15478   "TARGET_64BIT"
15479   "movsw"
15480   [(set_attr "type" "str")
15481    (set_attr "memory" "both")
15482    (set_attr "mode" "HI")])
15483
15484 (define_insn "*strmovqi_1"
15485   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15486         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15487    (set (match_operand:SI 0 "register_operand" "=D")
15488         (plus:SI (match_dup 2)
15489                  (const_int 1)))
15490    (set (match_operand:SI 1 "register_operand" "=S")
15491         (plus:SI (match_dup 3)
15492                  (const_int 1)))]
15493   "!TARGET_64BIT"
15494   "movsb"
15495   [(set_attr "type" "str")
15496    (set_attr "memory" "both")
15497    (set_attr "mode" "QI")])
15498
15499 (define_insn "*strmovqi_rex_1"
15500   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15501         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15502    (set (match_operand:DI 0 "register_operand" "=D")
15503         (plus:DI (match_dup 2)
15504                  (const_int 1)))
15505    (set (match_operand:DI 1 "register_operand" "=S")
15506         (plus:DI (match_dup 3)
15507                  (const_int 1)))]
15508   "TARGET_64BIT"
15509   "movsb"
15510   [(set_attr "type" "str")
15511    (set_attr "memory" "both")
15512    (set_attr "prefix_rex" "0")
15513    (set_attr "mode" "QI")])
15514
15515 (define_expand "rep_mov"
15516   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15517               (set (match_operand 0 "register_operand" "")
15518                    (match_operand 5 "" ""))
15519               (set (match_operand 2 "register_operand" "")
15520                    (match_operand 6 "" ""))
15521               (set (match_operand 1 "memory_operand" "")
15522                    (match_operand 3 "memory_operand" ""))
15523               (use (match_dup 4))])]
15524   ""
15525   "ix86_current_function_needs_cld = 1;")
15526
15527 (define_insn "*rep_movdi_rex64"
15528   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15529    (set (match_operand:DI 0 "register_operand" "=D")
15530         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15531                             (const_int 3))
15532                  (match_operand:DI 3 "register_operand" "0")))
15533    (set (match_operand:DI 1 "register_operand" "=S")
15534         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15535                  (match_operand:DI 4 "register_operand" "1")))
15536    (set (mem:BLK (match_dup 3))
15537         (mem:BLK (match_dup 4)))
15538    (use (match_dup 5))]
15539   "TARGET_64BIT"
15540   "rep{%;} movsq"
15541   [(set_attr "type" "str")
15542    (set_attr "prefix_rep" "1")
15543    (set_attr "memory" "both")
15544    (set_attr "mode" "DI")])
15545
15546 (define_insn "*rep_movsi"
15547   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15548    (set (match_operand:SI 0 "register_operand" "=D")
15549         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15550                             (const_int 2))
15551                  (match_operand:SI 3 "register_operand" "0")))
15552    (set (match_operand:SI 1 "register_operand" "=S")
15553         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15554                  (match_operand:SI 4 "register_operand" "1")))
15555    (set (mem:BLK (match_dup 3))
15556         (mem:BLK (match_dup 4)))
15557    (use (match_dup 5))]
15558   "!TARGET_64BIT"
15559   "rep{%;} movs{l|d}"
15560   [(set_attr "type" "str")
15561    (set_attr "prefix_rep" "1")
15562    (set_attr "memory" "both")
15563    (set_attr "mode" "SI")])
15564
15565 (define_insn "*rep_movsi_rex64"
15566   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15567    (set (match_operand:DI 0 "register_operand" "=D")
15568         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15569                             (const_int 2))
15570                  (match_operand:DI 3 "register_operand" "0")))
15571    (set (match_operand:DI 1 "register_operand" "=S")
15572         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15573                  (match_operand:DI 4 "register_operand" "1")))
15574    (set (mem:BLK (match_dup 3))
15575         (mem:BLK (match_dup 4)))
15576    (use (match_dup 5))]
15577   "TARGET_64BIT"
15578   "rep{%;} movs{l|d}"
15579   [(set_attr "type" "str")
15580    (set_attr "prefix_rep" "1")
15581    (set_attr "memory" "both")
15582    (set_attr "mode" "SI")])
15583
15584 (define_insn "*rep_movqi"
15585   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15586    (set (match_operand:SI 0 "register_operand" "=D")
15587         (plus:SI (match_operand:SI 3 "register_operand" "0")
15588                  (match_operand:SI 5 "register_operand" "2")))
15589    (set (match_operand:SI 1 "register_operand" "=S")
15590         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15591    (set (mem:BLK (match_dup 3))
15592         (mem:BLK (match_dup 4)))
15593    (use (match_dup 5))]
15594   "!TARGET_64BIT"
15595   "rep{%;} movsb"
15596   [(set_attr "type" "str")
15597    (set_attr "prefix_rep" "1")
15598    (set_attr "memory" "both")
15599    (set_attr "mode" "SI")])
15600
15601 (define_insn "*rep_movqi_rex64"
15602   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15603    (set (match_operand:DI 0 "register_operand" "=D")
15604         (plus:DI (match_operand:DI 3 "register_operand" "0")
15605                  (match_operand:DI 5 "register_operand" "2")))
15606    (set (match_operand:DI 1 "register_operand" "=S")
15607         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15608    (set (mem:BLK (match_dup 3))
15609         (mem:BLK (match_dup 4)))
15610    (use (match_dup 5))]
15611   "TARGET_64BIT"
15612   "rep{%;} movsb"
15613   [(set_attr "type" "str")
15614    (set_attr "prefix_rep" "1")
15615    (set_attr "memory" "both")
15616    (set_attr "mode" "SI")])
15617
15618 (define_expand "setmemsi"
15619    [(use (match_operand:BLK 0 "memory_operand" ""))
15620     (use (match_operand:SI 1 "nonmemory_operand" ""))
15621     (use (match_operand 2 "const_int_operand" ""))
15622     (use (match_operand 3 "const_int_operand" ""))
15623     (use (match_operand:SI 4 "const_int_operand" ""))
15624     (use (match_operand:SI 5 "const_int_operand" ""))]
15625   ""
15626 {
15627  if (ix86_expand_setmem (operands[0], operands[1],
15628                          operands[2], operands[3],
15629                          operands[4], operands[5]))
15630    DONE;
15631  else
15632    FAIL;
15633 })
15634
15635 (define_expand "setmemdi"
15636    [(use (match_operand:BLK 0 "memory_operand" ""))
15637     (use (match_operand:DI 1 "nonmemory_operand" ""))
15638     (use (match_operand 2 "const_int_operand" ""))
15639     (use (match_operand 3 "const_int_operand" ""))
15640     (use (match_operand 4 "const_int_operand" ""))
15641     (use (match_operand 5 "const_int_operand" ""))]
15642   "TARGET_64BIT"
15643 {
15644  if (ix86_expand_setmem (operands[0], operands[1],
15645                          operands[2], operands[3],
15646                          operands[4], operands[5]))
15647    DONE;
15648  else
15649    FAIL;
15650 })
15651
15652 ;; Most CPUs don't like single string operations
15653 ;; Handle this case here to simplify previous expander.
15654
15655 (define_expand "strset"
15656   [(set (match_operand 1 "memory_operand" "")
15657         (match_operand 2 "register_operand" ""))
15658    (parallel [(set (match_operand 0 "register_operand" "")
15659                    (match_dup 3))
15660               (clobber (reg:CC FLAGS_REG))])]
15661   ""
15662 {
15663   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15664     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15665
15666   /* If .md ever supports :P for Pmode, this can be directly
15667      in the pattern above.  */
15668   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15669                               GEN_INT (GET_MODE_SIZE (GET_MODE
15670                                                       (operands[2]))));
15671   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15672     {
15673       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15674                                       operands[3]));
15675       DONE;
15676     }
15677 })
15678
15679 (define_expand "strset_singleop"
15680   [(parallel [(set (match_operand 1 "memory_operand" "")
15681                    (match_operand 2 "register_operand" ""))
15682               (set (match_operand 0 "register_operand" "")
15683                    (match_operand 3 "" ""))])]
15684   ""
15685   "ix86_current_function_needs_cld = 1;")
15686
15687 (define_insn "*strsetdi_rex_1"
15688   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15689         (match_operand:DI 2 "register_operand" "a"))
15690    (set (match_operand:DI 0 "register_operand" "=D")
15691         (plus:DI (match_dup 1)
15692                  (const_int 8)))]
15693   "TARGET_64BIT"
15694   "stosq"
15695   [(set_attr "type" "str")
15696    (set_attr "memory" "store")
15697    (set_attr "mode" "DI")])
15698
15699 (define_insn "*strsetsi_1"
15700   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15701         (match_operand:SI 2 "register_operand" "a"))
15702    (set (match_operand:SI 0 "register_operand" "=D")
15703         (plus:SI (match_dup 1)
15704                  (const_int 4)))]
15705   "!TARGET_64BIT"
15706   "stos{l|d}"
15707   [(set_attr "type" "str")
15708    (set_attr "memory" "store")
15709    (set_attr "mode" "SI")])
15710
15711 (define_insn "*strsetsi_rex_1"
15712   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15713         (match_operand:SI 2 "register_operand" "a"))
15714    (set (match_operand:DI 0 "register_operand" "=D")
15715         (plus:DI (match_dup 1)
15716                  (const_int 4)))]
15717   "TARGET_64BIT"
15718   "stos{l|d}"
15719   [(set_attr "type" "str")
15720    (set_attr "memory" "store")
15721    (set_attr "mode" "SI")])
15722
15723 (define_insn "*strsethi_1"
15724   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15725         (match_operand:HI 2 "register_operand" "a"))
15726    (set (match_operand:SI 0 "register_operand" "=D")
15727         (plus:SI (match_dup 1)
15728                  (const_int 2)))]
15729   "!TARGET_64BIT"
15730   "stosw"
15731   [(set_attr "type" "str")
15732    (set_attr "memory" "store")
15733    (set_attr "mode" "HI")])
15734
15735 (define_insn "*strsethi_rex_1"
15736   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15737         (match_operand:HI 2 "register_operand" "a"))
15738    (set (match_operand:DI 0 "register_operand" "=D")
15739         (plus:DI (match_dup 1)
15740                  (const_int 2)))]
15741   "TARGET_64BIT"
15742   "stosw"
15743   [(set_attr "type" "str")
15744    (set_attr "memory" "store")
15745    (set_attr "mode" "HI")])
15746
15747 (define_insn "*strsetqi_1"
15748   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15749         (match_operand:QI 2 "register_operand" "a"))
15750    (set (match_operand:SI 0 "register_operand" "=D")
15751         (plus:SI (match_dup 1)
15752                  (const_int 1)))]
15753   "!TARGET_64BIT"
15754   "stosb"
15755   [(set_attr "type" "str")
15756    (set_attr "memory" "store")
15757    (set_attr "mode" "QI")])
15758
15759 (define_insn "*strsetqi_rex_1"
15760   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15761         (match_operand:QI 2 "register_operand" "a"))
15762    (set (match_operand:DI 0 "register_operand" "=D")
15763         (plus:DI (match_dup 1)
15764                  (const_int 1)))]
15765   "TARGET_64BIT"
15766   "stosb"
15767   [(set_attr "type" "str")
15768    (set_attr "memory" "store")
15769    (set_attr "prefix_rex" "0")
15770    (set_attr "mode" "QI")])
15771
15772 (define_expand "rep_stos"
15773   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15774               (set (match_operand 0 "register_operand" "")
15775                    (match_operand 4 "" ""))
15776               (set (match_operand 2 "memory_operand" "") (const_int 0))
15777               (use (match_operand 3 "register_operand" ""))
15778               (use (match_dup 1))])]
15779   ""
15780   "ix86_current_function_needs_cld = 1;")
15781
15782 (define_insn "*rep_stosdi_rex64"
15783   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15784    (set (match_operand:DI 0 "register_operand" "=D")
15785         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15786                             (const_int 3))
15787                  (match_operand:DI 3 "register_operand" "0")))
15788    (set (mem:BLK (match_dup 3))
15789         (const_int 0))
15790    (use (match_operand:DI 2 "register_operand" "a"))
15791    (use (match_dup 4))]
15792   "TARGET_64BIT"
15793   "rep{%;} stosq"
15794   [(set_attr "type" "str")
15795    (set_attr "prefix_rep" "1")
15796    (set_attr "memory" "store")
15797    (set_attr "mode" "DI")])
15798
15799 (define_insn "*rep_stossi"
15800   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15801    (set (match_operand:SI 0 "register_operand" "=D")
15802         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15803                             (const_int 2))
15804                  (match_operand:SI 3 "register_operand" "0")))
15805    (set (mem:BLK (match_dup 3))
15806         (const_int 0))
15807    (use (match_operand:SI 2 "register_operand" "a"))
15808    (use (match_dup 4))]
15809   "!TARGET_64BIT"
15810   "rep{%;} stos{l|d}"
15811   [(set_attr "type" "str")
15812    (set_attr "prefix_rep" "1")
15813    (set_attr "memory" "store")
15814    (set_attr "mode" "SI")])
15815
15816 (define_insn "*rep_stossi_rex64"
15817   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15818    (set (match_operand:DI 0 "register_operand" "=D")
15819         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15820                             (const_int 2))
15821                  (match_operand:DI 3 "register_operand" "0")))
15822    (set (mem:BLK (match_dup 3))
15823         (const_int 0))
15824    (use (match_operand:SI 2 "register_operand" "a"))
15825    (use (match_dup 4))]
15826   "TARGET_64BIT"
15827   "rep{%;} stos{l|d}"
15828   [(set_attr "type" "str")
15829    (set_attr "prefix_rep" "1")
15830    (set_attr "memory" "store")
15831    (set_attr "mode" "SI")])
15832
15833 (define_insn "*rep_stosqi"
15834   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15835    (set (match_operand:SI 0 "register_operand" "=D")
15836         (plus:SI (match_operand:SI 3 "register_operand" "0")
15837                  (match_operand:SI 4 "register_operand" "1")))
15838    (set (mem:BLK (match_dup 3))
15839         (const_int 0))
15840    (use (match_operand:QI 2 "register_operand" "a"))
15841    (use (match_dup 4))]
15842   "!TARGET_64BIT"
15843   "rep{%;} stosb"
15844   [(set_attr "type" "str")
15845    (set_attr "prefix_rep" "1")
15846    (set_attr "memory" "store")
15847    (set_attr "mode" "QI")])
15848
15849 (define_insn "*rep_stosqi_rex64"
15850   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15851    (set (match_operand:DI 0 "register_operand" "=D")
15852         (plus:DI (match_operand:DI 3 "register_operand" "0")
15853                  (match_operand:DI 4 "register_operand" "1")))
15854    (set (mem:BLK (match_dup 3))
15855         (const_int 0))
15856    (use (match_operand:QI 2 "register_operand" "a"))
15857    (use (match_dup 4))]
15858   "TARGET_64BIT"
15859   "rep{%;} stosb"
15860   [(set_attr "type" "str")
15861    (set_attr "prefix_rep" "1")
15862    (set_attr "memory" "store")
15863    (set_attr "prefix_rex" "0")
15864    (set_attr "mode" "QI")])
15865
15866 (define_expand "cmpstrnsi"
15867   [(set (match_operand:SI 0 "register_operand" "")
15868         (compare:SI (match_operand:BLK 1 "general_operand" "")
15869                     (match_operand:BLK 2 "general_operand" "")))
15870    (use (match_operand 3 "general_operand" ""))
15871    (use (match_operand 4 "immediate_operand" ""))]
15872   ""
15873 {
15874   rtx addr1, addr2, out, outlow, count, countreg, align;
15875
15876   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15877     FAIL;
15878
15879   /* Can't use this if the user has appropriated esi or edi.  */
15880   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15881     FAIL;
15882
15883   out = operands[0];
15884   if (!REG_P (out))
15885     out = gen_reg_rtx (SImode);
15886
15887   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15888   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15889   if (addr1 != XEXP (operands[1], 0))
15890     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15891   if (addr2 != XEXP (operands[2], 0))
15892     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15893
15894   count = operands[3];
15895   countreg = ix86_zero_extend_to_Pmode (count);
15896
15897   /* %%% Iff we are testing strict equality, we can use known alignment
15898      to good advantage.  This may be possible with combine, particularly
15899      once cc0 is dead.  */
15900   align = operands[4];
15901
15902   if (CONST_INT_P (count))
15903     {
15904       if (INTVAL (count) == 0)
15905         {
15906           emit_move_insn (operands[0], const0_rtx);
15907           DONE;
15908         }
15909       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15910                                      operands[1], operands[2]));
15911     }
15912   else
15913     {
15914       rtx (*cmp_insn)(rtx, rtx);
15915
15916       if (TARGET_64BIT)
15917         cmp_insn = gen_cmpdi_1;
15918       else
15919         cmp_insn = gen_cmpsi_1;
15920       emit_insn (cmp_insn (countreg, countreg));
15921       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15922                                   operands[1], operands[2]));
15923     }
15924
15925   outlow = gen_lowpart (QImode, out);
15926   emit_insn (gen_cmpintqi (outlow));
15927   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15928
15929   if (operands[0] != out)
15930     emit_move_insn (operands[0], out);
15931
15932   DONE;
15933 })
15934
15935 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15936
15937 (define_expand "cmpintqi"
15938   [(set (match_dup 1)
15939         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15940    (set (match_dup 2)
15941         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15942    (parallel [(set (match_operand:QI 0 "register_operand" "")
15943                    (minus:QI (match_dup 1)
15944                              (match_dup 2)))
15945               (clobber (reg:CC FLAGS_REG))])]
15946   ""
15947   "operands[1] = gen_reg_rtx (QImode);
15948    operands[2] = gen_reg_rtx (QImode);")
15949
15950 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15951 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15952
15953 (define_expand "cmpstrnqi_nz_1"
15954   [(parallel [(set (reg:CC FLAGS_REG)
15955                    (compare:CC (match_operand 4 "memory_operand" "")
15956                                (match_operand 5 "memory_operand" "")))
15957               (use (match_operand 2 "register_operand" ""))
15958               (use (match_operand:SI 3 "immediate_operand" ""))
15959               (clobber (match_operand 0 "register_operand" ""))
15960               (clobber (match_operand 1 "register_operand" ""))
15961               (clobber (match_dup 2))])]
15962   ""
15963   "ix86_current_function_needs_cld = 1;")
15964
15965 (define_insn "*cmpstrnqi_nz_1"
15966   [(set (reg:CC FLAGS_REG)
15967         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15968                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15969    (use (match_operand:SI 6 "register_operand" "2"))
15970    (use (match_operand:SI 3 "immediate_operand" "i"))
15971    (clobber (match_operand:SI 0 "register_operand" "=S"))
15972    (clobber (match_operand:SI 1 "register_operand" "=D"))
15973    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15974   "!TARGET_64BIT"
15975   "repz{%;} cmpsb"
15976   [(set_attr "type" "str")
15977    (set_attr "mode" "QI")
15978    (set_attr "prefix_rep" "1")])
15979
15980 (define_insn "*cmpstrnqi_nz_rex_1"
15981   [(set (reg:CC FLAGS_REG)
15982         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15983                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15984    (use (match_operand:DI 6 "register_operand" "2"))
15985    (use (match_operand:SI 3 "immediate_operand" "i"))
15986    (clobber (match_operand:DI 0 "register_operand" "=S"))
15987    (clobber (match_operand:DI 1 "register_operand" "=D"))
15988    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15989   "TARGET_64BIT"
15990   "repz{%;} cmpsb"
15991   [(set_attr "type" "str")
15992    (set_attr "mode" "QI")
15993    (set_attr "prefix_rex" "0")
15994    (set_attr "prefix_rep" "1")])
15995
15996 ;; The same, but the count is not known to not be zero.
15997
15998 (define_expand "cmpstrnqi_1"
15999   [(parallel [(set (reg:CC FLAGS_REG)
16000                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16001                                      (const_int 0))
16002                   (compare:CC (match_operand 4 "memory_operand" "")
16003                               (match_operand 5 "memory_operand" ""))
16004                   (const_int 0)))
16005               (use (match_operand:SI 3 "immediate_operand" ""))
16006               (use (reg:CC FLAGS_REG))
16007               (clobber (match_operand 0 "register_operand" ""))
16008               (clobber (match_operand 1 "register_operand" ""))
16009               (clobber (match_dup 2))])]
16010   ""
16011   "ix86_current_function_needs_cld = 1;")
16012
16013 (define_insn "*cmpstrnqi_1"
16014   [(set (reg:CC FLAGS_REG)
16015         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16016                              (const_int 0))
16017           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16018                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16019           (const_int 0)))
16020    (use (match_operand:SI 3 "immediate_operand" "i"))
16021    (use (reg:CC FLAGS_REG))
16022    (clobber (match_operand:SI 0 "register_operand" "=S"))
16023    (clobber (match_operand:SI 1 "register_operand" "=D"))
16024    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16025   "!TARGET_64BIT"
16026   "repz{%;} cmpsb"
16027   [(set_attr "type" "str")
16028    (set_attr "mode" "QI")
16029    (set_attr "prefix_rep" "1")])
16030
16031 (define_insn "*cmpstrnqi_rex_1"
16032   [(set (reg:CC FLAGS_REG)
16033         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16034                              (const_int 0))
16035           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16036                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16037           (const_int 0)))
16038    (use (match_operand:SI 3 "immediate_operand" "i"))
16039    (use (reg:CC FLAGS_REG))
16040    (clobber (match_operand:DI 0 "register_operand" "=S"))
16041    (clobber (match_operand:DI 1 "register_operand" "=D"))
16042    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16043   "TARGET_64BIT"
16044   "repz{%;} cmpsb"
16045   [(set_attr "type" "str")
16046    (set_attr "mode" "QI")
16047    (set_attr "prefix_rex" "0")
16048    (set_attr "prefix_rep" "1")])
16049
16050 (define_expand "strlensi"
16051   [(set (match_operand:SI 0 "register_operand" "")
16052         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16053                     (match_operand:QI 2 "immediate_operand" "")
16054                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16055   ""
16056 {
16057  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16058    DONE;
16059  else
16060    FAIL;
16061 })
16062
16063 (define_expand "strlendi"
16064   [(set (match_operand:DI 0 "register_operand" "")
16065         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16066                     (match_operand:QI 2 "immediate_operand" "")
16067                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16068   ""
16069 {
16070  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16071    DONE;
16072  else
16073    FAIL;
16074 })
16075
16076 (define_expand "strlenqi_1"
16077   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16078               (clobber (match_operand 1 "register_operand" ""))
16079               (clobber (reg:CC FLAGS_REG))])]
16080   ""
16081   "ix86_current_function_needs_cld = 1;")
16082
16083 (define_insn "*strlenqi_1"
16084   [(set (match_operand:SI 0 "register_operand" "=&c")
16085         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16086                     (match_operand:QI 2 "register_operand" "a")
16087                     (match_operand:SI 3 "immediate_operand" "i")
16088                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16089    (clobber (match_operand:SI 1 "register_operand" "=D"))
16090    (clobber (reg:CC FLAGS_REG))]
16091   "!TARGET_64BIT"
16092   "repnz{%;} scasb"
16093   [(set_attr "type" "str")
16094    (set_attr "mode" "QI")
16095    (set_attr "prefix_rep" "1")])
16096
16097 (define_insn "*strlenqi_rex_1"
16098   [(set (match_operand:DI 0 "register_operand" "=&c")
16099         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16100                     (match_operand:QI 2 "register_operand" "a")
16101                     (match_operand:DI 3 "immediate_operand" "i")
16102                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16103    (clobber (match_operand:DI 1 "register_operand" "=D"))
16104    (clobber (reg:CC FLAGS_REG))]
16105   "TARGET_64BIT"
16106   "repnz{%;} scasb"
16107   [(set_attr "type" "str")
16108    (set_attr "mode" "QI")
16109    (set_attr "prefix_rex" "0")
16110    (set_attr "prefix_rep" "1")])
16111
16112 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16113 ;; handled in combine, but it is not currently up to the task.
16114 ;; When used for their truth value, the cmpstrn* expanders generate
16115 ;; code like this:
16116 ;;
16117 ;;   repz cmpsb
16118 ;;   seta       %al
16119 ;;   setb       %dl
16120 ;;   cmpb       %al, %dl
16121 ;;   jcc        label
16122 ;;
16123 ;; The intermediate three instructions are unnecessary.
16124
16125 ;; This one handles cmpstrn*_nz_1...
16126 (define_peephole2
16127   [(parallel[
16128      (set (reg:CC FLAGS_REG)
16129           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16130                       (mem:BLK (match_operand 5 "register_operand" ""))))
16131      (use (match_operand 6 "register_operand" ""))
16132      (use (match_operand:SI 3 "immediate_operand" ""))
16133      (clobber (match_operand 0 "register_operand" ""))
16134      (clobber (match_operand 1 "register_operand" ""))
16135      (clobber (match_operand 2 "register_operand" ""))])
16136    (set (match_operand:QI 7 "register_operand" "")
16137         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16138    (set (match_operand:QI 8 "register_operand" "")
16139         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16140    (set (reg FLAGS_REG)
16141         (compare (match_dup 7) (match_dup 8)))
16142   ]
16143   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16144   [(parallel[
16145      (set (reg:CC FLAGS_REG)
16146           (compare:CC (mem:BLK (match_dup 4))
16147                       (mem:BLK (match_dup 5))))
16148      (use (match_dup 6))
16149      (use (match_dup 3))
16150      (clobber (match_dup 0))
16151      (clobber (match_dup 1))
16152      (clobber (match_dup 2))])]
16153   "")
16154
16155 ;; ...and this one handles cmpstrn*_1.
16156 (define_peephole2
16157   [(parallel[
16158      (set (reg:CC FLAGS_REG)
16159           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16160                                (const_int 0))
16161             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16162                         (mem:BLK (match_operand 5 "register_operand" "")))
16163             (const_int 0)))
16164      (use (match_operand:SI 3 "immediate_operand" ""))
16165      (use (reg:CC FLAGS_REG))
16166      (clobber (match_operand 0 "register_operand" ""))
16167      (clobber (match_operand 1 "register_operand" ""))
16168      (clobber (match_operand 2 "register_operand" ""))])
16169    (set (match_operand:QI 7 "register_operand" "")
16170         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16171    (set (match_operand:QI 8 "register_operand" "")
16172         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16173    (set (reg FLAGS_REG)
16174         (compare (match_dup 7) (match_dup 8)))
16175   ]
16176   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16177   [(parallel[
16178      (set (reg:CC FLAGS_REG)
16179           (if_then_else:CC (ne (match_dup 6)
16180                                (const_int 0))
16181             (compare:CC (mem:BLK (match_dup 4))
16182                         (mem:BLK (match_dup 5)))
16183             (const_int 0)))
16184      (use (match_dup 3))
16185      (use (reg:CC FLAGS_REG))
16186      (clobber (match_dup 0))
16187      (clobber (match_dup 1))
16188      (clobber (match_dup 2))])]
16189   "")
16190
16191
16192 \f
16193 ;; Conditional move instructions.
16194
16195 (define_expand "mov<mode>cc"
16196   [(set (match_operand:SWIM 0 "register_operand" "")
16197         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16198                            (match_operand:SWIM 2 "general_operand" "")
16199                            (match_operand:SWIM 3 "general_operand" "")))]
16200   ""
16201   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16202
16203 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16204 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16205 ;; So just document what we're doing explicitly.
16206
16207 (define_expand "x86_mov<mode>cc_0_m1"
16208   [(parallel
16209     [(set (match_operand:SWI48 0 "register_operand" "")
16210           (if_then_else:SWI48
16211             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16212              [(match_operand 1 "flags_reg_operand" "")
16213               (const_int 0)])
16214             (const_int -1)
16215             (const_int 0)))
16216      (clobber (reg:CC FLAGS_REG))])]
16217   ""
16218   "")
16219
16220 (define_insn "*x86_mov<mode>cc_0_m1"
16221   [(set (match_operand:SWI48 0 "register_operand" "=r")
16222         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16223                              [(reg FLAGS_REG) (const_int 0)])
16224           (const_int -1)
16225           (const_int 0)))
16226    (clobber (reg:CC FLAGS_REG))]
16227   ""
16228   "sbb{<imodesuffix>}\t%0, %0"
16229   ; Since we don't have the proper number of operands for an alu insn,
16230   ; fill in all the blanks.
16231   [(set_attr "type" "alu")
16232    (set_attr "use_carry" "1")
16233    (set_attr "pent_pair" "pu")
16234    (set_attr "memory" "none")
16235    (set_attr "imm_disp" "false")
16236    (set_attr "mode" "<MODE>")
16237    (set_attr "length_immediate" "0")])
16238
16239 (define_insn "*x86_mov<mode>cc_0_m1_se"
16240   [(set (match_operand:SWI48 0 "register_operand" "=r")
16241         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16242                              [(reg FLAGS_REG) (const_int 0)])
16243                             (const_int 1)
16244                             (const_int 0)))
16245    (clobber (reg:CC FLAGS_REG))]
16246   ""
16247   "sbb{<imodesuffix>}\t%0, %0"
16248   [(set_attr "type" "alu")
16249    (set_attr "use_carry" "1")
16250    (set_attr "pent_pair" "pu")
16251    (set_attr "memory" "none")
16252    (set_attr "imm_disp" "false")
16253    (set_attr "mode" "<MODE>")
16254    (set_attr "length_immediate" "0")])
16255
16256 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16257   [(set (match_operand:SWI48 0 "register_operand" "=r")
16258         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16259                     [(reg FLAGS_REG) (const_int 0)])))]
16260   ""
16261   "sbb{<imodesuffix>}\t%0, %0"
16262   [(set_attr "type" "alu")
16263    (set_attr "use_carry" "1")
16264    (set_attr "pent_pair" "pu")
16265    (set_attr "memory" "none")
16266    (set_attr "imm_disp" "false")
16267    (set_attr "mode" "<MODE>")
16268    (set_attr "length_immediate" "0")])
16269
16270 (define_insn "*mov<mode>cc_noc"
16271   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16272         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16273                                [(reg FLAGS_REG) (const_int 0)])
16274           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16275           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16276   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16277   "@
16278    cmov%O2%C1\t{%2, %0|%0, %2}
16279    cmov%O2%c1\t{%3, %0|%0, %3}"
16280   [(set_attr "type" "icmov")
16281    (set_attr "mode" "<MODE>")])
16282
16283 (define_insn_and_split "*movqicc_noc"
16284   [(set (match_operand:QI 0 "register_operand" "=r,r")
16285         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16286                            [(match_operand 4 "flags_reg_operand" "")
16287                             (const_int 0)])
16288                       (match_operand:QI 2 "register_operand" "r,0")
16289                       (match_operand:QI 3 "register_operand" "0,r")))]
16290   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16291   "#"
16292   "&& reload_completed"
16293   [(set (match_dup 0)
16294         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16295                       (match_dup 2)
16296                       (match_dup 3)))]
16297   "operands[0] = gen_lowpart (SImode, operands[0]);
16298    operands[2] = gen_lowpart (SImode, operands[2]);
16299    operands[3] = gen_lowpart (SImode, operands[3]);"
16300   [(set_attr "type" "icmov")
16301    (set_attr "mode" "SI")])
16302
16303 (define_expand "mov<mode>cc"
16304   [(set (match_operand:X87MODEF 0 "register_operand" "")
16305         (if_then_else:X87MODEF
16306           (match_operand 1 "ix86_fp_comparison_operator" "")
16307           (match_operand:X87MODEF 2 "register_operand" "")
16308           (match_operand:X87MODEF 3 "register_operand" "")))]
16309   "(TARGET_80387 && TARGET_CMOVE)
16310    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16311   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16312
16313 (define_insn "*movsfcc_1_387"
16314   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16315         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16316                                 [(reg FLAGS_REG) (const_int 0)])
16317                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16318                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16319   "TARGET_80387 && TARGET_CMOVE
16320    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16321   "@
16322    fcmov%F1\t{%2, %0|%0, %2}
16323    fcmov%f1\t{%3, %0|%0, %3}
16324    cmov%O2%C1\t{%2, %0|%0, %2}
16325    cmov%O2%c1\t{%3, %0|%0, %3}"
16326   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16327    (set_attr "mode" "SF,SF,SI,SI")])
16328
16329 (define_insn "*movdfcc_1"
16330   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16331         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16332                                 [(reg FLAGS_REG) (const_int 0)])
16333                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16334                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16335   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16336    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16337   "@
16338    fcmov%F1\t{%2, %0|%0, %2}
16339    fcmov%f1\t{%3, %0|%0, %3}
16340    #
16341    #"
16342   [(set_attr "type" "fcmov,fcmov,multi,multi")
16343    (set_attr "mode" "DF")])
16344
16345 (define_insn "*movdfcc_1_rex64"
16346   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16347         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16348                                 [(reg FLAGS_REG) (const_int 0)])
16349                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16350                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16351   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16352    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16353   "@
16354    fcmov%F1\t{%2, %0|%0, %2}
16355    fcmov%f1\t{%3, %0|%0, %3}
16356    cmov%O2%C1\t{%2, %0|%0, %2}
16357    cmov%O2%c1\t{%3, %0|%0, %3}"
16358   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16359    (set_attr "mode" "DF")])
16360
16361 (define_split
16362   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16363         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16364                                 [(match_operand 4 "flags_reg_operand" "")
16365                                  (const_int 0)])
16366                       (match_operand:DF 2 "nonimmediate_operand" "")
16367                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16368   "!TARGET_64BIT && reload_completed"
16369   [(set (match_dup 2)
16370         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16371                       (match_dup 5)
16372                       (match_dup 6)))
16373    (set (match_dup 3)
16374         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16375                       (match_dup 7)
16376                       (match_dup 8)))]
16377 {
16378   split_di (&operands[2], 2, &operands[5], &operands[7]);
16379   split_di (&operands[0], 1, &operands[2], &operands[3]);
16380 })
16381
16382 (define_insn "*movxfcc_1"
16383   [(set (match_operand:XF 0 "register_operand" "=f,f")
16384         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16385                                 [(reg FLAGS_REG) (const_int 0)])
16386                       (match_operand:XF 2 "register_operand" "f,0")
16387                       (match_operand:XF 3 "register_operand" "0,f")))]
16388   "TARGET_80387 && TARGET_CMOVE"
16389   "@
16390    fcmov%F1\t{%2, %0|%0, %2}
16391    fcmov%f1\t{%3, %0|%0, %3}"
16392   [(set_attr "type" "fcmov")
16393    (set_attr "mode" "XF")])
16394
16395 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16396 ;; the scalar versions to have only XMM registers as operands.
16397
16398 ;; XOP conditional move
16399 (define_insn "*xop_pcmov_<mode>"
16400   [(set (match_operand:MODEF 0 "register_operand" "=x")
16401         (if_then_else:MODEF
16402           (match_operand:MODEF 1 "register_operand" "x")
16403           (match_operand:MODEF 2 "register_operand" "x")
16404           (match_operand:MODEF 3 "register_operand" "x")))]
16405   "TARGET_XOP"
16406   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16407   [(set_attr "type" "sse4arg")])
16408
16409 ;; These versions of the min/max patterns are intentionally ignorant of
16410 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16411 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16412 ;; are undefined in this condition, we're certain this is correct.
16413
16414 (define_insn "*avx_<code><mode>3"
16415   [(set (match_operand:MODEF 0 "register_operand" "=x")
16416         (smaxmin:MODEF
16417           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16418           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16419   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16420   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16421   [(set_attr "type" "sseadd")
16422    (set_attr "prefix" "vex")
16423    (set_attr "mode" "<MODE>")])
16424
16425 (define_insn "<code><mode>3"
16426   [(set (match_operand:MODEF 0 "register_operand" "=x")
16427         (smaxmin:MODEF
16428           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16429           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16430   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16431   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16432   [(set_attr "type" "sseadd")
16433    (set_attr "mode" "<MODE>")])
16434
16435 ;; These versions of the min/max patterns implement exactly the operations
16436 ;;   min = (op1 < op2 ? op1 : op2)
16437 ;;   max = (!(op1 < op2) ? op1 : op2)
16438 ;; Their operands are not commutative, and thus they may be used in the
16439 ;; presence of -0.0 and NaN.
16440
16441 (define_insn "*avx_ieee_smin<mode>3"
16442   [(set (match_operand:MODEF 0 "register_operand" "=x")
16443         (unspec:MODEF
16444           [(match_operand:MODEF 1 "register_operand" "x")
16445            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16446          UNSPEC_IEEE_MIN))]
16447   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16448   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16449   [(set_attr "type" "sseadd")
16450    (set_attr "prefix" "vex")
16451    (set_attr "mode" "<MODE>")])
16452
16453 (define_insn "*ieee_smin<mode>3"
16454   [(set (match_operand:MODEF 0 "register_operand" "=x")
16455         (unspec:MODEF
16456           [(match_operand:MODEF 1 "register_operand" "0")
16457            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16458          UNSPEC_IEEE_MIN))]
16459   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16460   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16461   [(set_attr "type" "sseadd")
16462    (set_attr "mode" "<MODE>")])
16463
16464 (define_insn "*avx_ieee_smax<mode>3"
16465   [(set (match_operand:MODEF 0 "register_operand" "=x")
16466         (unspec:MODEF
16467           [(match_operand:MODEF 1 "register_operand" "0")
16468            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16469          UNSPEC_IEEE_MAX))]
16470   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16471   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16472   [(set_attr "type" "sseadd")
16473    (set_attr "prefix" "vex")
16474    (set_attr "mode" "<MODE>")])
16475
16476 (define_insn "*ieee_smax<mode>3"
16477   [(set (match_operand:MODEF 0 "register_operand" "=x")
16478         (unspec:MODEF
16479           [(match_operand:MODEF 1 "register_operand" "0")
16480            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16481          UNSPEC_IEEE_MAX))]
16482   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16483   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16484   [(set_attr "type" "sseadd")
16485    (set_attr "mode" "<MODE>")])
16486
16487 ;; Make two stack loads independent:
16488 ;;   fld aa              fld aa
16489 ;;   fld %st(0)     ->   fld bb
16490 ;;   fmul bb             fmul %st(1), %st
16491 ;;
16492 ;; Actually we only match the last two instructions for simplicity.
16493 (define_peephole2
16494   [(set (match_operand 0 "fp_register_operand" "")
16495         (match_operand 1 "fp_register_operand" ""))
16496    (set (match_dup 0)
16497         (match_operator 2 "binary_fp_operator"
16498            [(match_dup 0)
16499             (match_operand 3 "memory_operand" "")]))]
16500   "REGNO (operands[0]) != REGNO (operands[1])"
16501   [(set (match_dup 0) (match_dup 3))
16502    (set (match_dup 0) (match_dup 4))]
16503
16504   ;; The % modifier is not operational anymore in peephole2's, so we have to
16505   ;; swap the operands manually in the case of addition and multiplication.
16506   "if (COMMUTATIVE_ARITH_P (operands[2]))
16507      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16508                                  operands[0], operands[1]);
16509    else
16510      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16511                                  operands[1], operands[0]);")
16512
16513 ;; Conditional addition patterns
16514 (define_expand "add<mode>cc"
16515   [(match_operand:SWI 0 "register_operand" "")
16516    (match_operand 1 "comparison_operator" "")
16517    (match_operand:SWI 2 "register_operand" "")
16518    (match_operand:SWI 3 "const_int_operand" "")]
16519   ""
16520   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16521
16522 \f
16523 ;; Misc patterns (?)
16524
16525 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16526 ;; Otherwise there will be nothing to keep
16527 ;;
16528 ;; [(set (reg ebp) (reg esp))]
16529 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16530 ;;  (clobber (eflags)]
16531 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16532 ;;
16533 ;; in proper program order.
16534 (define_insn "pro_epilogue_adjust_stack_1"
16535   [(set (match_operand:SI 0 "register_operand" "=r,r")
16536         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16537                  (match_operand:SI 2 "immediate_operand" "i,i")))
16538    (clobber (reg:CC FLAGS_REG))
16539    (clobber (mem:BLK (scratch)))]
16540   "!TARGET_64BIT"
16541 {
16542   switch (get_attr_type (insn))
16543     {
16544     case TYPE_IMOV:
16545       return "mov{l}\t{%1, %0|%0, %1}";
16546
16547     case TYPE_ALU:
16548       if (CONST_INT_P (operands[2])
16549           && (INTVAL (operands[2]) == 128
16550               || (INTVAL (operands[2]) < 0
16551                   && INTVAL (operands[2]) != -128)))
16552         {
16553           operands[2] = GEN_INT (-INTVAL (operands[2]));
16554           return "sub{l}\t{%2, %0|%0, %2}";
16555         }
16556       return "add{l}\t{%2, %0|%0, %2}";
16557
16558     case TYPE_LEA:
16559       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16560       return "lea{l}\t{%a2, %0|%0, %a2}";
16561
16562     default:
16563       gcc_unreachable ();
16564     }
16565 }
16566   [(set (attr "type")
16567         (cond [(and (eq_attr "alternative" "0") 
16568                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16569                  (const_string "alu")
16570                (match_operand:SI 2 "const0_operand" "")
16571                  (const_string "imov")
16572               ]
16573               (const_string "lea")))
16574    (set (attr "length_immediate")
16575         (cond [(eq_attr "type" "imov")
16576                  (const_string "0")
16577                (and (eq_attr "type" "alu")
16578                     (match_operand 2 "const128_operand" ""))
16579                  (const_string "1")
16580               ]
16581               (const_string "*")))
16582    (set_attr "mode" "SI")])
16583
16584 (define_insn "pro_epilogue_adjust_stack_rex64"
16585   [(set (match_operand:DI 0 "register_operand" "=r,r")
16586         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16587                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16588    (clobber (reg:CC FLAGS_REG))
16589    (clobber (mem:BLK (scratch)))]
16590   "TARGET_64BIT"
16591 {
16592   switch (get_attr_type (insn))
16593     {
16594     case TYPE_IMOV:
16595       return "mov{q}\t{%1, %0|%0, %1}";
16596
16597     case TYPE_ALU:
16598       if (CONST_INT_P (operands[2])
16599           /* Avoid overflows.  */
16600           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16601           && (INTVAL (operands[2]) == 128
16602               || (INTVAL (operands[2]) < 0
16603                   && INTVAL (operands[2]) != -128)))
16604         {
16605           operands[2] = GEN_INT (-INTVAL (operands[2]));
16606           return "sub{q}\t{%2, %0|%0, %2}";
16607         }
16608       return "add{q}\t{%2, %0|%0, %2}";
16609
16610     case TYPE_LEA:
16611       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16612       return "lea{q}\t{%a2, %0|%0, %a2}";
16613
16614     default:
16615       gcc_unreachable ();
16616     }
16617 }
16618   [(set (attr "type")
16619         (cond [(and (eq_attr "alternative" "0")
16620                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16621                  (const_string "alu")
16622                (match_operand:DI 2 "const0_operand" "")
16623                  (const_string "imov")
16624               ]
16625               (const_string "lea")))
16626    (set (attr "length_immediate")
16627         (cond [(eq_attr "type" "imov")
16628                  (const_string "0")
16629                (and (eq_attr "type" "alu")
16630                     (match_operand 2 "const128_operand" ""))
16631                  (const_string "1")
16632               ]
16633               (const_string "*")))
16634    (set_attr "mode" "DI")])
16635
16636 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16637   [(set (match_operand:DI 0 "register_operand" "=r,r")
16638         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16639                  (match_operand:DI 3 "immediate_operand" "i,i")))
16640    (use (match_operand:DI 2 "register_operand" "r,r"))
16641    (clobber (reg:CC FLAGS_REG))
16642    (clobber (mem:BLK (scratch)))]
16643   "TARGET_64BIT"
16644 {
16645   switch (get_attr_type (insn))
16646     {
16647     case TYPE_ALU:
16648       return "add{q}\t{%2, %0|%0, %2}";
16649
16650     case TYPE_LEA:
16651       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16652       return "lea{q}\t{%a2, %0|%0, %a2}";
16653
16654     default:
16655       gcc_unreachable ();
16656     }
16657 }
16658   [(set_attr "type" "alu,lea")
16659    (set_attr "mode" "DI")])
16660
16661 (define_insn "allocate_stack_worker_32"
16662   [(set (match_operand:SI 0 "register_operand" "=a")
16663         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16664                             UNSPECV_STACK_PROBE))
16665    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16666    (clobber (reg:CC FLAGS_REG))]
16667   "!TARGET_64BIT && TARGET_STACK_PROBE"
16668   "call\t___chkstk"
16669   [(set_attr "type" "multi")
16670    (set_attr "length" "5")])
16671
16672 (define_insn "allocate_stack_worker_64"
16673   [(set (match_operand:DI 0 "register_operand" "=a")
16674         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16675                             UNSPECV_STACK_PROBE))
16676    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16677    (clobber (reg:DI R10_REG))
16678    (clobber (reg:DI R11_REG))
16679    (clobber (reg:CC FLAGS_REG))]
16680   "TARGET_64BIT && TARGET_STACK_PROBE"
16681   "call\t___chkstk"
16682   [(set_attr "type" "multi")
16683    (set_attr "length" "5")])
16684
16685 (define_expand "allocate_stack"
16686   [(match_operand 0 "register_operand" "")
16687    (match_operand 1 "general_operand" "")]
16688   "TARGET_STACK_PROBE"
16689 {
16690   rtx x;
16691
16692 #ifndef CHECK_STACK_LIMIT
16693 #define CHECK_STACK_LIMIT 0
16694 #endif
16695
16696   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16697       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16698     {
16699       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16700                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16701       if (x != stack_pointer_rtx)
16702         emit_move_insn (stack_pointer_rtx, x);
16703     }
16704   else
16705     {
16706       x = copy_to_mode_reg (Pmode, operands[1]);
16707       if (TARGET_64BIT)
16708         x = gen_allocate_stack_worker_64 (x, x);
16709       else
16710         x = gen_allocate_stack_worker_32 (x, x);
16711       emit_insn (x);
16712     }
16713
16714   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16715   DONE;
16716 })
16717
16718 ;; Use IOR for stack probes, this is shorter.
16719 (define_expand "probe_stack"
16720   [(match_operand 0 "memory_operand" "")]
16721   ""
16722 {
16723   if (GET_MODE (operands[0]) == DImode)
16724     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
16725   else
16726     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
16727   DONE;
16728 })
16729
16730 (define_expand "builtin_setjmp_receiver"
16731   [(label_ref (match_operand 0 "" ""))]
16732   "!TARGET_64BIT && flag_pic"
16733 {
16734 #if TARGET_MACHO
16735   if (TARGET_MACHO)
16736     {
16737       rtx xops[3];
16738       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16739       rtx label_rtx = gen_label_rtx ();
16740       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16741       xops[0] = xops[1] = picreg;
16742       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16743       ix86_expand_binary_operator (MINUS, SImode, xops);
16744     }
16745   else
16746 #endif
16747     emit_insn (gen_set_got (pic_offset_table_rtx));
16748   DONE;
16749 })
16750 \f
16751 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16752
16753 (define_split
16754   [(set (match_operand 0 "register_operand" "")
16755         (match_operator 3 "promotable_binary_operator"
16756            [(match_operand 1 "register_operand" "")
16757             (match_operand 2 "aligned_operand" "")]))
16758    (clobber (reg:CC FLAGS_REG))]
16759   "! TARGET_PARTIAL_REG_STALL && reload_completed
16760    && ((GET_MODE (operands[0]) == HImode
16761         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16762             /* ??? next two lines just !satisfies_constraint_K (...) */
16763             || !CONST_INT_P (operands[2])
16764             || satisfies_constraint_K (operands[2])))
16765        || (GET_MODE (operands[0]) == QImode
16766            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16767   [(parallel [(set (match_dup 0)
16768                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16769               (clobber (reg:CC FLAGS_REG))])]
16770   "operands[0] = gen_lowpart (SImode, operands[0]);
16771    operands[1] = gen_lowpart (SImode, operands[1]);
16772    if (GET_CODE (operands[3]) != ASHIFT)
16773      operands[2] = gen_lowpart (SImode, operands[2]);
16774    PUT_MODE (operands[3], SImode);")
16775
16776 ; Promote the QImode tests, as i386 has encoding of the AND
16777 ; instruction with 32-bit sign-extended immediate and thus the
16778 ; instruction size is unchanged, except in the %eax case for
16779 ; which it is increased by one byte, hence the ! optimize_size.
16780 (define_split
16781   [(set (match_operand 0 "flags_reg_operand" "")
16782         (match_operator 2 "compare_operator"
16783           [(and (match_operand 3 "aligned_operand" "")
16784                 (match_operand 4 "const_int_operand" ""))
16785            (const_int 0)]))
16786    (set (match_operand 1 "register_operand" "")
16787         (and (match_dup 3) (match_dup 4)))]
16788   "! TARGET_PARTIAL_REG_STALL && reload_completed
16789    && optimize_insn_for_speed_p ()
16790    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16791        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16792    /* Ensure that the operand will remain sign-extended immediate.  */
16793    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16794   [(parallel [(set (match_dup 0)
16795                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16796                                     (const_int 0)]))
16797               (set (match_dup 1)
16798                    (and:SI (match_dup 3) (match_dup 4)))])]
16799 {
16800   operands[4]
16801     = gen_int_mode (INTVAL (operands[4])
16802                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16803   operands[1] = gen_lowpart (SImode, operands[1]);
16804   operands[3] = gen_lowpart (SImode, operands[3]);
16805 })
16806
16807 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16808 ; the TEST instruction with 32-bit sign-extended immediate and thus
16809 ; the instruction size would at least double, which is not what we
16810 ; want even with ! optimize_size.
16811 (define_split
16812   [(set (match_operand 0 "flags_reg_operand" "")
16813         (match_operator 1 "compare_operator"
16814           [(and (match_operand:HI 2 "aligned_operand" "")
16815                 (match_operand:HI 3 "const_int_operand" ""))
16816            (const_int 0)]))]
16817   "! TARGET_PARTIAL_REG_STALL && reload_completed
16818    && ! TARGET_FAST_PREFIX
16819    && optimize_insn_for_speed_p ()
16820    /* Ensure that the operand will remain sign-extended immediate.  */
16821    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16822   [(set (match_dup 0)
16823         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16824                          (const_int 0)]))]
16825 {
16826   operands[3]
16827     = gen_int_mode (INTVAL (operands[3])
16828                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16829   operands[2] = gen_lowpart (SImode, operands[2]);
16830 })
16831
16832 (define_split
16833   [(set (match_operand 0 "register_operand" "")
16834         (neg (match_operand 1 "register_operand" "")))
16835    (clobber (reg:CC FLAGS_REG))]
16836   "! TARGET_PARTIAL_REG_STALL && reload_completed
16837    && (GET_MODE (operands[0]) == HImode
16838        || (GET_MODE (operands[0]) == QImode
16839            && (TARGET_PROMOTE_QImode
16840                || optimize_insn_for_size_p ())))"
16841   [(parallel [(set (match_dup 0)
16842                    (neg:SI (match_dup 1)))
16843               (clobber (reg:CC FLAGS_REG))])]
16844   "operands[0] = gen_lowpart (SImode, operands[0]);
16845    operands[1] = gen_lowpart (SImode, operands[1]);")
16846
16847 (define_split
16848   [(set (match_operand 0 "register_operand" "")
16849         (not (match_operand 1 "register_operand" "")))]
16850   "! TARGET_PARTIAL_REG_STALL && reload_completed
16851    && (GET_MODE (operands[0]) == HImode
16852        || (GET_MODE (operands[0]) == QImode
16853            && (TARGET_PROMOTE_QImode
16854                || optimize_insn_for_size_p ())))"
16855   [(set (match_dup 0)
16856         (not:SI (match_dup 1)))]
16857   "operands[0] = gen_lowpart (SImode, operands[0]);
16858    operands[1] = gen_lowpart (SImode, operands[1]);")
16859
16860 (define_split
16861   [(set (match_operand 0 "register_operand" "")
16862         (if_then_else (match_operator 1 "comparison_operator"
16863                                 [(reg FLAGS_REG) (const_int 0)])
16864                       (match_operand 2 "register_operand" "")
16865                       (match_operand 3 "register_operand" "")))]
16866   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16867    && (GET_MODE (operands[0]) == HImode
16868        || (GET_MODE (operands[0]) == QImode
16869            && (TARGET_PROMOTE_QImode
16870                || optimize_insn_for_size_p ())))"
16871   [(set (match_dup 0)
16872         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16873   "operands[0] = gen_lowpart (SImode, operands[0]);
16874    operands[2] = gen_lowpart (SImode, operands[2]);
16875    operands[3] = gen_lowpart (SImode, operands[3]);")
16876
16877 \f
16878 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16879 ;; transform a complex memory operation into two memory to register operations.
16880
16881 ;; Don't push memory operands
16882 (define_peephole2
16883   [(set (match_operand:SI 0 "push_operand" "")
16884         (match_operand:SI 1 "memory_operand" ""))
16885    (match_scratch:SI 2 "r")]
16886   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16887    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16888   [(set (match_dup 2) (match_dup 1))
16889    (set (match_dup 0) (match_dup 2))]
16890   "")
16891
16892 (define_peephole2
16893   [(set (match_operand:DI 0 "push_operand" "")
16894         (match_operand:DI 1 "memory_operand" ""))
16895    (match_scratch:DI 2 "r")]
16896   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16897    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16898   [(set (match_dup 2) (match_dup 1))
16899    (set (match_dup 0) (match_dup 2))]
16900   "")
16901
16902 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16903 ;; SImode pushes.
16904 (define_peephole2
16905   [(set (match_operand:SF 0 "push_operand" "")
16906         (match_operand:SF 1 "memory_operand" ""))
16907    (match_scratch:SF 2 "r")]
16908   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16909    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16910   [(set (match_dup 2) (match_dup 1))
16911    (set (match_dup 0) (match_dup 2))]
16912   "")
16913
16914 (define_peephole2
16915   [(set (match_operand:HI 0 "push_operand" "")
16916         (match_operand:HI 1 "memory_operand" ""))
16917    (match_scratch:HI 2 "r")]
16918   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16919    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16920   [(set (match_dup 2) (match_dup 1))
16921    (set (match_dup 0) (match_dup 2))]
16922   "")
16923
16924 (define_peephole2
16925   [(set (match_operand:QI 0 "push_operand" "")
16926         (match_operand:QI 1 "memory_operand" ""))
16927    (match_scratch:QI 2 "q")]
16928   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16929    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16930   [(set (match_dup 2) (match_dup 1))
16931    (set (match_dup 0) (match_dup 2))]
16932   "")
16933
16934 ;; Don't move an immediate directly to memory when the instruction
16935 ;; gets too big.
16936 (define_peephole2
16937   [(match_scratch:SI 1 "r")
16938    (set (match_operand:SI 0 "memory_operand" "")
16939         (const_int 0))]
16940   "optimize_insn_for_speed_p ()
16941    && ! TARGET_USE_MOV0
16942    && TARGET_SPLIT_LONG_MOVES
16943    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16944    && peep2_regno_dead_p (0, FLAGS_REG)"
16945   [(parallel [(set (match_dup 1) (const_int 0))
16946               (clobber (reg:CC FLAGS_REG))])
16947    (set (match_dup 0) (match_dup 1))]
16948   "")
16949
16950 (define_peephole2
16951   [(match_scratch:HI 1 "r")
16952    (set (match_operand:HI 0 "memory_operand" "")
16953         (const_int 0))]
16954   "optimize_insn_for_speed_p ()
16955    && ! TARGET_USE_MOV0
16956    && TARGET_SPLIT_LONG_MOVES
16957    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16958    && peep2_regno_dead_p (0, FLAGS_REG)"
16959   [(parallel [(set (match_dup 2) (const_int 0))
16960               (clobber (reg:CC FLAGS_REG))])
16961    (set (match_dup 0) (match_dup 1))]
16962   "operands[2] = gen_lowpart (SImode, operands[1]);")
16963
16964 (define_peephole2
16965   [(match_scratch:QI 1 "q")
16966    (set (match_operand:QI 0 "memory_operand" "")
16967         (const_int 0))]
16968   "optimize_insn_for_speed_p ()
16969    && ! TARGET_USE_MOV0
16970    && TARGET_SPLIT_LONG_MOVES
16971    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16972    && peep2_regno_dead_p (0, FLAGS_REG)"
16973   [(parallel [(set (match_dup 2) (const_int 0))
16974               (clobber (reg:CC FLAGS_REG))])
16975    (set (match_dup 0) (match_dup 1))]
16976   "operands[2] = gen_lowpart (SImode, operands[1]);")
16977
16978 (define_peephole2
16979   [(match_scratch:SI 2 "r")
16980    (set (match_operand:SI 0 "memory_operand" "")
16981         (match_operand:SI 1 "immediate_operand" ""))]
16982   "optimize_insn_for_speed_p ()
16983    && TARGET_SPLIT_LONG_MOVES
16984    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16985   [(set (match_dup 2) (match_dup 1))
16986    (set (match_dup 0) (match_dup 2))]
16987   "")
16988
16989 (define_peephole2
16990   [(match_scratch:HI 2 "r")
16991    (set (match_operand:HI 0 "memory_operand" "")
16992         (match_operand:HI 1 "immediate_operand" ""))]
16993   "optimize_insn_for_speed_p ()
16994    && TARGET_SPLIT_LONG_MOVES
16995    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16996   [(set (match_dup 2) (match_dup 1))
16997    (set (match_dup 0) (match_dup 2))]
16998   "")
16999
17000 (define_peephole2
17001   [(match_scratch:QI 2 "q")
17002    (set (match_operand:QI 0 "memory_operand" "")
17003         (match_operand:QI 1 "immediate_operand" ""))]
17004   "optimize_insn_for_speed_p ()
17005    && TARGET_SPLIT_LONG_MOVES
17006    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17007   [(set (match_dup 2) (match_dup 1))
17008    (set (match_dup 0) (match_dup 2))]
17009   "")
17010
17011 ;; Don't compare memory with zero, load and use a test instead.
17012 (define_peephole2
17013   [(set (match_operand 0 "flags_reg_operand" "")
17014         (match_operator 1 "compare_operator"
17015           [(match_operand:SI 2 "memory_operand" "")
17016            (const_int 0)]))
17017    (match_scratch:SI 3 "r")]
17018   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17019   [(set (match_dup 3) (match_dup 2))
17020    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17021   "")
17022
17023 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17024 ;; Don't split NOTs with a displacement operand, because resulting XOR
17025 ;; will not be pairable anyway.
17026 ;;
17027 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17028 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17029 ;; so this split helps here as well.
17030 ;;
17031 ;; Note: Can't do this as a regular split because we can't get proper
17032 ;; lifetime information then.
17033
17034 (define_peephole2
17035   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17036         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17037   "optimize_insn_for_speed_p ()
17038    && ((TARGET_NOT_UNPAIRABLE
17039         && (!MEM_P (operands[0])
17040             || !memory_displacement_operand (operands[0], SImode)))
17041        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17042    && peep2_regno_dead_p (0, FLAGS_REG)"
17043   [(parallel [(set (match_dup 0)
17044                    (xor:SI (match_dup 1) (const_int -1)))
17045               (clobber (reg:CC FLAGS_REG))])]
17046   "")
17047
17048 (define_peephole2
17049   [(set (match_operand:HI 0 "nonimmediate_operand" "")
17050         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17051   "optimize_insn_for_speed_p ()
17052    && ((TARGET_NOT_UNPAIRABLE
17053         && (!MEM_P (operands[0])
17054             || !memory_displacement_operand (operands[0], HImode)))
17055        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17056    && peep2_regno_dead_p (0, FLAGS_REG)"
17057   [(parallel [(set (match_dup 0)
17058                    (xor:HI (match_dup 1) (const_int -1)))
17059               (clobber (reg:CC FLAGS_REG))])]
17060   "")
17061
17062 (define_peephole2
17063   [(set (match_operand:QI 0 "nonimmediate_operand" "")
17064         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17065   "optimize_insn_for_speed_p ()
17066    && ((TARGET_NOT_UNPAIRABLE
17067         && (!MEM_P (operands[0])
17068             || !memory_displacement_operand (operands[0], QImode)))
17069        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17070    && peep2_regno_dead_p (0, FLAGS_REG)"
17071   [(parallel [(set (match_dup 0)
17072                    (xor:QI (match_dup 1) (const_int -1)))
17073               (clobber (reg:CC FLAGS_REG))])]
17074   "")
17075
17076 ;; Non pairable "test imm, reg" instructions can be translated to
17077 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17078 ;; byte opcode instead of two, have a short form for byte operands),
17079 ;; so do it for other CPUs as well.  Given that the value was dead,
17080 ;; this should not create any new dependencies.  Pass on the sub-word
17081 ;; versions if we're concerned about partial register stalls.
17082
17083 (define_peephole2
17084   [(set (match_operand 0 "flags_reg_operand" "")
17085         (match_operator 1 "compare_operator"
17086           [(and:SI (match_operand:SI 2 "register_operand" "")
17087                    (match_operand:SI 3 "immediate_operand" ""))
17088            (const_int 0)]))]
17089   "ix86_match_ccmode (insn, CCNOmode)
17090    && (true_regnum (operands[2]) != AX_REG
17091        || satisfies_constraint_K (operands[3]))
17092    && peep2_reg_dead_p (1, operands[2])"
17093   [(parallel
17094      [(set (match_dup 0)
17095            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17096                             (const_int 0)]))
17097       (set (match_dup 2)
17098            (and:SI (match_dup 2) (match_dup 3)))])]
17099   "")
17100
17101 ;; We don't need to handle HImode case, because it will be promoted to SImode
17102 ;; on ! TARGET_PARTIAL_REG_STALL
17103
17104 (define_peephole2
17105   [(set (match_operand 0 "flags_reg_operand" "")
17106         (match_operator 1 "compare_operator"
17107           [(and:QI (match_operand:QI 2 "register_operand" "")
17108                    (match_operand:QI 3 "immediate_operand" ""))
17109            (const_int 0)]))]
17110   "! TARGET_PARTIAL_REG_STALL
17111    && ix86_match_ccmode (insn, CCNOmode)
17112    && true_regnum (operands[2]) != AX_REG
17113    && peep2_reg_dead_p (1, operands[2])"
17114   [(parallel
17115      [(set (match_dup 0)
17116            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17117                             (const_int 0)]))
17118       (set (match_dup 2)
17119            (and:QI (match_dup 2) (match_dup 3)))])]
17120   "")
17121
17122 (define_peephole2
17123   [(set (match_operand 0 "flags_reg_operand" "")
17124         (match_operator 1 "compare_operator"
17125           [(and:SI
17126              (zero_extract:SI
17127                (match_operand 2 "ext_register_operand" "")
17128                (const_int 8)
17129                (const_int 8))
17130              (match_operand 3 "const_int_operand" ""))
17131            (const_int 0)]))]
17132   "! TARGET_PARTIAL_REG_STALL
17133    && ix86_match_ccmode (insn, CCNOmode)
17134    && true_regnum (operands[2]) != AX_REG
17135    && peep2_reg_dead_p (1, operands[2])"
17136   [(parallel [(set (match_dup 0)
17137                    (match_op_dup 1
17138                      [(and:SI
17139                         (zero_extract:SI
17140                           (match_dup 2)
17141                           (const_int 8)
17142                           (const_int 8))
17143                         (match_dup 3))
17144                       (const_int 0)]))
17145               (set (zero_extract:SI (match_dup 2)
17146                                     (const_int 8)
17147                                     (const_int 8))
17148                    (and:SI
17149                      (zero_extract:SI
17150                        (match_dup 2)
17151                        (const_int 8)
17152                        (const_int 8))
17153                      (match_dup 3)))])]
17154   "")
17155
17156 ;; Don't do logical operations with memory inputs.
17157 (define_peephole2
17158   [(match_scratch:SI 2 "r")
17159    (parallel [(set (match_operand:SI 0 "register_operand" "")
17160                    (match_operator:SI 3 "arith_or_logical_operator"
17161                      [(match_dup 0)
17162                       (match_operand:SI 1 "memory_operand" "")]))
17163               (clobber (reg:CC FLAGS_REG))])]
17164   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17165   [(set (match_dup 2) (match_dup 1))
17166    (parallel [(set (match_dup 0)
17167                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17168               (clobber (reg:CC FLAGS_REG))])]
17169   "")
17170
17171 (define_peephole2
17172   [(match_scratch:SI 2 "r")
17173    (parallel [(set (match_operand:SI 0 "register_operand" "")
17174                    (match_operator:SI 3 "arith_or_logical_operator"
17175                      [(match_operand:SI 1 "memory_operand" "")
17176                       (match_dup 0)]))
17177               (clobber (reg:CC FLAGS_REG))])]
17178   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17179   [(set (match_dup 2) (match_dup 1))
17180    (parallel [(set (match_dup 0)
17181                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17182               (clobber (reg:CC FLAGS_REG))])]
17183   "")
17184
17185 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17186 ;; refers to the destination of the load!
17187
17188 (define_peephole2
17189   [(set (match_operand:SI 0 "register_operand" "")
17190         (match_operand:SI 1 "register_operand" ""))
17191    (parallel [(set (match_dup 0)
17192                    (match_operator:SI 3 "commutative_operator"
17193                      [(match_dup 0)
17194                       (match_operand:SI 2 "memory_operand" "")]))
17195               (clobber (reg:CC FLAGS_REG))])]
17196   "REGNO (operands[0]) != REGNO (operands[1])
17197    && GENERAL_REGNO_P (REGNO (operands[0]))
17198    && GENERAL_REGNO_P (REGNO (operands[1]))"
17199   [(set (match_dup 0) (match_dup 4))
17200    (parallel [(set (match_dup 0)
17201                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17202               (clobber (reg:CC FLAGS_REG))])]
17203   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17204
17205 (define_peephole2
17206   [(set (match_operand 0 "register_operand" "")
17207         (match_operand 1 "register_operand" ""))
17208    (set (match_dup 0)
17209                    (match_operator 3 "commutative_operator"
17210                      [(match_dup 0)
17211                       (match_operand 2 "memory_operand" "")]))]
17212   "REGNO (operands[0]) != REGNO (operands[1])
17213    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17214        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17215   [(set (match_dup 0) (match_dup 2))
17216    (set (match_dup 0)
17217         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17218   "")
17219
17220 ; Don't do logical operations with memory outputs
17221 ;
17222 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17223 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17224 ; the same decoder scheduling characteristics as the original.
17225
17226 (define_peephole2
17227   [(match_scratch:SI 2 "r")
17228    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17229                    (match_operator:SI 3 "arith_or_logical_operator"
17230                      [(match_dup 0)
17231                       (match_operand:SI 1 "nonmemory_operand" "")]))
17232               (clobber (reg:CC FLAGS_REG))])]
17233   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17234    /* Do not split stack checking probes.  */
17235    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17236   [(set (match_dup 2) (match_dup 0))
17237    (parallel [(set (match_dup 2)
17238                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17239               (clobber (reg:CC FLAGS_REG))])
17240    (set (match_dup 0) (match_dup 2))]
17241   "")
17242
17243 (define_peephole2
17244   [(match_scratch:SI 2 "r")
17245    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17246                    (match_operator:SI 3 "arith_or_logical_operator"
17247                      [(match_operand:SI 1 "nonmemory_operand" "")
17248                       (match_dup 0)]))
17249               (clobber (reg:CC FLAGS_REG))])]
17250   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17251    /* Do not split stack checking probes.  */
17252    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17253   [(set (match_dup 2) (match_dup 0))
17254    (parallel [(set (match_dup 2)
17255                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17256               (clobber (reg:CC FLAGS_REG))])
17257    (set (match_dup 0) (match_dup 2))]
17258   "")
17259
17260 ;; Attempt to always use XOR for zeroing registers.
17261 (define_peephole2
17262   [(set (match_operand 0 "register_operand" "")
17263         (match_operand 1 "const0_operand" ""))]
17264   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17265    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17266    && GENERAL_REG_P (operands[0])
17267    && peep2_regno_dead_p (0, FLAGS_REG)"
17268   [(parallel [(set (match_dup 0) (const_int 0))
17269               (clobber (reg:CC FLAGS_REG))])]
17270 {
17271   operands[0] = gen_lowpart (word_mode, operands[0]);
17272 })
17273
17274 (define_peephole2
17275   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17276         (const_int 0))]
17277   "(GET_MODE (operands[0]) == QImode
17278     || GET_MODE (operands[0]) == HImode)
17279    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17280    && peep2_regno_dead_p (0, FLAGS_REG)"
17281   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17282               (clobber (reg:CC FLAGS_REG))])])
17283
17284 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17285 (define_peephole2
17286   [(set (match_operand 0 "register_operand" "")
17287         (const_int -1))]
17288   "(GET_MODE (operands[0]) == HImode
17289     || GET_MODE (operands[0]) == SImode
17290     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17291    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17292    && peep2_regno_dead_p (0, FLAGS_REG)"
17293   [(parallel [(set (match_dup 0) (const_int -1))
17294               (clobber (reg:CC FLAGS_REG))])]
17295   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17296                               operands[0]);")
17297
17298 ;; Attempt to convert simple leas to adds. These can be created by
17299 ;; move expanders.
17300 (define_peephole2
17301   [(set (match_operand:SI 0 "register_operand" "")
17302         (plus:SI (match_dup 0)
17303                  (match_operand:SI 1 "nonmemory_operand" "")))]
17304   "peep2_regno_dead_p (0, FLAGS_REG)"
17305   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17306               (clobber (reg:CC FLAGS_REG))])]
17307   "")
17308
17309 (define_peephole2
17310   [(set (match_operand:SI 0 "register_operand" "")
17311         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17312                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17313   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17314   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17315               (clobber (reg:CC FLAGS_REG))])]
17316   "operands[2] = gen_lowpart (SImode, operands[2]);")
17317
17318 (define_peephole2
17319   [(set (match_operand:DI 0 "register_operand" "")
17320         (plus:DI (match_dup 0)
17321                  (match_operand:DI 1 "x86_64_general_operand" "")))]
17322   "peep2_regno_dead_p (0, FLAGS_REG)"
17323   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17324               (clobber (reg:CC FLAGS_REG))])]
17325   "")
17326
17327 (define_peephole2
17328   [(set (match_operand:SI 0 "register_operand" "")
17329         (mult:SI (match_dup 0)
17330                  (match_operand:SI 1 "const_int_operand" "")))]
17331   "exact_log2 (INTVAL (operands[1])) >= 0
17332    && peep2_regno_dead_p (0, FLAGS_REG)"
17333   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17334               (clobber (reg:CC FLAGS_REG))])]
17335   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17336
17337 (define_peephole2
17338   [(set (match_operand:DI 0 "register_operand" "")
17339         (mult:DI (match_dup 0)
17340                  (match_operand:DI 1 "const_int_operand" "")))]
17341   "exact_log2 (INTVAL (operands[1])) >= 0
17342    && peep2_regno_dead_p (0, FLAGS_REG)"
17343   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17344               (clobber (reg:CC FLAGS_REG))])]
17345   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17346
17347 (define_peephole2
17348   [(set (match_operand:SI 0 "register_operand" "")
17349         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17350                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17351   "exact_log2 (INTVAL (operands[2])) >= 0
17352    && REGNO (operands[0]) == REGNO (operands[1])
17353    && peep2_regno_dead_p (0, FLAGS_REG)"
17354   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17355               (clobber (reg:CC FLAGS_REG))])]
17356   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17357
17358 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17359 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17360 ;; many CPUs it is also faster, since special hardware to avoid esp
17361 ;; dependencies is present.
17362
17363 ;; While some of these conversions may be done using splitters, we use peepholes
17364 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17365
17366 ;; Convert prologue esp subtractions to push.
17367 ;; We need register to push.  In order to keep verify_flow_info happy we have
17368 ;; two choices
17369 ;; - use scratch and clobber it in order to avoid dependencies
17370 ;; - use already live register
17371 ;; We can't use the second way right now, since there is no reliable way how to
17372 ;; verify that given register is live.  First choice will also most likely in
17373 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17374 ;; call clobbered registers are dead.  We may want to use base pointer as an
17375 ;; alternative when no register is available later.
17376
17377 (define_peephole2
17378   [(match_scratch:SI 0 "r")
17379    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17380               (clobber (reg:CC FLAGS_REG))
17381               (clobber (mem:BLK (scratch)))])]
17382   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17383   [(clobber (match_dup 0))
17384    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17385               (clobber (mem:BLK (scratch)))])])
17386
17387 (define_peephole2
17388   [(match_scratch:SI 0 "r")
17389    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17390               (clobber (reg:CC FLAGS_REG))
17391               (clobber (mem:BLK (scratch)))])]
17392   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17393   [(clobber (match_dup 0))
17394    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17395    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17396               (clobber (mem:BLK (scratch)))])])
17397
17398 ;; Convert esp subtractions to push.
17399 (define_peephole2
17400   [(match_scratch:SI 0 "r")
17401    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17402               (clobber (reg:CC FLAGS_REG))])]
17403   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17404   [(clobber (match_dup 0))
17405    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17406
17407 (define_peephole2
17408   [(match_scratch:SI 0 "r")
17409    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17410               (clobber (reg:CC FLAGS_REG))])]
17411   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17412   [(clobber (match_dup 0))
17413    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17414    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17415
17416 ;; Convert epilogue deallocator to pop.
17417 (define_peephole2
17418   [(match_scratch:SI 0 "r")
17419    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17420               (clobber (reg:CC FLAGS_REG))
17421               (clobber (mem:BLK (scratch)))])]
17422   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17423   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17424               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17425               (clobber (mem:BLK (scratch)))])]
17426   "")
17427
17428 ;; Two pops case is tricky, since pop causes dependency on destination register.
17429 ;; We use two registers if available.
17430 (define_peephole2
17431   [(match_scratch:SI 0 "r")
17432    (match_scratch:SI 1 "r")
17433    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17434               (clobber (reg:CC FLAGS_REG))
17435               (clobber (mem:BLK (scratch)))])]
17436   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17437   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17438               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17439               (clobber (mem:BLK (scratch)))])
17440    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17441               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17442   "")
17443
17444 (define_peephole2
17445   [(match_scratch:SI 0 "r")
17446    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17447               (clobber (reg:CC FLAGS_REG))
17448               (clobber (mem:BLK (scratch)))])]
17449   "optimize_insn_for_size_p ()"
17450   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17451               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17452               (clobber (mem:BLK (scratch)))])
17453    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17454               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17455   "")
17456
17457 ;; Convert esp additions to pop.
17458 (define_peephole2
17459   [(match_scratch:SI 0 "r")
17460    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17461               (clobber (reg:CC FLAGS_REG))])]
17462   ""
17463   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17464               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17465   "")
17466
17467 ;; Two pops case is tricky, since pop causes dependency on destination register.
17468 ;; We use two registers if available.
17469 (define_peephole2
17470   [(match_scratch:SI 0 "r")
17471    (match_scratch:SI 1 "r")
17472    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17473               (clobber (reg:CC FLAGS_REG))])]
17474   ""
17475   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17476               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17477    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17478               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17479   "")
17480
17481 (define_peephole2
17482   [(match_scratch:SI 0 "r")
17483    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17484               (clobber (reg:CC FLAGS_REG))])]
17485   "optimize_insn_for_size_p ()"
17486   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17487               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17488    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17489               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17490   "")
17491 \f
17492 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17493 ;; required and register dies.  Similarly for 128 to -128.
17494 (define_peephole2
17495   [(set (match_operand 0 "flags_reg_operand" "")
17496         (match_operator 1 "compare_operator"
17497           [(match_operand 2 "register_operand" "")
17498            (match_operand 3 "const_int_operand" "")]))]
17499   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17500      && incdec_operand (operands[3], GET_MODE (operands[3])))
17501     || (!TARGET_FUSE_CMP_AND_BRANCH
17502         && INTVAL (operands[3]) == 128))
17503    && ix86_match_ccmode (insn, CCGCmode)
17504    && peep2_reg_dead_p (1, operands[2])"
17505   [(parallel [(set (match_dup 0)
17506                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17507               (clobber (match_dup 2))])]
17508   "")
17509 \f
17510 (define_peephole2
17511   [(match_scratch:DI 0 "r")
17512    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17513               (clobber (reg:CC FLAGS_REG))
17514               (clobber (mem:BLK (scratch)))])]
17515   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17516   [(clobber (match_dup 0))
17517    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17518               (clobber (mem:BLK (scratch)))])])
17519
17520 (define_peephole2
17521   [(match_scratch:DI 0 "r")
17522    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17523               (clobber (reg:CC FLAGS_REG))
17524               (clobber (mem:BLK (scratch)))])]
17525   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17526   [(clobber (match_dup 0))
17527    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17528    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17529               (clobber (mem:BLK (scratch)))])])
17530
17531 ;; Convert esp subtractions to push.
17532 (define_peephole2
17533   [(match_scratch:DI 0 "r")
17534    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17535               (clobber (reg:CC FLAGS_REG))])]
17536   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17537   [(clobber (match_dup 0))
17538    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17539
17540 (define_peephole2
17541   [(match_scratch:DI 0 "r")
17542    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17543               (clobber (reg:CC FLAGS_REG))])]
17544   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17545   [(clobber (match_dup 0))
17546    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17547    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17548
17549 ;; Convert epilogue deallocator to pop.
17550 (define_peephole2
17551   [(match_scratch:DI 0 "r")
17552    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17553               (clobber (reg:CC FLAGS_REG))
17554               (clobber (mem:BLK (scratch)))])]
17555   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17556   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17557               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17558               (clobber (mem:BLK (scratch)))])]
17559   "")
17560
17561 ;; Two pops case is tricky, since pop causes dependency on destination register.
17562 ;; We use two registers if available.
17563 (define_peephole2
17564   [(match_scratch:DI 0 "r")
17565    (match_scratch:DI 1 "r")
17566    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17567               (clobber (reg:CC FLAGS_REG))
17568               (clobber (mem:BLK (scratch)))])]
17569   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17570   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17571               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17572               (clobber (mem:BLK (scratch)))])
17573    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17574               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17575   "")
17576
17577 (define_peephole2
17578   [(match_scratch:DI 0 "r")
17579    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17580               (clobber (reg:CC FLAGS_REG))
17581               (clobber (mem:BLK (scratch)))])]
17582   "optimize_insn_for_size_p ()"
17583   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17584               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17585               (clobber (mem:BLK (scratch)))])
17586    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17587               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17588   "")
17589
17590 ;; Convert esp additions to pop.
17591 (define_peephole2
17592   [(match_scratch:DI 0 "r")
17593    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17594               (clobber (reg:CC FLAGS_REG))])]
17595   ""
17596   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17597               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17598   "")
17599
17600 ;; Two pops case is tricky, since pop causes dependency on destination register.
17601 ;; We use two registers if available.
17602 (define_peephole2
17603   [(match_scratch:DI 0 "r")
17604    (match_scratch:DI 1 "r")
17605    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17606               (clobber (reg:CC FLAGS_REG))])]
17607   ""
17608   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17609               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17610    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17611               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17612   "")
17613
17614 (define_peephole2
17615   [(match_scratch:DI 0 "r")
17616    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17617               (clobber (reg:CC FLAGS_REG))])]
17618   "optimize_insn_for_size_p ()"
17619   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17620               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17621    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17622               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17623   "")
17624 \f
17625 ;; Convert imul by three, five and nine into lea
17626 (define_peephole2
17627   [(parallel
17628     [(set (match_operand:SI 0 "register_operand" "")
17629           (mult:SI (match_operand:SI 1 "register_operand" "")
17630                    (match_operand:SI 2 "const_int_operand" "")))
17631      (clobber (reg:CC FLAGS_REG))])]
17632   "INTVAL (operands[2]) == 3
17633    || INTVAL (operands[2]) == 5
17634    || INTVAL (operands[2]) == 9"
17635   [(set (match_dup 0)
17636         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17637                  (match_dup 1)))]
17638   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17639
17640 (define_peephole2
17641   [(parallel
17642     [(set (match_operand:SI 0 "register_operand" "")
17643           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17644                    (match_operand:SI 2 "const_int_operand" "")))
17645      (clobber (reg:CC FLAGS_REG))])]
17646   "optimize_insn_for_speed_p ()
17647    && (INTVAL (operands[2]) == 3
17648        || INTVAL (operands[2]) == 5
17649        || INTVAL (operands[2]) == 9)"
17650   [(set (match_dup 0) (match_dup 1))
17651    (set (match_dup 0)
17652         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17653                  (match_dup 0)))]
17654   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17655
17656 (define_peephole2
17657   [(parallel
17658     [(set (match_operand:DI 0 "register_operand" "")
17659           (mult:DI (match_operand:DI 1 "register_operand" "")
17660                    (match_operand:DI 2 "const_int_operand" "")))
17661      (clobber (reg:CC FLAGS_REG))])]
17662   "TARGET_64BIT
17663    && (INTVAL (operands[2]) == 3
17664        || INTVAL (operands[2]) == 5
17665        || INTVAL (operands[2]) == 9)"
17666   [(set (match_dup 0)
17667         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17668                  (match_dup 1)))]
17669   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17670
17671 (define_peephole2
17672   [(parallel
17673     [(set (match_operand:DI 0 "register_operand" "")
17674           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17675                    (match_operand:DI 2 "const_int_operand" "")))
17676      (clobber (reg:CC FLAGS_REG))])]
17677   "TARGET_64BIT
17678    && optimize_insn_for_speed_p ()
17679    && (INTVAL (operands[2]) == 3
17680        || INTVAL (operands[2]) == 5
17681        || INTVAL (operands[2]) == 9)"
17682   [(set (match_dup 0) (match_dup 1))
17683    (set (match_dup 0)
17684         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17685                  (match_dup 0)))]
17686   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17687
17688 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17689 ;; imul $32bit_imm, reg, reg is direct decoded.
17690 (define_peephole2
17691   [(match_scratch:DI 3 "r")
17692    (parallel [(set (match_operand:DI 0 "register_operand" "")
17693                    (mult:DI (match_operand:DI 1 "memory_operand" "")
17694                             (match_operand:DI 2 "immediate_operand" "")))
17695               (clobber (reg:CC FLAGS_REG))])]
17696   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17697    && !satisfies_constraint_K (operands[2])"
17698   [(set (match_dup 3) (match_dup 1))
17699    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17700               (clobber (reg:CC FLAGS_REG))])]
17701 "")
17702
17703 (define_peephole2
17704   [(match_scratch:SI 3 "r")
17705    (parallel [(set (match_operand:SI 0 "register_operand" "")
17706                    (mult:SI (match_operand:SI 1 "memory_operand" "")
17707                             (match_operand:SI 2 "immediate_operand" "")))
17708               (clobber (reg:CC FLAGS_REG))])]
17709   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17710    && !satisfies_constraint_K (operands[2])"
17711   [(set (match_dup 3) (match_dup 1))
17712    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
17713               (clobber (reg:CC FLAGS_REG))])]
17714 "")
17715
17716 (define_peephole2
17717   [(match_scratch:SI 3 "r")
17718    (parallel [(set (match_operand:DI 0 "register_operand" "")
17719                    (zero_extend:DI
17720                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17721                               (match_operand:SI 2 "immediate_operand" ""))))
17722               (clobber (reg:CC FLAGS_REG))])]
17723   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17724    && !satisfies_constraint_K (operands[2])"
17725   [(set (match_dup 3) (match_dup 1))
17726    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17727               (clobber (reg:CC FLAGS_REG))])]
17728 "")
17729
17730 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17731 ;; Convert it into imul reg, reg
17732 ;; It would be better to force assembler to encode instruction using long
17733 ;; immediate, but there is apparently no way to do so.
17734 (define_peephole2
17735   [(parallel [(set (match_operand:DI 0 "register_operand" "")
17736                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17737                             (match_operand:DI 2 "const_int_operand" "")))
17738               (clobber (reg:CC FLAGS_REG))])
17739    (match_scratch:DI 3 "r")]
17740   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17741    && satisfies_constraint_K (operands[2])"
17742   [(set (match_dup 3) (match_dup 2))
17743    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
17744               (clobber (reg:CC FLAGS_REG))])]
17745 {
17746   if (!rtx_equal_p (operands[0], operands[1]))
17747     emit_move_insn (operands[0], operands[1]);
17748 })
17749
17750 (define_peephole2
17751   [(parallel [(set (match_operand:SI 0 "register_operand" "")
17752                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17753                             (match_operand:SI 2 "const_int_operand" "")))
17754               (clobber (reg:CC FLAGS_REG))])
17755    (match_scratch:SI 3 "r")]
17756   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17757    && satisfies_constraint_K (operands[2])"
17758   [(set (match_dup 3) (match_dup 2))
17759    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
17760               (clobber (reg:CC FLAGS_REG))])]
17761 {
17762   if (!rtx_equal_p (operands[0], operands[1]))
17763     emit_move_insn (operands[0], operands[1]);
17764 })
17765
17766 (define_peephole2
17767   [(parallel [(set (match_operand:HI 0 "register_operand" "")
17768                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
17769                             (match_operand:HI 2 "immediate_operand" "")))
17770               (clobber (reg:CC FLAGS_REG))])
17771    (match_scratch:HI 3 "r")]
17772   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
17773   [(set (match_dup 3) (match_dup 2))
17774    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
17775               (clobber (reg:CC FLAGS_REG))])]
17776 {
17777   if (!rtx_equal_p (operands[0], operands[1]))
17778     emit_move_insn (operands[0], operands[1]);
17779 })
17780
17781 ;; After splitting up read-modify operations, array accesses with memory
17782 ;; operands might end up in form:
17783 ;;  sall    $2, %eax
17784 ;;  movl    4(%esp), %edx
17785 ;;  addl    %edx, %eax
17786 ;; instead of pre-splitting:
17787 ;;  sall    $2, %eax
17788 ;;  addl    4(%esp), %eax
17789 ;; Turn it into:
17790 ;;  movl    4(%esp), %edx
17791 ;;  leal    (%edx,%eax,4), %eax
17792
17793 (define_peephole2
17794   [(parallel [(set (match_operand 0 "register_operand" "")
17795                    (ashift (match_operand 1 "register_operand" "")
17796                            (match_operand 2 "const_int_operand" "")))
17797                (clobber (reg:CC FLAGS_REG))])
17798    (set (match_operand 3 "register_operand")
17799         (match_operand 4 "x86_64_general_operand" ""))
17800    (parallel [(set (match_operand 5 "register_operand" "")
17801                    (plus (match_operand 6 "register_operand" "")
17802                          (match_operand 7 "register_operand" "")))
17803                    (clobber (reg:CC FLAGS_REG))])]
17804   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17805    /* Validate MODE for lea.  */
17806    && ((!TARGET_PARTIAL_REG_STALL
17807         && (GET_MODE (operands[0]) == QImode
17808             || GET_MODE (operands[0]) == HImode))
17809        || GET_MODE (operands[0]) == SImode
17810        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17811    /* We reorder load and the shift.  */
17812    && !rtx_equal_p (operands[1], operands[3])
17813    && !reg_overlap_mentioned_p (operands[0], operands[4])
17814    /* Last PLUS must consist of operand 0 and 3.  */
17815    && !rtx_equal_p (operands[0], operands[3])
17816    && (rtx_equal_p (operands[3], operands[6])
17817        || rtx_equal_p (operands[3], operands[7]))
17818    && (rtx_equal_p (operands[0], operands[6])
17819        || rtx_equal_p (operands[0], operands[7]))
17820    /* The intermediate operand 0 must die or be same as output.  */
17821    && (rtx_equal_p (operands[0], operands[5])
17822        || peep2_reg_dead_p (3, operands[0]))"
17823   [(set (match_dup 3) (match_dup 4))
17824    (set (match_dup 0) (match_dup 1))]
17825 {
17826   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
17827   int scale = 1 << INTVAL (operands[2]);
17828   rtx index = gen_lowpart (Pmode, operands[1]);
17829   rtx base = gen_lowpart (Pmode, operands[3]);
17830   rtx dest = gen_lowpart (mode, operands[5]);
17831
17832   operands[1] = gen_rtx_PLUS (Pmode, base,
17833                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17834   if (mode != Pmode)
17835     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17836   operands[0] = dest;
17837 })
17838 \f
17839 ;; Call-value patterns last so that the wildcard operand does not
17840 ;; disrupt insn-recog's switch tables.
17841
17842 (define_insn "*call_value_pop_0"
17843   [(set (match_operand 0 "" "")
17844         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17845               (match_operand:SI 2 "" "")))
17846    (set (reg:SI SP_REG)
17847         (plus:SI (reg:SI SP_REG)
17848                  (match_operand:SI 3 "immediate_operand" "")))]
17849   "!TARGET_64BIT"
17850 {
17851   if (SIBLING_CALL_P (insn))
17852     return "jmp\t%P1";
17853   else
17854     return "call\t%P1";
17855 }
17856   [(set_attr "type" "callv")])
17857
17858 (define_insn "*call_value_pop_1"
17859   [(set (match_operand 0 "" "")
17860         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17861               (match_operand:SI 2 "" "")))
17862    (set (reg:SI SP_REG)
17863         (plus:SI (reg:SI SP_REG)
17864                  (match_operand:SI 3 "immediate_operand" "i")))]
17865   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17866 {
17867   if (constant_call_address_operand (operands[1], Pmode))
17868     return "call\t%P1";
17869   return "call\t%A1";
17870 }
17871   [(set_attr "type" "callv")])
17872
17873 (define_insn "*sibcall_value_pop_1"
17874   [(set (match_operand 0 "" "")
17875         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17876               (match_operand:SI 2 "" "")))
17877    (set (reg:SI SP_REG)
17878         (plus:SI (reg:SI SP_REG)
17879                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17880   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17881   "@
17882    jmp\t%P1
17883    jmp\t%A1"
17884   [(set_attr "type" "callv")])
17885
17886 (define_insn "*call_value_0"
17887   [(set (match_operand 0 "" "")
17888         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17889               (match_operand:SI 2 "" "")))]
17890   "!TARGET_64BIT"
17891 {
17892   if (SIBLING_CALL_P (insn))
17893     return "jmp\t%P1";
17894   else
17895     return "call\t%P1";
17896 }
17897   [(set_attr "type" "callv")])
17898
17899 (define_insn "*call_value_0_rex64"
17900   [(set (match_operand 0 "" "")
17901         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17902               (match_operand:DI 2 "const_int_operand" "")))]
17903   "TARGET_64BIT"
17904 {
17905   if (SIBLING_CALL_P (insn))
17906     return "jmp\t%P1";
17907   else
17908     return "call\t%P1";
17909 }
17910   [(set_attr "type" "callv")])
17911
17912 (define_insn "*call_value_0_rex64_ms_sysv"
17913   [(set (match_operand 0 "" "")
17914         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17915               (match_operand:DI 2 "const_int_operand" "")))
17916    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17917    (clobber (reg:TI XMM6_REG))
17918    (clobber (reg:TI XMM7_REG))
17919    (clobber (reg:TI XMM8_REG))
17920    (clobber (reg:TI XMM9_REG))
17921    (clobber (reg:TI XMM10_REG))
17922    (clobber (reg:TI XMM11_REG))
17923    (clobber (reg:TI XMM12_REG))
17924    (clobber (reg:TI XMM13_REG))
17925    (clobber (reg:TI XMM14_REG))
17926    (clobber (reg:TI XMM15_REG))
17927    (clobber (reg:DI SI_REG))
17928    (clobber (reg:DI DI_REG))]
17929   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17930 {
17931   if (SIBLING_CALL_P (insn))
17932     return "jmp\t%P1";
17933   else
17934     return "call\t%P1";
17935 }
17936   [(set_attr "type" "callv")])
17937
17938 (define_insn "*call_value_1"
17939   [(set (match_operand 0 "" "")
17940         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17941               (match_operand:SI 2 "" "")))]
17942   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17943 {
17944   if (constant_call_address_operand (operands[1], Pmode))
17945     return "call\t%P1";
17946   return "call\t%A1";
17947 }
17948   [(set_attr "type" "callv")])
17949
17950 (define_insn "*sibcall_value_1"
17951   [(set (match_operand 0 "" "")
17952         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17953               (match_operand:SI 2 "" "")))]
17954   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17955   "@
17956    jmp\t%P1
17957    jmp\t%A1"
17958   [(set_attr "type" "callv")])
17959
17960 (define_insn "*call_value_1_rex64"
17961   [(set (match_operand 0 "" "")
17962         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17963               (match_operand:DI 2 "" "")))]
17964   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17965    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17966 {
17967   if (constant_call_address_operand (operands[1], Pmode))
17968     return "call\t%P1";
17969   return "call\t%A1";
17970 }
17971   [(set_attr "type" "callv")])
17972
17973 (define_insn "*call_value_1_rex64_ms_sysv"
17974   [(set (match_operand 0 "" "")
17975         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17976               (match_operand:DI 2 "" "")))
17977    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17978    (clobber (reg:TI XMM6_REG))
17979    (clobber (reg:TI XMM7_REG))
17980    (clobber (reg:TI XMM8_REG))
17981    (clobber (reg:TI XMM9_REG))
17982    (clobber (reg:TI XMM10_REG))
17983    (clobber (reg:TI XMM11_REG))
17984    (clobber (reg:TI XMM12_REG))
17985    (clobber (reg:TI XMM13_REG))
17986    (clobber (reg:TI XMM14_REG))
17987    (clobber (reg:TI XMM15_REG))
17988    (clobber (reg:DI SI_REG))
17989    (clobber (reg:DI DI_REG))]
17990   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17991 {
17992   if (constant_call_address_operand (operands[1], Pmode))
17993     return "call\t%P1";
17994   return "call\t%A1";
17995 }
17996   [(set_attr "type" "callv")])
17997
17998 (define_insn "*call_value_1_rex64_large"
17999   [(set (match_operand 0 "" "")
18000         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18001               (match_operand:DI 2 "" "")))]
18002   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18003   "call\t%A1"
18004   [(set_attr "type" "callv")])
18005
18006 (define_insn "*sibcall_value_1_rex64"
18007   [(set (match_operand 0 "" "")
18008         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18009               (match_operand:DI 2 "" "")))]
18010   "TARGET_64BIT && SIBLING_CALL_P (insn)"
18011   "@
18012    jmp\t%P1
18013    jmp\t%A1"
18014   [(set_attr "type" "callv")])
18015 \f
18016 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18017 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18018 ;; caught for use by garbage collectors and the like.  Using an insn that
18019 ;; maps to SIGILL makes it more likely the program will rightfully die.
18020 ;; Keeping with tradition, "6" is in honor of #UD.
18021 (define_insn "trap"
18022   [(trap_if (const_int 1) (const_int 6))]
18023   ""
18024   { return ASM_SHORT "0x0b0f"; }
18025   [(set_attr "length" "2")])
18026
18027 (define_expand "sse_prologue_save"
18028   [(parallel [(set (match_operand:BLK 0 "" "")
18029                    (unspec:BLK [(reg:DI XMM0_REG)
18030                                 (reg:DI XMM1_REG)
18031                                 (reg:DI XMM2_REG)
18032                                 (reg:DI XMM3_REG)
18033                                 (reg:DI XMM4_REG)
18034                                 (reg:DI XMM5_REG)
18035                                 (reg:DI XMM6_REG)
18036                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18037               (clobber (reg:CC FLAGS_REG))
18038               (clobber (match_operand:DI 1 "register_operand" ""))
18039               (use (match_operand:DI 2 "immediate_operand" ""))
18040               (use (label_ref:DI (match_operand 3 "" "")))
18041               (clobber (match_operand:DI 4 "register_operand" ""))
18042               (use (match_dup 1))])]
18043   "TARGET_64BIT"
18044   "")
18045
18046 ;; Pre-reload version of prologue save.  Until after prologue generation we don't know
18047 ;; what the size of save instruction will be.
18048 ;; Operand 0+operand 6 is the memory save area
18049 ;; Operand 1 is number of registers to save (will get overwritten to operand 5)
18050 ;; Operand 2 is number of non-vaargs SSE arguments
18051 ;; Operand 3 is label starting the save block
18052 ;; Operand 4 is used for temporary computation of jump address
18053 (define_insn "*sse_prologue_save_insn1"
18054   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18055                           (match_operand:DI 6 "const_int_operand" "n")))
18056         (unspec:BLK [(reg:DI XMM0_REG)
18057                      (reg:DI XMM1_REG)
18058                      (reg:DI XMM2_REG)
18059                      (reg:DI XMM3_REG)
18060                      (reg:DI XMM4_REG)
18061                      (reg:DI XMM5_REG)
18062                      (reg:DI XMM6_REG)
18063                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18064    (clobber (reg:CC FLAGS_REG))
18065    (clobber (match_operand:DI 1 "register_operand" "=r"))
18066    (use (match_operand:DI 2 "const_int_operand" "i"))
18067    (use (label_ref:DI (match_operand 3 "" "X")))
18068    (clobber (match_operand:DI 4 "register_operand" "=&r"))
18069    (use (match_operand:DI 5 "register_operand" "1"))]
18070   "TARGET_64BIT
18071    && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18072    && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
18073   "#"
18074   [(set_attr "type" "other")
18075    (set_attr "memory" "store")
18076    (set_attr "mode" "DI")])
18077
18078 ;; We know size of save instruction; expand the computation of jump address
18079 ;; in the jumptable.
18080 (define_split
18081   [(parallel [(set (match_operand:BLK 0 "" "")
18082                     (unspec:BLK [(reg:DI XMM0_REG)
18083                                  (reg:DI XMM1_REG)
18084                                  (reg:DI XMM2_REG)
18085                                  (reg:DI XMM3_REG)
18086                                  (reg:DI XMM4_REG)
18087                                  (reg:DI XMM5_REG)
18088                                  (reg:DI XMM6_REG)
18089                                  (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18090                (clobber (reg:CC FLAGS_REG))
18091                (clobber (match_operand:DI 1 "register_operand" ""))
18092                (use (match_operand:DI 2 "const_int_operand" ""))
18093                (use (match_operand 3 "" ""))
18094                (clobber (match_operand:DI 4 "register_operand" ""))
18095                (use (match_operand:DI 5 "register_operand" ""))])]
18096   "reload_completed"
18097   [(parallel [(set (match_dup 0)
18098                    (unspec:BLK [(reg:DI XMM0_REG)
18099                                 (reg:DI XMM1_REG)
18100                                 (reg:DI XMM2_REG)
18101                                 (reg:DI XMM3_REG)
18102                                 (reg:DI XMM4_REG)
18103                                 (reg:DI XMM5_REG)
18104                                 (reg:DI XMM6_REG)
18105                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18106               (use (match_dup 1))
18107               (use (match_dup 2))
18108               (use (match_dup 3))
18109               (use (match_dup 5))])]
18110 {
18111   /* Movaps is 4 bytes, AVX and movsd is 5 bytes.  */
18112   int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
18113
18114   /* Compute address to jump to:
18115      label - eax*size + nnamed_sse_arguments*size. */
18116   if (size == 5)
18117     emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18118                             gen_rtx_PLUS
18119                               (Pmode,
18120                                gen_rtx_MULT (Pmode, operands[1],
18121                                              GEN_INT (4)),
18122                                operands[1])));
18123   else  if (size == 4)
18124     emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18125                             gen_rtx_MULT (Pmode, operands[1],
18126                                           GEN_INT (4))));
18127   else
18128     gcc_unreachable ();
18129   if (INTVAL (operands[2]))
18130     emit_move_insn
18131       (operands[1],
18132        gen_rtx_CONST (DImode,
18133                       gen_rtx_PLUS (DImode,
18134                                     operands[3],
18135                                     GEN_INT (INTVAL (operands[2])
18136                                              * size))));
18137   else
18138     emit_move_insn (operands[1], operands[3]);
18139   emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
18140   operands[5] = GEN_INT (size);
18141 })
18142
18143 (define_insn "sse_prologue_save_insn"
18144   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18145                           (match_operand:DI 4 "const_int_operand" "n")))
18146         (unspec:BLK [(reg:DI XMM0_REG)
18147                      (reg:DI XMM1_REG)
18148                      (reg:DI XMM2_REG)
18149                      (reg:DI XMM3_REG)
18150                      (reg:DI XMM4_REG)
18151                      (reg:DI XMM5_REG)
18152                      (reg:DI XMM6_REG)
18153                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18154    (use (match_operand:DI 1 "register_operand" "r"))
18155    (use (match_operand:DI 2 "const_int_operand" "i"))
18156    (use (label_ref:DI (match_operand 3 "" "X")))
18157    (use (match_operand:DI 5 "const_int_operand" "i"))]
18158   "TARGET_64BIT
18159    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18160    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18161 {
18162   int i;
18163   operands[0] = gen_rtx_MEM (Pmode,
18164                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18165   /* VEX instruction with a REX prefix will #UD.  */
18166   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18167     gcc_unreachable ();
18168
18169   output_asm_insn ("jmp\t%A1", operands);
18170   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18171     {
18172       operands[4] = adjust_address (operands[0], DImode, i*16);
18173       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18174       PUT_MODE (operands[4], TImode);
18175       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18176         output_asm_insn ("rex", operands);
18177       if (crtl->stack_alignment_needed < 128)
18178         output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
18179       else
18180         output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18181     }
18182   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18183                                      CODE_LABEL_NUMBER (operands[3]));
18184   return "";
18185 }
18186   [(set_attr "type" "other")
18187    (set_attr "length_immediate" "0")
18188    (set_attr "length_address" "0")
18189    ;; 2 bytes for jump and opernds[4] bytes for each save.
18190    (set (attr "length")
18191      (plus (const_int 2)
18192            (mult (symbol_ref ("INTVAL (operands[5])"))
18193                  (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
18194    (set_attr "memory" "store")
18195    (set_attr "modrm" "0")
18196    (set_attr "prefix" "maybe_vex")
18197    (set_attr "mode" "DI")])
18198
18199 (define_expand "prefetch"
18200   [(prefetch (match_operand 0 "address_operand" "")
18201              (match_operand:SI 1 "const_int_operand" "")
18202              (match_operand:SI 2 "const_int_operand" ""))]
18203   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18204 {
18205   int rw = INTVAL (operands[1]);
18206   int locality = INTVAL (operands[2]);
18207
18208   gcc_assert (rw == 0 || rw == 1);
18209   gcc_assert (locality >= 0 && locality <= 3);
18210   gcc_assert (GET_MODE (operands[0]) == Pmode
18211               || GET_MODE (operands[0]) == VOIDmode);
18212
18213   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18214      supported by SSE counterpart or the SSE prefetch is not available
18215      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18216      of locality.  */
18217   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18218     operands[2] = GEN_INT (3);
18219   else
18220     operands[1] = const0_rtx;
18221 })
18222
18223 (define_insn "*prefetch_sse"
18224   [(prefetch (match_operand:SI 0 "address_operand" "p")
18225              (const_int 0)
18226              (match_operand:SI 1 "const_int_operand" ""))]
18227   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18228 {
18229   static const char * const patterns[4] = {
18230    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18231   };
18232
18233   int locality = INTVAL (operands[1]);
18234   gcc_assert (locality >= 0 && locality <= 3);
18235
18236   return patterns[locality];
18237 }
18238   [(set_attr "type" "sse")
18239    (set_attr "atom_sse_attr" "prefetch")
18240    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18241    (set_attr "memory" "none")])
18242
18243 (define_insn "*prefetch_sse_rex"
18244   [(prefetch (match_operand:DI 0 "address_operand" "p")
18245              (const_int 0)
18246              (match_operand:SI 1 "const_int_operand" ""))]
18247   "TARGET_PREFETCH_SSE && TARGET_64BIT"
18248 {
18249   static const char * const patterns[4] = {
18250    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18251   };
18252
18253   int locality = INTVAL (operands[1]);
18254   gcc_assert (locality >= 0 && locality <= 3);
18255
18256   return patterns[locality];
18257 }
18258   [(set_attr "type" "sse")
18259    (set_attr "atom_sse_attr" "prefetch")
18260    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18261    (set_attr "memory" "none")])
18262
18263 (define_insn "*prefetch_3dnow"
18264   [(prefetch (match_operand:SI 0 "address_operand" "p")
18265              (match_operand:SI 1 "const_int_operand" "n")
18266              (const_int 3))]
18267   "TARGET_3DNOW && !TARGET_64BIT"
18268 {
18269   if (INTVAL (operands[1]) == 0)
18270     return "prefetch\t%a0";
18271   else
18272     return "prefetchw\t%a0";
18273 }
18274   [(set_attr "type" "mmx")
18275    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18276    (set_attr "memory" "none")])
18277
18278 (define_insn "*prefetch_3dnow_rex"
18279   [(prefetch (match_operand:DI 0 "address_operand" "p")
18280              (match_operand:SI 1 "const_int_operand" "n")
18281              (const_int 3))]
18282   "TARGET_3DNOW && TARGET_64BIT"
18283 {
18284   if (INTVAL (operands[1]) == 0)
18285     return "prefetch\t%a0";
18286   else
18287     return "prefetchw\t%a0";
18288 }
18289   [(set_attr "type" "mmx")
18290    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18291    (set_attr "memory" "none")])
18292
18293 (define_expand "stack_protect_set"
18294   [(match_operand 0 "memory_operand" "")
18295    (match_operand 1 "memory_operand" "")]
18296   ""
18297 {
18298 #ifdef TARGET_THREAD_SSP_OFFSET
18299   if (TARGET_64BIT)
18300     emit_insn (gen_stack_tls_protect_set_di (operands[0],
18301                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18302   else
18303     emit_insn (gen_stack_tls_protect_set_si (operands[0],
18304                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18305 #else
18306   if (TARGET_64BIT)
18307     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18308   else
18309     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18310 #endif
18311   DONE;
18312 })
18313
18314 (define_insn "stack_protect_set_si"
18315   [(set (match_operand:SI 0 "memory_operand" "=m")
18316         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18317    (set (match_scratch:SI 2 "=&r") (const_int 0))
18318    (clobber (reg:CC FLAGS_REG))]
18319   ""
18320   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18321   [(set_attr "type" "multi")])
18322
18323 (define_insn "stack_protect_set_di"
18324   [(set (match_operand:DI 0 "memory_operand" "=m")
18325         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18326    (set (match_scratch:DI 2 "=&r") (const_int 0))
18327    (clobber (reg:CC FLAGS_REG))]
18328   "TARGET_64BIT"
18329   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18330   [(set_attr "type" "multi")])
18331
18332 (define_insn "stack_tls_protect_set_si"
18333   [(set (match_operand:SI 0 "memory_operand" "=m")
18334         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18335    (set (match_scratch:SI 2 "=&r") (const_int 0))
18336    (clobber (reg:CC FLAGS_REG))]
18337   ""
18338   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18339   [(set_attr "type" "multi")])
18340
18341 (define_insn "stack_tls_protect_set_di"
18342   [(set (match_operand:DI 0 "memory_operand" "=m")
18343         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18344    (set (match_scratch:DI 2 "=&r") (const_int 0))
18345    (clobber (reg:CC FLAGS_REG))]
18346   "TARGET_64BIT"
18347   {
18348      /* The kernel uses a different segment register for performance reasons; a
18349         system call would not have to trash the userspace segment register,
18350         which would be expensive */
18351      if (ix86_cmodel != CM_KERNEL)
18352         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18353      else
18354         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18355   }
18356   [(set_attr "type" "multi")])
18357
18358 (define_expand "stack_protect_test"
18359   [(match_operand 0 "memory_operand" "")
18360    (match_operand 1 "memory_operand" "")
18361    (match_operand 2 "" "")]
18362   ""
18363 {
18364   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18365
18366 #ifdef TARGET_THREAD_SSP_OFFSET
18367   if (TARGET_64BIT)
18368     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18369                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18370   else
18371     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18372                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18373 #else
18374   if (TARGET_64BIT)
18375     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18376   else
18377     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18378 #endif
18379
18380   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18381                                   flags, const0_rtx, operands[2]));
18382   DONE;
18383 })
18384
18385 (define_insn "stack_protect_test_si"
18386   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18387         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18388                      (match_operand:SI 2 "memory_operand" "m")]
18389                     UNSPEC_SP_TEST))
18390    (clobber (match_scratch:SI 3 "=&r"))]
18391   ""
18392   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18393   [(set_attr "type" "multi")])
18394
18395 (define_insn "stack_protect_test_di"
18396   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18397         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18398                      (match_operand:DI 2 "memory_operand" "m")]
18399                     UNSPEC_SP_TEST))
18400    (clobber (match_scratch:DI 3 "=&r"))]
18401   "TARGET_64BIT"
18402   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18403   [(set_attr "type" "multi")])
18404
18405 (define_insn "stack_tls_protect_test_si"
18406   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18407         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18408                      (match_operand:SI 2 "const_int_operand" "i")]
18409                     UNSPEC_SP_TLS_TEST))
18410    (clobber (match_scratch:SI 3 "=r"))]
18411   ""
18412   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18413   [(set_attr "type" "multi")])
18414
18415 (define_insn "stack_tls_protect_test_di"
18416   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18417         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18418                      (match_operand:DI 2 "const_int_operand" "i")]
18419                     UNSPEC_SP_TLS_TEST))
18420    (clobber (match_scratch:DI 3 "=r"))]
18421   "TARGET_64BIT"
18422   {
18423      /* The kernel uses a different segment register for performance reasons; a
18424         system call would not have to trash the userspace segment register,
18425         which would be expensive */
18426      if (ix86_cmodel != CM_KERNEL)
18427         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18428      else
18429         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18430   }
18431   [(set_attr "type" "multi")])
18432
18433 (define_insn "sse4_2_crc32<mode>"
18434   [(set (match_operand:SI 0 "register_operand" "=r")
18435         (unspec:SI
18436           [(match_operand:SI 1 "register_operand" "0")
18437            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18438           UNSPEC_CRC32))]
18439   "TARGET_SSE4_2 || TARGET_CRC32"
18440   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18441   [(set_attr "type" "sselog1")
18442    (set_attr "prefix_rep" "1")
18443    (set_attr "prefix_extra" "1")
18444    (set (attr "prefix_data16")
18445      (if_then_else (match_operand:HI 2 "" "")
18446        (const_string "1")
18447        (const_string "*")))
18448    (set (attr "prefix_rex")
18449      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18450        (const_string "1")
18451        (const_string "*")))
18452    (set_attr "mode" "SI")])
18453
18454 (define_insn "sse4_2_crc32di"
18455   [(set (match_operand:DI 0 "register_operand" "=r")
18456         (unspec:DI
18457           [(match_operand:DI 1 "register_operand" "0")
18458            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18459           UNSPEC_CRC32))]
18460   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18461   "crc32{q}\t{%2, %0|%0, %2}"
18462   [(set_attr "type" "sselog1")
18463    (set_attr "prefix_rep" "1")
18464    (set_attr "prefix_extra" "1")
18465    (set_attr "mode" "DI")])
18466
18467 (define_expand "rdpmc"
18468   [(match_operand:DI 0 "register_operand" "")
18469    (match_operand:SI 1 "register_operand" "")]
18470   ""
18471 {
18472   rtx reg = gen_reg_rtx (DImode);
18473   rtx si;
18474
18475   /* Force operand 1 into ECX.  */
18476   rtx ecx = gen_rtx_REG (SImode, CX_REG);
18477   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18478   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18479                                 UNSPECV_RDPMC);
18480
18481   if (TARGET_64BIT)
18482     {
18483       rtvec vec = rtvec_alloc (2);
18484       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18485       rtx upper = gen_reg_rtx (DImode);
18486       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18487                                         gen_rtvec (1, const0_rtx),
18488                                         UNSPECV_RDPMC);
18489       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18490       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18491       emit_insn (load);
18492       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18493                                    NULL, 1, OPTAB_DIRECT);
18494       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18495                                  OPTAB_DIRECT);
18496     }
18497   else
18498     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18499   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18500   DONE;
18501 })
18502
18503 (define_insn "*rdpmc"
18504   [(set (match_operand:DI 0 "register_operand" "=A")
18505         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18506                             UNSPECV_RDPMC))]
18507   "!TARGET_64BIT"
18508   "rdpmc"
18509   [(set_attr "type" "other")
18510    (set_attr "length" "2")])
18511
18512 (define_insn "*rdpmc_rex64"
18513   [(set (match_operand:DI 0 "register_operand" "=a")
18514         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18515                             UNSPECV_RDPMC))
18516   (set (match_operand:DI 1 "register_operand" "=d")
18517        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18518   "TARGET_64BIT"
18519   "rdpmc"
18520   [(set_attr "type" "other")
18521    (set_attr "length" "2")])
18522
18523 (define_expand "rdtsc"
18524   [(set (match_operand:DI 0 "register_operand" "")
18525         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18526   ""
18527 {
18528   if (TARGET_64BIT)
18529     {
18530       rtvec vec = rtvec_alloc (2);
18531       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18532       rtx upper = gen_reg_rtx (DImode);
18533       rtx lower = gen_reg_rtx (DImode);
18534       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18535                                          gen_rtvec (1, const0_rtx),
18536                                          UNSPECV_RDTSC);
18537       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18538       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18539       emit_insn (load);
18540       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18541                                    NULL, 1, OPTAB_DIRECT);
18542       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18543                                    OPTAB_DIRECT);
18544       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18545       DONE;
18546     }
18547 })
18548
18549 (define_insn "*rdtsc"
18550   [(set (match_operand:DI 0 "register_operand" "=A")
18551         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18552   "!TARGET_64BIT"
18553   "rdtsc"
18554   [(set_attr "type" "other")
18555    (set_attr "length" "2")])
18556
18557 (define_insn "*rdtsc_rex64"
18558   [(set (match_operand:DI 0 "register_operand" "=a")
18559         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18560    (set (match_operand:DI 1 "register_operand" "=d")
18561         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18562   "TARGET_64BIT"
18563   "rdtsc"
18564   [(set_attr "type" "other")
18565    (set_attr "length" "2")])
18566
18567 (define_expand "rdtscp"
18568   [(match_operand:DI 0 "register_operand" "")
18569    (match_operand:SI 1 "memory_operand" "")]
18570   ""
18571 {
18572   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18573                                     gen_rtvec (1, const0_rtx),
18574                                     UNSPECV_RDTSCP);
18575   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18576                                     gen_rtvec (1, const0_rtx),
18577                                     UNSPECV_RDTSCP);
18578   rtx reg = gen_reg_rtx (DImode);
18579   rtx tmp = gen_reg_rtx (SImode);
18580
18581   if (TARGET_64BIT)
18582     {
18583       rtvec vec = rtvec_alloc (3);
18584       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18585       rtx upper = gen_reg_rtx (DImode);
18586       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18587       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18588       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18589       emit_insn (load);
18590       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18591                                    NULL, 1, OPTAB_DIRECT);
18592       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18593                                  OPTAB_DIRECT);
18594     }
18595   else
18596     {
18597       rtvec vec = rtvec_alloc (2);
18598       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18599       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18600       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18601       emit_insn (load);
18602     }
18603   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18604   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18605   DONE;
18606 })
18607
18608 (define_insn "*rdtscp"
18609   [(set (match_operand:DI 0 "register_operand" "=A")
18610         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18611    (set (match_operand:SI 1 "register_operand" "=c")
18612         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18613   "!TARGET_64BIT"
18614   "rdtscp"
18615   [(set_attr "type" "other")
18616    (set_attr "length" "3")])
18617
18618 (define_insn "*rdtscp_rex64"
18619   [(set (match_operand:DI 0 "register_operand" "=a")
18620         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18621    (set (match_operand:DI 1 "register_operand" "=d")
18622         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18623    (set (match_operand:SI 2 "register_operand" "=c")
18624         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18625   "TARGET_64BIT"
18626   "rdtscp"
18627   [(set_attr "type" "other")
18628    (set_attr "length" "3")])
18629
18630 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18631 ;;
18632 ;; LWP instructions
18633 ;;
18634 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18635
18636 (define_expand "lwp_llwpcb"
18637   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18638                     UNSPECV_LLWP_INTRINSIC)]
18639   "TARGET_LWP"
18640   "")
18641
18642 (define_insn "*lwp_llwpcb<mode>1"
18643   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18644                     UNSPECV_LLWP_INTRINSIC)]
18645   "TARGET_LWP"
18646   "llwpcb\t%0"
18647   [(set_attr "type" "lwp")
18648    (set_attr "mode" "<MODE>")
18649    (set_attr "length" "5")])
18650
18651 (define_expand "lwp_slwpcb"
18652   [(set (match_operand 0 "register_operand" "=r")
18653         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18654   "TARGET_LWP"
18655   {
18656     if (TARGET_64BIT)
18657       emit_insn (gen_lwp_slwpcbdi (operands[0]));
18658     else
18659       emit_insn (gen_lwp_slwpcbsi (operands[0]));
18660     DONE;
18661   })
18662
18663 (define_insn "lwp_slwpcb<mode>"
18664   [(set (match_operand:P 0 "register_operand" "=r")
18665         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18666   "TARGET_LWP"
18667   "slwpcb\t%0"
18668   [(set_attr "type" "lwp")
18669    (set_attr "mode" "<MODE>")
18670    (set_attr "length" "5")])
18671
18672 (define_expand "lwp_lwpval<mode>3"
18673   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18674                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18675                      (match_operand:SI 3 "const_int_operand" "i")]
18676                     UNSPECV_LWPVAL_INTRINSIC)]
18677   "TARGET_LWP"
18678   "/* Avoid unused variable warning.  */
18679    (void) operand0;")
18680
18681 (define_insn "*lwp_lwpval<mode>3_1"
18682   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18683                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18684                      (match_operand:SI 2 "const_int_operand" "i")]
18685                     UNSPECV_LWPVAL_INTRINSIC)]
18686   "TARGET_LWP"
18687   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18688   [(set_attr "type" "lwp")
18689    (set_attr "mode" "<MODE>")
18690    (set (attr "length")
18691         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18692
18693 (define_expand "lwp_lwpins<mode>3"
18694   [(set (reg:CCC FLAGS_REG)
18695         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18696                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18697                               (match_operand:SI 3 "const_int_operand" "i")]
18698                              UNSPECV_LWPINS_INTRINSIC))
18699    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18700         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18701   "TARGET_LWP"
18702   "")
18703
18704 (define_insn "*lwp_lwpins<mode>3_1"
18705   [(set (reg:CCC FLAGS_REG)
18706         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18707                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18708                               (match_operand:SI 2 "const_int_operand" "i")]
18709                              UNSPECV_LWPINS_INTRINSIC))]
18710   "TARGET_LWP"
18711   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18712   [(set_attr "type" "lwp")
18713    (set_attr "mode" "<MODE>")
18714    (set (attr "length")
18715         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18716
18717 (include "mmx.md")
18718 (include "sse.md")
18719 (include "sync.md")