OSDN Git Service

fb9cd645419d1f83913efb863649fba9a4af9c34
[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, 2011
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 ;; @ -- print a segment register of thread base pointer load
63
64 ;; UNSPEC usage:
65
66 (define_c_enum "unspec" [
67   ;; Relocation specifiers
68   UNSPEC_GOT
69   UNSPEC_GOTOFF
70   UNSPEC_GOTPCREL
71   UNSPEC_GOTTPOFF
72   UNSPEC_TPOFF
73   UNSPEC_NTPOFF
74   UNSPEC_DTPOFF
75   UNSPEC_GOTNTPOFF
76   UNSPEC_INDNTPOFF
77   UNSPEC_PLTOFF
78   UNSPEC_MACHOPIC_OFFSET
79   UNSPEC_PCREL
80
81   ;; Prologue support
82   UNSPEC_STACK_ALLOC
83   UNSPEC_SET_GOT
84   UNSPEC_REG_SAVE
85   UNSPEC_DEF_CFA
86   UNSPEC_SET_RIP
87   UNSPEC_SET_GOT_OFFSET
88   UNSPEC_MEMORY_BLOCKAGE
89   UNSPEC_STACK_CHECK
90
91   ;; TLS support
92   UNSPEC_TP
93   UNSPEC_TLS_GD
94   UNSPEC_TLS_LD_BASE
95   UNSPEC_TLSDESC
96   UNSPEC_TLS_IE_SUN
97
98   ;; Other random patterns
99   UNSPEC_SCAS
100   UNSPEC_FNSTSW
101   UNSPEC_SAHF
102   UNSPEC_PARITY
103   UNSPEC_FSTCW
104   UNSPEC_ADD_CARRY
105   UNSPEC_FLDCW
106   UNSPEC_REP
107   UNSPEC_LD_MPIC        ; load_macho_picbase
108   UNSPEC_TRUNC_NOOP
109   UNSPEC_DIV_ALREADY_SPLIT
110   UNSPEC_CALL_NEEDS_VZEROUPPER
111
112   ;; For SSE/MMX support:
113   UNSPEC_FIX_NOTRUNC
114   UNSPEC_MASKMOV
115   UNSPEC_MOVMSK
116   UNSPEC_MOVNT
117   UNSPEC_MOVU
118   UNSPEC_RCP
119   UNSPEC_RSQRT
120   UNSPEC_SFENCE
121   UNSPEC_PFRCP
122   UNSPEC_PFRCPIT1
123   UNSPEC_PFRCPIT2
124   UNSPEC_PFRSQRT
125   UNSPEC_PFRSQIT1
126   UNSPEC_MFENCE
127   UNSPEC_LFENCE
128   UNSPEC_PSADBW
129   UNSPEC_LDDQU
130   UNSPEC_MS_TO_SYSV_CALL
131
132   ;; Generic math support
133   UNSPEC_COPYSIGN
134   UNSPEC_IEEE_MIN       ; not commutative
135   UNSPEC_IEEE_MAX       ; not commutative
136
137   ;; x87 Floating point
138   UNSPEC_SIN
139   UNSPEC_COS
140   UNSPEC_FPATAN
141   UNSPEC_FYL2X
142   UNSPEC_FYL2XP1
143   UNSPEC_FRNDINT
144   UNSPEC_FIST
145   UNSPEC_F2XM1
146   UNSPEC_TAN
147   UNSPEC_FXAM
148
149   ;; x87 Rounding
150   UNSPEC_FRNDINT_FLOOR
151   UNSPEC_FRNDINT_CEIL
152   UNSPEC_FRNDINT_TRUNC
153   UNSPEC_FRNDINT_MASK_PM
154   UNSPEC_FIST_FLOOR
155   UNSPEC_FIST_CEIL
156
157   ;; x87 Double output FP
158   UNSPEC_SINCOS_COS
159   UNSPEC_SINCOS_SIN
160   UNSPEC_XTRACT_FRACT
161   UNSPEC_XTRACT_EXP
162   UNSPEC_FSCALE_FRACT
163   UNSPEC_FSCALE_EXP
164   UNSPEC_FPREM_F
165   UNSPEC_FPREM_U
166   UNSPEC_FPREM1_F
167   UNSPEC_FPREM1_U
168
169   UNSPEC_C2_FLAG
170   UNSPEC_FXAM_MEM
171
172   ;; SSP patterns
173   UNSPEC_SP_SET
174   UNSPEC_SP_TEST
175   UNSPEC_SP_TLS_SET
176   UNSPEC_SP_TLS_TEST
177
178   ;; SSSE3
179   UNSPEC_PSHUFB
180   UNSPEC_PSIGN
181   UNSPEC_PALIGNR
182
183   ;; For SSE4A support
184   UNSPEC_EXTRQI
185   UNSPEC_EXTRQ
186   UNSPEC_INSERTQI
187   UNSPEC_INSERTQ
188
189   ;; For SSE4.1 support
190   UNSPEC_BLENDV
191   UNSPEC_INSERTPS
192   UNSPEC_DP
193   UNSPEC_MOVNTDQA
194   UNSPEC_MPSADBW
195   UNSPEC_PHMINPOSUW
196   UNSPEC_PTEST
197   UNSPEC_ROUND
198
199   ;; For SSE4.2 support
200   UNSPEC_CRC32
201   UNSPEC_PCMPESTR
202   UNSPEC_PCMPISTR
203
204   ;; For FMA4 support
205   UNSPEC_FMADDSUB
206   UNSPEC_XOP_UNSIGNED_CMP
207   UNSPEC_XOP_TRUEFALSE
208   UNSPEC_XOP_PERMUTE
209   UNSPEC_FRCZ
210
211   ;; For AES support
212   UNSPEC_AESENC
213   UNSPEC_AESENCLAST
214   UNSPEC_AESDEC
215   UNSPEC_AESDECLAST
216   UNSPEC_AESIMC
217   UNSPEC_AESKEYGENASSIST
218
219   ;; For PCLMUL support
220   UNSPEC_PCLMUL
221
222   ;; For AVX support
223   UNSPEC_PCMP
224   UNSPEC_VPERMIL
225   UNSPEC_VPERMIL2
226   UNSPEC_VPERMIL2F128
227   UNSPEC_CAST
228   UNSPEC_VTESTP
229   UNSPEC_VCVTPH2PS
230   UNSPEC_VCVTPS2PH
231
232   ;; For BMI support
233   UNSPEC_BEXTR
234
235   ;; For RDRAND support
236   UNSPEC_RDRAND
237 ])
238
239 (define_c_enum "unspecv" [
240   UNSPECV_BLOCKAGE
241   UNSPECV_STACK_PROBE
242   UNSPECV_PROBE_STACK_RANGE
243   UNSPECV_EMMS
244   UNSPECV_LDMXCSR
245   UNSPECV_STMXCSR
246   UNSPECV_FEMMS
247   UNSPECV_CLFLUSH
248   UNSPECV_ALIGN
249   UNSPECV_MONITOR
250   UNSPECV_MWAIT
251   UNSPECV_CMPXCHG
252   UNSPECV_XCHG
253   UNSPECV_LOCK
254   UNSPECV_PROLOGUE_USE
255   UNSPECV_CLD
256   UNSPECV_NOPS
257   UNSPECV_VZEROALL
258   UNSPECV_VZEROUPPER
259   UNSPECV_RDTSC
260   UNSPECV_RDTSCP
261   UNSPECV_RDPMC
262   UNSPECV_LLWP_INTRINSIC
263   UNSPECV_SLWP_INTRINSIC
264   UNSPECV_LWPVAL_INTRINSIC
265   UNSPECV_LWPINS_INTRINSIC
266   UNSPECV_RDFSBASE
267   UNSPECV_RDGSBASE
268   UNSPECV_WRFSBASE
269   UNSPECV_WRGSBASE
270   UNSPECV_SPLIT_STACK_RETURN
271 ])
272
273 ;; Constants to represent rounding modes in the ROUND instruction
274 (define_constants
275   [(ROUND_FLOOR                 0x1)
276    (ROUND_CEIL                  0x2)
277    (ROUND_TRUNC                 0x3)
278    (ROUND_MXCSR                 0x4)
279    (ROUND_NO_EXC                0x8)
280   ])
281
282 ;; Constants to represent pcomtrue/pcomfalse variants
283 (define_constants
284   [(PCOM_FALSE                  0)
285    (PCOM_TRUE                   1)
286    (COM_FALSE_S                 2)
287    (COM_FALSE_P                 3)
288    (COM_TRUE_S                  4)
289    (COM_TRUE_P                  5)
290   ])
291
292 ;; Constants used in the XOP pperm instruction
293 (define_constants
294   [(PPERM_SRC                   0x00)   /* copy source */
295    (PPERM_INVERT                0x20)   /* invert source */
296    (PPERM_REVERSE               0x40)   /* bit reverse source */
297    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
298    (PPERM_ZERO                  0x80)   /* all 0's */
299    (PPERM_ONES                  0xa0)   /* all 1's */
300    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
301    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
302    (PPERM_SRC1                  0x00)   /* use first source byte */
303    (PPERM_SRC2                  0x10)   /* use second source byte */
304    ])
305
306 ;; Registers by name.
307 (define_constants
308   [(AX_REG                       0)
309    (DX_REG                       1)
310    (CX_REG                       2)
311    (BX_REG                       3)
312    (SI_REG                       4)
313    (DI_REG                       5)
314    (BP_REG                       6)
315    (SP_REG                       7)
316    (ST0_REG                      8)
317    (ST1_REG                      9)
318    (ST2_REG                     10)
319    (ST3_REG                     11)
320    (ST4_REG                     12)
321    (ST5_REG                     13)
322    (ST6_REG                     14)
323    (ST7_REG                     15)
324    (FLAGS_REG                   17)
325    (FPSR_REG                    18)
326    (FPCR_REG                    19)
327    (XMM0_REG                    21)
328    (XMM1_REG                    22)
329    (XMM2_REG                    23)
330    (XMM3_REG                    24)
331    (XMM4_REG                    25)
332    (XMM5_REG                    26)
333    (XMM6_REG                    27)
334    (XMM7_REG                    28)
335    (MM0_REG                     29)
336    (MM1_REG                     30)
337    (MM2_REG                     31)
338    (MM3_REG                     32)
339    (MM4_REG                     33)
340    (MM5_REG                     34)
341    (MM6_REG                     35)
342    (MM7_REG                     36)
343    (R8_REG                      37)
344    (R9_REG                      38)
345    (R10_REG                     39)
346    (R11_REG                     40)
347    (R12_REG                     41)
348    (R13_REG                     42)
349    (XMM8_REG                    45)
350    (XMM9_REG                    46)
351    (XMM10_REG                   47)
352    (XMM11_REG                   48)
353    (XMM12_REG                   49)
354    (XMM13_REG                   50)
355    (XMM14_REG                   51)
356    (XMM15_REG                   52)
357   ])
358
359 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
360 ;; from i386.c.
361
362 ;; In C guard expressions, put expressions which may be compile-time
363 ;; constants first.  This allows for better optimization.  For
364 ;; example, write "TARGET_64BIT && reload_completed", not
365 ;; "reload_completed && TARGET_64BIT".
366
367 \f
368 ;; Processor type.
369 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
370                     atom,generic64,amdfam10,bdver1,btver1"
371   (const (symbol_ref "ix86_schedule")))
372
373 ;; A basic instruction type.  Refinements due to arguments to be
374 ;; provided in other attributes.
375 (define_attr "type"
376   "other,multi,
377    alu,alu1,negnot,imov,imovx,lea,
378    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
379    icmp,test,ibr,setcc,icmov,
380    push,pop,call,callv,leave,
381    str,bitmanip,
382    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
383    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
384    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
385    ssemuladd,sse4arg,lwp,
386    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
387   (const_string "other"))
388
389 ;; Main data type used by the insn
390 (define_attr "mode"
391   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
392   (const_string "unknown"))
393
394 ;; The CPU unit operations uses.
395 (define_attr "unit" "integer,i387,sse,mmx,unknown"
396   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
397            (const_string "i387")
398          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
399                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
400                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
401            (const_string "sse")
402          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
403            (const_string "mmx")
404          (eq_attr "type" "other")
405            (const_string "unknown")]
406          (const_string "integer")))
407
408 ;; The (bounding maximum) length of an instruction immediate.
409 (define_attr "length_immediate" ""
410   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
411                           bitmanip")
412            (const_int 0)
413          (eq_attr "unit" "i387,sse,mmx")
414            (const_int 0)
415          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
416                           imul,icmp,push,pop")
417            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
418          (eq_attr "type" "imov,test")
419            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
420          (eq_attr "type" "call")
421            (if_then_else (match_operand 0 "constant_call_address_operand" "")
422              (const_int 4)
423              (const_int 0))
424          (eq_attr "type" "callv")
425            (if_then_else (match_operand 1 "constant_call_address_operand" "")
426              (const_int 4)
427              (const_int 0))
428          ;; We don't know the size before shorten_branches.  Expect
429          ;; the instruction to fit for better scheduling.
430          (eq_attr "type" "ibr")
431            (const_int 1)
432          ]
433          (symbol_ref "/* Update immediate_length and other attributes! */
434                       gcc_unreachable (),1")))
435
436 ;; The (bounding maximum) length of an instruction address.
437 (define_attr "length_address" ""
438   (cond [(eq_attr "type" "str,other,multi,fxch")
439            (const_int 0)
440          (and (eq_attr "type" "call")
441               (match_operand 0 "constant_call_address_operand" ""))
442              (const_int 0)
443          (and (eq_attr "type" "callv")
444               (match_operand 1 "constant_call_address_operand" ""))
445              (const_int 0)
446          ]
447          (symbol_ref "ix86_attr_length_address_default (insn)")))
448
449 ;; Set when length prefix is used.
450 (define_attr "prefix_data16" ""
451   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
452            (const_int 0)
453          (eq_attr "mode" "HI")
454            (const_int 1)
455          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
456            (const_int 1)
457         ]
458         (const_int 0)))
459
460 ;; Set when string REP prefix is used.
461 (define_attr "prefix_rep" ""
462   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
463            (const_int 0)
464          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
465            (const_int 1)
466         ]
467         (const_int 0)))
468
469 ;; Set when 0f opcode prefix is used.
470 (define_attr "prefix_0f" ""
471   (if_then_else
472     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
473          (eq_attr "unit" "sse,mmx"))
474     (const_int 1)
475     (const_int 0)))
476
477 ;; Set when REX opcode prefix is used.
478 (define_attr "prefix_rex" ""
479   (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
480            (const_int 0)
481          (and (eq_attr "mode" "DI")
482               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
483                    (eq_attr "unit" "!mmx")))
484            (const_int 1)
485          (and (eq_attr "mode" "QI")
486               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
487                   (const_int 0)))
488            (const_int 1)
489          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
490              (const_int 0))
491            (const_int 1)
492          (and (eq_attr "type" "imovx")
493               (match_operand:QI 1 "ext_QIreg_operand" ""))
494            (const_int 1)
495         ]
496         (const_int 0)))
497
498 ;; There are also additional prefixes in 3DNOW, SSSE3.
499 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
500 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
501 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
502 (define_attr "prefix_extra" ""
503   (cond [(eq_attr "type" "ssemuladd,sse4arg")
504            (const_int 2)
505          (eq_attr "type" "sseiadd1,ssecvt1")
506            (const_int 1)
507         ]
508         (const_int 0)))
509
510 ;; Prefix used: original, VEX or maybe VEX.
511 (define_attr "prefix" "orig,vex,maybe_vex"
512   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
513     (const_string "vex")
514     (const_string "orig")))
515
516 ;; VEX W bit is used.
517 (define_attr "prefix_vex_w" "" (const_int 0))
518
519 ;; The length of VEX prefix
520 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
521 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
522 ;; still prefix_0f 1, with prefix_extra 1.
523 (define_attr "length_vex" ""
524   (if_then_else (and (eq_attr "prefix_0f" "1")
525                      (eq_attr "prefix_extra" "0"))
526     (if_then_else (eq_attr "prefix_vex_w" "1")
527       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
528       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
529     (if_then_else (eq_attr "prefix_vex_w" "1")
530       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
531       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
532
533 ;; Set when modrm byte is used.
534 (define_attr "modrm" ""
535   (cond [(eq_attr "type" "str,leave")
536            (const_int 0)
537          (eq_attr "unit" "i387")
538            (const_int 0)
539          (and (eq_attr "type" "incdec")
540               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
541                    (ior (match_operand:SI 1 "register_operand" "")
542                         (match_operand:HI 1 "register_operand" ""))))
543            (const_int 0)
544          (and (eq_attr "type" "push")
545               (not (match_operand 1 "memory_operand" "")))
546            (const_int 0)
547          (and (eq_attr "type" "pop")
548               (not (match_operand 0 "memory_operand" "")))
549            (const_int 0)
550          (and (eq_attr "type" "imov")
551               (and (not (eq_attr "mode" "DI"))
552                    (ior (and (match_operand 0 "register_operand" "")
553                              (match_operand 1 "immediate_operand" ""))
554                         (ior (and (match_operand 0 "ax_reg_operand" "")
555                                   (match_operand 1 "memory_displacement_only_operand" ""))
556                              (and (match_operand 0 "memory_displacement_only_operand" "")
557                                   (match_operand 1 "ax_reg_operand" ""))))))
558            (const_int 0)
559          (and (eq_attr "type" "call")
560               (match_operand 0 "constant_call_address_operand" ""))
561              (const_int 0)
562          (and (eq_attr "type" "callv")
563               (match_operand 1 "constant_call_address_operand" ""))
564              (const_int 0)
565          (and (eq_attr "type" "alu,alu1,icmp,test")
566               (match_operand 0 "ax_reg_operand" ""))
567              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
568          ]
569          (const_int 1)))
570
571 ;; The (bounding maximum) length of an instruction in bytes.
572 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
573 ;; Later we may want to split them and compute proper length as for
574 ;; other insns.
575 (define_attr "length" ""
576   (cond [(eq_attr "type" "other,multi,fistp,frndint")
577            (const_int 16)
578          (eq_attr "type" "fcmp")
579            (const_int 4)
580          (eq_attr "unit" "i387")
581            (plus (const_int 2)
582                  (plus (attr "prefix_data16")
583                        (attr "length_address")))
584          (ior (eq_attr "prefix" "vex")
585               (and (eq_attr "prefix" "maybe_vex")
586                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
587            (plus (attr "length_vex")
588                  (plus (attr "length_immediate")
589                        (plus (attr "modrm")
590                              (attr "length_address"))))]
591          (plus (plus (attr "modrm")
592                      (plus (attr "prefix_0f")
593                            (plus (attr "prefix_rex")
594                                  (plus (attr "prefix_extra")
595                                        (const_int 1)))))
596                (plus (attr "prefix_rep")
597                      (plus (attr "prefix_data16")
598                            (plus (attr "length_immediate")
599                                  (attr "length_address")))))))
600
601 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
602 ;; `store' if there is a simple memory reference therein, or `unknown'
603 ;; if the instruction is complex.
604
605 (define_attr "memory" "none,load,store,both,unknown"
606   (cond [(eq_attr "type" "other,multi,str,lwp")
607            (const_string "unknown")
608          (eq_attr "type" "lea,fcmov,fpspc")
609            (const_string "none")
610          (eq_attr "type" "fistp,leave")
611            (const_string "both")
612          (eq_attr "type" "frndint")
613            (const_string "load")
614          (eq_attr "type" "push")
615            (if_then_else (match_operand 1 "memory_operand" "")
616              (const_string "both")
617              (const_string "store"))
618          (eq_attr "type" "pop")
619            (if_then_else (match_operand 0 "memory_operand" "")
620              (const_string "both")
621              (const_string "load"))
622          (eq_attr "type" "setcc")
623            (if_then_else (match_operand 0 "memory_operand" "")
624              (const_string "store")
625              (const_string "none"))
626          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
627            (if_then_else (ior (match_operand 0 "memory_operand" "")
628                               (match_operand 1 "memory_operand" ""))
629              (const_string "load")
630              (const_string "none"))
631          (eq_attr "type" "ibr")
632            (if_then_else (match_operand 0 "memory_operand" "")
633              (const_string "load")
634              (const_string "none"))
635          (eq_attr "type" "call")
636            (if_then_else (match_operand 0 "constant_call_address_operand" "")
637              (const_string "none")
638              (const_string "load"))
639          (eq_attr "type" "callv")
640            (if_then_else (match_operand 1 "constant_call_address_operand" "")
641              (const_string "none")
642              (const_string "load"))
643          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
644               (match_operand 1 "memory_operand" ""))
645            (const_string "both")
646          (and (match_operand 0 "memory_operand" "")
647               (match_operand 1 "memory_operand" ""))
648            (const_string "both")
649          (match_operand 0 "memory_operand" "")
650            (const_string "store")
651          (match_operand 1 "memory_operand" "")
652            (const_string "load")
653          (and (eq_attr "type"
654                  "!alu1,negnot,ishift1,
655                    imov,imovx,icmp,test,bitmanip,
656                    fmov,fcmp,fsgn,
657                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
658                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
659               (match_operand 2 "memory_operand" ""))
660            (const_string "load")
661          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
662               (match_operand 3 "memory_operand" ""))
663            (const_string "load")
664         ]
665         (const_string "none")))
666
667 ;; Indicates if an instruction has both an immediate and a displacement.
668
669 (define_attr "imm_disp" "false,true,unknown"
670   (cond [(eq_attr "type" "other,multi")
671            (const_string "unknown")
672          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
673               (and (match_operand 0 "memory_displacement_operand" "")
674                    (match_operand 1 "immediate_operand" "")))
675            (const_string "true")
676          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
677               (and (match_operand 0 "memory_displacement_operand" "")
678                    (match_operand 2 "immediate_operand" "")))
679            (const_string "true")
680         ]
681         (const_string "false")))
682
683 ;; Indicates if an FP operation has an integer source.
684
685 (define_attr "fp_int_src" "false,true"
686   (const_string "false"))
687
688 ;; Defines rounding mode of an FP operation.
689
690 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
691   (const_string "any"))
692
693 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
694 (define_attr "use_carry" "0,1" (const_string "0"))
695
696 ;; Define attribute to indicate unaligned ssemov insns
697 (define_attr "movu" "0,1" (const_string "0"))
698
699 ;; Used to control the "enabled" attribute on a per-instruction basis.
700 (define_attr "isa" "base,noavx,avx"
701   (const_string "base"))
702
703 (define_attr "enabled" ""
704   (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
705          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
706         ]
707         (const_int 1)))
708
709 ;; Describe a user's asm statement.
710 (define_asm_attributes
711   [(set_attr "length" "128")
712    (set_attr "type" "multi")])
713
714 (define_code_iterator plusminus [plus minus])
715
716 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
717
718 ;; Base name for define_insn
719 (define_code_attr plusminus_insn
720   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
721    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
722
723 ;; Base name for insn mnemonic.
724 (define_code_attr plusminus_mnemonic
725   [(plus "add") (ss_plus "adds") (us_plus "addus")
726    (minus "sub") (ss_minus "subs") (us_minus "subus")])
727 (define_code_attr plusminus_carry_mnemonic
728   [(plus "adc") (minus "sbb")])
729
730 ;; Mark commutative operators as such in constraints.
731 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
732                         (minus "") (ss_minus "") (us_minus "")])
733
734 ;; Mapping of signed max and min
735 (define_code_iterator smaxmin [smax smin])
736
737 ;; Mapping of unsigned max and min
738 (define_code_iterator umaxmin [umax umin])
739
740 ;; Base name for integer and FP insn mnemonic
741 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
742                               (umax "maxu") (umin "minu")])
743 (define_code_attr maxmin_float [(smax "max") (smin "min")])
744
745 ;; Mapping of logic operators
746 (define_code_iterator any_logic [and ior xor])
747 (define_code_iterator any_or [ior xor])
748
749 ;; Base name for insn mnemonic.
750 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
751
752 ;; Mapping of shift-right operators
753 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
754
755 ;; Base name for define_insn
756 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
757
758 ;; Base name for insn mnemonic.
759 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
760
761 ;; Mapping of rotate operators
762 (define_code_iterator any_rotate [rotate rotatert])
763
764 ;; Base name for define_insn
765 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
766
767 ;; Base name for insn mnemonic.
768 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
769
770 ;; Mapping of abs neg operators
771 (define_code_iterator absneg [abs neg])
772
773 ;; Base name for x87 insn mnemonic.
774 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
775
776 ;; Used in signed and unsigned widening multiplications.
777 (define_code_iterator any_extend [sign_extend zero_extend])
778
779 ;; Various insn prefixes for signed and unsigned operations.
780 (define_code_attr u [(sign_extend "") (zero_extend "u")
781                      (div "") (udiv "u")])
782 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
783
784 ;; Used in signed and unsigned divisions.
785 (define_code_iterator any_div [div udiv])
786
787 ;; Instruction prefix for signed and unsigned operations.
788 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
789                              (div "i") (udiv "")])
790
791 ;; 64bit single word integer modes.
792 (define_mode_iterator SWI1248x [QI HI SI DI])
793
794 ;; 64bit single word integer modes without QImode and HImode.
795 (define_mode_iterator SWI48x [SI DI])
796
797 ;; Single word integer modes.
798 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
799
800 ;; Single word integer modes without SImode and DImode.
801 (define_mode_iterator SWI12 [QI HI])
802
803 ;; Single word integer modes without DImode.
804 (define_mode_iterator SWI124 [QI HI SI])
805
806 ;; Single word integer modes without QImode and DImode.
807 (define_mode_iterator SWI24 [HI SI])
808
809 ;; Single word integer modes without QImode.
810 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
811
812 ;; Single word integer modes without QImode and HImode.
813 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
814
815 ;; All math-dependant single and double word integer modes.
816 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
817                              (HI "TARGET_HIMODE_MATH")
818                              SI DI (TI "TARGET_64BIT")])
819
820 ;; Math-dependant single word integer modes.
821 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
822                             (HI "TARGET_HIMODE_MATH")
823                             SI (DI "TARGET_64BIT")])
824
825 ;; Math-dependant single word integer modes without DImode.
826 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
827                                (HI "TARGET_HIMODE_MATH")
828                                SI])
829
830 ;; Math-dependant single word integer modes without QImode.
831 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
832                                SI (DI "TARGET_64BIT")])
833
834 ;; Double word integer modes.
835 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
836                            (TI "TARGET_64BIT")])
837
838 ;; Double word integer modes as mode attribute.
839 (define_mode_attr DWI [(SI "DI") (DI "TI")])
840 (define_mode_attr dwi [(SI "di") (DI "ti")])
841
842 ;; Half mode for double word integer modes.
843 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
844                             (DI "TARGET_64BIT")])
845
846 ;; Instruction suffix for integer modes.
847 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
848
849 ;; Pointer size prefix for integer modes (Intel asm dialect)
850 (define_mode_attr iptrsize [(QI "BYTE")
851                             (HI "WORD")
852                             (SI "DWORD")
853                             (DI "QWORD")])
854
855 ;; Register class for integer modes.
856 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
857
858 ;; Immediate operand constraint for integer modes.
859 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
860
861 ;; General operand constraint for word modes.
862 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
863
864 ;; Immediate operand constraint for double integer modes.
865 (define_mode_attr di [(SI "iF") (DI "e")])
866
867 ;; Immediate operand constraint for shifts.
868 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
869
870 ;; General operand predicate for integer modes.
871 (define_mode_attr general_operand
872         [(QI "general_operand")
873          (HI "general_operand")
874          (SI "general_operand")
875          (DI "x86_64_general_operand")
876          (TI "x86_64_general_operand")])
877
878 ;; General sign/zero extend operand predicate for integer modes.
879 (define_mode_attr general_szext_operand
880         [(QI "general_operand")
881          (HI "general_operand")
882          (SI "general_operand")
883          (DI "x86_64_szext_general_operand")])
884
885 ;; Immediate operand predicate for integer modes.
886 (define_mode_attr immediate_operand
887         [(QI "immediate_operand")
888          (HI "immediate_operand")
889          (SI "immediate_operand")
890          (DI "x86_64_immediate_operand")])
891
892 ;; Nonmemory operand predicate for integer modes.
893 (define_mode_attr nonmemory_operand
894         [(QI "nonmemory_operand")
895          (HI "nonmemory_operand")
896          (SI "nonmemory_operand")
897          (DI "x86_64_nonmemory_operand")])
898
899 ;; Operand predicate for shifts.
900 (define_mode_attr shift_operand
901         [(QI "nonimmediate_operand")
902          (HI "nonimmediate_operand")
903          (SI "nonimmediate_operand")
904          (DI "shiftdi_operand")
905          (TI "register_operand")])
906
907 ;; Operand predicate for shift argument.
908 (define_mode_attr shift_immediate_operand
909         [(QI "const_1_to_31_operand")
910          (HI "const_1_to_31_operand")
911          (SI "const_1_to_31_operand")
912          (DI "const_1_to_63_operand")])
913
914 ;; Input operand predicate for arithmetic left shifts.
915 (define_mode_attr ashl_input_operand
916         [(QI "nonimmediate_operand")
917          (HI "nonimmediate_operand")
918          (SI "nonimmediate_operand")
919          (DI "ashldi_input_operand")
920          (TI "reg_or_pm1_operand")])
921
922 ;; SSE and x87 SFmode and DFmode floating point modes
923 (define_mode_iterator MODEF [SF DF])
924
925 ;; All x87 floating point modes
926 (define_mode_iterator X87MODEF [SF DF XF])
927
928 ;; All integer modes handled by x87 fisttp operator.
929 (define_mode_iterator X87MODEI [HI SI DI])
930
931 ;; All integer modes handled by integer x87 operators.
932 (define_mode_iterator X87MODEI12 [HI SI])
933
934 ;; All integer modes handled by SSE cvtts?2si* operators.
935 (define_mode_iterator SSEMODEI24 [SI DI])
936
937 ;; SSE instruction suffix for various modes
938 (define_mode_attr ssemodesuffix
939   [(SF "ss") (DF "sd")
940    (V8SF "ps") (V4DF "pd")
941    (V4SF "ps") (V2DF "pd")
942    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
943    (V8SI "si")])
944
945 ;; SSE vector suffix for floating point modes
946 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
947
948 ;; SSE vector mode corresponding to a scalar mode
949 (define_mode_attr ssevecmode
950   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
951
952 ;; Instruction suffix for REX 64bit operators.
953 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
954
955 ;; This mode iterator allows :P to be used for patterns that operate on
956 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
957 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
958 \f
959 ;; Scheduling descriptions
960
961 (include "pentium.md")
962 (include "ppro.md")
963 (include "k6.md")
964 (include "athlon.md")
965 (include "bdver1.md")
966 (include "geode.md")
967 (include "atom.md")
968 (include "core2.md")
969
970 \f
971 ;; Operand and operator predicates and constraints
972
973 (include "predicates.md")
974 (include "constraints.md")
975
976 \f
977 ;; Compare and branch/compare and store instructions.
978
979 (define_expand "cbranch<mode>4"
980   [(set (reg:CC FLAGS_REG)
981         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
982                     (match_operand:SDWIM 2 "<general_operand>" "")))
983    (set (pc) (if_then_else
984                (match_operator 0 "ordered_comparison_operator"
985                 [(reg:CC FLAGS_REG) (const_int 0)])
986                (label_ref (match_operand 3 "" ""))
987                (pc)))]
988   ""
989 {
990   if (MEM_P (operands[1]) && MEM_P (operands[2]))
991     operands[1] = force_reg (<MODE>mode, operands[1]);
992   ix86_expand_branch (GET_CODE (operands[0]),
993                       operands[1], operands[2], operands[3]);
994   DONE;
995 })
996
997 (define_expand "cstore<mode>4"
998   [(set (reg:CC FLAGS_REG)
999         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1000                     (match_operand:SWIM 3 "<general_operand>" "")))
1001    (set (match_operand:QI 0 "register_operand" "")
1002         (match_operator 1 "ordered_comparison_operator"
1003           [(reg:CC FLAGS_REG) (const_int 0)]))]
1004   ""
1005 {
1006   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1007     operands[2] = force_reg (<MODE>mode, operands[2]);
1008   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1009                      operands[2], operands[3]);
1010   DONE;
1011 })
1012
1013 (define_expand "cmp<mode>_1"
1014   [(set (reg:CC FLAGS_REG)
1015         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1016                     (match_operand:SWI48 1 "<general_operand>" "")))])
1017
1018 (define_insn "*cmp<mode>_ccno_1"
1019   [(set (reg FLAGS_REG)
1020         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1021                  (match_operand:SWI 1 "const0_operand" "")))]
1022   "ix86_match_ccmode (insn, CCNOmode)"
1023   "@
1024    test{<imodesuffix>}\t%0, %0
1025    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1026   [(set_attr "type" "test,icmp")
1027    (set_attr "length_immediate" "0,1")
1028    (set_attr "mode" "<MODE>")])
1029
1030 (define_insn "*cmp<mode>_1"
1031   [(set (reg FLAGS_REG)
1032         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1033                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1034   "ix86_match_ccmode (insn, CCmode)"
1035   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1036   [(set_attr "type" "icmp")
1037    (set_attr "mode" "<MODE>")])
1038
1039 (define_insn "*cmp<mode>_minus_1"
1040   [(set (reg FLAGS_REG)
1041         (compare
1042           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1043                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1044           (const_int 0)))]
1045   "ix86_match_ccmode (insn, CCGOCmode)"
1046   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1047   [(set_attr "type" "icmp")
1048    (set_attr "mode" "<MODE>")])
1049
1050 (define_insn "*cmpqi_ext_1"
1051   [(set (reg FLAGS_REG)
1052         (compare
1053           (match_operand:QI 0 "general_operand" "Qm")
1054           (subreg:QI
1055             (zero_extract:SI
1056               (match_operand 1 "ext_register_operand" "Q")
1057               (const_int 8)
1058               (const_int 8)) 0)))]
1059   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1060   "cmp{b}\t{%h1, %0|%0, %h1}"
1061   [(set_attr "type" "icmp")
1062    (set_attr "mode" "QI")])
1063
1064 (define_insn "*cmpqi_ext_1_rex64"
1065   [(set (reg FLAGS_REG)
1066         (compare
1067           (match_operand:QI 0 "register_operand" "Q")
1068           (subreg:QI
1069             (zero_extract:SI
1070               (match_operand 1 "ext_register_operand" "Q")
1071               (const_int 8)
1072               (const_int 8)) 0)))]
1073   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1074   "cmp{b}\t{%h1, %0|%0, %h1}"
1075   [(set_attr "type" "icmp")
1076    (set_attr "mode" "QI")])
1077
1078 (define_insn "*cmpqi_ext_2"
1079   [(set (reg FLAGS_REG)
1080         (compare
1081           (subreg:QI
1082             (zero_extract:SI
1083               (match_operand 0 "ext_register_operand" "Q")
1084               (const_int 8)
1085               (const_int 8)) 0)
1086           (match_operand:QI 1 "const0_operand" "")))]
1087   "ix86_match_ccmode (insn, CCNOmode)"
1088   "test{b}\t%h0, %h0"
1089   [(set_attr "type" "test")
1090    (set_attr "length_immediate" "0")
1091    (set_attr "mode" "QI")])
1092
1093 (define_expand "cmpqi_ext_3"
1094   [(set (reg:CC FLAGS_REG)
1095         (compare:CC
1096           (subreg:QI
1097             (zero_extract:SI
1098               (match_operand 0 "ext_register_operand" "")
1099               (const_int 8)
1100               (const_int 8)) 0)
1101           (match_operand:QI 1 "immediate_operand" "")))])
1102
1103 (define_insn "*cmpqi_ext_3_insn"
1104   [(set (reg FLAGS_REG)
1105         (compare
1106           (subreg:QI
1107             (zero_extract:SI
1108               (match_operand 0 "ext_register_operand" "Q")
1109               (const_int 8)
1110               (const_int 8)) 0)
1111           (match_operand:QI 1 "general_operand" "Qmn")))]
1112   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1113   "cmp{b}\t{%1, %h0|%h0, %1}"
1114   [(set_attr "type" "icmp")
1115    (set_attr "modrm" "1")
1116    (set_attr "mode" "QI")])
1117
1118 (define_insn "*cmpqi_ext_3_insn_rex64"
1119   [(set (reg FLAGS_REG)
1120         (compare
1121           (subreg:QI
1122             (zero_extract:SI
1123               (match_operand 0 "ext_register_operand" "Q")
1124               (const_int 8)
1125               (const_int 8)) 0)
1126           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1127   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1128   "cmp{b}\t{%1, %h0|%h0, %1}"
1129   [(set_attr "type" "icmp")
1130    (set_attr "modrm" "1")
1131    (set_attr "mode" "QI")])
1132
1133 (define_insn "*cmpqi_ext_4"
1134   [(set (reg FLAGS_REG)
1135         (compare
1136           (subreg:QI
1137             (zero_extract:SI
1138               (match_operand 0 "ext_register_operand" "Q")
1139               (const_int 8)
1140               (const_int 8)) 0)
1141           (subreg:QI
1142             (zero_extract:SI
1143               (match_operand 1 "ext_register_operand" "Q")
1144               (const_int 8)
1145               (const_int 8)) 0)))]
1146   "ix86_match_ccmode (insn, CCmode)"
1147   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1148   [(set_attr "type" "icmp")
1149    (set_attr "mode" "QI")])
1150
1151 ;; These implement float point compares.
1152 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1153 ;; which would allow mix and match FP modes on the compares.  Which is what
1154 ;; the old patterns did, but with many more of them.
1155
1156 (define_expand "cbranchxf4"
1157   [(set (reg:CC FLAGS_REG)
1158         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1159                     (match_operand:XF 2 "nonmemory_operand" "")))
1160    (set (pc) (if_then_else
1161               (match_operator 0 "ix86_fp_comparison_operator"
1162                [(reg:CC FLAGS_REG)
1163                 (const_int 0)])
1164               (label_ref (match_operand 3 "" ""))
1165               (pc)))]
1166   "TARGET_80387"
1167 {
1168   ix86_expand_branch (GET_CODE (operands[0]),
1169                       operands[1], operands[2], operands[3]);
1170   DONE;
1171 })
1172
1173 (define_expand "cstorexf4"
1174   [(set (reg:CC FLAGS_REG)
1175         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1176                     (match_operand:XF 3 "nonmemory_operand" "")))
1177    (set (match_operand:QI 0 "register_operand" "")
1178               (match_operator 1 "ix86_fp_comparison_operator"
1179                [(reg:CC FLAGS_REG)
1180                 (const_int 0)]))]
1181   "TARGET_80387"
1182 {
1183   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1184                      operands[2], operands[3]);
1185   DONE;
1186 })
1187
1188 (define_expand "cbranch<mode>4"
1189   [(set (reg:CC FLAGS_REG)
1190         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1191                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1192    (set (pc) (if_then_else
1193               (match_operator 0 "ix86_fp_comparison_operator"
1194                [(reg:CC FLAGS_REG)
1195                 (const_int 0)])
1196               (label_ref (match_operand 3 "" ""))
1197               (pc)))]
1198   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1199 {
1200   ix86_expand_branch (GET_CODE (operands[0]),
1201                       operands[1], operands[2], operands[3]);
1202   DONE;
1203 })
1204
1205 (define_expand "cstore<mode>4"
1206   [(set (reg:CC FLAGS_REG)
1207         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1208                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1209    (set (match_operand:QI 0 "register_operand" "")
1210               (match_operator 1 "ix86_fp_comparison_operator"
1211                [(reg:CC FLAGS_REG)
1212                 (const_int 0)]))]
1213   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1214 {
1215   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1216                      operands[2], operands[3]);
1217   DONE;
1218 })
1219
1220 (define_expand "cbranchcc4"
1221   [(set (pc) (if_then_else
1222               (match_operator 0 "comparison_operator"
1223                [(match_operand 1 "flags_reg_operand" "")
1224                 (match_operand 2 "const0_operand" "")])
1225               (label_ref (match_operand 3 "" ""))
1226               (pc)))]
1227   ""
1228 {
1229   ix86_expand_branch (GET_CODE (operands[0]),
1230                       operands[1], operands[2], operands[3]);
1231   DONE;
1232 })
1233
1234 (define_expand "cstorecc4"
1235   [(set (match_operand:QI 0 "register_operand" "")
1236               (match_operator 1 "comparison_operator"
1237                [(match_operand 2 "flags_reg_operand" "")
1238                 (match_operand 3 "const0_operand" "")]))]
1239   ""
1240 {
1241   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1242                      operands[2], operands[3]);
1243   DONE;
1244 })
1245
1246
1247 ;; FP compares, step 1:
1248 ;; Set the FP condition codes.
1249 ;;
1250 ;; CCFPmode     compare with exceptions
1251 ;; CCFPUmode    compare with no exceptions
1252
1253 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1254 ;; used to manage the reg stack popping would not be preserved.
1255
1256 (define_insn "*cmpfp_0"
1257   [(set (match_operand:HI 0 "register_operand" "=a")
1258         (unspec:HI
1259           [(compare:CCFP
1260              (match_operand 1 "register_operand" "f")
1261              (match_operand 2 "const0_operand" ""))]
1262         UNSPEC_FNSTSW))]
1263   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1264    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1265   "* return output_fp_compare (insn, operands, 0, 0);"
1266   [(set_attr "type" "multi")
1267    (set_attr "unit" "i387")
1268    (set (attr "mode")
1269      (cond [(match_operand:SF 1 "" "")
1270               (const_string "SF")
1271             (match_operand:DF 1 "" "")
1272               (const_string "DF")
1273            ]
1274            (const_string "XF")))])
1275
1276 (define_insn_and_split "*cmpfp_0_cc"
1277   [(set (reg:CCFP FLAGS_REG)
1278         (compare:CCFP
1279           (match_operand 1 "register_operand" "f")
1280           (match_operand 2 "const0_operand" "")))
1281    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1282   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1283    && TARGET_SAHF && !TARGET_CMOVE
1284    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1285   "#"
1286   "&& reload_completed"
1287   [(set (match_dup 0)
1288         (unspec:HI
1289           [(compare:CCFP (match_dup 1)(match_dup 2))]
1290         UNSPEC_FNSTSW))
1291    (set (reg:CC FLAGS_REG)
1292         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1293   ""
1294   [(set_attr "type" "multi")
1295    (set_attr "unit" "i387")
1296    (set (attr "mode")
1297      (cond [(match_operand:SF 1 "" "")
1298               (const_string "SF")
1299             (match_operand:DF 1 "" "")
1300               (const_string "DF")
1301            ]
1302            (const_string "XF")))])
1303
1304 (define_insn "*cmpfp_xf"
1305   [(set (match_operand:HI 0 "register_operand" "=a")
1306         (unspec:HI
1307           [(compare:CCFP
1308              (match_operand:XF 1 "register_operand" "f")
1309              (match_operand:XF 2 "register_operand" "f"))]
1310           UNSPEC_FNSTSW))]
1311   "TARGET_80387"
1312   "* return output_fp_compare (insn, operands, 0, 0);"
1313   [(set_attr "type" "multi")
1314    (set_attr "unit" "i387")
1315    (set_attr "mode" "XF")])
1316
1317 (define_insn_and_split "*cmpfp_xf_cc"
1318   [(set (reg:CCFP FLAGS_REG)
1319         (compare:CCFP
1320           (match_operand:XF 1 "register_operand" "f")
1321           (match_operand:XF 2 "register_operand" "f")))
1322    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1323   "TARGET_80387
1324    && TARGET_SAHF && !TARGET_CMOVE"
1325   "#"
1326   "&& reload_completed"
1327   [(set (match_dup 0)
1328         (unspec:HI
1329           [(compare:CCFP (match_dup 1)(match_dup 2))]
1330         UNSPEC_FNSTSW))
1331    (set (reg:CC FLAGS_REG)
1332         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1333   ""
1334   [(set_attr "type" "multi")
1335    (set_attr "unit" "i387")
1336    (set_attr "mode" "XF")])
1337
1338 (define_insn "*cmpfp_<mode>"
1339   [(set (match_operand:HI 0 "register_operand" "=a")
1340         (unspec:HI
1341           [(compare:CCFP
1342              (match_operand:MODEF 1 "register_operand" "f")
1343              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1344           UNSPEC_FNSTSW))]
1345   "TARGET_80387"
1346   "* return output_fp_compare (insn, operands, 0, 0);"
1347   [(set_attr "type" "multi")
1348    (set_attr "unit" "i387")
1349    (set_attr "mode" "<MODE>")])
1350
1351 (define_insn_and_split "*cmpfp_<mode>_cc"
1352   [(set (reg:CCFP FLAGS_REG)
1353         (compare:CCFP
1354           (match_operand:MODEF 1 "register_operand" "f")
1355           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1356    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1357   "TARGET_80387
1358    && TARGET_SAHF && !TARGET_CMOVE"
1359   "#"
1360   "&& reload_completed"
1361   [(set (match_dup 0)
1362         (unspec:HI
1363           [(compare:CCFP (match_dup 1)(match_dup 2))]
1364         UNSPEC_FNSTSW))
1365    (set (reg:CC FLAGS_REG)
1366         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1367   ""
1368   [(set_attr "type" "multi")
1369    (set_attr "unit" "i387")
1370    (set_attr "mode" "<MODE>")])
1371
1372 (define_insn "*cmpfp_u"
1373   [(set (match_operand:HI 0 "register_operand" "=a")
1374         (unspec:HI
1375           [(compare:CCFPU
1376              (match_operand 1 "register_operand" "f")
1377              (match_operand 2 "register_operand" "f"))]
1378           UNSPEC_FNSTSW))]
1379   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1380    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1381   "* return output_fp_compare (insn, operands, 0, 1);"
1382   [(set_attr "type" "multi")
1383    (set_attr "unit" "i387")
1384    (set (attr "mode")
1385      (cond [(match_operand:SF 1 "" "")
1386               (const_string "SF")
1387             (match_operand:DF 1 "" "")
1388               (const_string "DF")
1389            ]
1390            (const_string "XF")))])
1391
1392 (define_insn_and_split "*cmpfp_u_cc"
1393   [(set (reg:CCFPU FLAGS_REG)
1394         (compare:CCFPU
1395           (match_operand 1 "register_operand" "f")
1396           (match_operand 2 "register_operand" "f")))
1397    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1398   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1399    && TARGET_SAHF && !TARGET_CMOVE
1400    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1401   "#"
1402   "&& reload_completed"
1403   [(set (match_dup 0)
1404         (unspec:HI
1405           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1406         UNSPEC_FNSTSW))
1407    (set (reg:CC FLAGS_REG)
1408         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1409   ""
1410   [(set_attr "type" "multi")
1411    (set_attr "unit" "i387")
1412    (set (attr "mode")
1413      (cond [(match_operand:SF 1 "" "")
1414               (const_string "SF")
1415             (match_operand:DF 1 "" "")
1416               (const_string "DF")
1417            ]
1418            (const_string "XF")))])
1419
1420 (define_insn "*cmpfp_<mode>"
1421   [(set (match_operand:HI 0 "register_operand" "=a")
1422         (unspec:HI
1423           [(compare:CCFP
1424              (match_operand 1 "register_operand" "f")
1425              (match_operator 3 "float_operator"
1426                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1427           UNSPEC_FNSTSW))]
1428   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1429    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1430    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1431   "* return output_fp_compare (insn, operands, 0, 0);"
1432   [(set_attr "type" "multi")
1433    (set_attr "unit" "i387")
1434    (set_attr "fp_int_src" "true")
1435    (set_attr "mode" "<MODE>")])
1436
1437 (define_insn_and_split "*cmpfp_<mode>_cc"
1438   [(set (reg:CCFP FLAGS_REG)
1439         (compare:CCFP
1440           (match_operand 1 "register_operand" "f")
1441           (match_operator 3 "float_operator"
1442             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1443    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1444   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1445    && TARGET_SAHF && !TARGET_CMOVE
1446    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1447    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1448   "#"
1449   "&& reload_completed"
1450   [(set (match_dup 0)
1451         (unspec:HI
1452           [(compare:CCFP
1453              (match_dup 1)
1454              (match_op_dup 3 [(match_dup 2)]))]
1455         UNSPEC_FNSTSW))
1456    (set (reg:CC FLAGS_REG)
1457         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1458   ""
1459   [(set_attr "type" "multi")
1460    (set_attr "unit" "i387")
1461    (set_attr "fp_int_src" "true")
1462    (set_attr "mode" "<MODE>")])
1463
1464 ;; FP compares, step 2
1465 ;; Move the fpsw to ax.
1466
1467 (define_insn "x86_fnstsw_1"
1468   [(set (match_operand:HI 0 "register_operand" "=a")
1469         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1470   "TARGET_80387"
1471   "fnstsw\t%0"
1472   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1473    (set_attr "mode" "SI")
1474    (set_attr "unit" "i387")])
1475
1476 ;; FP compares, step 3
1477 ;; Get ax into flags, general case.
1478
1479 (define_insn "x86_sahf_1"
1480   [(set (reg:CC FLAGS_REG)
1481         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1482                    UNSPEC_SAHF))]
1483   "TARGET_SAHF"
1484 {
1485 #ifndef HAVE_AS_IX86_SAHF
1486   if (TARGET_64BIT)
1487     return ASM_BYTE "0x9e";
1488   else
1489 #endif
1490   return "sahf";
1491 }
1492   [(set_attr "length" "1")
1493    (set_attr "athlon_decode" "vector")
1494    (set_attr "amdfam10_decode" "direct")
1495    (set_attr "bdver1_decode" "direct")
1496    (set_attr "mode" "SI")])
1497
1498 ;; Pentium Pro can do steps 1 through 3 in one go.
1499 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1500 (define_insn "*cmpfp_i_mixed"
1501   [(set (reg:CCFP FLAGS_REG)
1502         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1503                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1504   "TARGET_MIX_SSE_I387
1505    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1506    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507   "* return output_fp_compare (insn, operands, 1, 0);"
1508   [(set_attr "type" "fcmp,ssecomi")
1509    (set_attr "prefix" "orig,maybe_vex")
1510    (set (attr "mode")
1511      (if_then_else (match_operand:SF 1 "" "")
1512         (const_string "SF")
1513         (const_string "DF")))
1514    (set (attr "prefix_rep")
1515         (if_then_else (eq_attr "type" "ssecomi")
1516                       (const_string "0")
1517                       (const_string "*")))
1518    (set (attr "prefix_data16")
1519         (cond [(eq_attr "type" "fcmp")
1520                  (const_string "*")
1521                (eq_attr "mode" "DF")
1522                  (const_string "1")
1523               ]
1524               (const_string "0")))
1525    (set_attr "athlon_decode" "vector")
1526    (set_attr "amdfam10_decode" "direct")
1527    (set_attr "bdver1_decode" "double")])
1528
1529 (define_insn "*cmpfp_i_sse"
1530   [(set (reg:CCFP FLAGS_REG)
1531         (compare:CCFP (match_operand 0 "register_operand" "x")
1532                       (match_operand 1 "nonimmediate_operand" "xm")))]
1533   "TARGET_SSE_MATH
1534    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1535    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1536   "* return output_fp_compare (insn, operands, 1, 0);"
1537   [(set_attr "type" "ssecomi")
1538    (set_attr "prefix" "maybe_vex")
1539    (set (attr "mode")
1540      (if_then_else (match_operand:SF 1 "" "")
1541         (const_string "SF")
1542         (const_string "DF")))
1543    (set_attr "prefix_rep" "0")
1544    (set (attr "prefix_data16")
1545         (if_then_else (eq_attr "mode" "DF")
1546                       (const_string "1")
1547                       (const_string "0")))
1548    (set_attr "athlon_decode" "vector")
1549    (set_attr "amdfam10_decode" "direct")
1550    (set_attr "bdver1_decode" "double")])
1551
1552 (define_insn "*cmpfp_i_i387"
1553   [(set (reg:CCFP FLAGS_REG)
1554         (compare:CCFP (match_operand 0 "register_operand" "f")
1555                       (match_operand 1 "register_operand" "f")))]
1556   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1557    && TARGET_CMOVE
1558    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1559    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560   "* return output_fp_compare (insn, operands, 1, 0);"
1561   [(set_attr "type" "fcmp")
1562    (set (attr "mode")
1563      (cond [(match_operand:SF 1 "" "")
1564               (const_string "SF")
1565             (match_operand:DF 1 "" "")
1566               (const_string "DF")
1567            ]
1568            (const_string "XF")))
1569    (set_attr "athlon_decode" "vector")
1570    (set_attr "amdfam10_decode" "direct")
1571    (set_attr "bdver1_decode" "double")])
1572
1573 (define_insn "*cmpfp_iu_mixed"
1574   [(set (reg:CCFPU FLAGS_REG)
1575         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1576                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1577   "TARGET_MIX_SSE_I387
1578    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1579    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580   "* return output_fp_compare (insn, operands, 1, 1);"
1581   [(set_attr "type" "fcmp,ssecomi")
1582    (set_attr "prefix" "orig,maybe_vex")
1583    (set (attr "mode")
1584      (if_then_else (match_operand:SF 1 "" "")
1585         (const_string "SF")
1586         (const_string "DF")))
1587    (set (attr "prefix_rep")
1588         (if_then_else (eq_attr "type" "ssecomi")
1589                       (const_string "0")
1590                       (const_string "*")))
1591    (set (attr "prefix_data16")
1592         (cond [(eq_attr "type" "fcmp")
1593                  (const_string "*")
1594                (eq_attr "mode" "DF")
1595                  (const_string "1")
1596               ]
1597               (const_string "0")))
1598    (set_attr "athlon_decode" "vector")
1599    (set_attr "amdfam10_decode" "direct")
1600    (set_attr "bdver1_decode" "double")])
1601
1602 (define_insn "*cmpfp_iu_sse"
1603   [(set (reg:CCFPU FLAGS_REG)
1604         (compare:CCFPU (match_operand 0 "register_operand" "x")
1605                        (match_operand 1 "nonimmediate_operand" "xm")))]
1606   "TARGET_SSE_MATH
1607    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1608    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1609   "* return output_fp_compare (insn, operands, 1, 1);"
1610   [(set_attr "type" "ssecomi")
1611    (set_attr "prefix" "maybe_vex")
1612    (set (attr "mode")
1613      (if_then_else (match_operand:SF 1 "" "")
1614         (const_string "SF")
1615         (const_string "DF")))
1616    (set_attr "prefix_rep" "0")
1617    (set (attr "prefix_data16")
1618         (if_then_else (eq_attr "mode" "DF")
1619                       (const_string "1")
1620                       (const_string "0")))
1621    (set_attr "athlon_decode" "vector")
1622    (set_attr "amdfam10_decode" "direct")
1623    (set_attr "bdver1_decode" "double")])
1624
1625 (define_insn "*cmpfp_iu_387"
1626   [(set (reg:CCFPU FLAGS_REG)
1627         (compare:CCFPU (match_operand 0 "register_operand" "f")
1628                        (match_operand 1 "register_operand" "f")))]
1629   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1630    && TARGET_CMOVE
1631    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1632    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1633   "* return output_fp_compare (insn, operands, 1, 1);"
1634   [(set_attr "type" "fcmp")
1635    (set (attr "mode")
1636      (cond [(match_operand:SF 1 "" "")
1637               (const_string "SF")
1638             (match_operand:DF 1 "" "")
1639               (const_string "DF")
1640            ]
1641            (const_string "XF")))
1642    (set_attr "athlon_decode" "vector")
1643    (set_attr "amdfam10_decode" "direct")
1644    (set_attr "bdver1_decode" "direct")])
1645 \f
1646 ;; Push/pop instructions.
1647
1648 (define_insn "*push<mode>2"
1649   [(set (match_operand:DWI 0 "push_operand" "=<")
1650         (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1651   ""
1652   "#")
1653
1654 (define_split
1655   [(set (match_operand:TI 0 "push_operand" "")
1656         (match_operand:TI 1 "general_operand" ""))]
1657   "TARGET_64BIT && reload_completed
1658    && !SSE_REG_P (operands[1])"
1659   [(const_int 0)]
1660   "ix86_split_long_move (operands); DONE;")
1661
1662 (define_insn "*pushdi2_rex64"
1663   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1664         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1665   "TARGET_64BIT"
1666   "@
1667    push{q}\t%1
1668    #"
1669   [(set_attr "type" "push,multi")
1670    (set_attr "mode" "DI")])
1671
1672 ;; Convert impossible pushes of immediate to existing instructions.
1673 ;; First try to get scratch register and go through it.  In case this
1674 ;; fails, push sign extended lower part first and then overwrite
1675 ;; upper part by 32bit move.
1676 (define_peephole2
1677   [(match_scratch:DI 2 "r")
1678    (set (match_operand:DI 0 "push_operand" "")
1679         (match_operand:DI 1 "immediate_operand" ""))]
1680   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1681    && !x86_64_immediate_operand (operands[1], DImode)"
1682   [(set (match_dup 2) (match_dup 1))
1683    (set (match_dup 0) (match_dup 2))])
1684
1685 ;; We need to define this as both peepholer and splitter for case
1686 ;; peephole2 pass is not run.
1687 ;; "&& 1" is needed to keep it from matching the previous pattern.
1688 (define_peephole2
1689   [(set (match_operand:DI 0 "push_operand" "")
1690         (match_operand:DI 1 "immediate_operand" ""))]
1691   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1692    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1693   [(set (match_dup 0) (match_dup 1))
1694    (set (match_dup 2) (match_dup 3))]
1695 {
1696   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1697
1698   operands[1] = gen_lowpart (DImode, operands[2]);
1699   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1700                                                    GEN_INT (4)));
1701 })
1702
1703 (define_split
1704   [(set (match_operand:DI 0 "push_operand" "")
1705         (match_operand:DI 1 "immediate_operand" ""))]
1706   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1707                     ? epilogue_completed : reload_completed)
1708    && !symbolic_operand (operands[1], DImode)
1709    && !x86_64_immediate_operand (operands[1], DImode)"
1710   [(set (match_dup 0) (match_dup 1))
1711    (set (match_dup 2) (match_dup 3))]
1712 {
1713   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1714
1715   operands[1] = gen_lowpart (DImode, operands[2]);
1716   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1717                                                    GEN_INT (4)));
1718 })
1719
1720 (define_split
1721   [(set (match_operand:DI 0 "push_operand" "")
1722         (match_operand:DI 1 "general_operand" ""))]
1723   "!TARGET_64BIT && reload_completed
1724    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1725   [(const_int 0)]
1726   "ix86_split_long_move (operands); DONE;")
1727
1728 (define_insn "*pushsi2"
1729   [(set (match_operand:SI 0 "push_operand" "=<")
1730         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1731   "!TARGET_64BIT"
1732   "push{l}\t%1"
1733   [(set_attr "type" "push")
1734    (set_attr "mode" "SI")])
1735
1736 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1737 ;; "push a byte/word".  But actually we use pushl, which has the effect
1738 ;; of rounding the amount pushed up to a word.
1739
1740 ;; For TARGET_64BIT we always round up to 8 bytes.
1741 (define_insn "*push<mode>2_rex64"
1742   [(set (match_operand:SWI124 0 "push_operand" "=X")
1743         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1744   "TARGET_64BIT"
1745   "push{q}\t%q1"
1746   [(set_attr "type" "push")
1747    (set_attr "mode" "DI")])
1748
1749 (define_insn "*push<mode>2"
1750   [(set (match_operand:SWI12 0 "push_operand" "=X")
1751         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1752   "!TARGET_64BIT"
1753   "push{l}\t%k1"
1754   [(set_attr "type" "push")
1755    (set_attr "mode" "SI")])
1756
1757 (define_insn "*push<mode>2_prologue"
1758   [(set (match_operand:P 0 "push_operand" "=<")
1759         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1760    (clobber (mem:BLK (scratch)))]
1761   ""
1762   "push{<imodesuffix>}\t%1"
1763   [(set_attr "type" "push")
1764    (set_attr "mode" "<MODE>")])
1765
1766 (define_insn "*pop<mode>1"
1767   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1768         (match_operand:P 1 "pop_operand" ">"))]
1769   ""
1770   "pop{<imodesuffix>}\t%0"
1771   [(set_attr "type" "pop")
1772    (set_attr "mode" "<MODE>")])
1773
1774 (define_insn "*pop<mode>1_epilogue"
1775   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1776         (match_operand:P 1 "pop_operand" ">"))
1777    (clobber (mem:BLK (scratch)))]
1778   ""
1779   "pop{<imodesuffix>}\t%0"
1780   [(set_attr "type" "pop")
1781    (set_attr "mode" "<MODE>")])
1782 \f
1783 ;; Move instructions.
1784
1785 (define_expand "movoi"
1786   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1787         (match_operand:OI 1 "general_operand" ""))]
1788   "TARGET_AVX"
1789   "ix86_expand_move (OImode, operands); DONE;")
1790
1791 (define_expand "movti"
1792   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1793         (match_operand:TI 1 "nonimmediate_operand" ""))]
1794   "TARGET_64BIT || TARGET_SSE"
1795 {
1796   if (TARGET_64BIT)
1797     ix86_expand_move (TImode, operands);
1798   else if (push_operand (operands[0], TImode))
1799     ix86_expand_push (TImode, operands[1]);
1800   else
1801     ix86_expand_vector_move (TImode, operands);
1802   DONE;
1803 })
1804
1805 ;; This expands to what emit_move_complex would generate if we didn't
1806 ;; have a movti pattern.  Having this avoids problems with reload on
1807 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1808 ;; to have around all the time.
1809 (define_expand "movcdi"
1810   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1811         (match_operand:CDI 1 "general_operand" ""))]
1812   ""
1813 {
1814   if (push_operand (operands[0], CDImode))
1815     emit_move_complex_push (CDImode, operands[0], operands[1]);
1816   else
1817     emit_move_complex_parts (operands[0], operands[1]);
1818   DONE;
1819 })
1820
1821 (define_expand "mov<mode>"
1822   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1823         (match_operand:SWI1248x 1 "general_operand" ""))]
1824   ""
1825   "ix86_expand_move (<MODE>mode, operands); DONE;")
1826
1827 (define_insn "*mov<mode>_xor"
1828   [(set (match_operand:SWI48 0 "register_operand" "=r")
1829         (match_operand:SWI48 1 "const0_operand" ""))
1830    (clobber (reg:CC FLAGS_REG))]
1831   "reload_completed"
1832   "xor{l}\t%k0, %k0"
1833   [(set_attr "type" "alu1")
1834    (set_attr "mode" "SI")
1835    (set_attr "length_immediate" "0")])
1836
1837 (define_insn "*mov<mode>_or"
1838   [(set (match_operand:SWI48 0 "register_operand" "=r")
1839         (match_operand:SWI48 1 "const_int_operand" ""))
1840    (clobber (reg:CC FLAGS_REG))]
1841   "reload_completed
1842    && operands[1] == constm1_rtx"
1843   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1844   [(set_attr "type" "alu1")
1845    (set_attr "mode" "<MODE>")
1846    (set_attr "length_immediate" "1")])
1847
1848 (define_insn "*movoi_internal_avx"
1849   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1850         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1851   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1852 {
1853   switch (which_alternative)
1854     {
1855     case 0:
1856       return "vxorps\t%0, %0, %0";
1857     case 1:
1858     case 2:
1859       if (misaligned_operand (operands[0], OImode)
1860           || misaligned_operand (operands[1], OImode))
1861         return "vmovdqu\t{%1, %0|%0, %1}";
1862       else
1863         return "vmovdqa\t{%1, %0|%0, %1}";
1864     default:
1865       gcc_unreachable ();
1866     }
1867 }
1868   [(set_attr "type" "sselog1,ssemov,ssemov")
1869    (set_attr "prefix" "vex")
1870    (set_attr "mode" "OI")])
1871
1872 (define_insn "*movti_internal_rex64"
1873   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1874         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1875   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1876 {
1877   switch (which_alternative)
1878     {
1879     case 0:
1880     case 1:
1881       return "#";
1882     case 2:
1883       if (get_attr_mode (insn) == MODE_V4SF)
1884         return "%vxorps\t%0, %d0";
1885       else
1886         return "%vpxor\t%0, %d0";
1887     case 3:
1888     case 4:
1889       /* TDmode values are passed as TImode on the stack.  Moving them
1890          to stack may result in unaligned memory access.  */
1891       if (misaligned_operand (operands[0], TImode)
1892           || misaligned_operand (operands[1], TImode))
1893         {
1894           if (get_attr_mode (insn) == MODE_V4SF)
1895             return "%vmovups\t{%1, %0|%0, %1}";
1896           else
1897             return "%vmovdqu\t{%1, %0|%0, %1}";
1898         }
1899       else
1900         {
1901           if (get_attr_mode (insn) == MODE_V4SF)
1902             return "%vmovaps\t{%1, %0|%0, %1}";
1903           else
1904             return "%vmovdqa\t{%1, %0|%0, %1}";
1905         }
1906     default:
1907       gcc_unreachable ();
1908     }
1909 }
1910   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1911    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1912    (set (attr "mode")
1913         (cond [(eq_attr "alternative" "2,3")
1914                  (if_then_else
1915                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1916                        (const_int 0))
1917                    (const_string "V4SF")
1918                    (const_string "TI"))
1919                (eq_attr "alternative" "4")
1920                  (if_then_else
1921                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1922                             (const_int 0))
1923                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1924                             (const_int 0)))
1925                    (const_string "V4SF")
1926                    (const_string "TI"))]
1927                (const_string "DI")))])
1928
1929 (define_split
1930   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1931         (match_operand:TI 1 "general_operand" ""))]
1932   "reload_completed
1933    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1934   [(const_int 0)]
1935   "ix86_split_long_move (operands); DONE;")
1936
1937 (define_insn "*movti_internal_sse"
1938   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1939         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1940   "TARGET_SSE && !TARGET_64BIT
1941    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942 {
1943   switch (which_alternative)
1944     {
1945     case 0:
1946       if (get_attr_mode (insn) == MODE_V4SF)
1947         return "%vxorps\t%0, %d0";
1948       else
1949         return "%vpxor\t%0, %d0";
1950     case 1:
1951     case 2:
1952       /* TDmode values are passed as TImode on the stack.  Moving them
1953          to stack may result in unaligned memory access.  */
1954       if (misaligned_operand (operands[0], TImode)
1955           || misaligned_operand (operands[1], TImode))
1956         {
1957           if (get_attr_mode (insn) == MODE_V4SF)
1958             return "%vmovups\t{%1, %0|%0, %1}";
1959           else
1960             return "%vmovdqu\t{%1, %0|%0, %1}";
1961         }
1962       else
1963         {
1964           if (get_attr_mode (insn) == MODE_V4SF)
1965             return "%vmovaps\t{%1, %0|%0, %1}";
1966           else
1967             return "%vmovdqa\t{%1, %0|%0, %1}";
1968         }
1969     default:
1970       gcc_unreachable ();
1971     }
1972 }
1973   [(set_attr "type" "sselog1,ssemov,ssemov")
1974    (set_attr "prefix" "maybe_vex")
1975    (set (attr "mode")
1976         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1977                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1978                         (const_int 0)))
1979                  (const_string "V4SF")
1980                (and (eq_attr "alternative" "2")
1981                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1982                         (const_int 0)))
1983                  (const_string "V4SF")]
1984               (const_string "TI")))])
1985
1986 (define_insn "*movdi_internal_rex64"
1987   [(set (match_operand:DI 0 "nonimmediate_operand"
1988           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1989         (match_operand:DI 1 "general_operand"
1990           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1991   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1992 {
1993   switch (get_attr_type (insn))
1994     {
1995     case TYPE_SSECVT:
1996       if (SSE_REG_P (operands[0]))
1997         return "movq2dq\t{%1, %0|%0, %1}";
1998       else
1999         return "movdq2q\t{%1, %0|%0, %1}";
2000
2001     case TYPE_SSEMOV:
2002       if (get_attr_mode (insn) == MODE_TI)
2003         return "%vmovdqa\t{%1, %0|%0, %1}";
2004       /* Handle broken assemblers that require movd instead of movq.  */
2005       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2006         return "%vmovd\t{%1, %0|%0, %1}";
2007       else
2008         return "%vmovq\t{%1, %0|%0, %1}";
2009
2010     case TYPE_MMXMOV:
2011       /* Handle broken assemblers that require movd instead of movq.  */
2012       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2013         return "movd\t{%1, %0|%0, %1}";
2014       else
2015         return "movq\t{%1, %0|%0, %1}";
2016
2017     case TYPE_SSELOG1:
2018       return "%vpxor\t%0, %d0";
2019
2020     case TYPE_MMX:
2021       return "pxor\t%0, %0";
2022
2023     case TYPE_MULTI:
2024       return "#";
2025
2026     case TYPE_LEA:
2027       return "lea{q}\t{%a1, %0|%0, %a1}";
2028
2029     default:
2030       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2031       if (get_attr_mode (insn) == MODE_SI)
2032         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2033       else if (which_alternative == 2)
2034         return "movabs{q}\t{%1, %0|%0, %1}";
2035       else
2036         return "mov{q}\t{%1, %0|%0, %1}";
2037     }
2038 }
2039   [(set (attr "type")
2040      (cond [(eq_attr "alternative" "5")
2041               (const_string "mmx")
2042             (eq_attr "alternative" "6,7,8,9,10")
2043               (const_string "mmxmov")
2044             (eq_attr "alternative" "11")
2045               (const_string "sselog1")
2046             (eq_attr "alternative" "12,13,14,15,16")
2047               (const_string "ssemov")
2048             (eq_attr "alternative" "17,18")
2049               (const_string "ssecvt")
2050             (eq_attr "alternative" "4")
2051               (const_string "multi")
2052             (match_operand:DI 1 "pic_32bit_operand" "")
2053               (const_string "lea")
2054            ]
2055            (const_string "imov")))
2056    (set (attr "modrm")
2057      (if_then_else
2058        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2059          (const_string "0")
2060          (const_string "*")))
2061    (set (attr "length_immediate")
2062      (if_then_else
2063        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2064          (const_string "8")
2065          (const_string "*")))
2066    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2067    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2068    (set (attr "prefix")
2069      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2070        (const_string "maybe_vex")
2071        (const_string "orig")))
2072    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2073
2074 ;; Convert impossible stores of immediate to existing instructions.
2075 ;; First try to get scratch register and go through it.  In case this
2076 ;; fails, move by 32bit parts.
2077 (define_peephole2
2078   [(match_scratch:DI 2 "r")
2079    (set (match_operand:DI 0 "memory_operand" "")
2080         (match_operand:DI 1 "immediate_operand" ""))]
2081   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2082    && !x86_64_immediate_operand (operands[1], DImode)"
2083   [(set (match_dup 2) (match_dup 1))
2084    (set (match_dup 0) (match_dup 2))])
2085
2086 ;; We need to define this as both peepholer and splitter for case
2087 ;; peephole2 pass is not run.
2088 ;; "&& 1" is needed to keep it from matching the previous pattern.
2089 (define_peephole2
2090   [(set (match_operand:DI 0 "memory_operand" "")
2091         (match_operand:DI 1 "immediate_operand" ""))]
2092   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2093    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2094   [(set (match_dup 2) (match_dup 3))
2095    (set (match_dup 4) (match_dup 5))]
2096   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2097
2098 (define_split
2099   [(set (match_operand:DI 0 "memory_operand" "")
2100         (match_operand:DI 1 "immediate_operand" ""))]
2101   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2102                     ? epilogue_completed : reload_completed)
2103    && !symbolic_operand (operands[1], DImode)
2104    && !x86_64_immediate_operand (operands[1], DImode)"
2105   [(set (match_dup 2) (match_dup 3))
2106    (set (match_dup 4) (match_dup 5))]
2107   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2108
2109 (define_insn "*movdi_internal"
2110   [(set (match_operand:DI 0 "nonimmediate_operand"
2111                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2112         (match_operand:DI 1 "general_operand"
2113                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2114   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2115   "@
2116    #
2117    #
2118    pxor\t%0, %0
2119    movq\t{%1, %0|%0, %1}
2120    movq\t{%1, %0|%0, %1}
2121    %vpxor\t%0, %d0
2122    %vmovq\t{%1, %0|%0, %1}
2123    %vmovdqa\t{%1, %0|%0, %1}
2124    %vmovq\t{%1, %0|%0, %1}
2125    xorps\t%0, %0
2126    movlps\t{%1, %0|%0, %1}
2127    movaps\t{%1, %0|%0, %1}
2128    movlps\t{%1, %0|%0, %1}"
2129   [(set (attr "isa")
2130      (if_then_else (eq_attr "alternative" "9,10,11,12")
2131        (const_string "noavx")
2132        (const_string "base")))
2133    (set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2134    (set (attr "prefix")
2135      (if_then_else (eq_attr "alternative" "5,6,7,8")
2136        (const_string "maybe_vex")
2137        (const_string "orig")))
2138    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2139
2140 (define_split
2141   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2142         (match_operand:DI 1 "general_operand" ""))]
2143   "!TARGET_64BIT && reload_completed
2144    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2145    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2146   [(const_int 0)]
2147   "ix86_split_long_move (operands); DONE;")
2148
2149 (define_insn "*movsi_internal"
2150   [(set (match_operand:SI 0 "nonimmediate_operand"
2151                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2152         (match_operand:SI 1 "general_operand"
2153                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2154   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2155 {
2156   switch (get_attr_type (insn))
2157     {
2158     case TYPE_SSELOG1:
2159       if (get_attr_mode (insn) == MODE_TI)
2160         return "%vpxor\t%0, %d0";
2161       return "%vxorps\t%0, %d0";
2162
2163     case TYPE_SSEMOV:
2164       switch (get_attr_mode (insn))
2165         {
2166         case MODE_TI:
2167           return "%vmovdqa\t{%1, %0|%0, %1}";
2168         case MODE_V4SF:
2169           return "%vmovaps\t{%1, %0|%0, %1}";
2170         case MODE_SI:
2171           return "%vmovd\t{%1, %0|%0, %1}";
2172         case MODE_SF:
2173           return "%vmovss\t{%1, %0|%0, %1}";
2174         default:
2175           gcc_unreachable ();
2176         }
2177
2178     case TYPE_MMX:
2179       return "pxor\t%0, %0";
2180
2181     case TYPE_MMXMOV:
2182       if (get_attr_mode (insn) == MODE_DI)
2183         return "movq\t{%1, %0|%0, %1}";
2184       return "movd\t{%1, %0|%0, %1}";
2185
2186     case TYPE_LEA:
2187       return "lea{l}\t{%a1, %0|%0, %a1}";
2188
2189     default:
2190       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2191       return "mov{l}\t{%1, %0|%0, %1}";
2192     }
2193 }
2194   [(set (attr "type")
2195      (cond [(eq_attr "alternative" "2")
2196               (const_string "mmx")
2197             (eq_attr "alternative" "3,4,5")
2198               (const_string "mmxmov")
2199             (eq_attr "alternative" "6")
2200               (const_string "sselog1")
2201             (eq_attr "alternative" "7,8,9,10,11")
2202               (const_string "ssemov")
2203             (match_operand:DI 1 "pic_32bit_operand" "")
2204               (const_string "lea")
2205            ]
2206            (const_string "imov")))
2207    (set (attr "prefix")
2208      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2209        (const_string "orig")
2210        (const_string "maybe_vex")))
2211    (set (attr "prefix_data16")
2212      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2213        (const_string "1")
2214        (const_string "*")))
2215    (set (attr "mode")
2216      (cond [(eq_attr "alternative" "2,3")
2217               (const_string "DI")
2218             (eq_attr "alternative" "6,7")
2219               (if_then_else
2220                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2221                 (const_string "V4SF")
2222                 (const_string "TI"))
2223             (and (eq_attr "alternative" "8,9,10,11")
2224                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2225               (const_string "SF")
2226            ]
2227            (const_string "SI")))])
2228
2229 (define_insn "*movhi_internal"
2230   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2231         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2232   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2233 {
2234   switch (get_attr_type (insn))
2235     {
2236     case TYPE_IMOVX:
2237       /* movzwl is faster than movw on p2 due to partial word stalls,
2238          though not as fast as an aligned movl.  */
2239       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2240     default:
2241       if (get_attr_mode (insn) == MODE_SI)
2242         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2243       else
2244         return "mov{w}\t{%1, %0|%0, %1}";
2245     }
2246 }
2247   [(set (attr "type")
2248      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2249                 (const_int 0))
2250               (const_string "imov")
2251             (and (eq_attr "alternative" "0")
2252                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2253                           (const_int 0))
2254                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2255                           (const_int 0))))
2256               (const_string "imov")
2257             (and (eq_attr "alternative" "1,2")
2258                  (match_operand:HI 1 "aligned_operand" ""))
2259               (const_string "imov")
2260             (and (ne (symbol_ref "TARGET_MOVX")
2261                      (const_int 0))
2262                  (eq_attr "alternative" "0,2"))
2263               (const_string "imovx")
2264            ]
2265            (const_string "imov")))
2266     (set (attr "mode")
2267       (cond [(eq_attr "type" "imovx")
2268                (const_string "SI")
2269              (and (eq_attr "alternative" "1,2")
2270                   (match_operand:HI 1 "aligned_operand" ""))
2271                (const_string "SI")
2272              (and (eq_attr "alternative" "0")
2273                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2274                            (const_int 0))
2275                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2276                            (const_int 0))))
2277                (const_string "SI")
2278             ]
2279             (const_string "HI")))])
2280
2281 ;; Situation is quite tricky about when to choose full sized (SImode) move
2282 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2283 ;; partial register dependency machines (such as AMD Athlon), where QImode
2284 ;; moves issue extra dependency and for partial register stalls machines
2285 ;; that don't use QImode patterns (and QImode move cause stall on the next
2286 ;; instruction).
2287 ;;
2288 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2289 ;; register stall machines with, where we use QImode instructions, since
2290 ;; partial register stall can be caused there.  Then we use movzx.
2291 (define_insn "*movqi_internal"
2292   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2293         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2294   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2295 {
2296   switch (get_attr_type (insn))
2297     {
2298     case TYPE_IMOVX:
2299       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2300       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2301     default:
2302       if (get_attr_mode (insn) == MODE_SI)
2303         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2304       else
2305         return "mov{b}\t{%1, %0|%0, %1}";
2306     }
2307 }
2308   [(set (attr "type")
2309      (cond [(and (eq_attr "alternative" "5")
2310                  (not (match_operand:QI 1 "aligned_operand" "")))
2311               (const_string "imovx")
2312             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2313                 (const_int 0))
2314               (const_string "imov")
2315             (and (eq_attr "alternative" "3")
2316                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2317                           (const_int 0))
2318                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2319                           (const_int 0))))
2320               (const_string "imov")
2321             (eq_attr "alternative" "3,5")
2322               (const_string "imovx")
2323             (and (ne (symbol_ref "TARGET_MOVX")
2324                      (const_int 0))
2325                  (eq_attr "alternative" "2"))
2326               (const_string "imovx")
2327            ]
2328            (const_string "imov")))
2329    (set (attr "mode")
2330       (cond [(eq_attr "alternative" "3,4,5")
2331                (const_string "SI")
2332              (eq_attr "alternative" "6")
2333                (const_string "QI")
2334              (eq_attr "type" "imovx")
2335                (const_string "SI")
2336              (and (eq_attr "type" "imov")
2337                   (and (eq_attr "alternative" "0,1")
2338                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2339                                 (const_int 0))
2340                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2341                                      (const_int 0))
2342                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2343                                      (const_int 0))))))
2344                (const_string "SI")
2345              ;; Avoid partial register stalls when not using QImode arithmetic
2346              (and (eq_attr "type" "imov")
2347                   (and (eq_attr "alternative" "0,1")
2348                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2349                                 (const_int 0))
2350                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2351                                 (const_int 0)))))
2352                (const_string "SI")
2353            ]
2354            (const_string "QI")))])
2355
2356 ;; Stores and loads of ax to arbitrary constant address.
2357 ;; We fake an second form of instruction to force reload to load address
2358 ;; into register when rax is not available
2359 (define_insn "*movabs<mode>_1"
2360   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2361         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2362   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2363   "@
2364    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2365    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2366   [(set_attr "type" "imov")
2367    (set_attr "modrm" "0,*")
2368    (set_attr "length_address" "8,0")
2369    (set_attr "length_immediate" "0,*")
2370    (set_attr "memory" "store")
2371    (set_attr "mode" "<MODE>")])
2372
2373 (define_insn "*movabs<mode>_2"
2374   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2375         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2376   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2377   "@
2378    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2379    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2380   [(set_attr "type" "imov")
2381    (set_attr "modrm" "0,*")
2382    (set_attr "length_address" "8,0")
2383    (set_attr "length_immediate" "0")
2384    (set_attr "memory" "load")
2385    (set_attr "mode" "<MODE>")])
2386
2387 (define_insn "*swap<mode>"
2388   [(set (match_operand:SWI48 0 "register_operand" "+r")
2389         (match_operand:SWI48 1 "register_operand" "+r"))
2390    (set (match_dup 1)
2391         (match_dup 0))]
2392   ""
2393   "xchg{<imodesuffix>}\t%1, %0"
2394   [(set_attr "type" "imov")
2395    (set_attr "mode" "<MODE>")
2396    (set_attr "pent_pair" "np")
2397    (set_attr "athlon_decode" "vector")
2398    (set_attr "amdfam10_decode" "double")
2399    (set_attr "bdver1_decode" "double")])
2400
2401 (define_insn "*swap<mode>_1"
2402   [(set (match_operand:SWI12 0 "register_operand" "+r")
2403         (match_operand:SWI12 1 "register_operand" "+r"))
2404    (set (match_dup 1)
2405         (match_dup 0))]
2406   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2407   "xchg{l}\t%k1, %k0"
2408   [(set_attr "type" "imov")
2409    (set_attr "mode" "SI")
2410    (set_attr "pent_pair" "np")
2411    (set_attr "athlon_decode" "vector")
2412    (set_attr "amdfam10_decode" "double")
2413    (set_attr "bdver1_decode" "double")])
2414
2415 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2416 ;; is disabled for AMDFAM10
2417 (define_insn "*swap<mode>_2"
2418   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2419         (match_operand:SWI12 1 "register_operand" "+<r>"))
2420    (set (match_dup 1)
2421         (match_dup 0))]
2422   "TARGET_PARTIAL_REG_STALL"
2423   "xchg{<imodesuffix>}\t%1, %0"
2424   [(set_attr "type" "imov")
2425    (set_attr "mode" "<MODE>")
2426    (set_attr "pent_pair" "np")
2427    (set_attr "athlon_decode" "vector")])
2428
2429 (define_expand "movstrict<mode>"
2430   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2431         (match_operand:SWI12 1 "general_operand" ""))]
2432   ""
2433 {
2434   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2435     FAIL;
2436   if (GET_CODE (operands[0]) == SUBREG
2437       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2438     FAIL;
2439   /* Don't generate memory->memory moves, go through a register */
2440   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2441     operands[1] = force_reg (<MODE>mode, operands[1]);
2442 })
2443
2444 (define_insn "*movstrict<mode>_1"
2445   [(set (strict_low_part
2446           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2447         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2448   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2449    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2450   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2451   [(set_attr "type" "imov")
2452    (set_attr "mode" "<MODE>")])
2453
2454 (define_insn "*movstrict<mode>_xor"
2455   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2456         (match_operand:SWI12 1 "const0_operand" ""))
2457    (clobber (reg:CC FLAGS_REG))]
2458   "reload_completed"
2459   "xor{<imodesuffix>}\t%0, %0"
2460   [(set_attr "type" "alu1")
2461    (set_attr "mode" "<MODE>")
2462    (set_attr "length_immediate" "0")])
2463
2464 (define_insn "*mov<mode>_extv_1"
2465   [(set (match_operand:SWI24 0 "register_operand" "=R")
2466         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2467                             (const_int 8)
2468                             (const_int 8)))]
2469   ""
2470   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2471   [(set_attr "type" "imovx")
2472    (set_attr "mode" "SI")])
2473
2474 (define_insn "*movqi_extv_1_rex64"
2475   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2476         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2477                          (const_int 8)
2478                          (const_int 8)))]
2479   "TARGET_64BIT"
2480 {
2481   switch (get_attr_type (insn))
2482     {
2483     case TYPE_IMOVX:
2484       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2485     default:
2486       return "mov{b}\t{%h1, %0|%0, %h1}";
2487     }
2488 }
2489   [(set (attr "type")
2490      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2491                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2492                              (ne (symbol_ref "TARGET_MOVX")
2493                                  (const_int 0))))
2494         (const_string "imovx")
2495         (const_string "imov")))
2496    (set (attr "mode")
2497      (if_then_else (eq_attr "type" "imovx")
2498         (const_string "SI")
2499         (const_string "QI")))])
2500
2501 (define_insn "*movqi_extv_1"
2502   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2503         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2504                          (const_int 8)
2505                          (const_int 8)))]
2506   "!TARGET_64BIT"
2507 {
2508   switch (get_attr_type (insn))
2509     {
2510     case TYPE_IMOVX:
2511       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2512     default:
2513       return "mov{b}\t{%h1, %0|%0, %h1}";
2514     }
2515 }
2516   [(set (attr "type")
2517      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2518                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2519                              (ne (symbol_ref "TARGET_MOVX")
2520                                  (const_int 0))))
2521         (const_string "imovx")
2522         (const_string "imov")))
2523    (set (attr "mode")
2524      (if_then_else (eq_attr "type" "imovx")
2525         (const_string "SI")
2526         (const_string "QI")))])
2527
2528 (define_insn "*mov<mode>_extzv_1"
2529   [(set (match_operand:SWI48 0 "register_operand" "=R")
2530         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2531                             (const_int 8)
2532                             (const_int 8)))]
2533   ""
2534   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2535   [(set_attr "type" "imovx")
2536    (set_attr "mode" "SI")])
2537
2538 (define_insn "*movqi_extzv_2_rex64"
2539   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2540         (subreg:QI
2541           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2542                            (const_int 8)
2543                            (const_int 8)) 0))]
2544   "TARGET_64BIT"
2545 {
2546   switch (get_attr_type (insn))
2547     {
2548     case TYPE_IMOVX:
2549       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2550     default:
2551       return "mov{b}\t{%h1, %0|%0, %h1}";
2552     }
2553 }
2554   [(set (attr "type")
2555      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2556                         (ne (symbol_ref "TARGET_MOVX")
2557                             (const_int 0)))
2558         (const_string "imovx")
2559         (const_string "imov")))
2560    (set (attr "mode")
2561      (if_then_else (eq_attr "type" "imovx")
2562         (const_string "SI")
2563         (const_string "QI")))])
2564
2565 (define_insn "*movqi_extzv_2"
2566   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2567         (subreg:QI
2568           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2569                            (const_int 8)
2570                            (const_int 8)) 0))]
2571   "!TARGET_64BIT"
2572 {
2573   switch (get_attr_type (insn))
2574     {
2575     case TYPE_IMOVX:
2576       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2577     default:
2578       return "mov{b}\t{%h1, %0|%0, %h1}";
2579     }
2580 }
2581   [(set (attr "type")
2582      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2583                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2584                              (ne (symbol_ref "TARGET_MOVX")
2585                                  (const_int 0))))
2586         (const_string "imovx")
2587         (const_string "imov")))
2588    (set (attr "mode")
2589      (if_then_else (eq_attr "type" "imovx")
2590         (const_string "SI")
2591         (const_string "QI")))])
2592
2593 (define_expand "mov<mode>_insv_1"
2594   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2595                             (const_int 8)
2596                             (const_int 8))
2597         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2598
2599 (define_insn "*mov<mode>_insv_1_rex64"
2600   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2601                              (const_int 8)
2602                              (const_int 8))
2603         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2604   "TARGET_64BIT"
2605   "mov{b}\t{%b1, %h0|%h0, %b1}"
2606   [(set_attr "type" "imov")
2607    (set_attr "mode" "QI")])
2608
2609 (define_insn "*movsi_insv_1"
2610   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2611                          (const_int 8)
2612                          (const_int 8))
2613         (match_operand:SI 1 "general_operand" "Qmn"))]
2614   "!TARGET_64BIT"
2615   "mov{b}\t{%b1, %h0|%h0, %b1}"
2616   [(set_attr "type" "imov")
2617    (set_attr "mode" "QI")])
2618
2619 (define_insn "*movqi_insv_2"
2620   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2621                          (const_int 8)
2622                          (const_int 8))
2623         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2624                      (const_int 8)))]
2625   ""
2626   "mov{b}\t{%h1, %h0|%h0, %h1}"
2627   [(set_attr "type" "imov")
2628    (set_attr "mode" "QI")])
2629 \f
2630 ;; Floating point push instructions.
2631
2632 (define_insn "*pushtf"
2633   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2634         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2635   "TARGET_SSE2"
2636 {
2637   /* This insn should be already split before reg-stack.  */
2638   gcc_unreachable ();
2639 }
2640   [(set_attr "type" "multi")
2641    (set_attr "unit" "sse,*,*")
2642    (set_attr "mode" "TF,SI,SI")])
2643
2644 (define_split
2645   [(set (match_operand:TF 0 "push_operand" "")
2646         (match_operand:TF 1 "sse_reg_operand" ""))]
2647   "TARGET_SSE2 && reload_completed"
2648   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2649    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2650
2651 (define_split
2652   [(set (match_operand:TF 0 "push_operand" "")
2653         (match_operand:TF 1 "general_operand" ""))]
2654   "TARGET_SSE2 && reload_completed
2655    && !SSE_REG_P (operands[1])"
2656   [(const_int 0)]
2657   "ix86_split_long_move (operands); DONE;")
2658
2659 (define_insn "*pushxf"
2660   [(set (match_operand:XF 0 "push_operand" "=<,<")
2661         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2662   "optimize_function_for_speed_p (cfun)"
2663 {
2664   /* This insn should be already split before reg-stack.  */
2665   gcc_unreachable ();
2666 }
2667   [(set_attr "type" "multi")
2668    (set_attr "unit" "i387,*")
2669    (set_attr "mode" "XF,SI")])
2670
2671 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2672 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2673 ;; Pushing using integer instructions is longer except for constants
2674 ;; and direct memory references (assuming that any given constant is pushed
2675 ;; only once, but this ought to be handled elsewhere).
2676
2677 (define_insn "*pushxf_nointeger"
2678   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2679         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2680   "optimize_function_for_size_p (cfun)"
2681 {
2682   /* This insn should be already split before reg-stack.  */
2683   gcc_unreachable ();
2684 }
2685   [(set_attr "type" "multi")
2686    (set_attr "unit" "i387,*,*")
2687    (set_attr "mode" "XF,SI,SI")])
2688
2689 (define_split
2690   [(set (match_operand:XF 0 "push_operand" "")
2691         (match_operand:XF 1 "fp_register_operand" ""))]
2692   "reload_completed"
2693   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2694    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2695   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2696
2697 (define_split
2698   [(set (match_operand:XF 0 "push_operand" "")
2699         (match_operand:XF 1 "general_operand" ""))]
2700   "reload_completed
2701    && !FP_REG_P (operands[1])"
2702   [(const_int 0)]
2703   "ix86_split_long_move (operands); DONE;")
2704
2705 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2706 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2707 ;; On the average, pushdf using integers can be still shorter.
2708
2709 (define_insn "*pushdf"
2710   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2711         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2712   ""
2713 {
2714   /* This insn should be already split before reg-stack.  */
2715   gcc_unreachable ();
2716 }
2717   [(set_attr "type" "multi")
2718    (set_attr "unit" "i387,*,*")
2719    (set_attr "mode" "DF,SI,DF")])
2720
2721 ;; %%% Kill this when call knows how to work this out.
2722 (define_split
2723   [(set (match_operand:DF 0 "push_operand" "")
2724         (match_operand:DF 1 "any_fp_register_operand" ""))]
2725   "reload_completed"
2726   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2727    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2728
2729 (define_split
2730   [(set (match_operand:DF 0 "push_operand" "")
2731         (match_operand:DF 1 "general_operand" ""))]
2732   "reload_completed
2733    && !ANY_FP_REG_P (operands[1])"
2734   [(const_int 0)]
2735   "ix86_split_long_move (operands); DONE;")
2736
2737 (define_insn "*pushsf_rex64"
2738   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2739         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2740   "TARGET_64BIT"
2741 {
2742   /* Anything else should be already split before reg-stack.  */
2743   gcc_assert (which_alternative == 1);
2744   return "push{q}\t%q1";
2745 }
2746   [(set_attr "type" "multi,push,multi")
2747    (set_attr "unit" "i387,*,*")
2748    (set_attr "mode" "SF,DI,SF")])
2749
2750 (define_insn "*pushsf"
2751   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2752         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2753   "!TARGET_64BIT"
2754 {
2755   /* Anything else should be already split before reg-stack.  */
2756   gcc_assert (which_alternative == 1);
2757   return "push{l}\t%1";
2758 }
2759   [(set_attr "type" "multi,push,multi")
2760    (set_attr "unit" "i387,*,*")
2761    (set_attr "mode" "SF,SI,SF")])
2762
2763 (define_split
2764   [(set (match_operand:SF 0 "push_operand" "")
2765         (match_operand:SF 1 "memory_operand" ""))]
2766   "reload_completed
2767    && MEM_P (operands[1])
2768    && (operands[2] = find_constant_src (insn))"
2769   [(set (match_dup 0)
2770         (match_dup 2))])
2771
2772 ;; %%% Kill this when call knows how to work this out.
2773 (define_split
2774   [(set (match_operand:SF 0 "push_operand" "")
2775         (match_operand:SF 1 "any_fp_register_operand" ""))]
2776   "reload_completed"
2777   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779   "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2780 \f
2781 ;; Floating point move instructions.
2782
2783 (define_expand "movtf"
2784   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2785         (match_operand:TF 1 "nonimmediate_operand" ""))]
2786   "TARGET_SSE2"
2787 {
2788   ix86_expand_move (TFmode, operands);
2789   DONE;
2790 })
2791
2792 (define_expand "mov<mode>"
2793   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2794         (match_operand:X87MODEF 1 "general_operand" ""))]
2795   ""
2796   "ix86_expand_move (<MODE>mode, operands); DONE;")
2797
2798 (define_insn "*movtf_internal"
2799   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2800         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2801   "TARGET_SSE2
2802    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2803 {
2804   switch (which_alternative)
2805     {
2806     case 0:
2807     case 1:
2808       if (get_attr_mode (insn) == MODE_V4SF)
2809         return "%vmovaps\t{%1, %0|%0, %1}";
2810       else
2811         return "%vmovdqa\t{%1, %0|%0, %1}";
2812
2813     case 2:
2814       return standard_sse_constant_opcode (insn, operands[1]);
2815
2816     case 3:
2817     case 4:
2818         return "#";
2819
2820     default:
2821       gcc_unreachable ();
2822     }
2823 }
2824   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2825    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2826    (set (attr "mode")
2827         (cond [(eq_attr "alternative" "0,2")
2828                  (if_then_else
2829                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2830                        (const_int 0))
2831                    (const_string "V4SF")
2832                    (const_string "TI"))
2833                (eq_attr "alternative" "1")
2834                  (if_then_else
2835                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2836                             (const_int 0))
2837                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2838                             (const_int 0)))
2839                    (const_string "V4SF")
2840                    (const_string "TI"))]
2841                (const_string "DI")))])
2842
2843 (define_split
2844   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2845         (match_operand:TF 1 "general_operand" ""))]
2846   "reload_completed
2847    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2848   [(const_int 0)]
2849   "ix86_split_long_move (operands); DONE;")
2850
2851 (define_insn "*movxf_internal"
2852   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,Yx*r  ,o")
2853         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2854   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2855    && (!can_create_pseudo_p ()
2856        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2857        || GET_CODE (operands[1]) != CONST_DOUBLE
2858        || (optimize_function_for_size_p (cfun)
2859            && standard_80387_constant_p (operands[1]) > 0)
2860        || memory_operand (operands[0], XFmode))"
2861 {
2862   switch (which_alternative)
2863     {
2864     case 0:
2865     case 1:
2866       return output_387_reg_move (insn, operands);
2867
2868     case 2:
2869       return standard_80387_constant_opcode (operands[1]);
2870
2871     case 3: case 4:
2872       return "#";
2873     default:
2874       gcc_unreachable ();
2875     }
2876 }
2877   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2878    (set_attr "mode" "XF,XF,XF,SI,SI")])
2879
2880 (define_split
2881   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2882         (match_operand:XF 1 "general_operand" ""))]
2883   "reload_completed
2884    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2885    && ! (FP_REG_P (operands[0]) ||
2886          (GET_CODE (operands[0]) == SUBREG
2887           && FP_REG_P (SUBREG_REG (operands[0]))))
2888    && ! (FP_REG_P (operands[1]) ||
2889          (GET_CODE (operands[1]) == SUBREG
2890           && FP_REG_P (SUBREG_REG (operands[1]))))"
2891   [(const_int 0)]
2892   "ix86_split_long_move (operands); DONE;")
2893
2894 (define_insn "*movdf_internal_rex64"
2895   [(set (match_operand:DF 0 "nonimmediate_operand"
2896                 "=f,m,f,r ,m,!r,!m,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2897         (match_operand:DF 1 "general_operand"
2898                 "fm,f,G,rm,r,F ,F ,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2899   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2900    && (!can_create_pseudo_p ()
2901        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2902        || GET_CODE (operands[1]) != CONST_DOUBLE
2903        || (optimize_function_for_size_p (cfun)
2904            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2905                 && standard_80387_constant_p (operands[1]) > 0)
2906                || (TARGET_SSE2 && TARGET_SSE_MATH
2907                    && standard_sse_constant_p (operands[1]))))
2908        || memory_operand (operands[0], DFmode))"
2909 {
2910   switch (which_alternative)
2911     {
2912     case 0:
2913     case 1:
2914       return output_387_reg_move (insn, operands);
2915
2916     case 2:
2917       return standard_80387_constant_opcode (operands[1]);
2918
2919     case 3:
2920     case 4:
2921       return "mov{q}\t{%1, %0|%0, %1}";
2922
2923     case 5:
2924       return "movabs{q}\t{%1, %0|%0, %1}";
2925
2926     case 6:
2927       return "#";
2928
2929     case 7:
2930       return standard_sse_constant_opcode (insn, operands[1]);
2931
2932     case 8:
2933     case 9:
2934     case 10:
2935       switch (get_attr_mode (insn))
2936         {
2937         case MODE_V4SF:
2938           return "%vmovaps\t{%1, %0|%0, %1}";
2939         case MODE_V2DF:
2940           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2941             return "%vmovaps\t{%1, %0|%0, %1}";
2942           else
2943             return "%vmovapd\t{%1, %0|%0, %1}";
2944         case MODE_TI:
2945           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2946             return "%vmovaps\t{%1, %0|%0, %1}";
2947           else
2948             return "%vmovdqa\t{%1, %0|%0, %1}";
2949         case MODE_DI:
2950           return "%vmovq\t{%1, %0|%0, %1}";
2951         case MODE_DF:
2952           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2953             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2954           else
2955             return "%vmovsd\t{%1, %0|%0, %1}";
2956         case MODE_V1DF:
2957           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2958         case MODE_V2SF:
2959           return "%vmovlps\t{%1, %d0|%d0, %1}";
2960         default:
2961           gcc_unreachable ();
2962         }
2963
2964     case 11:
2965     case 12:
2966       /* Handle broken assemblers that require movd instead of movq.  */
2967       return "%vmovd\t{%1, %0|%0, %1}";
2968
2969     default:
2970       gcc_unreachable();
2971     }
2972 }
2973   [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2974    (set (attr "modrm")
2975      (if_then_else
2976        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2977          (const_string "0")
2978          (const_string "*")))
2979    (set (attr "length_immediate")
2980      (if_then_else
2981        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2982          (const_string "8")
2983          (const_string "*")))
2984    (set (attr "prefix")
2985      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2986        (const_string "orig")
2987        (const_string "maybe_vex")))
2988    (set (attr "prefix_data16")
2989      (if_then_else (eq_attr "mode" "V1DF")
2990        (const_string "1")
2991        (const_string "*")))
2992    (set (attr "mode")
2993         (cond [(eq_attr "alternative" "0,1,2")
2994                  (const_string "DF")
2995                (eq_attr "alternative" "3,4,5,6,11,12")
2996                  (const_string "DI")
2997
2998                /* For SSE1, we have many fewer alternatives.  */
2999                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3000                  (cond [(eq_attr "alternative" "7,8")
3001                           (const_string "V4SF")
3002                        ]
3003                    (const_string "V2SF"))
3004
3005                /* xorps is one byte shorter.  */
3006                (eq_attr "alternative" "7")
3007                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3008                             (const_int 0))
3009                           (const_string "V4SF")
3010                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3011                             (const_int 0))
3012                           (const_string "TI")
3013                        ]
3014                        (const_string "V2DF"))
3015
3016                /* For architectures resolving dependencies on
3017                   whole SSE registers use APD move to break dependency
3018                   chains, otherwise use short move to avoid extra work.
3019
3020                   movaps encodes one byte shorter.  */
3021                (eq_attr "alternative" "8")
3022                  (cond
3023                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3024                         (const_int 0))
3025                       (const_string "V4SF")
3026                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3027                         (const_int 0))
3028                       (const_string "V2DF")
3029                    ]
3030                    (const_string "DF"))
3031                /* For architectures resolving dependencies on register
3032                   parts we may avoid extra work to zero out upper part
3033                   of register.  */
3034                (eq_attr "alternative" "9")
3035                  (if_then_else
3036                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3037                        (const_int 0))
3038                    (const_string "V1DF")
3039                    (const_string "DF"))
3040               ]
3041               (const_string "DF")))])
3042
3043 ;; Possible store forwarding (partial memory) stall in alternative 4.
3044 (define_insn "*movdf_internal"
3045   [(set (match_operand:DF 0 "nonimmediate_operand"
3046                 "=f,m,f,Yd*r  ,o    ,Y2*x,Y2*x,Y2*x,m  ")
3047         (match_operand:DF 1 "general_operand"
3048                 "fm,f,G,Yd*roF,FYd*r,C   ,Y2*x,m   ,Y2*x"))]
3049   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3050    && (!can_create_pseudo_p ()
3051        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3052        || GET_CODE (operands[1]) != CONST_DOUBLE
3053        || (!TARGET_INTEGER_DFMODE_MOVES
3054            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3055                 && standard_80387_constant_p (operands[1]) > 0)
3056                || (TARGET_SSE2 && TARGET_SSE_MATH
3057                    && standard_sse_constant_p (operands[1])))
3058            && !memory_operand (operands[0], DFmode))
3059        || ((TARGET_INTEGER_DFMODE_MOVES
3060             || !TARGET_MEMORY_MISMATCH_STALL)
3061            && memory_operand (operands[0], DFmode)))"
3062 {
3063   switch (which_alternative)
3064     {
3065     case 0:
3066     case 1:
3067       return output_387_reg_move (insn, operands);
3068
3069     case 2:
3070       return standard_80387_constant_opcode (operands[1]);
3071
3072     case 3:
3073     case 4:
3074       return "#";
3075
3076     case 5:
3077       return standard_sse_constant_opcode (insn, operands[1]);
3078
3079     case 6:
3080     case 7:
3081     case 8:
3082       switch (get_attr_mode (insn))
3083         {
3084         case MODE_V4SF:
3085           return "%vmovaps\t{%1, %0|%0, %1}";
3086         case MODE_V2DF:
3087           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3088             return "%vmovaps\t{%1, %0|%0, %1}";
3089           else
3090             return "%vmovapd\t{%1, %0|%0, %1}";
3091         case MODE_TI:
3092           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093             return "%vmovaps\t{%1, %0|%0, %1}";
3094           else
3095             return "%vmovdqa\t{%1, %0|%0, %1}";
3096         case MODE_DI:
3097           return "%vmovq\t{%1, %0|%0, %1}";
3098         case MODE_DF:
3099           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3100             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3101           else
3102             return "%vmovsd\t{%1, %0|%0, %1}";
3103         case MODE_V1DF:
3104           if (TARGET_AVX && REG_P (operands[0]))
3105             return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3106           else
3107             return "%vmovlpd\t{%1, %0|%0, %1}";
3108         case MODE_V2SF:
3109           if (TARGET_AVX && REG_P (operands[0]))
3110             return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3111           else
3112             return "%vmovlps\t{%1, %0|%0, %1}";
3113         default:
3114           gcc_unreachable ();
3115         }
3116
3117     default:
3118       gcc_unreachable ();
3119     }
3120 }
3121   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3122    (set (attr "prefix")
3123      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3124        (const_string "orig")
3125        (const_string "maybe_vex")))
3126    (set (attr "prefix_data16")
3127      (if_then_else (eq_attr "mode" "V1DF")
3128        (const_string "1")
3129        (const_string "*")))
3130    (set (attr "mode")
3131         (cond [(eq_attr "alternative" "0,1,2")
3132                  (const_string "DF")
3133                (eq_attr "alternative" "3,4")
3134                  (const_string "SI")
3135
3136                /* For SSE1, we have many fewer alternatives.  */
3137                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3138                  (cond [(eq_attr "alternative" "5,6")
3139                           (const_string "V4SF")
3140                        ]
3141                    (const_string "V2SF"))
3142
3143                /* xorps is one byte shorter.  */
3144                (eq_attr "alternative" "5")
3145                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3146                             (const_int 0))
3147                           (const_string "V4SF")
3148                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3149                             (const_int 0))
3150                           (const_string "TI")
3151                        ]
3152                        (const_string "V2DF"))
3153
3154                /* For architectures resolving dependencies on
3155                   whole SSE registers use APD move to break dependency
3156                   chains, otherwise use short move to avoid extra work.
3157
3158                   movaps encodes one byte shorter.  */
3159                (eq_attr "alternative" "6")
3160                  (cond
3161                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3162                         (const_int 0))
3163                       (const_string "V4SF")
3164                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3165                         (const_int 0))
3166                       (const_string "V2DF")
3167                    ]
3168                    (const_string "DF"))
3169                /* For architectures resolving dependencies on register
3170                   parts we may avoid extra work to zero out upper part
3171                   of register.  */
3172                (eq_attr "alternative" "7")
3173                  (if_then_else
3174                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3175                        (const_int 0))
3176                    (const_string "V1DF")
3177                    (const_string "DF"))
3178               ]
3179               (const_string "DF")))])
3180
3181 (define_split
3182   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3183         (match_operand:DF 1 "general_operand" ""))]
3184   "reload_completed
3185    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3186    && ! (ANY_FP_REG_P (operands[0]) ||
3187          (GET_CODE (operands[0]) == SUBREG
3188           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3189    && ! (ANY_FP_REG_P (operands[1]) ||
3190          (GET_CODE (operands[1]) == SUBREG
3191           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3192   [(const_int 0)]
3193   "ix86_split_long_move (operands); DONE;")
3194
3195 (define_insn "*movsf_internal"
3196   [(set (match_operand:SF 0 "nonimmediate_operand"
3197           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3198         (match_operand:SF 1 "general_operand"
3199           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3200   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3201    && (!can_create_pseudo_p ()
3202        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3203        || GET_CODE (operands[1]) != CONST_DOUBLE
3204        || (optimize_function_for_size_p (cfun)
3205            && ((!TARGET_SSE_MATH
3206                 && standard_80387_constant_p (operands[1]) > 0)
3207                || (TARGET_SSE_MATH
3208                    && standard_sse_constant_p (operands[1]))))
3209        || memory_operand (operands[0], SFmode))"
3210 {
3211   switch (which_alternative)
3212     {
3213     case 0:
3214     case 1:
3215       return output_387_reg_move (insn, operands);
3216
3217     case 2:
3218       return standard_80387_constant_opcode (operands[1]);
3219
3220     case 3:
3221     case 4:
3222       return "mov{l}\t{%1, %0|%0, %1}";
3223
3224     case 5:
3225       return standard_sse_constant_opcode (insn, operands[1]);
3226
3227     case 6:
3228       if (get_attr_mode (insn) == MODE_V4SF)
3229         return "%vmovaps\t{%1, %0|%0, %1}";
3230       else
3231         return "%vmovss\t{%1, %d0|%d0, %1}";
3232     case 7:
3233       if (TARGET_AVX && REG_P (operands[1]))
3234         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3235       else
3236         return "%vmovss\t{%1, %0|%0, %1}";
3237     case 8:
3238       return "%vmovss\t{%1, %0|%0, %1}";
3239
3240     case 9: case 10: case 14: case 15:
3241       return "movd\t{%1, %0|%0, %1}";
3242
3243     case 11:
3244       return "movq\t{%1, %0|%0, %1}";
3245
3246     case 12: case 13:
3247       return "%vmovd\t{%1, %0|%0, %1}";
3248
3249     default:
3250       gcc_unreachable ();
3251     }
3252 }
3253   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3254    (set (attr "prefix")
3255      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3256        (const_string "maybe_vex")
3257        (const_string "orig")))
3258    (set (attr "mode")
3259         (cond [(eq_attr "alternative" "3,4,9,10")
3260                  (const_string "SI")
3261                (eq_attr "alternative" "5")
3262                  (if_then_else
3263                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3264                                  (const_int 0))
3265                              (ne (symbol_ref "TARGET_SSE2")
3266                                  (const_int 0)))
3267                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3268                             (const_int 0)))
3269                    (const_string "TI")
3270                    (const_string "V4SF"))
3271                /* For architectures resolving dependencies on
3272                   whole SSE registers use APS move to break dependency
3273                   chains, otherwise use short move to avoid extra work.
3274
3275                   Do the same for architectures resolving dependencies on
3276                   the parts.  While in DF mode it is better to always handle
3277                   just register parts, the SF mode is different due to lack
3278                   of instructions to load just part of the register.  It is
3279                   better to maintain the whole registers in single format
3280                   to avoid problems on using packed logical operations.  */
3281                (eq_attr "alternative" "6")
3282                  (if_then_else
3283                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3284                             (const_int 0))
3285                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3286                             (const_int 0)))
3287                    (const_string "V4SF")
3288                    (const_string "SF"))
3289                (eq_attr "alternative" "11")
3290                  (const_string "DI")]
3291                (const_string "SF")))])
3292
3293 (define_split
3294   [(set (match_operand 0 "register_operand" "")
3295         (match_operand 1 "memory_operand" ""))]
3296   "reload_completed
3297    && MEM_P (operands[1])
3298    && (GET_MODE (operands[0]) == TFmode
3299        || GET_MODE (operands[0]) == XFmode
3300        || GET_MODE (operands[0]) == DFmode
3301        || GET_MODE (operands[0]) == SFmode)
3302    && (operands[2] = find_constant_src (insn))"
3303   [(set (match_dup 0) (match_dup 2))]
3304 {
3305   rtx c = operands[2];
3306   rtx r = operands[0];
3307
3308   if (GET_CODE (r) == SUBREG)
3309     r = SUBREG_REG (r);
3310
3311   if (SSE_REG_P (r))
3312     {
3313       if (!standard_sse_constant_p (c))
3314         FAIL;
3315     }
3316   else if (FP_REG_P (r))
3317     {
3318       if (standard_80387_constant_p (c) < 1)
3319         FAIL;
3320     }
3321   else if (MMX_REG_P (r))
3322     FAIL;
3323 })
3324
3325 (define_split
3326   [(set (match_operand 0 "register_operand" "")
3327         (float_extend (match_operand 1 "memory_operand" "")))]
3328   "reload_completed
3329    && MEM_P (operands[1])
3330    && (GET_MODE (operands[0]) == TFmode
3331        || GET_MODE (operands[0]) == XFmode
3332        || GET_MODE (operands[0]) == DFmode
3333        || GET_MODE (operands[0]) == SFmode)
3334    && (operands[2] = find_constant_src (insn))"
3335   [(set (match_dup 0) (match_dup 2))]
3336 {
3337   rtx c = operands[2];
3338   rtx r = operands[0];
3339
3340   if (GET_CODE (r) == SUBREG)
3341     r = SUBREG_REG (r);
3342
3343   if (SSE_REG_P (r))
3344     {
3345       if (!standard_sse_constant_p (c))
3346         FAIL;
3347     }
3348   else if (FP_REG_P (r))
3349     {
3350       if (standard_80387_constant_p (c) < 1)
3351         FAIL;
3352     }
3353   else if (MMX_REG_P (r))
3354     FAIL;
3355 })
3356
3357 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3358 (define_split
3359   [(set (match_operand:X87MODEF 0 "register_operand" "")
3360         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3361   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3362    && (standard_80387_constant_p (operands[1]) == 8
3363        || standard_80387_constant_p (operands[1]) == 9)"
3364   [(set (match_dup 0)(match_dup 1))
3365    (set (match_dup 0)
3366         (neg:X87MODEF (match_dup 0)))]
3367 {
3368   REAL_VALUE_TYPE r;
3369
3370   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3371   if (real_isnegzero (&r))
3372     operands[1] = CONST0_RTX (<MODE>mode);
3373   else
3374     operands[1] = CONST1_RTX (<MODE>mode);
3375 })
3376
3377 (define_insn "swapxf"
3378   [(set (match_operand:XF 0 "register_operand" "+f")
3379         (match_operand:XF 1 "register_operand" "+f"))
3380    (set (match_dup 1)
3381         (match_dup 0))]
3382   "TARGET_80387"
3383 {
3384   if (STACK_TOP_P (operands[0]))
3385     return "fxch\t%1";
3386   else
3387     return "fxch\t%0";
3388 }
3389   [(set_attr "type" "fxch")
3390    (set_attr "mode" "XF")])
3391
3392 (define_insn "*swap<mode>"
3393   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3394         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3395    (set (match_dup 1)
3396         (match_dup 0))]
3397   "TARGET_80387 || reload_completed"
3398 {
3399   if (STACK_TOP_P (operands[0]))
3400     return "fxch\t%1";
3401   else
3402     return "fxch\t%0";
3403 }
3404   [(set_attr "type" "fxch")
3405    (set_attr "mode" "<MODE>")])
3406 \f
3407 ;; Zero extension instructions
3408
3409 (define_expand "zero_extendsidi2"
3410   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3411         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3412   ""
3413 {
3414   if (!TARGET_64BIT)
3415     {
3416       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3417       DONE;
3418     }
3419 })
3420
3421 (define_insn "*zero_extendsidi2_rex64"
3422   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3423         (zero_extend:DI
3424          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3425   "TARGET_64BIT"
3426   "@
3427    mov\t{%k1, %k0|%k0, %k1}
3428    #
3429    movd\t{%1, %0|%0, %1}
3430    movd\t{%1, %0|%0, %1}
3431    %vmovd\t{%1, %0|%0, %1}
3432    %vmovd\t{%1, %0|%0, %1}"
3433   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3434    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3435    (set_attr "prefix_0f" "0,*,*,*,*,*")
3436    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3437
3438 (define_split
3439   [(set (match_operand:DI 0 "memory_operand" "")
3440         (zero_extend:DI (match_dup 0)))]
3441   "TARGET_64BIT"
3442   [(set (match_dup 4) (const_int 0))]
3443   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3444
3445 ;; %%% Kill me once multi-word ops are sane.
3446 (define_insn "zero_extendsidi2_1"
3447   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3448         (zero_extend:DI
3449          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3450    (clobber (reg:CC FLAGS_REG))]
3451   "!TARGET_64BIT"
3452   "@
3453    #
3454    #
3455    #
3456    movd\t{%1, %0|%0, %1}
3457    movd\t{%1, %0|%0, %1}
3458    %vmovd\t{%1, %0|%0, %1}
3459    %vmovd\t{%1, %0|%0, %1}"
3460   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3461    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3462    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3463
3464 (define_split
3465   [(set (match_operand:DI 0 "register_operand" "")
3466         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3467    (clobber (reg:CC FLAGS_REG))]
3468   "!TARGET_64BIT && reload_completed
3469    && true_regnum (operands[0]) == true_regnum (operands[1])"
3470   [(set (match_dup 4) (const_int 0))]
3471   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3472
3473 (define_split
3474   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3475         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3476    (clobber (reg:CC FLAGS_REG))]
3477   "!TARGET_64BIT && reload_completed
3478    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3479   [(set (match_dup 3) (match_dup 1))
3480    (set (match_dup 4) (const_int 0))]
3481   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3482
3483 (define_insn "zero_extend<mode>di2"
3484   [(set (match_operand:DI 0 "register_operand" "=r")
3485         (zero_extend:DI
3486          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3487   "TARGET_64BIT"
3488   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3489   [(set_attr "type" "imovx")
3490    (set_attr "mode" "SI")])
3491
3492 (define_expand "zero_extendhisi2"
3493   [(set (match_operand:SI 0 "register_operand" "")
3494         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3495   ""
3496 {
3497   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3498     {
3499       operands[1] = force_reg (HImode, operands[1]);
3500       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3501       DONE;
3502     }
3503 })
3504
3505 (define_insn_and_split "zero_extendhisi2_and"
3506   [(set (match_operand:SI 0 "register_operand" "=r")
3507         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3508    (clobber (reg:CC FLAGS_REG))]
3509   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3510   "#"
3511   "&& reload_completed"
3512   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3513               (clobber (reg:CC FLAGS_REG))])]
3514   ""
3515   [(set_attr "type" "alu1")
3516    (set_attr "mode" "SI")])
3517
3518 (define_insn "*zero_extendhisi2_movzwl"
3519   [(set (match_operand:SI 0 "register_operand" "=r")
3520         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3521   "!TARGET_ZERO_EXTEND_WITH_AND
3522    || optimize_function_for_size_p (cfun)"
3523   "movz{wl|x}\t{%1, %0|%0, %1}"
3524   [(set_attr "type" "imovx")
3525    (set_attr "mode" "SI")])
3526
3527 (define_expand "zero_extendqi<mode>2"
3528   [(parallel
3529     [(set (match_operand:SWI24 0 "register_operand" "")
3530           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3531      (clobber (reg:CC FLAGS_REG))])])
3532
3533 (define_insn "*zero_extendqi<mode>2_and"
3534   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3535         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3536    (clobber (reg:CC FLAGS_REG))]
3537   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3538   "#"
3539   [(set_attr "type" "alu1")
3540    (set_attr "mode" "<MODE>")])
3541
3542 ;; When source and destination does not overlap, clear destination
3543 ;; first and then do the movb
3544 (define_split
3545   [(set (match_operand:SWI24 0 "register_operand" "")
3546         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3547    (clobber (reg:CC FLAGS_REG))]
3548   "reload_completed
3549    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3550    && ANY_QI_REG_P (operands[0])
3551    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3552    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3553   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3554 {
3555   operands[2] = gen_lowpart (QImode, operands[0]);
3556   ix86_expand_clear (operands[0]);
3557 })
3558
3559 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3560   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3561         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3562    (clobber (reg:CC FLAGS_REG))]
3563   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3564   "#"
3565   [(set_attr "type" "imovx,alu1")
3566    (set_attr "mode" "<MODE>")])
3567
3568 ;; For the movzbl case strip only the clobber
3569 (define_split
3570   [(set (match_operand:SWI24 0 "register_operand" "")
3571         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3572    (clobber (reg:CC FLAGS_REG))]
3573   "reload_completed
3574    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3575    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3576   [(set (match_dup 0)
3577         (zero_extend:SWI24 (match_dup 1)))])
3578
3579 ; zero extend to SImode to avoid partial register stalls
3580 (define_insn "*zero_extendqi<mode>2_movzbl"
3581   [(set (match_operand:SWI24 0 "register_operand" "=r")
3582         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3583   "reload_completed
3584    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3585   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3586   [(set_attr "type" "imovx")
3587    (set_attr "mode" "SI")])
3588
3589 ;; Rest is handled by single and.
3590 (define_split
3591   [(set (match_operand:SWI24 0 "register_operand" "")
3592         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3593    (clobber (reg:CC FLAGS_REG))]
3594   "reload_completed
3595    && true_regnum (operands[0]) == true_regnum (operands[1])"
3596   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3597               (clobber (reg:CC FLAGS_REG))])])
3598 \f
3599 ;; Sign extension instructions
3600
3601 (define_expand "extendsidi2"
3602   [(set (match_operand:DI 0 "register_operand" "")
3603         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3604   ""
3605 {
3606   if (!TARGET_64BIT)
3607     {
3608       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3609       DONE;
3610     }
3611 })
3612
3613 (define_insn "*extendsidi2_rex64"
3614   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3615         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3616   "TARGET_64BIT"
3617   "@
3618    {cltq|cdqe}
3619    movs{lq|x}\t{%1, %0|%0, %1}"
3620   [(set_attr "type" "imovx")
3621    (set_attr "mode" "DI")
3622    (set_attr "prefix_0f" "0")
3623    (set_attr "modrm" "0,1")])
3624
3625 (define_insn "extendsidi2_1"
3626   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3627         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3628    (clobber (reg:CC FLAGS_REG))
3629    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3630   "!TARGET_64BIT"
3631   "#")
3632
3633 ;; Extend to memory case when source register does die.
3634 (define_split
3635   [(set (match_operand:DI 0 "memory_operand" "")
3636         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3637    (clobber (reg:CC FLAGS_REG))
3638    (clobber (match_operand:SI 2 "register_operand" ""))]
3639   "(reload_completed
3640     && dead_or_set_p (insn, operands[1])
3641     && !reg_mentioned_p (operands[1], operands[0]))"
3642   [(set (match_dup 3) (match_dup 1))
3643    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3644               (clobber (reg:CC FLAGS_REG))])
3645    (set (match_dup 4) (match_dup 1))]
3646   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3647
3648 ;; Extend to memory case when source register does not die.
3649 (define_split
3650   [(set (match_operand:DI 0 "memory_operand" "")
3651         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3652    (clobber (reg:CC FLAGS_REG))
3653    (clobber (match_operand:SI 2 "register_operand" ""))]
3654   "reload_completed"
3655   [(const_int 0)]
3656 {
3657   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3658
3659   emit_move_insn (operands[3], operands[1]);
3660
3661   /* Generate a cltd if possible and doing so it profitable.  */
3662   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3663       && true_regnum (operands[1]) == AX_REG
3664       && true_regnum (operands[2]) == DX_REG)
3665     {
3666       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3667     }
3668   else
3669     {
3670       emit_move_insn (operands[2], operands[1]);
3671       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3672     }
3673   emit_move_insn (operands[4], operands[2]);
3674   DONE;
3675 })
3676
3677 ;; Extend to register case.  Optimize case where source and destination
3678 ;; registers match and cases where we can use cltd.
3679 (define_split
3680   [(set (match_operand:DI 0 "register_operand" "")
3681         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3682    (clobber (reg:CC FLAGS_REG))
3683    (clobber (match_scratch:SI 2 ""))]
3684   "reload_completed"
3685   [(const_int 0)]
3686 {
3687   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3688
3689   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3690     emit_move_insn (operands[3], operands[1]);
3691
3692   /* Generate a cltd if possible and doing so it profitable.  */
3693   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3694       && true_regnum (operands[3]) == AX_REG
3695       && true_regnum (operands[4]) == DX_REG)
3696     {
3697       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3698       DONE;
3699     }
3700
3701   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3702     emit_move_insn (operands[4], operands[1]);
3703
3704   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3705   DONE;
3706 })
3707
3708 (define_insn "extend<mode>di2"
3709   [(set (match_operand:DI 0 "register_operand" "=r")
3710         (sign_extend:DI
3711          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3712   "TARGET_64BIT"
3713   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3714   [(set_attr "type" "imovx")
3715    (set_attr "mode" "DI")])
3716
3717 (define_insn "extendhisi2"
3718   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3719         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3720   ""
3721 {
3722   switch (get_attr_prefix_0f (insn))
3723     {
3724     case 0:
3725       return "{cwtl|cwde}";
3726     default:
3727       return "movs{wl|x}\t{%1, %0|%0, %1}";
3728     }
3729 }
3730   [(set_attr "type" "imovx")
3731    (set_attr "mode" "SI")
3732    (set (attr "prefix_0f")
3733      ;; movsx is short decodable while cwtl is vector decoded.
3734      (if_then_else (and (eq_attr "cpu" "!k6")
3735                         (eq_attr "alternative" "0"))
3736         (const_string "0")
3737         (const_string "1")))
3738    (set (attr "modrm")
3739      (if_then_else (eq_attr "prefix_0f" "0")
3740         (const_string "0")
3741         (const_string "1")))])
3742
3743 (define_insn "*extendhisi2_zext"
3744   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3745         (zero_extend:DI
3746          (sign_extend:SI
3747           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3748   "TARGET_64BIT"
3749 {
3750   switch (get_attr_prefix_0f (insn))
3751     {
3752     case 0:
3753       return "{cwtl|cwde}";
3754     default:
3755       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3756     }
3757 }
3758   [(set_attr "type" "imovx")
3759    (set_attr "mode" "SI")
3760    (set (attr "prefix_0f")
3761      ;; movsx is short decodable while cwtl is vector decoded.
3762      (if_then_else (and (eq_attr "cpu" "!k6")
3763                         (eq_attr "alternative" "0"))
3764         (const_string "0")
3765         (const_string "1")))
3766    (set (attr "modrm")
3767      (if_then_else (eq_attr "prefix_0f" "0")
3768         (const_string "0")
3769         (const_string "1")))])
3770
3771 (define_insn "extendqisi2"
3772   [(set (match_operand:SI 0 "register_operand" "=r")
3773         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3774   ""
3775   "movs{bl|x}\t{%1, %0|%0, %1}"
3776    [(set_attr "type" "imovx")
3777     (set_attr "mode" "SI")])
3778
3779 (define_insn "*extendqisi2_zext"
3780   [(set (match_operand:DI 0 "register_operand" "=r")
3781         (zero_extend:DI
3782           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3783   "TARGET_64BIT"
3784   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3785    [(set_attr "type" "imovx")
3786     (set_attr "mode" "SI")])
3787
3788 (define_insn "extendqihi2"
3789   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3790         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3791   ""
3792 {
3793   switch (get_attr_prefix_0f (insn))
3794     {
3795     case 0:
3796       return "{cbtw|cbw}";
3797     default:
3798       return "movs{bw|x}\t{%1, %0|%0, %1}";
3799     }
3800 }
3801   [(set_attr "type" "imovx")
3802    (set_attr "mode" "HI")
3803    (set (attr "prefix_0f")
3804      ;; movsx is short decodable while cwtl is vector decoded.
3805      (if_then_else (and (eq_attr "cpu" "!k6")
3806                         (eq_attr "alternative" "0"))
3807         (const_string "0")
3808         (const_string "1")))
3809    (set (attr "modrm")
3810      (if_then_else (eq_attr "prefix_0f" "0")
3811         (const_string "0")
3812         (const_string "1")))])
3813 \f
3814 ;; Conversions between float and double.
3815
3816 ;; These are all no-ops in the model used for the 80387.
3817 ;; So just emit moves.
3818
3819 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3820 (define_split
3821   [(set (match_operand:DF 0 "push_operand" "")
3822         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3823   "reload_completed"
3824   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3825    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3826
3827 (define_split
3828   [(set (match_operand:XF 0 "push_operand" "")
3829         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3830   "reload_completed"
3831   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3832    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3833   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3834
3835 (define_expand "extendsfdf2"
3836   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3837         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3838   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3839 {
3840   /* ??? Needed for compress_float_constant since all fp constants
3841      are TARGET_LEGITIMATE_CONSTANT_P.  */
3842   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3843     {
3844       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3845           && standard_80387_constant_p (operands[1]) > 0)
3846         {
3847           operands[1] = simplify_const_unary_operation
3848             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3849           emit_move_insn_1 (operands[0], operands[1]);
3850           DONE;
3851         }
3852       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3853     }
3854 })
3855
3856 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3857    cvtss2sd:
3858       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3859       cvtps2pd xmm2,xmm1
3860    We do the conversion post reload to avoid producing of 128bit spills
3861    that might lead to ICE on 32bit target.  The sequence unlikely combine
3862    anyway.  */
3863 (define_split
3864   [(set (match_operand:DF 0 "register_operand" "")
3865         (float_extend:DF
3866           (match_operand:SF 1 "nonimmediate_operand" "")))]
3867   "TARGET_USE_VECTOR_FP_CONVERTS
3868    && optimize_insn_for_speed_p ()
3869    && reload_completed && SSE_REG_P (operands[0])"
3870    [(set (match_dup 2)
3871          (float_extend:V2DF
3872            (vec_select:V2SF
3873              (match_dup 3)
3874              (parallel [(const_int 0) (const_int 1)]))))]
3875 {
3876   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3877   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3878   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3879      Try to avoid move when unpacking can be done in source.  */
3880   if (REG_P (operands[1]))
3881     {
3882       /* If it is unsafe to overwrite upper half of source, we need
3883          to move to destination and unpack there.  */
3884       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3885            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3886           && true_regnum (operands[0]) != true_regnum (operands[1]))
3887         {
3888           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3889           emit_move_insn (tmp, operands[1]);
3890         }
3891       else
3892         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3893       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3894                                              operands[3]));
3895     }
3896   else
3897     emit_insn (gen_vec_setv4sf_0 (operands[3],
3898                                   CONST0_RTX (V4SFmode), operands[1]));
3899 })
3900
3901 (define_insn "*extendsfdf2_mixed"
3902   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3903         (float_extend:DF
3904           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3905   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3906 {
3907   switch (which_alternative)
3908     {
3909     case 0:
3910     case 1:
3911       return output_387_reg_move (insn, operands);
3912
3913     case 2:
3914       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3915
3916     default:
3917       gcc_unreachable ();
3918     }
3919 }
3920   [(set_attr "type" "fmov,fmov,ssecvt")
3921    (set_attr "prefix" "orig,orig,maybe_vex")
3922    (set_attr "mode" "SF,XF,DF")])
3923
3924 (define_insn "*extendsfdf2_sse"
3925   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3926         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3927   "TARGET_SSE2 && TARGET_SSE_MATH"
3928   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3929   [(set_attr "type" "ssecvt")
3930    (set_attr "prefix" "maybe_vex")
3931    (set_attr "mode" "DF")])
3932
3933 (define_insn "*extendsfdf2_i387"
3934   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3935         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3936   "TARGET_80387"
3937   "* return output_387_reg_move (insn, operands);"
3938   [(set_attr "type" "fmov")
3939    (set_attr "mode" "SF,XF")])
3940
3941 (define_expand "extend<mode>xf2"
3942   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3943         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3944   "TARGET_80387"
3945 {
3946   /* ??? Needed for compress_float_constant since all fp constants
3947      are TARGET_LEGITIMATE_CONSTANT_P.  */
3948   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3949     {
3950       if (standard_80387_constant_p (operands[1]) > 0)
3951         {
3952           operands[1] = simplify_const_unary_operation
3953             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3954           emit_move_insn_1 (operands[0], operands[1]);
3955           DONE;
3956         }
3957       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3958     }
3959 })
3960
3961 (define_insn "*extend<mode>xf2_i387"
3962   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3963         (float_extend:XF
3964           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3965   "TARGET_80387"
3966   "* return output_387_reg_move (insn, operands);"
3967   [(set_attr "type" "fmov")
3968    (set_attr "mode" "<MODE>,XF")])
3969
3970 ;; %%% This seems bad bad news.
3971 ;; This cannot output into an f-reg because there is no way to be sure
3972 ;; of truncating in that case.  Otherwise this is just like a simple move
3973 ;; insn.  So we pretend we can output to a reg in order to get better
3974 ;; register preferencing, but we really use a stack slot.
3975
3976 ;; Conversion from DFmode to SFmode.
3977
3978 (define_expand "truncdfsf2"
3979   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3980         (float_truncate:SF
3981           (match_operand:DF 1 "nonimmediate_operand" "")))]
3982   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3983 {
3984   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3985     ;
3986   else if (flag_unsafe_math_optimizations)
3987     ;
3988   else
3989     {
3990       enum ix86_stack_slot slot = (virtuals_instantiated
3991                                    ? SLOT_TEMP
3992                                    : SLOT_VIRTUAL);
3993       rtx temp = assign_386_stack_local (SFmode, slot);
3994       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3995       DONE;
3996     }
3997 })
3998
3999 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4000    cvtsd2ss:
4001       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4002       cvtpd2ps xmm2,xmm1
4003    We do the conversion post reload to avoid producing of 128bit spills
4004    that might lead to ICE on 32bit target.  The sequence unlikely combine
4005    anyway.  */
4006 (define_split
4007   [(set (match_operand:SF 0 "register_operand" "")
4008         (float_truncate:SF
4009           (match_operand:DF 1 "nonimmediate_operand" "")))]
4010   "TARGET_USE_VECTOR_FP_CONVERTS
4011    && optimize_insn_for_speed_p ()
4012    && reload_completed && SSE_REG_P (operands[0])"
4013    [(set (match_dup 2)
4014          (vec_concat:V4SF
4015            (float_truncate:V2SF
4016              (match_dup 4))
4017            (match_dup 3)))]
4018 {
4019   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4020   operands[3] = CONST0_RTX (V2SFmode);
4021   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4022   /* Use movsd for loading from memory, unpcklpd for registers.
4023      Try to avoid move when unpacking can be done in source, or SSE3
4024      movddup is available.  */
4025   if (REG_P (operands[1]))
4026     {
4027       if (!TARGET_SSE3
4028           && true_regnum (operands[0]) != true_regnum (operands[1])
4029           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4030               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4031         {
4032           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4033           emit_move_insn (tmp, operands[1]);
4034           operands[1] = tmp;
4035         }
4036       else if (!TARGET_SSE3)
4037         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4038       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4039     }
4040   else
4041     emit_insn (gen_sse2_loadlpd (operands[4],
4042                                  CONST0_RTX (V2DFmode), operands[1]));
4043 })
4044
4045 (define_expand "truncdfsf2_with_temp"
4046   [(parallel [(set (match_operand:SF 0 "" "")
4047                    (float_truncate:SF (match_operand:DF 1 "" "")))
4048               (clobber (match_operand:SF 2 "" ""))])])
4049
4050 (define_insn "*truncdfsf_fast_mixed"
4051   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4052         (float_truncate:SF
4053           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4054   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4055 {
4056   switch (which_alternative)
4057     {
4058     case 0:
4059       return output_387_reg_move (insn, operands);
4060     case 1:
4061       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4062     default:
4063       gcc_unreachable ();
4064     }
4065 }
4066   [(set_attr "type" "fmov,ssecvt")
4067    (set_attr "prefix" "orig,maybe_vex")
4068    (set_attr "mode" "SF")])
4069
4070 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4071 ;; because nothing we do here is unsafe.
4072 (define_insn "*truncdfsf_fast_sse"
4073   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4074         (float_truncate:SF
4075           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4076   "TARGET_SSE2 && TARGET_SSE_MATH"
4077   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4078   [(set_attr "type" "ssecvt")
4079    (set_attr "prefix" "maybe_vex")
4080    (set_attr "mode" "SF")])
4081
4082 (define_insn "*truncdfsf_fast_i387"
4083   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4084         (float_truncate:SF
4085           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4086   "TARGET_80387 && flag_unsafe_math_optimizations"
4087   "* return output_387_reg_move (insn, operands);"
4088   [(set_attr "type" "fmov")
4089    (set_attr "mode" "SF")])
4090
4091 (define_insn "*truncdfsf_mixed"
4092   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4093         (float_truncate:SF
4094           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4095    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4096   "TARGET_MIX_SSE_I387"
4097 {
4098   switch (which_alternative)
4099     {
4100     case 0:
4101       return output_387_reg_move (insn, operands);
4102     case 1:
4103       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4104
4105     default:
4106       return "#";
4107     }
4108 }
4109   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4110    (set_attr "unit" "*,*,i387,i387,i387")
4111    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4112    (set_attr "mode" "SF")])
4113
4114 (define_insn "*truncdfsf_i387"
4115   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4116         (float_truncate:SF
4117           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4118    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4119   "TARGET_80387"
4120 {
4121   switch (which_alternative)
4122     {
4123     case 0:
4124       return output_387_reg_move (insn, operands);
4125
4126     default:
4127       return "#";
4128     }
4129 }
4130   [(set_attr "type" "fmov,multi,multi,multi")
4131    (set_attr "unit" "*,i387,i387,i387")
4132    (set_attr "mode" "SF")])
4133
4134 (define_insn "*truncdfsf2_i387_1"
4135   [(set (match_operand:SF 0 "memory_operand" "=m")
4136         (float_truncate:SF
4137           (match_operand:DF 1 "register_operand" "f")))]
4138   "TARGET_80387
4139    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4140    && !TARGET_MIX_SSE_I387"
4141   "* return output_387_reg_move (insn, operands);"
4142   [(set_attr "type" "fmov")
4143    (set_attr "mode" "SF")])
4144
4145 (define_split
4146   [(set (match_operand:SF 0 "register_operand" "")
4147         (float_truncate:SF
4148          (match_operand:DF 1 "fp_register_operand" "")))
4149    (clobber (match_operand 2 "" ""))]
4150   "reload_completed"
4151   [(set (match_dup 2) (match_dup 1))
4152    (set (match_dup 0) (match_dup 2))]
4153   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4154
4155 ;; Conversion from XFmode to {SF,DF}mode
4156
4157 (define_expand "truncxf<mode>2"
4158   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4159                    (float_truncate:MODEF
4160                      (match_operand:XF 1 "register_operand" "")))
4161               (clobber (match_dup 2))])]
4162   "TARGET_80387"
4163 {
4164   if (flag_unsafe_math_optimizations)
4165     {
4166       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4167       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4168       if (reg != operands[0])
4169         emit_move_insn (operands[0], reg);
4170       DONE;
4171     }
4172   else
4173     {
4174       enum ix86_stack_slot slot = (virtuals_instantiated
4175                                    ? SLOT_TEMP
4176                                    : SLOT_VIRTUAL);
4177       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4178     }
4179 })
4180
4181 (define_insn "*truncxfsf2_mixed"
4182   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4183         (float_truncate:SF
4184           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4185    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4186   "TARGET_80387"
4187 {
4188   gcc_assert (!which_alternative);
4189   return output_387_reg_move (insn, operands);
4190 }
4191   [(set_attr "type" "fmov,multi,multi,multi")
4192    (set_attr "unit" "*,i387,i387,i387")
4193    (set_attr "mode" "SF")])
4194
4195 (define_insn "*truncxfdf2_mixed"
4196   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4197         (float_truncate:DF
4198           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4199    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4200   "TARGET_80387"
4201 {
4202   gcc_assert (!which_alternative);
4203   return output_387_reg_move (insn, operands);
4204 }
4205   [(set_attr "type" "fmov,multi,multi,multi")
4206    (set_attr "unit" "*,i387,i387,i387")
4207    (set_attr "mode" "DF")])
4208
4209 (define_insn "truncxf<mode>2_i387_noop"
4210   [(set (match_operand:MODEF 0 "register_operand" "=f")
4211         (float_truncate:MODEF
4212           (match_operand:XF 1 "register_operand" "f")))]
4213   "TARGET_80387 && flag_unsafe_math_optimizations"
4214   "* return output_387_reg_move (insn, operands);"
4215   [(set_attr "type" "fmov")
4216    (set_attr "mode" "<MODE>")])
4217
4218 (define_insn "*truncxf<mode>2_i387"
4219   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4220         (float_truncate:MODEF
4221           (match_operand:XF 1 "register_operand" "f")))]
4222   "TARGET_80387"
4223   "* return output_387_reg_move (insn, operands);"
4224   [(set_attr "type" "fmov")
4225    (set_attr "mode" "<MODE>")])
4226
4227 (define_split
4228   [(set (match_operand:MODEF 0 "register_operand" "")
4229         (float_truncate:MODEF
4230           (match_operand:XF 1 "register_operand" "")))
4231    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4232   "TARGET_80387 && reload_completed"
4233   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4234    (set (match_dup 0) (match_dup 2))])
4235
4236 (define_split
4237   [(set (match_operand:MODEF 0 "memory_operand" "")
4238         (float_truncate:MODEF
4239           (match_operand:XF 1 "register_operand" "")))
4240    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4241   "TARGET_80387"
4242   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4243 \f
4244 ;; Signed conversion to DImode.
4245
4246 (define_expand "fix_truncxfdi2"
4247   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4249               (clobber (reg:CC FLAGS_REG))])]
4250   "TARGET_80387"
4251 {
4252   if (TARGET_FISTTP)
4253    {
4254      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4255      DONE;
4256    }
4257 })
4258
4259 (define_expand "fix_trunc<mode>di2"
4260   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4262               (clobber (reg:CC FLAGS_REG))])]
4263   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4264 {
4265   if (TARGET_FISTTP
4266       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4267    {
4268      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4269      DONE;
4270    }
4271   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4272    {
4273      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275      if (out != operands[0])
4276         emit_move_insn (operands[0], out);
4277      DONE;
4278    }
4279 })
4280
4281 ;; Signed conversion to SImode.
4282
4283 (define_expand "fix_truncxfsi2"
4284   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4286               (clobber (reg:CC FLAGS_REG))])]
4287   "TARGET_80387"
4288 {
4289   if (TARGET_FISTTP)
4290    {
4291      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4292      DONE;
4293    }
4294 })
4295
4296 (define_expand "fix_trunc<mode>si2"
4297   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4299               (clobber (reg:CC FLAGS_REG))])]
4300   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4301 {
4302   if (TARGET_FISTTP
4303       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4304    {
4305      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4306      DONE;
4307    }
4308   if (SSE_FLOAT_MODE_P (<MODE>mode))
4309    {
4310      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312      if (out != operands[0])
4313         emit_move_insn (operands[0], out);
4314      DONE;
4315    }
4316 })
4317
4318 ;; Signed conversion to HImode.
4319
4320 (define_expand "fix_trunc<mode>hi2"
4321   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323               (clobber (reg:CC FLAGS_REG))])]
4324   "TARGET_80387
4325    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4326 {
4327   if (TARGET_FISTTP)
4328    {
4329      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4330      DONE;
4331    }
4332 })
4333
4334 ;; Unsigned conversion to SImode.
4335
4336 (define_expand "fixuns_trunc<mode>si2"
4337   [(parallel
4338     [(set (match_operand:SI 0 "register_operand" "")
4339           (unsigned_fix:SI
4340             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4341      (use (match_dup 2))
4342      (clobber (match_scratch:<ssevecmode> 3 ""))
4343      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4344   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4345 {
4346   enum machine_mode mode = <MODE>mode;
4347   enum machine_mode vecmode = <ssevecmode>mode;
4348   REAL_VALUE_TYPE TWO31r;
4349   rtx two31;
4350
4351   if (optimize_insn_for_size_p ())
4352     FAIL;
4353
4354   real_ldexp (&TWO31r, &dconst1, 31);
4355   two31 = const_double_from_real_value (TWO31r, mode);
4356   two31 = ix86_build_const_vector (vecmode, true, two31);
4357   operands[2] = force_reg (vecmode, two31);
4358 })
4359
4360 (define_insn_and_split "*fixuns_trunc<mode>_1"
4361   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4362         (unsigned_fix:SI
4363           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4364    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4365    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4366    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4367   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4368    && optimize_function_for_speed_p (cfun)"
4369   "#"
4370   "&& reload_completed"
4371   [(const_int 0)]
4372 {
4373   ix86_split_convert_uns_si_sse (operands);
4374   DONE;
4375 })
4376
4377 ;; Unsigned conversion to HImode.
4378 ;; Without these patterns, we'll try the unsigned SI conversion which
4379 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4380
4381 (define_expand "fixuns_trunc<mode>hi2"
4382   [(set (match_dup 2)
4383         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4384    (set (match_operand:HI 0 "nonimmediate_operand" "")
4385         (subreg:HI (match_dup 2) 0))]
4386   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4387   "operands[2] = gen_reg_rtx (SImode);")
4388
4389 ;; When SSE is available, it is always faster to use it!
4390 (define_insn "fix_trunc<mode>di_sse"
4391   [(set (match_operand:DI 0 "register_operand" "=r,r")
4392         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4393   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4394    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4395   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4396   [(set_attr "type" "sseicvt")
4397    (set_attr "prefix" "maybe_vex")
4398    (set_attr "prefix_rex" "1")
4399    (set_attr "mode" "<MODE>")
4400    (set_attr "athlon_decode" "double,vector")
4401    (set_attr "amdfam10_decode" "double,double")
4402    (set_attr "bdver1_decode" "double,double")])
4403
4404 (define_insn "fix_trunc<mode>si_sse"
4405   [(set (match_operand:SI 0 "register_operand" "=r,r")
4406         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4407   "SSE_FLOAT_MODE_P (<MODE>mode)
4408    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4409   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4410   [(set_attr "type" "sseicvt")
4411    (set_attr "prefix" "maybe_vex")
4412    (set_attr "mode" "<MODE>")
4413    (set_attr "athlon_decode" "double,vector")
4414    (set_attr "amdfam10_decode" "double,double")
4415    (set_attr "bdver1_decode" "double,double")])
4416
4417 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4418 (define_peephole2
4419   [(set (match_operand:MODEF 0 "register_operand" "")
4420         (match_operand:MODEF 1 "memory_operand" ""))
4421    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4422         (fix:SSEMODEI24 (match_dup 0)))]
4423   "TARGET_SHORTEN_X87_SSE
4424    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4425    && peep2_reg_dead_p (2, operands[0])"
4426   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4427
4428 ;; Avoid vector decoded forms of the instruction.
4429 (define_peephole2
4430   [(match_scratch:DF 2 "Y2")
4431    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4432         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4433   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4434   [(set (match_dup 2) (match_dup 1))
4435    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4436
4437 (define_peephole2
4438   [(match_scratch:SF 2 "x")
4439    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4440         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4441   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4442   [(set (match_dup 2) (match_dup 1))
4443    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4444
4445 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4446   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4447         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4448   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4449    && TARGET_FISTTP
4450    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4451          && (TARGET_64BIT || <MODE>mode != DImode))
4452         && TARGET_SSE_MATH)
4453    && can_create_pseudo_p ()"
4454   "#"
4455   "&& 1"
4456   [(const_int 0)]
4457 {
4458   if (memory_operand (operands[0], VOIDmode))
4459     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4460   else
4461     {
4462       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4463       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4464                                                             operands[1],
4465                                                             operands[2]));
4466     }
4467   DONE;
4468 }
4469   [(set_attr "type" "fisttp")
4470    (set_attr "mode" "<MODE>")])
4471
4472 (define_insn "fix_trunc<mode>_i387_fisttp"
4473   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4474         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4475    (clobber (match_scratch:XF 2 "=&1f"))]
4476   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4477    && TARGET_FISTTP
4478    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4479          && (TARGET_64BIT || <MODE>mode != DImode))
4480         && TARGET_SSE_MATH)"
4481   "* return output_fix_trunc (insn, operands, 1);"
4482   [(set_attr "type" "fisttp")
4483    (set_attr "mode" "<MODE>")])
4484
4485 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4486   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4487         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4488    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4489    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4490   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4491    && TARGET_FISTTP
4492    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4493         && (TARGET_64BIT || <MODE>mode != DImode))
4494         && TARGET_SSE_MATH)"
4495   "#"
4496   [(set_attr "type" "fisttp")
4497    (set_attr "mode" "<MODE>")])
4498
4499 (define_split
4500   [(set (match_operand:X87MODEI 0 "register_operand" "")
4501         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4502    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4503    (clobber (match_scratch 3 ""))]
4504   "reload_completed"
4505   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4506               (clobber (match_dup 3))])
4507    (set (match_dup 0) (match_dup 2))])
4508
4509 (define_split
4510   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4511         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4512    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4513    (clobber (match_scratch 3 ""))]
4514   "reload_completed"
4515   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4516               (clobber (match_dup 3))])])
4517
4518 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4519 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4520 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4521 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4522 ;; function in i386.c.
4523 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4524   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4525         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4526    (clobber (reg:CC FLAGS_REG))]
4527   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528    && !TARGET_FISTTP
4529    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4530          && (TARGET_64BIT || <MODE>mode != DImode))
4531    && can_create_pseudo_p ()"
4532   "#"
4533   "&& 1"
4534   [(const_int 0)]
4535 {
4536   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4537
4538   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4539   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4540   if (memory_operand (operands[0], VOIDmode))
4541     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4542                                          operands[2], operands[3]));
4543   else
4544     {
4545       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4546       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4547                                                      operands[2], operands[3],
4548                                                      operands[4]));
4549     }
4550   DONE;
4551 }
4552   [(set_attr "type" "fistp")
4553    (set_attr "i387_cw" "trunc")
4554    (set_attr "mode" "<MODE>")])
4555
4556 (define_insn "fix_truncdi_i387"
4557   [(set (match_operand:DI 0 "memory_operand" "=m")
4558         (fix:DI (match_operand 1 "register_operand" "f")))
4559    (use (match_operand:HI 2 "memory_operand" "m"))
4560    (use (match_operand:HI 3 "memory_operand" "m"))
4561    (clobber (match_scratch:XF 4 "=&1f"))]
4562   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4563    && !TARGET_FISTTP
4564    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4565   "* return output_fix_trunc (insn, operands, 0);"
4566   [(set_attr "type" "fistp")
4567    (set_attr "i387_cw" "trunc")
4568    (set_attr "mode" "DI")])
4569
4570 (define_insn "fix_truncdi_i387_with_temp"
4571   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4572         (fix:DI (match_operand 1 "register_operand" "f,f")))
4573    (use (match_operand:HI 2 "memory_operand" "m,m"))
4574    (use (match_operand:HI 3 "memory_operand" "m,m"))
4575    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4576    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4577   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4578    && !TARGET_FISTTP
4579    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4580   "#"
4581   [(set_attr "type" "fistp")
4582    (set_attr "i387_cw" "trunc")
4583    (set_attr "mode" "DI")])
4584
4585 (define_split
4586   [(set (match_operand:DI 0 "register_operand" "")
4587         (fix:DI (match_operand 1 "register_operand" "")))
4588    (use (match_operand:HI 2 "memory_operand" ""))
4589    (use (match_operand:HI 3 "memory_operand" ""))
4590    (clobber (match_operand:DI 4 "memory_operand" ""))
4591    (clobber (match_scratch 5 ""))]
4592   "reload_completed"
4593   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4594               (use (match_dup 2))
4595               (use (match_dup 3))
4596               (clobber (match_dup 5))])
4597    (set (match_dup 0) (match_dup 4))])
4598
4599 (define_split
4600   [(set (match_operand:DI 0 "memory_operand" "")
4601         (fix:DI (match_operand 1 "register_operand" "")))
4602    (use (match_operand:HI 2 "memory_operand" ""))
4603    (use (match_operand:HI 3 "memory_operand" ""))
4604    (clobber (match_operand:DI 4 "memory_operand" ""))
4605    (clobber (match_scratch 5 ""))]
4606   "reload_completed"
4607   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4608               (use (match_dup 2))
4609               (use (match_dup 3))
4610               (clobber (match_dup 5))])])
4611
4612 (define_insn "fix_trunc<mode>_i387"
4613   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4614         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4615    (use (match_operand:HI 2 "memory_operand" "m"))
4616    (use (match_operand:HI 3 "memory_operand" "m"))]
4617   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4618    && !TARGET_FISTTP
4619    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4620   "* return output_fix_trunc (insn, operands, 0);"
4621   [(set_attr "type" "fistp")
4622    (set_attr "i387_cw" "trunc")
4623    (set_attr "mode" "<MODE>")])
4624
4625 (define_insn "fix_trunc<mode>_i387_with_temp"
4626   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4627         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4628    (use (match_operand:HI 2 "memory_operand" "m,m"))
4629    (use (match_operand:HI 3 "memory_operand" "m,m"))
4630    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4631   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4632    && !TARGET_FISTTP
4633    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4634   "#"
4635   [(set_attr "type" "fistp")
4636    (set_attr "i387_cw" "trunc")
4637    (set_attr "mode" "<MODE>")])
4638
4639 (define_split
4640   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4641         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4642    (use (match_operand:HI 2 "memory_operand" ""))
4643    (use (match_operand:HI 3 "memory_operand" ""))
4644    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4645   "reload_completed"
4646   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4647               (use (match_dup 2))
4648               (use (match_dup 3))])
4649    (set (match_dup 0) (match_dup 4))])
4650
4651 (define_split
4652   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4653         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4654    (use (match_operand:HI 2 "memory_operand" ""))
4655    (use (match_operand:HI 3 "memory_operand" ""))
4656    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4657   "reload_completed"
4658   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4659               (use (match_dup 2))
4660               (use (match_dup 3))])])
4661
4662 (define_insn "x86_fnstcw_1"
4663   [(set (match_operand:HI 0 "memory_operand" "=m")
4664         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4665   "TARGET_80387"
4666   "fnstcw\t%0"
4667   [(set (attr "length")
4668         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4669    (set_attr "mode" "HI")
4670    (set_attr "unit" "i387")
4671    (set_attr "bdver1_decode" "vector")])
4672
4673 (define_insn "x86_fldcw_1"
4674   [(set (reg:HI FPCR_REG)
4675         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4676   "TARGET_80387"
4677   "fldcw\t%0"
4678   [(set (attr "length")
4679         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4680    (set_attr "mode" "HI")
4681    (set_attr "unit" "i387")
4682    (set_attr "athlon_decode" "vector")
4683    (set_attr "amdfam10_decode" "vector")
4684    (set_attr "bdver1_decode" "vector")])
4685 \f
4686 ;; Conversion between fixed point and floating point.
4687
4688 ;; Even though we only accept memory inputs, the backend _really_
4689 ;; wants to be able to do this between registers.
4690
4691 (define_expand "floathi<mode>2"
4692   [(set (match_operand:X87MODEF 0 "register_operand" "")
4693         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4694   "TARGET_80387
4695    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4696        || TARGET_MIX_SSE_I387)")
4697
4698 ;; Pre-reload splitter to add memory clobber to the pattern.
4699 (define_insn_and_split "*floathi<mode>2_1"
4700   [(set (match_operand:X87MODEF 0 "register_operand" "")
4701         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4702   "TARGET_80387
4703    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4704        || TARGET_MIX_SSE_I387)
4705    && can_create_pseudo_p ()"
4706   "#"
4707   "&& 1"
4708   [(parallel [(set (match_dup 0)
4709               (float:X87MODEF (match_dup 1)))
4710    (clobber (match_dup 2))])]
4711   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4712
4713 (define_insn "*floathi<mode>2_i387_with_temp"
4714   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4715         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4716   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4717   "TARGET_80387
4718    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4719        || TARGET_MIX_SSE_I387)"
4720   "#"
4721   [(set_attr "type" "fmov,multi")
4722    (set_attr "mode" "<MODE>")
4723    (set_attr "unit" "*,i387")
4724    (set_attr "fp_int_src" "true")])
4725
4726 (define_insn "*floathi<mode>2_i387"
4727   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4728         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4729   "TARGET_80387
4730    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4731        || TARGET_MIX_SSE_I387)"
4732   "fild%Z1\t%1"
4733   [(set_attr "type" "fmov")
4734    (set_attr "mode" "<MODE>")
4735    (set_attr "fp_int_src" "true")])
4736
4737 (define_split
4738   [(set (match_operand:X87MODEF 0 "register_operand" "")
4739         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4740    (clobber (match_operand:HI 2 "memory_operand" ""))]
4741   "TARGET_80387
4742    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4743        || TARGET_MIX_SSE_I387)
4744    && reload_completed"
4745   [(set (match_dup 2) (match_dup 1))
4746    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4747
4748 (define_split
4749   [(set (match_operand:X87MODEF 0 "register_operand" "")
4750         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4751    (clobber (match_operand:HI 2 "memory_operand" ""))]
4752    "TARGET_80387
4753     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4754         || TARGET_MIX_SSE_I387)
4755     && reload_completed"
4756   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4757
4758 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4759   [(set (match_operand:X87MODEF 0 "register_operand" "")
4760         (float:X87MODEF
4761           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4762   "TARGET_80387
4763    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4764        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4765 {
4766   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4767         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4768       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4769     {
4770       rtx reg = gen_reg_rtx (XFmode);
4771       rtx (*insn)(rtx, rtx);
4772
4773       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4774
4775       if (<X87MODEF:MODE>mode == SFmode)
4776         insn = gen_truncxfsf2;
4777       else if (<X87MODEF:MODE>mode == DFmode)
4778         insn = gen_truncxfdf2;
4779       else
4780         gcc_unreachable ();
4781
4782       emit_insn (insn (operands[0], reg));
4783       DONE;
4784     }
4785 })
4786
4787 ;; Pre-reload splitter to add memory clobber to the pattern.
4788 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4789   [(set (match_operand:X87MODEF 0 "register_operand" "")
4790         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4791   "((TARGET_80387
4792      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4793      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4794            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4795          || TARGET_MIX_SSE_I387))
4796     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4797         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4798         && ((<SSEMODEI24:MODE>mode == SImode
4799              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4800              && optimize_function_for_speed_p (cfun)
4801              && flag_trapping_math)
4802             || !(TARGET_INTER_UNIT_CONVERSIONS
4803                  || optimize_function_for_size_p (cfun)))))
4804    && can_create_pseudo_p ()"
4805   "#"
4806   "&& 1"
4807   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4808               (clobber (match_dup 2))])]
4809 {
4810   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4811
4812   /* Avoid store forwarding (partial memory) stall penalty
4813      by passing DImode value through XMM registers.  */
4814   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4815       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4816       && optimize_function_for_speed_p (cfun))
4817     {
4818       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4819                                                             operands[1],
4820                                                             operands[2]));
4821       DONE;
4822     }
4823 })
4824
4825 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4826   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4827         (float:MODEF
4828           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4829    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4830   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4831    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4832   "#"
4833   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4834    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4835    (set_attr "unit" "*,i387,*,*,*")
4836    (set_attr "athlon_decode" "*,*,double,direct,double")
4837    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4838    (set_attr "bdver1_decode" "*,*,double,direct,double")
4839    (set_attr "fp_int_src" "true")])
4840
4841 (define_insn "*floatsi<mode>2_vector_mixed"
4842   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4843         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4844   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4845    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4846   "@
4847    fild%Z1\t%1
4848    #"
4849   [(set_attr "type" "fmov,sseicvt")
4850    (set_attr "mode" "<MODE>,<ssevecmode>")
4851    (set_attr "unit" "i387,*")
4852    (set_attr "athlon_decode" "*,direct")
4853    (set_attr "amdfam10_decode" "*,double")
4854    (set_attr "bdver1_decode" "*,direct")
4855    (set_attr "fp_int_src" "true")])
4856
4857 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4858   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4859         (float:MODEF
4860           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4861   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4862   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4863    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4864   "#"
4865   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4866    (set_attr "mode" "<MODEF:MODE>")
4867    (set_attr "unit" "*,i387,*,*")
4868    (set_attr "athlon_decode" "*,*,double,direct")
4869    (set_attr "amdfam10_decode" "*,*,vector,double")
4870    (set_attr "bdver1_decode" "*,*,double,direct")
4871    (set_attr "fp_int_src" "true")])
4872
4873 (define_split
4874   [(set (match_operand:MODEF 0 "register_operand" "")
4875         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4876    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4877   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4878    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4879    && TARGET_INTER_UNIT_CONVERSIONS
4880    && reload_completed
4881    && (SSE_REG_P (operands[0])
4882        || (GET_CODE (operands[0]) == SUBREG
4883            && SSE_REG_P (operands[0])))"
4884   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4885
4886 (define_split
4887   [(set (match_operand:MODEF 0 "register_operand" "")
4888         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4889    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4890   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4891    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4892    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4893    && reload_completed
4894    && (SSE_REG_P (operands[0])
4895        || (GET_CODE (operands[0]) == SUBREG
4896            && SSE_REG_P (operands[0])))"
4897   [(set (match_dup 2) (match_dup 1))
4898    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4899
4900 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
4901   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4902         (float:MODEF
4903           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
4904   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4905    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4906    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4907   "@
4908    fild%Z1\t%1
4909    %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
4910    %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4911   [(set_attr "type" "fmov,sseicvt,sseicvt")
4912    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4913    (set_attr "mode" "<MODEF:MODE>")
4914    (set (attr "prefix_rex")
4915      (if_then_else
4916        (and (eq_attr "prefix" "maybe_vex")
4917             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4918        (const_string "1")
4919        (const_string "*")))
4920    (set_attr "unit" "i387,*,*")
4921    (set_attr "athlon_decode" "*,double,direct")
4922    (set_attr "amdfam10_decode" "*,vector,double")
4923    (set_attr "bdver1_decode" "*,double,direct")
4924    (set_attr "fp_int_src" "true")])
4925
4926 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
4927   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4928         (float:MODEF
4929           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
4930   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4931    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4932    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4933   "@
4934    fild%Z1\t%1
4935    %vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
4936   [(set_attr "type" "fmov,sseicvt")
4937    (set_attr "prefix" "orig,maybe_vex")
4938    (set_attr "mode" "<MODEF:MODE>")
4939    (set (attr "prefix_rex")
4940      (if_then_else
4941        (and (eq_attr "prefix" "maybe_vex")
4942             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
4943        (const_string "1")
4944        (const_string "*")))
4945    (set_attr "athlon_decode" "*,direct")
4946    (set_attr "amdfam10_decode" "*,double")
4947    (set_attr "bdver1_decode" "*,direct")
4948    (set_attr "fp_int_src" "true")])
4949
4950 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4951   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4952         (float:MODEF
4953           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4954    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4955   "TARGET_SSE2 && TARGET_SSE_MATH
4956    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4957   "#"
4958   [(set_attr "type" "sseicvt")
4959    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4960    (set_attr "athlon_decode" "double,direct,double")
4961    (set_attr "amdfam10_decode" "vector,double,double")
4962    (set_attr "bdver1_decode" "double,direct,double")
4963    (set_attr "fp_int_src" "true")])
4964
4965 (define_insn "*floatsi<mode>2_vector_sse"
4966   [(set (match_operand:MODEF 0 "register_operand" "=x")
4967         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4968   "TARGET_SSE2 && TARGET_SSE_MATH
4969    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4970   "#"
4971   [(set_attr "type" "sseicvt")
4972    (set_attr "mode" "<MODE>")
4973    (set_attr "athlon_decode" "direct")
4974    (set_attr "amdfam10_decode" "double")
4975    (set_attr "bdver1_decode" "direct")
4976    (set_attr "fp_int_src" "true")])
4977
4978 (define_split
4979   [(set (match_operand:MODEF 0 "register_operand" "")
4980         (float:MODEF (match_operand:SI 1 "register_operand" "")))
4981    (clobber (match_operand:SI 2 "memory_operand" ""))]
4982   "TARGET_SSE2 && TARGET_SSE_MATH
4983    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4984    && reload_completed
4985    && (SSE_REG_P (operands[0])
4986        || (GET_CODE (operands[0]) == SUBREG
4987            && SSE_REG_P (operands[0])))"
4988   [(const_int 0)]
4989 {
4990   rtx op1 = operands[1];
4991
4992   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4993                                      <MODE>mode, 0);
4994   if (GET_CODE (op1) == SUBREG)
4995     op1 = SUBREG_REG (op1);
4996
4997   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4998     {
4999       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5000       emit_insn (gen_sse2_loadld (operands[4],
5001                                   CONST0_RTX (V4SImode), operands[1]));
5002     }
5003   /* We can ignore possible trapping value in the
5004      high part of SSE register for non-trapping math. */
5005   else if (SSE_REG_P (op1) && !flag_trapping_math)
5006     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5007   else
5008     {
5009       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5010       emit_move_insn (operands[2], operands[1]);
5011       emit_insn (gen_sse2_loadld (operands[4],
5012                                   CONST0_RTX (V4SImode), operands[2]));
5013     }
5014   emit_insn
5015     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5016   DONE;
5017 })
5018
5019 (define_split
5020   [(set (match_operand:MODEF 0 "register_operand" "")
5021         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5022    (clobber (match_operand:SI 2 "memory_operand" ""))]
5023   "TARGET_SSE2 && TARGET_SSE_MATH
5024    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5025    && reload_completed
5026    && (SSE_REG_P (operands[0])
5027        || (GET_CODE (operands[0]) == SUBREG
5028            && SSE_REG_P (operands[0])))"
5029   [(const_int 0)]
5030 {
5031   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5032                                      <MODE>mode, 0);
5033   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5034
5035   emit_insn (gen_sse2_loadld (operands[4],
5036                               CONST0_RTX (V4SImode), operands[1]));
5037   emit_insn
5038     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5039   DONE;
5040 })
5041
5042 (define_split
5043   [(set (match_operand:MODEF 0 "register_operand" "")
5044         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5045   "TARGET_SSE2 && TARGET_SSE_MATH
5046    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5047    && reload_completed
5048    && (SSE_REG_P (operands[0])
5049        || (GET_CODE (operands[0]) == SUBREG
5050            && SSE_REG_P (operands[0])))"
5051   [(const_int 0)]
5052 {
5053   rtx op1 = operands[1];
5054
5055   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5056                                      <MODE>mode, 0);
5057   if (GET_CODE (op1) == SUBREG)
5058     op1 = SUBREG_REG (op1);
5059
5060   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5061     {
5062       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5063       emit_insn (gen_sse2_loadld (operands[4],
5064                                   CONST0_RTX (V4SImode), operands[1]));
5065     }
5066   /* We can ignore possible trapping value in the
5067      high part of SSE register for non-trapping math. */
5068   else if (SSE_REG_P (op1) && !flag_trapping_math)
5069     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5070   else
5071     gcc_unreachable ();
5072   emit_insn
5073     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5074   DONE;
5075 })
5076
5077 (define_split
5078   [(set (match_operand:MODEF 0 "register_operand" "")
5079         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5080   "TARGET_SSE2 && TARGET_SSE_MATH
5081    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5082    && reload_completed
5083    && (SSE_REG_P (operands[0])
5084        || (GET_CODE (operands[0]) == SUBREG
5085            && SSE_REG_P (operands[0])))"
5086   [(const_int 0)]
5087 {
5088   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5089                                      <MODE>mode, 0);
5090   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5091
5092   emit_insn (gen_sse2_loadld (operands[4],
5093                               CONST0_RTX (V4SImode), operands[1]));
5094   emit_insn
5095     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5096   DONE;
5097 })
5098
5099 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5100   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5101         (float:MODEF
5102           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5103   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5104   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5105    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5106   "#"
5107   [(set_attr "type" "sseicvt")
5108    (set_attr "mode" "<MODEF:MODE>")
5109    (set_attr "athlon_decode" "double,direct")
5110    (set_attr "amdfam10_decode" "vector,double")
5111    (set_attr "bdver1_decode" "double,direct")
5112    (set_attr "fp_int_src" "true")])
5113
5114 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5115   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5116         (float:MODEF
5117           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5118   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5119    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5120    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5121   "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5122   [(set_attr "type" "sseicvt")
5123    (set_attr "prefix" "maybe_vex")
5124    (set_attr "mode" "<MODEF:MODE>")
5125    (set (attr "prefix_rex")
5126      (if_then_else
5127        (and (eq_attr "prefix" "maybe_vex")
5128             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5129        (const_string "1")
5130        (const_string "*")))
5131    (set_attr "athlon_decode" "double,direct")
5132    (set_attr "amdfam10_decode" "vector,double")
5133    (set_attr "bdver1_decode" "double,direct")
5134    (set_attr "fp_int_src" "true")])
5135
5136 (define_split
5137   [(set (match_operand:MODEF 0 "register_operand" "")
5138         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5139    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5140   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5141    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5142    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5143    && reload_completed
5144    && (SSE_REG_P (operands[0])
5145        || (GET_CODE (operands[0]) == SUBREG
5146            && SSE_REG_P (operands[0])))"
5147   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5148
5149 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5150   [(set (match_operand:MODEF 0 "register_operand" "=x")
5151         (float:MODEF
5152           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5153   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5154    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5155    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5156   "%vcvtsi2<MODEF:ssemodesuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5157   [(set_attr "type" "sseicvt")
5158    (set_attr "prefix" "maybe_vex")
5159    (set_attr "mode" "<MODEF:MODE>")
5160    (set (attr "prefix_rex")
5161      (if_then_else
5162        (and (eq_attr "prefix" "maybe_vex")
5163             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5164        (const_string "1")
5165        (const_string "*")))
5166    (set_attr "athlon_decode" "direct")
5167    (set_attr "amdfam10_decode" "double")
5168    (set_attr "bdver1_decode" "direct")
5169    (set_attr "fp_int_src" "true")])
5170
5171 (define_split
5172   [(set (match_operand:MODEF 0 "register_operand" "")
5173         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5174    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5175   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5176    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5177    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5178    && reload_completed
5179    && (SSE_REG_P (operands[0])
5180        || (GET_CODE (operands[0]) == SUBREG
5181            && SSE_REG_P (operands[0])))"
5182   [(set (match_dup 2) (match_dup 1))
5183    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5184
5185 (define_split
5186   [(set (match_operand:MODEF 0 "register_operand" "")
5187         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5188    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5189   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5190    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5191    && reload_completed
5192    && (SSE_REG_P (operands[0])
5193        || (GET_CODE (operands[0]) == SUBREG
5194            && SSE_REG_P (operands[0])))"
5195   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5196
5197 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5198   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5199         (float:X87MODEF
5200           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5201   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5202   "TARGET_80387
5203    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5204   "@
5205    fild%Z1\t%1
5206    #"
5207   [(set_attr "type" "fmov,multi")
5208    (set_attr "mode" "<X87MODEF:MODE>")
5209    (set_attr "unit" "*,i387")
5210    (set_attr "fp_int_src" "true")])
5211
5212 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5213   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5214         (float:X87MODEF
5215           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5216   "TARGET_80387
5217    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5218   "fild%Z1\t%1"
5219   [(set_attr "type" "fmov")
5220    (set_attr "mode" "<X87MODEF:MODE>")
5221    (set_attr "fp_int_src" "true")])
5222
5223 (define_split
5224   [(set (match_operand:X87MODEF 0 "register_operand" "")
5225         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5226    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5227   "TARGET_80387
5228    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5229    && reload_completed
5230    && FP_REG_P (operands[0])"
5231   [(set (match_dup 2) (match_dup 1))
5232    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5233
5234 (define_split
5235   [(set (match_operand:X87MODEF 0 "register_operand" "")
5236         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5237    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5238   "TARGET_80387
5239    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5240    && reload_completed
5241    && FP_REG_P (operands[0])"
5242   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5243
5244 ;; Avoid store forwarding (partial memory) stall penalty
5245 ;; by passing DImode value through XMM registers.  */
5246
5247 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5248   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5249         (float:X87MODEF
5250           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5251    (clobber (match_scratch:V4SI 3 "=X,x"))
5252    (clobber (match_scratch:V4SI 4 "=X,x"))
5253    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5254   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5255    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5256    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5257   "#"
5258   [(set_attr "type" "multi")
5259    (set_attr "mode" "<X87MODEF:MODE>")
5260    (set_attr "unit" "i387")
5261    (set_attr "fp_int_src" "true")])
5262
5263 (define_split
5264   [(set (match_operand:X87MODEF 0 "register_operand" "")
5265         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5266    (clobber (match_scratch:V4SI 3 ""))
5267    (clobber (match_scratch:V4SI 4 ""))
5268    (clobber (match_operand:DI 2 "memory_operand" ""))]
5269   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5270    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5271    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5272    && reload_completed
5273    && FP_REG_P (operands[0])"
5274   [(set (match_dup 2) (match_dup 3))
5275    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5276 {
5277   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5278      Assemble the 64-bit DImode value in an xmm register.  */
5279   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5280                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5281   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5282                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5283   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5284                                          operands[4]));
5285
5286   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5287 })
5288
5289 (define_split
5290   [(set (match_operand:X87MODEF 0 "register_operand" "")
5291         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5292    (clobber (match_scratch:V4SI 3 ""))
5293    (clobber (match_scratch:V4SI 4 ""))
5294    (clobber (match_operand:DI 2 "memory_operand" ""))]
5295   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5296    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5297    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5298    && reload_completed
5299    && FP_REG_P (operands[0])"
5300   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5301
5302 ;; Avoid store forwarding (partial memory) stall penalty by extending
5303 ;; SImode value to DImode through XMM register instead of pushing two
5304 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5305 ;; targets benefit from this optimization. Also note that fild
5306 ;; loads from memory only.
5307
5308 (define_insn "*floatunssi<mode>2_1"
5309   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5310         (unsigned_float:X87MODEF
5311           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5312    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5313    (clobber (match_scratch:SI 3 "=X,x"))]
5314   "!TARGET_64BIT
5315    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5316    && TARGET_SSE"
5317   "#"
5318   [(set_attr "type" "multi")
5319    (set_attr "mode" "<MODE>")])
5320
5321 (define_split
5322   [(set (match_operand:X87MODEF 0 "register_operand" "")
5323         (unsigned_float:X87MODEF
5324           (match_operand:SI 1 "register_operand" "")))
5325    (clobber (match_operand:DI 2 "memory_operand" ""))
5326    (clobber (match_scratch:SI 3 ""))]
5327   "!TARGET_64BIT
5328    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5329    && TARGET_SSE
5330    && reload_completed"
5331   [(set (match_dup 2) (match_dup 1))
5332    (set (match_dup 0)
5333         (float:X87MODEF (match_dup 2)))]
5334   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5335
5336 (define_split
5337   [(set (match_operand:X87MODEF 0 "register_operand" "")
5338         (unsigned_float:X87MODEF
5339           (match_operand:SI 1 "memory_operand" "")))
5340    (clobber (match_operand:DI 2 "memory_operand" ""))
5341    (clobber (match_scratch:SI 3 ""))]
5342   "!TARGET_64BIT
5343    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5344    && TARGET_SSE
5345    && reload_completed"
5346   [(set (match_dup 2) (match_dup 3))
5347    (set (match_dup 0)
5348         (float:X87MODEF (match_dup 2)))]
5349 {
5350   emit_move_insn (operands[3], operands[1]);
5351   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5352 })
5353
5354 (define_expand "floatunssi<mode>2"
5355   [(parallel
5356      [(set (match_operand:X87MODEF 0 "register_operand" "")
5357            (unsigned_float:X87MODEF
5358              (match_operand:SI 1 "nonimmediate_operand" "")))
5359       (clobber (match_dup 2))
5360       (clobber (match_scratch:SI 3 ""))])]
5361   "!TARGET_64BIT
5362    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5363         && TARGET_SSE)
5364        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5365 {
5366   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5367     {
5368       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5369       DONE;
5370     }
5371   else
5372     {
5373       enum ix86_stack_slot slot = (virtuals_instantiated
5374                                    ? SLOT_TEMP
5375                                    : SLOT_VIRTUAL);
5376       operands[2] = assign_386_stack_local (DImode, slot);
5377     }
5378 })
5379
5380 (define_expand "floatunsdisf2"
5381   [(use (match_operand:SF 0 "register_operand" ""))
5382    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5383   "TARGET_64BIT && TARGET_SSE_MATH"
5384   "x86_emit_floatuns (operands); DONE;")
5385
5386 (define_expand "floatunsdidf2"
5387   [(use (match_operand:DF 0 "register_operand" ""))
5388    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5389   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5390    && TARGET_SSE2 && TARGET_SSE_MATH"
5391 {
5392   if (TARGET_64BIT)
5393     x86_emit_floatuns (operands);
5394   else
5395     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5396   DONE;
5397 })
5398 \f
5399 ;; Add instructions
5400
5401 (define_expand "add<mode>3"
5402   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5403         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5404                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5405   ""
5406   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5407
5408 (define_insn_and_split "*add<dwi>3_doubleword"
5409   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5410         (plus:<DWI>
5411           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5412           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5413    (clobber (reg:CC FLAGS_REG))]
5414   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5415   "#"
5416   "reload_completed"
5417   [(parallel [(set (reg:CC FLAGS_REG)
5418                    (unspec:CC [(match_dup 1) (match_dup 2)]
5419                               UNSPEC_ADD_CARRY))
5420               (set (match_dup 0)
5421                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5422    (parallel [(set (match_dup 3)
5423                    (plus:DWIH
5424                      (match_dup 4)
5425                      (plus:DWIH
5426                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5427                        (match_dup 5))))
5428               (clobber (reg:CC FLAGS_REG))])]
5429   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5430
5431 (define_insn "*add<mode>3_cc"
5432   [(set (reg:CC FLAGS_REG)
5433         (unspec:CC
5434           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5435            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5436           UNSPEC_ADD_CARRY))
5437    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5438         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5439   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5440   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5441   [(set_attr "type" "alu")
5442    (set_attr "mode" "<MODE>")])
5443
5444 (define_insn "addqi3_cc"
5445   [(set (reg:CC FLAGS_REG)
5446         (unspec:CC
5447           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5448            (match_operand:QI 2 "general_operand" "qn,qm")]
5449           UNSPEC_ADD_CARRY))
5450    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5451         (plus:QI (match_dup 1) (match_dup 2)))]
5452   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5453   "add{b}\t{%2, %0|%0, %2}"
5454   [(set_attr "type" "alu")
5455    (set_attr "mode" "QI")])
5456
5457 (define_insn "*lea_1"
5458   [(set (match_operand:P 0 "register_operand" "=r")
5459         (match_operand:P 1 "no_seg_address_operand" "p"))]
5460   ""
5461   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5462   [(set_attr "type" "lea")
5463    (set_attr "mode" "<MODE>")])
5464
5465 (define_insn "*lea_2"
5466   [(set (match_operand:SI 0 "register_operand" "=r")
5467         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5468   "TARGET_64BIT"
5469   "lea{l}\t{%a1, %0|%0, %a1}"
5470   [(set_attr "type" "lea")
5471    (set_attr "mode" "SI")])
5472
5473 (define_insn "*lea_2_zext"
5474   [(set (match_operand:DI 0 "register_operand" "=r")
5475         (zero_extend:DI
5476           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5477   "TARGET_64BIT"
5478   "lea{l}\t{%a1, %k0|%k0, %a1}"
5479   [(set_attr "type" "lea")
5480    (set_attr "mode" "SI")])
5481
5482 (define_insn "*add<mode>_1"
5483   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5484         (plus:SWI48
5485           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5486           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5487    (clobber (reg:CC FLAGS_REG))]
5488   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5489 {
5490   switch (get_attr_type (insn))
5491     {
5492     case TYPE_LEA:
5493       return "#";
5494
5495     case TYPE_INCDEC:
5496       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5497       if (operands[2] == const1_rtx)
5498         return "inc{<imodesuffix>}\t%0";
5499       else
5500         {
5501           gcc_assert (operands[2] == constm1_rtx);
5502           return "dec{<imodesuffix>}\t%0";
5503         }
5504
5505     default:
5506       /* For most processors, ADD is faster than LEA.  This alternative
5507          was added to use ADD as much as possible.  */
5508       if (which_alternative == 2)
5509         {
5510           rtx tmp;
5511           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5512         }
5513         
5514       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5516         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5517
5518       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5519     }
5520 }
5521   [(set (attr "type")
5522      (cond [(eq_attr "alternative" "3")
5523               (const_string "lea")
5524             (match_operand:SWI48 2 "incdec_operand" "")
5525               (const_string "incdec")
5526            ]
5527            (const_string "alu")))
5528    (set (attr "length_immediate")
5529       (if_then_else
5530         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5531         (const_string "1")
5532         (const_string "*")))
5533    (set_attr "mode" "<MODE>")])
5534
5535 ;; It may seem that nonimmediate operand is proper one for operand 1.
5536 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5537 ;; we take care in ix86_binary_operator_ok to not allow two memory
5538 ;; operands so proper swapping will be done in reload.  This allow
5539 ;; patterns constructed from addsi_1 to match.
5540
5541 (define_insn "*addsi_1_zext"
5542   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5543         (zero_extend:DI
5544           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5545                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5546    (clobber (reg:CC FLAGS_REG))]
5547   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5548 {
5549   switch (get_attr_type (insn))
5550     {
5551     case TYPE_LEA:
5552       return "#";
5553
5554     case TYPE_INCDEC:
5555       if (operands[2] == const1_rtx)
5556         return "inc{l}\t%k0";
5557       else
5558         {
5559           gcc_assert (operands[2] == constm1_rtx);
5560           return "dec{l}\t%k0";
5561         }
5562
5563     default:
5564       /* For most processors, ADD is faster than LEA.  This alternative
5565          was added to use ADD as much as possible.  */
5566       if (which_alternative == 1)
5567         {
5568           rtx tmp;
5569           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5570         }
5571
5572       if (x86_maybe_negate_const_int (&operands[2], SImode))
5573         return "sub{l}\t{%2, %k0|%k0, %2}";
5574
5575       return "add{l}\t{%2, %k0|%k0, %2}";
5576     }
5577 }
5578   [(set (attr "type")
5579      (cond [(eq_attr "alternative" "2")
5580               (const_string "lea")
5581             (match_operand:SI 2 "incdec_operand" "")
5582               (const_string "incdec")
5583            ]
5584            (const_string "alu")))
5585    (set (attr "length_immediate")
5586       (if_then_else
5587         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5588         (const_string "1")
5589         (const_string "*")))
5590    (set_attr "mode" "SI")])
5591
5592 (define_insn "*addhi_1"
5593   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5594         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5595                  (match_operand:HI 2 "general_operand" "rn,rm")))
5596    (clobber (reg:CC FLAGS_REG))]
5597   "TARGET_PARTIAL_REG_STALL
5598    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5599 {
5600   switch (get_attr_type (insn))
5601     {
5602     case TYPE_INCDEC:
5603       if (operands[2] == const1_rtx)
5604         return "inc{w}\t%0";
5605       else
5606         {
5607           gcc_assert (operands[2] == constm1_rtx);
5608           return "dec{w}\t%0";
5609         }
5610
5611     default:
5612       if (x86_maybe_negate_const_int (&operands[2], HImode))
5613         return "sub{w}\t{%2, %0|%0, %2}";
5614
5615       return "add{w}\t{%2, %0|%0, %2}";
5616     }
5617 }
5618   [(set (attr "type")
5619      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5620         (const_string "incdec")
5621         (const_string "alu")))
5622    (set (attr "length_immediate")
5623       (if_then_else
5624         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5625         (const_string "1")
5626         (const_string "*")))
5627    (set_attr "mode" "HI")])
5628
5629 (define_insn "*addhi_1_lea"
5630   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5631         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5632                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5633    (clobber (reg:CC FLAGS_REG))]
5634   "!TARGET_PARTIAL_REG_STALL
5635    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5636 {
5637   switch (get_attr_type (insn))
5638     {
5639     case TYPE_LEA:
5640       return "#";
5641
5642     case TYPE_INCDEC:
5643       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644       if (operands[2] == const1_rtx)
5645         return "inc{w}\t%0";
5646       else
5647         {
5648           gcc_assert (operands[2] == constm1_rtx);
5649           return "dec{w}\t%0";
5650         }
5651
5652     default:
5653       /* For most processors, ADD is faster than LEA.  This alternative
5654          was added to use ADD as much as possible.  */
5655       if (which_alternative == 2)
5656         {
5657           rtx tmp;
5658           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5659         }
5660
5661       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5662       if (x86_maybe_negate_const_int (&operands[2], HImode))
5663         return "sub{w}\t{%2, %0|%0, %2}";
5664
5665       return "add{w}\t{%2, %0|%0, %2}";
5666     }
5667 }
5668   [(set (attr "type")
5669      (cond [(eq_attr "alternative" "3")
5670               (const_string "lea")
5671             (match_operand:HI 2 "incdec_operand" "")
5672               (const_string "incdec")
5673            ]
5674            (const_string "alu")))
5675    (set (attr "length_immediate")
5676       (if_then_else
5677         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5678         (const_string "1")
5679         (const_string "*")))
5680    (set_attr "mode" "HI,HI,HI,SI")])
5681
5682 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5683 (define_insn "*addqi_1"
5684   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5685         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5686                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5687    (clobber (reg:CC FLAGS_REG))]
5688   "TARGET_PARTIAL_REG_STALL
5689    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5690 {
5691   int widen = (which_alternative == 2);
5692   switch (get_attr_type (insn))
5693     {
5694     case TYPE_INCDEC:
5695       if (operands[2] == const1_rtx)
5696         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5697       else
5698         {
5699           gcc_assert (operands[2] == constm1_rtx);
5700           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5701         }
5702
5703     default:
5704       if (x86_maybe_negate_const_int (&operands[2], QImode))
5705         {
5706           if (widen)
5707             return "sub{l}\t{%2, %k0|%k0, %2}";
5708           else
5709             return "sub{b}\t{%2, %0|%0, %2}";
5710         }
5711       if (widen)
5712         return "add{l}\t{%k2, %k0|%k0, %k2}";
5713       else
5714         return "add{b}\t{%2, %0|%0, %2}";
5715     }
5716 }
5717   [(set (attr "type")
5718      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5719         (const_string "incdec")
5720         (const_string "alu")))
5721    (set (attr "length_immediate")
5722       (if_then_else
5723         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5724         (const_string "1")
5725         (const_string "*")))
5726    (set_attr "mode" "QI,QI,SI")])
5727
5728 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5729 (define_insn "*addqi_1_lea"
5730   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5731         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5732                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5733    (clobber (reg:CC FLAGS_REG))]
5734   "!TARGET_PARTIAL_REG_STALL
5735    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5736 {
5737   int widen = (which_alternative == 3 || which_alternative == 4);
5738
5739   switch (get_attr_type (insn))
5740     {
5741     case TYPE_LEA:
5742       return "#";
5743
5744     case TYPE_INCDEC:
5745       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5746       if (operands[2] == const1_rtx)
5747         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5748       else
5749         {
5750           gcc_assert (operands[2] == constm1_rtx);
5751           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5752         }
5753
5754     default:
5755       /* For most processors, ADD is faster than LEA.  These alternatives
5756          were added to use ADD as much as possible.  */
5757       if (which_alternative == 2 || which_alternative == 4)
5758         {
5759           rtx tmp;
5760           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5761         }
5762
5763       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5764       if (x86_maybe_negate_const_int (&operands[2], QImode))
5765         {
5766           if (widen)
5767             return "sub{l}\t{%2, %k0|%k0, %2}";
5768           else
5769             return "sub{b}\t{%2, %0|%0, %2}";
5770         }
5771       if (widen)
5772         return "add{l}\t{%k2, %k0|%k0, %k2}";
5773       else
5774         return "add{b}\t{%2, %0|%0, %2}";
5775     }
5776 }
5777   [(set (attr "type")
5778      (cond [(eq_attr "alternative" "5")
5779               (const_string "lea")
5780             (match_operand:QI 2 "incdec_operand" "")
5781               (const_string "incdec")
5782            ]
5783            (const_string "alu")))
5784    (set (attr "length_immediate")
5785       (if_then_else
5786         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5787         (const_string "1")
5788         (const_string "*")))
5789    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5790
5791 (define_insn "*addqi_1_slp"
5792   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5793         (plus:QI (match_dup 0)
5794                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5795    (clobber (reg:CC FLAGS_REG))]
5796   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5797    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5798 {
5799   switch (get_attr_type (insn))
5800     {
5801     case TYPE_INCDEC:
5802       if (operands[1] == const1_rtx)
5803         return "inc{b}\t%0";
5804       else
5805         {
5806           gcc_assert (operands[1] == constm1_rtx);
5807           return "dec{b}\t%0";
5808         }
5809
5810     default:
5811       if (x86_maybe_negate_const_int (&operands[1], QImode))
5812         return "sub{b}\t{%1, %0|%0, %1}";
5813
5814       return "add{b}\t{%1, %0|%0, %1}";
5815     }
5816 }
5817   [(set (attr "type")
5818      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5819         (const_string "incdec")
5820         (const_string "alu1")))
5821    (set (attr "memory")
5822      (if_then_else (match_operand 1 "memory_operand" "")
5823         (const_string "load")
5824         (const_string "none")))
5825    (set_attr "mode" "QI")])
5826
5827 ;; Convert lea to the lea pattern to avoid flags dependency.
5828 (define_split
5829   [(set (match_operand 0 "register_operand" "")
5830         (plus (match_operand 1 "register_operand" "")
5831               (match_operand 2 "nonmemory_operand" "")))
5832    (clobber (reg:CC FLAGS_REG))]
5833   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5834   [(const_int 0)]
5835 {
5836   rtx pat;
5837   enum machine_mode mode = GET_MODE (operands[0]);
5838
5839   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5840      may confuse gen_lowpart.  */
5841   if (mode != Pmode)
5842     {
5843       operands[1] = gen_lowpart (Pmode, operands[1]);
5844       operands[2] = gen_lowpart (Pmode, operands[2]);
5845     }
5846
5847   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5848
5849   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5850     operands[0] = gen_lowpart (SImode, operands[0]);
5851
5852   if (TARGET_64BIT && mode != Pmode)
5853     pat = gen_rtx_SUBREG (SImode, pat, 0);
5854
5855   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5856   DONE;
5857 })
5858
5859 ;; Convert lea to the lea pattern to avoid flags dependency.
5860 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5861 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5862 (define_split
5863   [(set (match_operand:DI 0 "register_operand" "")
5864         (plus:DI (match_operand:DI 1 "register_operand" "")
5865                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
5866    (clobber (reg:CC FLAGS_REG))]
5867   "TARGET_64BIT && reload_completed 
5868    && true_regnum (operands[0]) != true_regnum (operands[1])"
5869   [(set (match_dup 0)
5870         (plus:DI (match_dup 1) (match_dup 2)))])
5871
5872 ;; Convert lea to the lea pattern to avoid flags dependency.
5873 (define_split
5874   [(set (match_operand:DI 0 "register_operand" "")
5875         (zero_extend:DI
5876           (plus:SI (match_operand:SI 1 "register_operand" "")
5877                    (match_operand:SI 2 "nonmemory_operand" ""))))
5878    (clobber (reg:CC FLAGS_REG))]
5879   "TARGET_64BIT && reload_completed
5880    && ix86_lea_for_add_ok (insn, operands)"
5881   [(set (match_dup 0)
5882         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5883 {
5884   operands[1] = gen_lowpart (DImode, operands[1]);
5885   operands[2] = gen_lowpart (DImode, operands[2]);
5886 })
5887
5888 (define_insn "*add<mode>_2"
5889   [(set (reg FLAGS_REG)
5890         (compare
5891           (plus:SWI
5892             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5893             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5894           (const_int 0)))
5895    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5896         (plus:SWI (match_dup 1) (match_dup 2)))]
5897   "ix86_match_ccmode (insn, CCGOCmode)
5898    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5899 {
5900   switch (get_attr_type (insn))
5901     {
5902     case TYPE_INCDEC:
5903       if (operands[2] == const1_rtx)
5904         return "inc{<imodesuffix>}\t%0";
5905       else
5906         {
5907           gcc_assert (operands[2] == constm1_rtx);
5908           return "dec{<imodesuffix>}\t%0";
5909         }
5910
5911     default:
5912       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5913         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5914
5915       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5916     }
5917 }
5918   [(set (attr "type")
5919      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5920         (const_string "incdec")
5921         (const_string "alu")))
5922    (set (attr "length_immediate")
5923       (if_then_else
5924         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5925         (const_string "1")
5926         (const_string "*")))
5927    (set_attr "mode" "<MODE>")])
5928
5929 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5930 (define_insn "*addsi_2_zext"
5931   [(set (reg FLAGS_REG)
5932         (compare
5933           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5934                    (match_operand:SI 2 "general_operand" "g"))
5935           (const_int 0)))
5936    (set (match_operand:DI 0 "register_operand" "=r")
5937         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5938   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5939    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5940 {
5941   switch (get_attr_type (insn))
5942     {
5943     case TYPE_INCDEC:
5944       if (operands[2] == const1_rtx)
5945         return "inc{l}\t%k0";
5946       else
5947         {
5948           gcc_assert (operands[2] == constm1_rtx);
5949           return "dec{l}\t%k0";
5950         }
5951
5952     default:
5953       if (x86_maybe_negate_const_int (&operands[2], SImode))
5954         return "sub{l}\t{%2, %k0|%k0, %2}";
5955
5956       return "add{l}\t{%2, %k0|%k0, %2}";
5957     }
5958 }
5959   [(set (attr "type")
5960      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5961         (const_string "incdec")
5962         (const_string "alu")))
5963    (set (attr "length_immediate")
5964       (if_then_else
5965         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5966         (const_string "1")
5967         (const_string "*")))
5968    (set_attr "mode" "SI")])
5969
5970 (define_insn "*add<mode>_3"
5971   [(set (reg FLAGS_REG)
5972         (compare
5973           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5974           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5975    (clobber (match_scratch:SWI 0 "=<r>"))]
5976   "ix86_match_ccmode (insn, CCZmode)
5977    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5978 {
5979   switch (get_attr_type (insn))
5980     {
5981     case TYPE_INCDEC:
5982       if (operands[2] == const1_rtx)
5983         return "inc{<imodesuffix>}\t%0";
5984       else
5985         {
5986           gcc_assert (operands[2] == constm1_rtx);
5987           return "dec{<imodesuffix>}\t%0";
5988         }
5989
5990     default:
5991       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5992         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5993
5994       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5995     }
5996 }
5997   [(set (attr "type")
5998      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5999         (const_string "incdec")
6000         (const_string "alu")))
6001    (set (attr "length_immediate")
6002       (if_then_else
6003         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6004         (const_string "1")
6005         (const_string "*")))
6006    (set_attr "mode" "<MODE>")])
6007
6008 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6009 (define_insn "*addsi_3_zext"
6010   [(set (reg FLAGS_REG)
6011         (compare
6012           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6013           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6014    (set (match_operand:DI 0 "register_operand" "=r")
6015         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6016   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6017    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6018 {
6019   switch (get_attr_type (insn))
6020     {
6021     case TYPE_INCDEC:
6022       if (operands[2] == const1_rtx)
6023         return "inc{l}\t%k0";
6024       else
6025         {
6026           gcc_assert (operands[2] == constm1_rtx);
6027           return "dec{l}\t%k0";
6028         }
6029
6030     default:
6031       if (x86_maybe_negate_const_int (&operands[2], SImode))
6032         return "sub{l}\t{%2, %k0|%k0, %2}";
6033
6034       return "add{l}\t{%2, %k0|%k0, %2}";
6035     }
6036 }
6037   [(set (attr "type")
6038      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6039         (const_string "incdec")
6040         (const_string "alu")))
6041    (set (attr "length_immediate")
6042       (if_then_else
6043         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6044         (const_string "1")
6045         (const_string "*")))
6046    (set_attr "mode" "SI")])
6047
6048 ; For comparisons against 1, -1 and 128, we may generate better code
6049 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6050 ; is matched then.  We can't accept general immediate, because for
6051 ; case of overflows,  the result is messed up.
6052 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6053 ; only for comparisons not depending on it.
6054
6055 (define_insn "*adddi_4"
6056   [(set (reg FLAGS_REG)
6057         (compare
6058           (match_operand:DI 1 "nonimmediate_operand" "0")
6059           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6060    (clobber (match_scratch:DI 0 "=rm"))]
6061   "TARGET_64BIT
6062    && ix86_match_ccmode (insn, CCGCmode)"
6063 {
6064   switch (get_attr_type (insn))
6065     {
6066     case TYPE_INCDEC:
6067       if (operands[2] == constm1_rtx)
6068         return "inc{q}\t%0";
6069       else
6070         {
6071           gcc_assert (operands[2] == const1_rtx);
6072           return "dec{q}\t%0";
6073         }
6074
6075     default:
6076       if (x86_maybe_negate_const_int (&operands[2], DImode))
6077         return "add{q}\t{%2, %0|%0, %2}";
6078
6079       return "sub{q}\t{%2, %0|%0, %2}";
6080     }
6081 }
6082   [(set (attr "type")
6083      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6084         (const_string "incdec")
6085         (const_string "alu")))
6086    (set (attr "length_immediate")
6087       (if_then_else
6088         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6089         (const_string "1")
6090         (const_string "*")))
6091    (set_attr "mode" "DI")])
6092
6093 ; For comparisons against 1, -1 and 128, we may generate better code
6094 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6095 ; is matched then.  We can't accept general immediate, because for
6096 ; case of overflows,  the result is messed up.
6097 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6098 ; only for comparisons not depending on it.
6099
6100 (define_insn "*add<mode>_4"
6101   [(set (reg FLAGS_REG)
6102         (compare
6103           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6104           (match_operand:SWI124 2 "const_int_operand" "n")))
6105    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6106   "ix86_match_ccmode (insn, CCGCmode)"
6107 {
6108   switch (get_attr_type (insn))
6109     {
6110     case TYPE_INCDEC:
6111       if (operands[2] == constm1_rtx)
6112         return "inc{<imodesuffix>}\t%0";
6113       else
6114         {
6115           gcc_assert (operands[2] == const1_rtx);
6116           return "dec{<imodesuffix>}\t%0";
6117         }
6118
6119     default:
6120       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6121         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6122
6123       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6124     }
6125 }
6126   [(set (attr "type")
6127      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6128         (const_string "incdec")
6129         (const_string "alu")))
6130    (set (attr "length_immediate")
6131       (if_then_else
6132         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6133         (const_string "1")
6134         (const_string "*")))
6135    (set_attr "mode" "<MODE>")])
6136
6137 (define_insn "*add<mode>_5"
6138   [(set (reg FLAGS_REG)
6139         (compare
6140           (plus:SWI
6141             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6142             (match_operand:SWI 2 "<general_operand>" "<g>"))
6143           (const_int 0)))
6144    (clobber (match_scratch:SWI 0 "=<r>"))]
6145   "ix86_match_ccmode (insn, CCGOCmode)
6146    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6147 {
6148   switch (get_attr_type (insn))
6149     {
6150     case TYPE_INCDEC:
6151       if (operands[2] == const1_rtx)
6152         return "inc{<imodesuffix>}\t%0";
6153       else
6154         {
6155           gcc_assert (operands[2] == constm1_rtx);
6156           return "dec{<imodesuffix>}\t%0";
6157         }
6158
6159     default:
6160       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6161         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6162
6163       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6164     }
6165 }
6166   [(set (attr "type")
6167      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6168         (const_string "incdec")
6169         (const_string "alu")))
6170    (set (attr "length_immediate")
6171       (if_then_else
6172         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6173         (const_string "1")
6174         (const_string "*")))
6175    (set_attr "mode" "<MODE>")])
6176
6177 (define_insn "*addqi_ext_1_rex64"
6178   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6179                          (const_int 8)
6180                          (const_int 8))
6181         (plus:SI
6182           (zero_extract:SI
6183             (match_operand 1 "ext_register_operand" "0")
6184             (const_int 8)
6185             (const_int 8))
6186           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6187    (clobber (reg:CC FLAGS_REG))]
6188   "TARGET_64BIT"
6189 {
6190   switch (get_attr_type (insn))
6191     {
6192     case TYPE_INCDEC:
6193       if (operands[2] == const1_rtx)
6194         return "inc{b}\t%h0";
6195       else
6196         {
6197           gcc_assert (operands[2] == constm1_rtx);
6198           return "dec{b}\t%h0";
6199         }
6200
6201     default:
6202       return "add{b}\t{%2, %h0|%h0, %2}";
6203     }
6204 }
6205   [(set (attr "type")
6206      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6207         (const_string "incdec")
6208         (const_string "alu")))
6209    (set_attr "modrm" "1")
6210    (set_attr "mode" "QI")])
6211
6212 (define_insn "addqi_ext_1"
6213   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6214                          (const_int 8)
6215                          (const_int 8))
6216         (plus:SI
6217           (zero_extract:SI
6218             (match_operand 1 "ext_register_operand" "0")
6219             (const_int 8)
6220             (const_int 8))
6221           (match_operand:QI 2 "general_operand" "Qmn")))
6222    (clobber (reg:CC FLAGS_REG))]
6223   "!TARGET_64BIT"
6224 {
6225   switch (get_attr_type (insn))
6226     {
6227     case TYPE_INCDEC:
6228       if (operands[2] == const1_rtx)
6229         return "inc{b}\t%h0";
6230       else
6231         {
6232           gcc_assert (operands[2] == constm1_rtx);
6233           return "dec{b}\t%h0";
6234         }
6235
6236     default:
6237       return "add{b}\t{%2, %h0|%h0, %2}";
6238     }
6239 }
6240   [(set (attr "type")
6241      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6242         (const_string "incdec")
6243         (const_string "alu")))
6244    (set_attr "modrm" "1")
6245    (set_attr "mode" "QI")])
6246
6247 (define_insn "*addqi_ext_2"
6248   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6249                          (const_int 8)
6250                          (const_int 8))
6251         (plus:SI
6252           (zero_extract:SI
6253             (match_operand 1 "ext_register_operand" "%0")
6254             (const_int 8)
6255             (const_int 8))
6256           (zero_extract:SI
6257             (match_operand 2 "ext_register_operand" "Q")
6258             (const_int 8)
6259             (const_int 8))))
6260    (clobber (reg:CC FLAGS_REG))]
6261   ""
6262   "add{b}\t{%h2, %h0|%h0, %h2}"
6263   [(set_attr "type" "alu")
6264    (set_attr "mode" "QI")])
6265
6266 ;; The lea patterns for non-Pmodes needs to be matched by
6267 ;; several insns converted to real lea by splitters.
6268
6269 (define_insn_and_split "*lea_general_1"
6270   [(set (match_operand 0 "register_operand" "=r")
6271         (plus (plus (match_operand 1 "index_register_operand" "l")
6272                     (match_operand 2 "register_operand" "r"))
6273               (match_operand 3 "immediate_operand" "i")))]
6274   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6275     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6276    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6277    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6278    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6279    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6280        || GET_MODE (operands[3]) == VOIDmode)"
6281   "#"
6282   "&& reload_completed"
6283   [(const_int 0)]
6284 {
6285   rtx pat;
6286   operands[0] = gen_lowpart (SImode, operands[0]);
6287   operands[1] = gen_lowpart (Pmode, operands[1]);
6288   operands[2] = gen_lowpart (Pmode, operands[2]);
6289   operands[3] = gen_lowpart (Pmode, operands[3]);
6290   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6291                       operands[3]);
6292   if (Pmode != SImode)
6293     pat = gen_rtx_SUBREG (SImode, pat, 0);
6294   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6295   DONE;
6296 }
6297   [(set_attr "type" "lea")
6298    (set_attr "mode" "SI")])
6299
6300 (define_insn_and_split "*lea_general_1_zext"
6301   [(set (match_operand:DI 0 "register_operand" "=r")
6302         (zero_extend:DI
6303           (plus:SI (plus:SI
6304                      (match_operand:SI 1 "index_register_operand" "l")
6305                      (match_operand:SI 2 "register_operand" "r"))
6306                    (match_operand:SI 3 "immediate_operand" "i"))))]
6307   "TARGET_64BIT"
6308   "#"
6309   "&& reload_completed"
6310   [(set (match_dup 0)
6311         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6312                                                      (match_dup 2))
6313                                             (match_dup 3)) 0)))]
6314 {
6315   operands[1] = gen_lowpart (Pmode, operands[1]);
6316   operands[2] = gen_lowpart (Pmode, operands[2]);
6317   operands[3] = gen_lowpart (Pmode, operands[3]);
6318 }
6319   [(set_attr "type" "lea")
6320    (set_attr "mode" "SI")])
6321
6322 (define_insn_and_split "*lea_general_2"
6323   [(set (match_operand 0 "register_operand" "=r")
6324         (plus (mult (match_operand 1 "index_register_operand" "l")
6325                     (match_operand 2 "const248_operand" "i"))
6326               (match_operand 3 "nonmemory_operand" "ri")))]
6327   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6328     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6329    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6330    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6331    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6332        || GET_MODE (operands[3]) == VOIDmode)"
6333   "#"
6334   "&& reload_completed"
6335   [(const_int 0)]
6336 {
6337   rtx pat;
6338   operands[0] = gen_lowpart (SImode, operands[0]);
6339   operands[1] = gen_lowpart (Pmode, operands[1]);
6340   operands[3] = gen_lowpart (Pmode, operands[3]);
6341   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6342                       operands[3]);
6343   if (Pmode != SImode)
6344     pat = gen_rtx_SUBREG (SImode, pat, 0);
6345   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6346   DONE;
6347 }
6348   [(set_attr "type" "lea")
6349    (set_attr "mode" "SI")])
6350
6351 (define_insn_and_split "*lea_general_2_zext"
6352   [(set (match_operand:DI 0 "register_operand" "=r")
6353         (zero_extend:DI
6354           (plus:SI (mult:SI
6355                      (match_operand:SI 1 "index_register_operand" "l")
6356                      (match_operand:SI 2 "const248_operand" "n"))
6357                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6358   "TARGET_64BIT"
6359   "#"
6360   "&& reload_completed"
6361   [(set (match_dup 0)
6362         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6363                                                      (match_dup 2))
6364                                             (match_dup 3)) 0)))]
6365 {
6366   operands[1] = gen_lowpart (Pmode, operands[1]);
6367   operands[3] = gen_lowpart (Pmode, operands[3]);
6368 }
6369   [(set_attr "type" "lea")
6370    (set_attr "mode" "SI")])
6371
6372 (define_insn_and_split "*lea_general_3"
6373   [(set (match_operand 0 "register_operand" "=r")
6374         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6375                           (match_operand 2 "const248_operand" "i"))
6376                     (match_operand 3 "register_operand" "r"))
6377               (match_operand 4 "immediate_operand" "i")))]
6378   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6379     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6380    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6381    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6382    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6383   "#"
6384   "&& reload_completed"
6385   [(const_int 0)]
6386 {
6387   rtx pat;
6388   operands[0] = gen_lowpart (SImode, operands[0]);
6389   operands[1] = gen_lowpart (Pmode, operands[1]);
6390   operands[3] = gen_lowpart (Pmode, operands[3]);
6391   operands[4] = gen_lowpart (Pmode, operands[4]);
6392   pat = gen_rtx_PLUS (Pmode,
6393                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6394                                                          operands[2]),
6395                                     operands[3]),
6396                       operands[4]);
6397   if (Pmode != SImode)
6398     pat = gen_rtx_SUBREG (SImode, pat, 0);
6399   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6400   DONE;
6401 }
6402   [(set_attr "type" "lea")
6403    (set_attr "mode" "SI")])
6404
6405 (define_insn_and_split "*lea_general_3_zext"
6406   [(set (match_operand:DI 0 "register_operand" "=r")
6407         (zero_extend:DI
6408           (plus:SI (plus:SI
6409                      (mult:SI
6410                        (match_operand:SI 1 "index_register_operand" "l")
6411                        (match_operand:SI 2 "const248_operand" "n"))
6412                      (match_operand:SI 3 "register_operand" "r"))
6413                    (match_operand:SI 4 "immediate_operand" "i"))))]
6414   "TARGET_64BIT"
6415   "#"
6416   "&& reload_completed"
6417   [(set (match_dup 0)
6418         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6419                                                               (match_dup 2))
6420                                                      (match_dup 3))
6421                                             (match_dup 4)) 0)))]
6422 {
6423   operands[1] = gen_lowpart (Pmode, operands[1]);
6424   operands[3] = gen_lowpart (Pmode, operands[3]);
6425   operands[4] = gen_lowpart (Pmode, operands[4]);
6426 }
6427   [(set_attr "type" "lea")
6428    (set_attr "mode" "SI")])
6429 \f
6430 ;; Subtract instructions
6431
6432 (define_expand "sub<mode>3"
6433   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6434         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6435                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6436   ""
6437   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6438
6439 (define_insn_and_split "*sub<dwi>3_doubleword"
6440   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6441         (minus:<DWI>
6442           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6443           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6444    (clobber (reg:CC FLAGS_REG))]
6445   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6446   "#"
6447   "reload_completed"
6448   [(parallel [(set (reg:CC FLAGS_REG)
6449                    (compare:CC (match_dup 1) (match_dup 2)))
6450               (set (match_dup 0)
6451                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6452    (parallel [(set (match_dup 3)
6453                    (minus:DWIH
6454                      (match_dup 4)
6455                      (plus:DWIH
6456                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6457                        (match_dup 5))))
6458               (clobber (reg:CC FLAGS_REG))])]
6459   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6460
6461 (define_insn "*sub<mode>_1"
6462   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6463         (minus:SWI
6464           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6465           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6466    (clobber (reg:CC FLAGS_REG))]
6467   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6468   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6469   [(set_attr "type" "alu")
6470    (set_attr "mode" "<MODE>")])
6471
6472 (define_insn "*subsi_1_zext"
6473   [(set (match_operand:DI 0 "register_operand" "=r")
6474         (zero_extend:DI
6475           (minus:SI (match_operand:SI 1 "register_operand" "0")
6476                     (match_operand:SI 2 "general_operand" "g"))))
6477    (clobber (reg:CC FLAGS_REG))]
6478   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6479   "sub{l}\t{%2, %k0|%k0, %2}"
6480   [(set_attr "type" "alu")
6481    (set_attr "mode" "SI")])
6482
6483 (define_insn "*subqi_1_slp"
6484   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6485         (minus:QI (match_dup 0)
6486                   (match_operand:QI 1 "general_operand" "qn,qm")))
6487    (clobber (reg:CC FLAGS_REG))]
6488   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6489    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6490   "sub{b}\t{%1, %0|%0, %1}"
6491   [(set_attr "type" "alu1")
6492    (set_attr "mode" "QI")])
6493
6494 (define_insn "*sub<mode>_2"
6495   [(set (reg FLAGS_REG)
6496         (compare
6497           (minus:SWI
6498             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6499             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6500           (const_int 0)))
6501    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6502         (minus:SWI (match_dup 1) (match_dup 2)))]
6503   "ix86_match_ccmode (insn, CCGOCmode)
6504    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6505   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6506   [(set_attr "type" "alu")
6507    (set_attr "mode" "<MODE>")])
6508
6509 (define_insn "*subsi_2_zext"
6510   [(set (reg FLAGS_REG)
6511         (compare
6512           (minus:SI (match_operand:SI 1 "register_operand" "0")
6513                     (match_operand:SI 2 "general_operand" "g"))
6514           (const_int 0)))
6515    (set (match_operand:DI 0 "register_operand" "=r")
6516         (zero_extend:DI
6517           (minus:SI (match_dup 1)
6518                     (match_dup 2))))]
6519   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6520    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6521   "sub{l}\t{%2, %k0|%k0, %2}"
6522   [(set_attr "type" "alu")
6523    (set_attr "mode" "SI")])
6524
6525 (define_insn "*sub<mode>_3"
6526   [(set (reg FLAGS_REG)
6527         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6528                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6529    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6530         (minus:SWI (match_dup 1) (match_dup 2)))]
6531   "ix86_match_ccmode (insn, CCmode)
6532    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6533   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6534   [(set_attr "type" "alu")
6535    (set_attr "mode" "<MODE>")])
6536
6537 (define_insn "*subsi_3_zext"
6538   [(set (reg FLAGS_REG)
6539         (compare (match_operand:SI 1 "register_operand" "0")
6540                  (match_operand:SI 2 "general_operand" "g")))
6541    (set (match_operand:DI 0 "register_operand" "=r")
6542         (zero_extend:DI
6543           (minus:SI (match_dup 1)
6544                     (match_dup 2))))]
6545   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6546    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6547   "sub{l}\t{%2, %1|%1, %2}"
6548   [(set_attr "type" "alu")
6549    (set_attr "mode" "SI")])
6550 \f
6551 ;; Add with carry and subtract with borrow
6552
6553 (define_expand "<plusminus_insn><mode>3_carry"
6554   [(parallel
6555     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6556           (plusminus:SWI
6557             (match_operand:SWI 1 "nonimmediate_operand" "")
6558             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6559                        [(match_operand 3 "flags_reg_operand" "")
6560                         (const_int 0)])
6561                       (match_operand:SWI 2 "<general_operand>" ""))))
6562      (clobber (reg:CC FLAGS_REG))])]
6563   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6564
6565 (define_insn "*<plusminus_insn><mode>3_carry"
6566   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6567         (plusminus:SWI
6568           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6569           (plus:SWI
6570             (match_operator 3 "ix86_carry_flag_operator"
6571              [(reg FLAGS_REG) (const_int 0)])
6572             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6573    (clobber (reg:CC FLAGS_REG))]
6574   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6575   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6576   [(set_attr "type" "alu")
6577    (set_attr "use_carry" "1")
6578    (set_attr "pent_pair" "pu")
6579    (set_attr "mode" "<MODE>")])
6580
6581 (define_insn "*addsi3_carry_zext"
6582   [(set (match_operand:DI 0 "register_operand" "=r")
6583         (zero_extend:DI
6584           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6585                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6586                              [(reg FLAGS_REG) (const_int 0)])
6587                             (match_operand:SI 2 "general_operand" "g")))))
6588    (clobber (reg:CC FLAGS_REG))]
6589   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6590   "adc{l}\t{%2, %k0|%k0, %2}"
6591   [(set_attr "type" "alu")
6592    (set_attr "use_carry" "1")
6593    (set_attr "pent_pair" "pu")
6594    (set_attr "mode" "SI")])
6595
6596 (define_insn "*subsi3_carry_zext"
6597   [(set (match_operand:DI 0 "register_operand" "=r")
6598         (zero_extend:DI
6599           (minus:SI (match_operand:SI 1 "register_operand" "0")
6600                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6601                               [(reg FLAGS_REG) (const_int 0)])
6602                              (match_operand:SI 2 "general_operand" "g")))))
6603    (clobber (reg:CC FLAGS_REG))]
6604   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6605   "sbb{l}\t{%2, %k0|%k0, %2}"
6606   [(set_attr "type" "alu")
6607    (set_attr "pent_pair" "pu")
6608    (set_attr "mode" "SI")])
6609 \f
6610 ;; Overflow setting add and subtract instructions
6611
6612 (define_insn "*add<mode>3_cconly_overflow"
6613   [(set (reg:CCC FLAGS_REG)
6614         (compare:CCC
6615           (plus:SWI
6616             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6617             (match_operand:SWI 2 "<general_operand>" "<g>"))
6618           (match_dup 1)))
6619    (clobber (match_scratch:SWI 0 "=<r>"))]
6620   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6621   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6622   [(set_attr "type" "alu")
6623    (set_attr "mode" "<MODE>")])
6624
6625 (define_insn "*sub<mode>3_cconly_overflow"
6626   [(set (reg:CCC FLAGS_REG)
6627         (compare:CCC
6628           (minus:SWI
6629             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6630             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6631           (match_dup 0)))]
6632   ""
6633   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6634   [(set_attr "type" "icmp")
6635    (set_attr "mode" "<MODE>")])
6636
6637 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6638   [(set (reg:CCC FLAGS_REG)
6639         (compare:CCC
6640             (plusminus:SWI
6641                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6642                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6643             (match_dup 1)))
6644    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6645         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6646   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6647   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6648   [(set_attr "type" "alu")
6649    (set_attr "mode" "<MODE>")])
6650
6651 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6652   [(set (reg:CCC FLAGS_REG)
6653         (compare:CCC
6654           (plusminus:SI
6655             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6656             (match_operand:SI 2 "general_operand" "g"))
6657           (match_dup 1)))
6658    (set (match_operand:DI 0 "register_operand" "=r")
6659         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6660   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6661   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6662   [(set_attr "type" "alu")
6663    (set_attr "mode" "SI")])
6664
6665 ;; The patterns that match these are at the end of this file.
6666
6667 (define_expand "<plusminus_insn>xf3"
6668   [(set (match_operand:XF 0 "register_operand" "")
6669         (plusminus:XF
6670           (match_operand:XF 1 "register_operand" "")
6671           (match_operand:XF 2 "register_operand" "")))]
6672   "TARGET_80387")
6673
6674 (define_expand "<plusminus_insn><mode>3"
6675   [(set (match_operand:MODEF 0 "register_operand" "")
6676         (plusminus:MODEF
6677           (match_operand:MODEF 1 "register_operand" "")
6678           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6679   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6680     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6681 \f
6682 ;; Multiply instructions
6683
6684 (define_expand "mul<mode>3"
6685   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6686                    (mult:SWIM248
6687                      (match_operand:SWIM248 1 "register_operand" "")
6688                      (match_operand:SWIM248 2 "<general_operand>" "")))
6689               (clobber (reg:CC FLAGS_REG))])])
6690
6691 (define_expand "mulqi3"
6692   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6693                    (mult:QI
6694                      (match_operand:QI 1 "register_operand" "")
6695                      (match_operand:QI 2 "nonimmediate_operand" "")))
6696               (clobber (reg:CC FLAGS_REG))])]
6697   "TARGET_QIMODE_MATH")
6698
6699 ;; On AMDFAM10
6700 ;; IMUL reg32/64, reg32/64, imm8        Direct
6701 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6702 ;; IMUL reg32/64, reg32/64, imm32       Direct
6703 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6704 ;; IMUL reg32/64, reg32/64              Direct
6705 ;; IMUL reg32/64, mem32/64              Direct
6706 ;;
6707 ;; On BDVER1, all above IMULs use DirectPath
6708
6709 (define_insn "*mul<mode>3_1"
6710   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6711         (mult:SWI48
6712           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6713           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6714    (clobber (reg:CC FLAGS_REG))]
6715   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6716   "@
6717    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6718    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6719    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6720   [(set_attr "type" "imul")
6721    (set_attr "prefix_0f" "0,0,1")
6722    (set (attr "athlon_decode")
6723         (cond [(eq_attr "cpu" "athlon")
6724                   (const_string "vector")
6725                (eq_attr "alternative" "1")
6726                   (const_string "vector")
6727                (and (eq_attr "alternative" "2")
6728                     (match_operand 1 "memory_operand" ""))
6729                   (const_string "vector")]
6730               (const_string "direct")))
6731    (set (attr "amdfam10_decode")
6732         (cond [(and (eq_attr "alternative" "0,1")
6733                     (match_operand 1 "memory_operand" ""))
6734                   (const_string "vector")]
6735               (const_string "direct")))
6736    (set_attr "bdver1_decode" "direct")
6737    (set_attr "mode" "<MODE>")])
6738
6739 (define_insn "*mulsi3_1_zext"
6740   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6741         (zero_extend:DI
6742           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6743                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6744    (clobber (reg:CC FLAGS_REG))]
6745   "TARGET_64BIT
6746    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6747   "@
6748    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6749    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6750    imul{l}\t{%2, %k0|%k0, %2}"
6751   [(set_attr "type" "imul")
6752    (set_attr "prefix_0f" "0,0,1")
6753    (set (attr "athlon_decode")
6754         (cond [(eq_attr "cpu" "athlon")
6755                   (const_string "vector")
6756                (eq_attr "alternative" "1")
6757                   (const_string "vector")
6758                (and (eq_attr "alternative" "2")
6759                     (match_operand 1 "memory_operand" ""))
6760                   (const_string "vector")]
6761               (const_string "direct")))
6762    (set (attr "amdfam10_decode")
6763         (cond [(and (eq_attr "alternative" "0,1")
6764                     (match_operand 1 "memory_operand" ""))
6765                   (const_string "vector")]
6766               (const_string "direct")))
6767    (set_attr "bdver1_decode" "direct")
6768    (set_attr "mode" "SI")])
6769
6770 ;; On AMDFAM10
6771 ;; IMUL reg16, reg16, imm8      VectorPath
6772 ;; IMUL reg16, mem16, imm8      VectorPath
6773 ;; IMUL reg16, reg16, imm16     VectorPath
6774 ;; IMUL reg16, mem16, imm16     VectorPath
6775 ;; IMUL reg16, reg16            Direct
6776 ;; IMUL reg16, mem16            Direct
6777 ;;
6778 ;; On BDVER1, all HI MULs use DoublePath
6779
6780 (define_insn "*mulhi3_1"
6781   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6782         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6783                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6784    (clobber (reg:CC FLAGS_REG))]
6785   "TARGET_HIMODE_MATH
6786    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6787   "@
6788    imul{w}\t{%2, %1, %0|%0, %1, %2}
6789    imul{w}\t{%2, %1, %0|%0, %1, %2}
6790    imul{w}\t{%2, %0|%0, %2}"
6791   [(set_attr "type" "imul")
6792    (set_attr "prefix_0f" "0,0,1")
6793    (set (attr "athlon_decode")
6794         (cond [(eq_attr "cpu" "athlon")
6795                   (const_string "vector")
6796                (eq_attr "alternative" "1,2")
6797                   (const_string "vector")]
6798               (const_string "direct")))
6799    (set (attr "amdfam10_decode")
6800         (cond [(eq_attr "alternative" "0,1")
6801                   (const_string "vector")]
6802               (const_string "direct")))
6803    (set_attr "bdver1_decode" "double")
6804    (set_attr "mode" "HI")])
6805
6806 ;;On AMDFAM10 and BDVER1
6807 ;; MUL reg8     Direct
6808 ;; MUL mem8     Direct
6809
6810 (define_insn "*mulqi3_1"
6811   [(set (match_operand:QI 0 "register_operand" "=a")
6812         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6813                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6814    (clobber (reg:CC FLAGS_REG))]
6815   "TARGET_QIMODE_MATH
6816    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6817   "mul{b}\t%2"
6818   [(set_attr "type" "imul")
6819    (set_attr "length_immediate" "0")
6820    (set (attr "athlon_decode")
6821      (if_then_else (eq_attr "cpu" "athlon")
6822         (const_string "vector")
6823         (const_string "direct")))
6824    (set_attr "amdfam10_decode" "direct")
6825    (set_attr "bdver1_decode" "direct")
6826    (set_attr "mode" "QI")])
6827
6828 (define_expand "<u>mul<mode><dwi>3"
6829   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6830                    (mult:<DWI>
6831                      (any_extend:<DWI>
6832                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6833                      (any_extend:<DWI>
6834                        (match_operand:DWIH 2 "register_operand" ""))))
6835               (clobber (reg:CC FLAGS_REG))])])
6836
6837 (define_expand "<u>mulqihi3"
6838   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6839                    (mult:HI
6840                      (any_extend:HI
6841                        (match_operand:QI 1 "nonimmediate_operand" ""))
6842                      (any_extend:HI
6843                        (match_operand:QI 2 "register_operand" ""))))
6844               (clobber (reg:CC FLAGS_REG))])]
6845   "TARGET_QIMODE_MATH")
6846
6847 (define_insn "*<u>mul<mode><dwi>3_1"
6848   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6849         (mult:<DWI>
6850           (any_extend:<DWI>
6851             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6852           (any_extend:<DWI>
6853             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6854    (clobber (reg:CC FLAGS_REG))]
6855   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856   "<sgnprefix>mul{<imodesuffix>}\t%2"
6857   [(set_attr "type" "imul")
6858    (set_attr "length_immediate" "0")
6859    (set (attr "athlon_decode")
6860      (if_then_else (eq_attr "cpu" "athlon")
6861         (const_string "vector")
6862         (const_string "double")))
6863    (set_attr "amdfam10_decode" "double")
6864    (set_attr "bdver1_decode" "direct")
6865    (set_attr "mode" "<MODE>")])
6866
6867 (define_insn "*<u>mulqihi3_1"
6868   [(set (match_operand:HI 0 "register_operand" "=a")
6869         (mult:HI
6870           (any_extend:HI
6871             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6872           (any_extend:HI
6873             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6874    (clobber (reg:CC FLAGS_REG))]
6875   "TARGET_QIMODE_MATH
6876    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6877   "<sgnprefix>mul{b}\t%2"
6878   [(set_attr "type" "imul")
6879    (set_attr "length_immediate" "0")
6880    (set (attr "athlon_decode")
6881      (if_then_else (eq_attr "cpu" "athlon")
6882         (const_string "vector")
6883         (const_string "direct")))
6884    (set_attr "amdfam10_decode" "direct")
6885    (set_attr "bdver1_decode" "direct")
6886    (set_attr "mode" "QI")])
6887
6888 (define_expand "<s>mul<mode>3_highpart"
6889   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6890                    (truncate:SWI48
6891                      (lshiftrt:<DWI>
6892                        (mult:<DWI>
6893                          (any_extend:<DWI>
6894                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6895                          (any_extend:<DWI>
6896                            (match_operand:SWI48 2 "register_operand" "")))
6897                        (match_dup 4))))
6898               (clobber (match_scratch:SWI48 3 ""))
6899               (clobber (reg:CC FLAGS_REG))])]
6900   ""
6901   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6902
6903 (define_insn "*<s>muldi3_highpart_1"
6904   [(set (match_operand:DI 0 "register_operand" "=d")
6905         (truncate:DI
6906           (lshiftrt:TI
6907             (mult:TI
6908               (any_extend:TI
6909                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6910               (any_extend:TI
6911                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6912             (const_int 64))))
6913    (clobber (match_scratch:DI 3 "=1"))
6914    (clobber (reg:CC FLAGS_REG))]
6915   "TARGET_64BIT
6916    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6917   "<sgnprefix>mul{q}\t%2"
6918   [(set_attr "type" "imul")
6919    (set_attr "length_immediate" "0")
6920    (set (attr "athlon_decode")
6921      (if_then_else (eq_attr "cpu" "athlon")
6922         (const_string "vector")
6923         (const_string "double")))
6924    (set_attr "amdfam10_decode" "double")
6925    (set_attr "bdver1_decode" "direct")
6926    (set_attr "mode" "DI")])
6927
6928 (define_insn "*<s>mulsi3_highpart_1"
6929   [(set (match_operand:SI 0 "register_operand" "=d")
6930         (truncate:SI
6931           (lshiftrt:DI
6932             (mult:DI
6933               (any_extend:DI
6934                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6935               (any_extend:DI
6936                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6937             (const_int 32))))
6938    (clobber (match_scratch:SI 3 "=1"))
6939    (clobber (reg:CC FLAGS_REG))]
6940   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6941   "<sgnprefix>mul{l}\t%2"
6942   [(set_attr "type" "imul")
6943    (set_attr "length_immediate" "0")
6944    (set (attr "athlon_decode")
6945      (if_then_else (eq_attr "cpu" "athlon")
6946         (const_string "vector")
6947         (const_string "double")))
6948    (set_attr "amdfam10_decode" "double")
6949    (set_attr "bdver1_decode" "direct")
6950    (set_attr "mode" "SI")])
6951
6952 (define_insn "*<s>mulsi3_highpart_zext"
6953   [(set (match_operand:DI 0 "register_operand" "=d")
6954         (zero_extend:DI (truncate:SI
6955           (lshiftrt:DI
6956             (mult:DI (any_extend:DI
6957                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6958                      (any_extend:DI
6959                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6960             (const_int 32)))))
6961    (clobber (match_scratch:SI 3 "=1"))
6962    (clobber (reg:CC FLAGS_REG))]
6963   "TARGET_64BIT
6964    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6965   "<sgnprefix>mul{l}\t%2"
6966   [(set_attr "type" "imul")
6967    (set_attr "length_immediate" "0")
6968    (set (attr "athlon_decode")
6969      (if_then_else (eq_attr "cpu" "athlon")
6970         (const_string "vector")
6971         (const_string "double")))
6972    (set_attr "amdfam10_decode" "double")
6973    (set_attr "bdver1_decode" "direct")
6974    (set_attr "mode" "SI")])
6975
6976 ;; The patterns that match these are at the end of this file.
6977
6978 (define_expand "mulxf3"
6979   [(set (match_operand:XF 0 "register_operand" "")
6980         (mult:XF (match_operand:XF 1 "register_operand" "")
6981                  (match_operand:XF 2 "register_operand" "")))]
6982   "TARGET_80387")
6983
6984 (define_expand "mul<mode>3"
6985   [(set (match_operand:MODEF 0 "register_operand" "")
6986         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6987                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6988   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6989     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6990 \f
6991 ;; Divide instructions
6992
6993 ;; The patterns that match these are at the end of this file.
6994
6995 (define_expand "divxf3"
6996   [(set (match_operand:XF 0 "register_operand" "")
6997         (div:XF (match_operand:XF 1 "register_operand" "")
6998                 (match_operand:XF 2 "register_operand" "")))]
6999   "TARGET_80387")
7000
7001 (define_expand "divdf3"
7002   [(set (match_operand:DF 0 "register_operand" "")
7003         (div:DF (match_operand:DF 1 "register_operand" "")
7004                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7005    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7006     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7007
7008 (define_expand "divsf3"
7009   [(set (match_operand:SF 0 "register_operand" "")
7010         (div:SF (match_operand:SF 1 "register_operand" "")
7011                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7012   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7013     || TARGET_SSE_MATH"
7014 {
7015   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7016       && flag_finite_math_only && !flag_trapping_math
7017       && flag_unsafe_math_optimizations)
7018     {
7019       ix86_emit_swdivsf (operands[0], operands[1],
7020                          operands[2], SFmode);
7021       DONE;
7022     }
7023 })
7024 \f
7025 ;; Divmod instructions.
7026
7027 (define_expand "divmod<mode>4"
7028   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7029                    (div:SWIM248
7030                      (match_operand:SWIM248 1 "register_operand" "")
7031                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7032               (set (match_operand:SWIM248 3 "register_operand" "")
7033                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7034               (clobber (reg:CC FLAGS_REG))])])
7035
7036 ;; Split with 8bit unsigned divide:
7037 ;;      if (dividend an divisor are in [0-255])
7038 ;;         use 8bit unsigned integer divide
7039 ;;       else
7040 ;;         use original integer divide
7041 (define_split
7042   [(set (match_operand:SWI48 0 "register_operand" "")
7043         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7044                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7045    (set (match_operand:SWI48 1 "register_operand" "")
7046         (mod:SWI48 (match_dup 2) (match_dup 3)))
7047    (clobber (reg:CC FLAGS_REG))]
7048   "TARGET_USE_8BIT_IDIV
7049    && TARGET_QIMODE_MATH
7050    && can_create_pseudo_p ()
7051    && !optimize_insn_for_size_p ()"
7052   [(const_int 0)]
7053   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7054
7055 (define_insn_and_split "divmod<mode>4_1"
7056   [(set (match_operand:SWI48 0 "register_operand" "=a")
7057         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7058                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7059    (set (match_operand:SWI48 1 "register_operand" "=&d")
7060         (mod:SWI48 (match_dup 2) (match_dup 3)))
7061    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7062    (clobber (reg:CC FLAGS_REG))]
7063   ""
7064   "#"
7065   "reload_completed"
7066   [(parallel [(set (match_dup 1)
7067                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7068               (clobber (reg:CC FLAGS_REG))])
7069    (parallel [(set (match_dup 0)
7070                    (div:SWI48 (match_dup 2) (match_dup 3)))
7071               (set (match_dup 1)
7072                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7073               (use (match_dup 1))
7074               (clobber (reg:CC FLAGS_REG))])]
7075 {
7076   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7077
7078   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7079     operands[4] = operands[2];
7080   else
7081     {
7082       /* Avoid use of cltd in favor of a mov+shift.  */
7083       emit_move_insn (operands[1], operands[2]);
7084       operands[4] = operands[1];
7085     }
7086 }
7087   [(set_attr "type" "multi")
7088    (set_attr "mode" "<MODE>")])
7089
7090 (define_insn_and_split "*divmod<mode>4"
7091   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7092         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7093                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7094    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7095         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7096    (clobber (reg:CC FLAGS_REG))]
7097   ""
7098   "#"
7099   "reload_completed"
7100   [(parallel [(set (match_dup 1)
7101                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7102               (clobber (reg:CC FLAGS_REG))])
7103    (parallel [(set (match_dup 0)
7104                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7105               (set (match_dup 1)
7106                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7107               (use (match_dup 1))
7108               (clobber (reg:CC FLAGS_REG))])]
7109 {
7110   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7111
7112   if (<MODE>mode != HImode
7113       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7114     operands[4] = operands[2];
7115   else
7116     {
7117       /* Avoid use of cltd in favor of a mov+shift.  */
7118       emit_move_insn (operands[1], operands[2]);
7119       operands[4] = operands[1];
7120     }
7121 }
7122   [(set_attr "type" "multi")
7123    (set_attr "mode" "<MODE>")])
7124
7125 (define_insn "*divmod<mode>4_noext"
7126   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7127         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7128                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7129    (set (match_operand:SWIM248 1 "register_operand" "=d")
7130         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7131    (use (match_operand:SWIM248 4 "register_operand" "1"))
7132    (clobber (reg:CC FLAGS_REG))]
7133   ""
7134   "idiv{<imodesuffix>}\t%3"
7135   [(set_attr "type" "idiv")
7136    (set_attr "mode" "<MODE>")])
7137
7138 (define_expand "divmodqi4"
7139   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7140                    (div:QI
7141                      (match_operand:QI 1 "register_operand" "")
7142                      (match_operand:QI 2 "nonimmediate_operand" "")))
7143               (set (match_operand:QI 3 "register_operand" "")
7144                    (mod:QI (match_dup 1) (match_dup 2)))
7145               (clobber (reg:CC FLAGS_REG))])]
7146   "TARGET_QIMODE_MATH"
7147 {
7148   rtx div, mod, insn;
7149   rtx tmp0, tmp1;
7150   
7151   tmp0 = gen_reg_rtx (HImode);
7152   tmp1 = gen_reg_rtx (HImode);
7153
7154   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7155      in AX.  */
7156   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7157   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7158
7159   /* Extract remainder from AH.  */
7160   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7161   insn = emit_move_insn (operands[3], tmp1);
7162
7163   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7164   set_unique_reg_note (insn, REG_EQUAL, mod);
7165
7166   /* Extract quotient from AL.  */
7167   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7168
7169   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7170   set_unique_reg_note (insn, REG_EQUAL, div);
7171
7172   DONE;
7173 })
7174
7175 ;; Divide AX by r/m8, with result stored in
7176 ;; AL <- Quotient
7177 ;; AH <- Remainder
7178 ;; Change div/mod to HImode and extend the second argument to HImode
7179 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7180 ;; combine may fail.
7181 (define_insn "divmodhiqi3"
7182   [(set (match_operand:HI 0 "register_operand" "=a")
7183         (ior:HI
7184           (ashift:HI
7185             (zero_extend:HI
7186               (truncate:QI
7187                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7188                         (sign_extend:HI
7189                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7190             (const_int 8))
7191           (zero_extend:HI
7192             (truncate:QI
7193               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7194    (clobber (reg:CC FLAGS_REG))]
7195   "TARGET_QIMODE_MATH"
7196   "idiv{b}\t%2"
7197   [(set_attr "type" "idiv")
7198    (set_attr "mode" "QI")])
7199
7200 (define_expand "udivmod<mode>4"
7201   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7202                    (udiv:SWIM248
7203                      (match_operand:SWIM248 1 "register_operand" "")
7204                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7205               (set (match_operand:SWIM248 3 "register_operand" "")
7206                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7207               (clobber (reg:CC FLAGS_REG))])])
7208
7209 ;; Split with 8bit unsigned divide:
7210 ;;      if (dividend an divisor are in [0-255])
7211 ;;         use 8bit unsigned integer divide
7212 ;;       else
7213 ;;         use original integer divide
7214 (define_split
7215   [(set (match_operand:SWI48 0 "register_operand" "")
7216         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7217                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7218    (set (match_operand:SWI48 1 "register_operand" "")
7219         (umod:SWI48 (match_dup 2) (match_dup 3)))
7220    (clobber (reg:CC FLAGS_REG))]
7221   "TARGET_USE_8BIT_IDIV
7222    && TARGET_QIMODE_MATH
7223    && can_create_pseudo_p ()
7224    && !optimize_insn_for_size_p ()"
7225   [(const_int 0)]
7226   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7227
7228 (define_insn_and_split "udivmod<mode>4_1"
7229   [(set (match_operand:SWI48 0 "register_operand" "=a")
7230         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7231                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7232    (set (match_operand:SWI48 1 "register_operand" "=&d")
7233         (umod:SWI48 (match_dup 2) (match_dup 3)))
7234    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7235    (clobber (reg:CC FLAGS_REG))]
7236   ""
7237   "#"
7238   "reload_completed"
7239   [(set (match_dup 1) (const_int 0))
7240    (parallel [(set (match_dup 0)
7241                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7242               (set (match_dup 1)
7243                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7244               (use (match_dup 1))
7245               (clobber (reg:CC FLAGS_REG))])]
7246   ""
7247   [(set_attr "type" "multi")
7248    (set_attr "mode" "<MODE>")])
7249
7250 (define_insn_and_split "*udivmod<mode>4"
7251   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7252         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7253                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7254    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7255         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7256    (clobber (reg:CC FLAGS_REG))]
7257   ""
7258   "#"
7259   "reload_completed"
7260   [(set (match_dup 1) (const_int 0))
7261    (parallel [(set (match_dup 0)
7262                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7263               (set (match_dup 1)
7264                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7265               (use (match_dup 1))
7266               (clobber (reg:CC FLAGS_REG))])]
7267   ""
7268   [(set_attr "type" "multi")
7269    (set_attr "mode" "<MODE>")])
7270
7271 (define_insn "*udivmod<mode>4_noext"
7272   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7273         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7274                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7275    (set (match_operand:SWIM248 1 "register_operand" "=d")
7276         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7277    (use (match_operand:SWIM248 4 "register_operand" "1"))
7278    (clobber (reg:CC FLAGS_REG))]
7279   ""
7280   "div{<imodesuffix>}\t%3"
7281   [(set_attr "type" "idiv")
7282    (set_attr "mode" "<MODE>")])
7283
7284 (define_expand "udivmodqi4"
7285   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7286                    (udiv:QI
7287                      (match_operand:QI 1 "register_operand" "")
7288                      (match_operand:QI 2 "nonimmediate_operand" "")))
7289               (set (match_operand:QI 3 "register_operand" "")
7290                    (umod:QI (match_dup 1) (match_dup 2)))
7291               (clobber (reg:CC FLAGS_REG))])]
7292   "TARGET_QIMODE_MATH"
7293 {
7294   rtx div, mod, insn;
7295   rtx tmp0, tmp1;
7296   
7297   tmp0 = gen_reg_rtx (HImode);
7298   tmp1 = gen_reg_rtx (HImode);
7299
7300   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7301      in AX.  */
7302   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7303   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7304
7305   /* Extract remainder from AH.  */
7306   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7307   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7308   insn = emit_move_insn (operands[3], tmp1);
7309
7310   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7311   set_unique_reg_note (insn, REG_EQUAL, mod);
7312
7313   /* Extract quotient from AL.  */
7314   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7315
7316   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7317   set_unique_reg_note (insn, REG_EQUAL, div);
7318
7319   DONE;
7320 })
7321
7322 (define_insn "udivmodhiqi3"
7323   [(set (match_operand:HI 0 "register_operand" "=a")
7324         (ior:HI
7325           (ashift:HI
7326             (zero_extend:HI
7327               (truncate:QI
7328                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7329                         (zero_extend:HI
7330                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7331             (const_int 8))
7332           (zero_extend:HI
7333             (truncate:QI
7334               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7335    (clobber (reg:CC FLAGS_REG))]
7336   "TARGET_QIMODE_MATH"
7337   "div{b}\t%2"
7338   [(set_attr "type" "idiv")
7339    (set_attr "mode" "QI")])
7340
7341 ;; We cannot use div/idiv for double division, because it causes
7342 ;; "division by zero" on the overflow and that's not what we expect
7343 ;; from truncate.  Because true (non truncating) double division is
7344 ;; never generated, we can't create this insn anyway.
7345 ;
7346 ;(define_insn ""
7347 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7348 ;       (truncate:SI
7349 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7350 ;                  (zero_extend:DI
7351 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7352 ;   (set (match_operand:SI 3 "register_operand" "=d")
7353 ;       (truncate:SI
7354 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7355 ;   (clobber (reg:CC FLAGS_REG))]
7356 ;  ""
7357 ;  "div{l}\t{%2, %0|%0, %2}"
7358 ;  [(set_attr "type" "idiv")])
7359 \f
7360 ;;- Logical AND instructions
7361
7362 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7363 ;; Note that this excludes ah.
7364
7365 (define_expand "testsi_ccno_1"
7366   [(set (reg:CCNO FLAGS_REG)
7367         (compare:CCNO
7368           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7369                   (match_operand:SI 1 "nonmemory_operand" ""))
7370           (const_int 0)))])
7371
7372 (define_expand "testqi_ccz_1"
7373   [(set (reg:CCZ FLAGS_REG)
7374         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7375                              (match_operand:QI 1 "nonmemory_operand" ""))
7376                  (const_int 0)))])
7377
7378 (define_expand "testdi_ccno_1"
7379   [(set (reg:CCNO FLAGS_REG)
7380         (compare:CCNO
7381           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7382                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7383           (const_int 0)))]
7384   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7385
7386 (define_insn "*testdi_1"
7387   [(set (reg FLAGS_REG)
7388         (compare
7389          (and:DI
7390           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7391           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7392          (const_int 0)))]
7393   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7394    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7395   "@
7396    test{l}\t{%k1, %k0|%k0, %k1}
7397    test{l}\t{%k1, %k0|%k0, %k1}
7398    test{q}\t{%1, %0|%0, %1}
7399    test{q}\t{%1, %0|%0, %1}
7400    test{q}\t{%1, %0|%0, %1}"
7401   [(set_attr "type" "test")
7402    (set_attr "modrm" "0,1,0,1,1")
7403    (set_attr "mode" "SI,SI,DI,DI,DI")])
7404
7405 (define_insn "*testqi_1_maybe_si"
7406   [(set (reg FLAGS_REG)
7407         (compare
7408           (and:QI
7409             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7410             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7411           (const_int 0)))]
7412    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7413     && ix86_match_ccmode (insn,
7414                          CONST_INT_P (operands[1])
7415                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7416 {
7417   if (which_alternative == 3)
7418     {
7419       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7420         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7421       return "test{l}\t{%1, %k0|%k0, %1}";
7422     }
7423   return "test{b}\t{%1, %0|%0, %1}";
7424 }
7425   [(set_attr "type" "test")
7426    (set_attr "modrm" "0,1,1,1")
7427    (set_attr "mode" "QI,QI,QI,SI")
7428    (set_attr "pent_pair" "uv,np,uv,np")])
7429
7430 (define_insn "*test<mode>_1"
7431   [(set (reg FLAGS_REG)
7432         (compare
7433          (and:SWI124
7434           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7435           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7436          (const_int 0)))]
7437   "ix86_match_ccmode (insn, CCNOmode)
7438    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7439   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7440   [(set_attr "type" "test")
7441    (set_attr "modrm" "0,1,1")
7442    (set_attr "mode" "<MODE>")
7443    (set_attr "pent_pair" "uv,np,uv")])
7444
7445 (define_expand "testqi_ext_ccno_0"
7446   [(set (reg:CCNO FLAGS_REG)
7447         (compare:CCNO
7448           (and:SI
7449             (zero_extract:SI
7450               (match_operand 0 "ext_register_operand" "")
7451               (const_int 8)
7452               (const_int 8))
7453             (match_operand 1 "const_int_operand" ""))
7454           (const_int 0)))])
7455
7456 (define_insn "*testqi_ext_0"
7457   [(set (reg FLAGS_REG)
7458         (compare
7459           (and:SI
7460             (zero_extract:SI
7461               (match_operand 0 "ext_register_operand" "Q")
7462               (const_int 8)
7463               (const_int 8))
7464             (match_operand 1 "const_int_operand" "n"))
7465           (const_int 0)))]
7466   "ix86_match_ccmode (insn, CCNOmode)"
7467   "test{b}\t{%1, %h0|%h0, %1}"
7468   [(set_attr "type" "test")
7469    (set_attr "mode" "QI")
7470    (set_attr "length_immediate" "1")
7471    (set_attr "modrm" "1")
7472    (set_attr "pent_pair" "np")])
7473
7474 (define_insn "*testqi_ext_1_rex64"
7475   [(set (reg FLAGS_REG)
7476         (compare
7477           (and:SI
7478             (zero_extract:SI
7479               (match_operand 0 "ext_register_operand" "Q")
7480               (const_int 8)
7481               (const_int 8))
7482             (zero_extend:SI
7483               (match_operand:QI 1 "register_operand" "Q")))
7484           (const_int 0)))]
7485   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7486   "test{b}\t{%1, %h0|%h0, %1}"
7487   [(set_attr "type" "test")
7488    (set_attr "mode" "QI")])
7489
7490 (define_insn "*testqi_ext_1"
7491   [(set (reg FLAGS_REG)
7492         (compare
7493           (and:SI
7494             (zero_extract:SI
7495               (match_operand 0 "ext_register_operand" "Q")
7496               (const_int 8)
7497               (const_int 8))
7498             (zero_extend:SI
7499               (match_operand:QI 1 "general_operand" "Qm")))
7500           (const_int 0)))]
7501   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7502   "test{b}\t{%1, %h0|%h0, %1}"
7503   [(set_attr "type" "test")
7504    (set_attr "mode" "QI")])
7505
7506 (define_insn "*testqi_ext_2"
7507   [(set (reg FLAGS_REG)
7508         (compare
7509           (and:SI
7510             (zero_extract:SI
7511               (match_operand 0 "ext_register_operand" "Q")
7512               (const_int 8)
7513               (const_int 8))
7514             (zero_extract:SI
7515               (match_operand 1 "ext_register_operand" "Q")
7516               (const_int 8)
7517               (const_int 8)))
7518           (const_int 0)))]
7519   "ix86_match_ccmode (insn, CCNOmode)"
7520   "test{b}\t{%h1, %h0|%h0, %h1}"
7521   [(set_attr "type" "test")
7522    (set_attr "mode" "QI")])
7523
7524 (define_insn "*testqi_ext_3_rex64"
7525   [(set (reg FLAGS_REG)
7526         (compare (zero_extract:DI
7527                    (match_operand 0 "nonimmediate_operand" "rm")
7528                    (match_operand:DI 1 "const_int_operand" "")
7529                    (match_operand:DI 2 "const_int_operand" ""))
7530                  (const_int 0)))]
7531   "TARGET_64BIT
7532    && ix86_match_ccmode (insn, CCNOmode)
7533    && INTVAL (operands[1]) > 0
7534    && INTVAL (operands[2]) >= 0
7535    /* Ensure that resulting mask is zero or sign extended operand.  */
7536    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7537        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7538            && INTVAL (operands[1]) > 32))
7539    && (GET_MODE (operands[0]) == SImode
7540        || GET_MODE (operands[0]) == DImode
7541        || GET_MODE (operands[0]) == HImode
7542        || GET_MODE (operands[0]) == QImode)"
7543   "#")
7544
7545 ;; Combine likes to form bit extractions for some tests.  Humor it.
7546 (define_insn "*testqi_ext_3"
7547   [(set (reg FLAGS_REG)
7548         (compare (zero_extract:SI
7549                    (match_operand 0 "nonimmediate_operand" "rm")
7550                    (match_operand:SI 1 "const_int_operand" "")
7551                    (match_operand:SI 2 "const_int_operand" ""))
7552                  (const_int 0)))]
7553   "ix86_match_ccmode (insn, CCNOmode)
7554    && INTVAL (operands[1]) > 0
7555    && INTVAL (operands[2]) >= 0
7556    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7557    && (GET_MODE (operands[0]) == SImode
7558        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7559        || GET_MODE (operands[0]) == HImode
7560        || GET_MODE (operands[0]) == QImode)"
7561   "#")
7562
7563 (define_split
7564   [(set (match_operand 0 "flags_reg_operand" "")
7565         (match_operator 1 "compare_operator"
7566           [(zero_extract
7567              (match_operand 2 "nonimmediate_operand" "")
7568              (match_operand 3 "const_int_operand" "")
7569              (match_operand 4 "const_int_operand" ""))
7570            (const_int 0)]))]
7571   "ix86_match_ccmode (insn, CCNOmode)"
7572   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7573 {
7574   rtx val = operands[2];
7575   HOST_WIDE_INT len = INTVAL (operands[3]);
7576   HOST_WIDE_INT pos = INTVAL (operands[4]);
7577   HOST_WIDE_INT mask;
7578   enum machine_mode mode, submode;
7579
7580   mode = GET_MODE (val);
7581   if (MEM_P (val))
7582     {
7583       /* ??? Combine likes to put non-volatile mem extractions in QImode
7584          no matter the size of the test.  So find a mode that works.  */
7585       if (! MEM_VOLATILE_P (val))
7586         {
7587           mode = smallest_mode_for_size (pos + len, MODE_INT);
7588           val = adjust_address (val, mode, 0);
7589         }
7590     }
7591   else if (GET_CODE (val) == SUBREG
7592            && (submode = GET_MODE (SUBREG_REG (val)),
7593                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7594            && pos + len <= GET_MODE_BITSIZE (submode)
7595            && GET_MODE_CLASS (submode) == MODE_INT)
7596     {
7597       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7598       mode = submode;
7599       val = SUBREG_REG (val);
7600     }
7601   else if (mode == HImode && pos + len <= 8)
7602     {
7603       /* Small HImode tests can be converted to QImode.  */
7604       mode = QImode;
7605       val = gen_lowpart (QImode, val);
7606     }
7607
7608   if (len == HOST_BITS_PER_WIDE_INT)
7609     mask = -1;
7610   else
7611     mask = ((HOST_WIDE_INT)1 << len) - 1;
7612   mask <<= pos;
7613
7614   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7615 })
7616
7617 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7618 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7619 ;; this is relatively important trick.
7620 ;; Do the conversion only post-reload to avoid limiting of the register class
7621 ;; to QI regs.
7622 (define_split
7623   [(set (match_operand 0 "flags_reg_operand" "")
7624         (match_operator 1 "compare_operator"
7625           [(and (match_operand 2 "register_operand" "")
7626                 (match_operand 3 "const_int_operand" ""))
7627            (const_int 0)]))]
7628    "reload_completed
7629     && QI_REG_P (operands[2])
7630     && GET_MODE (operands[2]) != QImode
7631     && ((ix86_match_ccmode (insn, CCZmode)
7632          && !(INTVAL (operands[3]) & ~(255 << 8)))
7633         || (ix86_match_ccmode (insn, CCNOmode)
7634             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7635   [(set (match_dup 0)
7636         (match_op_dup 1
7637           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7638                    (match_dup 3))
7639            (const_int 0)]))]
7640   "operands[2] = gen_lowpart (SImode, operands[2]);
7641    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7642
7643 (define_split
7644   [(set (match_operand 0 "flags_reg_operand" "")
7645         (match_operator 1 "compare_operator"
7646           [(and (match_operand 2 "nonimmediate_operand" "")
7647                 (match_operand 3 "const_int_operand" ""))
7648            (const_int 0)]))]
7649    "reload_completed
7650     && GET_MODE (operands[2]) != QImode
7651     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7652     && ((ix86_match_ccmode (insn, CCZmode)
7653          && !(INTVAL (operands[3]) & ~255))
7654         || (ix86_match_ccmode (insn, CCNOmode)
7655             && !(INTVAL (operands[3]) & ~127)))"
7656   [(set (match_dup 0)
7657         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7658                          (const_int 0)]))]
7659   "operands[2] = gen_lowpart (QImode, operands[2]);
7660    operands[3] = gen_lowpart (QImode, operands[3]);")
7661
7662 ;; %%% This used to optimize known byte-wide and operations to memory,
7663 ;; and sometimes to QImode registers.  If this is considered useful,
7664 ;; it should be done with splitters.
7665
7666 (define_expand "and<mode>3"
7667   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7668         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7669                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7670   ""
7671   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7672
7673 (define_insn "*anddi_1"
7674   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7675         (and:DI
7676          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7677          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7678    (clobber (reg:CC FLAGS_REG))]
7679   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7680 {
7681   switch (get_attr_type (insn))
7682     {
7683     case TYPE_IMOVX:
7684       {
7685         enum machine_mode mode;
7686
7687         gcc_assert (CONST_INT_P (operands[2]));
7688         if (INTVAL (operands[2]) == 0xff)
7689           mode = QImode;
7690         else
7691           {
7692             gcc_assert (INTVAL (operands[2]) == 0xffff);
7693             mode = HImode;
7694           }
7695
7696         operands[1] = gen_lowpart (mode, operands[1]);
7697         if (mode == QImode)
7698           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7699         else
7700           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7701       }
7702
7703     default:
7704       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7705       if (get_attr_mode (insn) == MODE_SI)
7706         return "and{l}\t{%k2, %k0|%k0, %k2}";
7707       else
7708         return "and{q}\t{%2, %0|%0, %2}";
7709     }
7710 }
7711   [(set_attr "type" "alu,alu,alu,imovx")
7712    (set_attr "length_immediate" "*,*,*,0")
7713    (set (attr "prefix_rex")
7714      (if_then_else
7715        (and (eq_attr "type" "imovx")
7716             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7717                  (match_operand 1 "ext_QIreg_operand" "")))
7718        (const_string "1")
7719        (const_string "*")))
7720    (set_attr "mode" "SI,DI,DI,SI")])
7721
7722 (define_insn "*andsi_1"
7723   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7724         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7725                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7726    (clobber (reg:CC FLAGS_REG))]
7727   "ix86_binary_operator_ok (AND, SImode, operands)"
7728 {
7729   switch (get_attr_type (insn))
7730     {
7731     case TYPE_IMOVX:
7732       {
7733         enum machine_mode mode;
7734
7735         gcc_assert (CONST_INT_P (operands[2]));
7736         if (INTVAL (operands[2]) == 0xff)
7737           mode = QImode;
7738         else
7739           {
7740             gcc_assert (INTVAL (operands[2]) == 0xffff);
7741             mode = HImode;
7742           }
7743
7744         operands[1] = gen_lowpart (mode, operands[1]);
7745         if (mode == QImode)
7746           return "movz{bl|x}\t{%1, %0|%0, %1}";
7747         else
7748           return "movz{wl|x}\t{%1, %0|%0, %1}";
7749       }
7750
7751     default:
7752       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7753       return "and{l}\t{%2, %0|%0, %2}";
7754     }
7755 }
7756   [(set_attr "type" "alu,alu,imovx")
7757    (set (attr "prefix_rex")
7758      (if_then_else
7759        (and (eq_attr "type" "imovx")
7760             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7761                  (match_operand 1 "ext_QIreg_operand" "")))
7762        (const_string "1")
7763        (const_string "*")))
7764    (set_attr "length_immediate" "*,*,0")
7765    (set_attr "mode" "SI")])
7766
7767 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7768 (define_insn "*andsi_1_zext"
7769   [(set (match_operand:DI 0 "register_operand" "=r")
7770         (zero_extend:DI
7771           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7772                   (match_operand:SI 2 "general_operand" "g"))))
7773    (clobber (reg:CC FLAGS_REG))]
7774   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7775   "and{l}\t{%2, %k0|%k0, %2}"
7776   [(set_attr "type" "alu")
7777    (set_attr "mode" "SI")])
7778
7779 (define_insn "*andhi_1"
7780   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7781         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7782                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7783    (clobber (reg:CC FLAGS_REG))]
7784   "ix86_binary_operator_ok (AND, HImode, operands)"
7785 {
7786   switch (get_attr_type (insn))
7787     {
7788     case TYPE_IMOVX:
7789       gcc_assert (CONST_INT_P (operands[2]));
7790       gcc_assert (INTVAL (operands[2]) == 0xff);
7791       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7792
7793     default:
7794       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7795
7796       return "and{w}\t{%2, %0|%0, %2}";
7797     }
7798 }
7799   [(set_attr "type" "alu,alu,imovx")
7800    (set_attr "length_immediate" "*,*,0")
7801    (set (attr "prefix_rex")
7802      (if_then_else
7803        (and (eq_attr "type" "imovx")
7804             (match_operand 1 "ext_QIreg_operand" ""))
7805        (const_string "1")
7806        (const_string "*")))
7807    (set_attr "mode" "HI,HI,SI")])
7808
7809 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7810 (define_insn "*andqi_1"
7811   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7812         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7813                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7814    (clobber (reg:CC FLAGS_REG))]
7815   "ix86_binary_operator_ok (AND, QImode, operands)"
7816   "@
7817    and{b}\t{%2, %0|%0, %2}
7818    and{b}\t{%2, %0|%0, %2}
7819    and{l}\t{%k2, %k0|%k0, %k2}"
7820   [(set_attr "type" "alu")
7821    (set_attr "mode" "QI,QI,SI")])
7822
7823 (define_insn "*andqi_1_slp"
7824   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7825         (and:QI (match_dup 0)
7826                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7827    (clobber (reg:CC FLAGS_REG))]
7828   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7829    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7830   "and{b}\t{%1, %0|%0, %1}"
7831   [(set_attr "type" "alu1")
7832    (set_attr "mode" "QI")])
7833
7834 (define_split
7835   [(set (match_operand 0 "register_operand" "")
7836         (and (match_dup 0)
7837              (const_int -65536)))
7838    (clobber (reg:CC FLAGS_REG))]
7839   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7840     || optimize_function_for_size_p (cfun)"
7841   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7842   "operands[1] = gen_lowpart (HImode, operands[0]);")
7843
7844 (define_split
7845   [(set (match_operand 0 "ext_register_operand" "")
7846         (and (match_dup 0)
7847              (const_int -256)))
7848    (clobber (reg:CC FLAGS_REG))]
7849   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7850    && reload_completed"
7851   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7852   "operands[1] = gen_lowpart (QImode, operands[0]);")
7853
7854 (define_split
7855   [(set (match_operand 0 "ext_register_operand" "")
7856         (and (match_dup 0)
7857              (const_int -65281)))
7858    (clobber (reg:CC FLAGS_REG))]
7859   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7860    && reload_completed"
7861   [(parallel [(set (zero_extract:SI (match_dup 0)
7862                                     (const_int 8)
7863                                     (const_int 8))
7864                    (xor:SI
7865                      (zero_extract:SI (match_dup 0)
7866                                       (const_int 8)
7867                                       (const_int 8))
7868                      (zero_extract:SI (match_dup 0)
7869                                       (const_int 8)
7870                                       (const_int 8))))
7871               (clobber (reg:CC FLAGS_REG))])]
7872   "operands[0] = gen_lowpart (SImode, operands[0]);")
7873
7874 (define_insn "*anddi_2"
7875   [(set (reg FLAGS_REG)
7876         (compare
7877          (and:DI
7878           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7879           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7880          (const_int 0)))
7881    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7882         (and:DI (match_dup 1) (match_dup 2)))]
7883   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7884    && ix86_binary_operator_ok (AND, DImode, operands)"
7885   "@
7886    and{l}\t{%k2, %k0|%k0, %k2}
7887    and{q}\t{%2, %0|%0, %2}
7888    and{q}\t{%2, %0|%0, %2}"
7889   [(set_attr "type" "alu")
7890    (set_attr "mode" "SI,DI,DI")])
7891
7892 (define_insn "*andqi_2_maybe_si"
7893   [(set (reg FLAGS_REG)
7894         (compare (and:QI
7895                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7896                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7897                  (const_int 0)))
7898    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7899         (and:QI (match_dup 1) (match_dup 2)))]
7900   "ix86_binary_operator_ok (AND, QImode, operands)
7901    && ix86_match_ccmode (insn,
7902                          CONST_INT_P (operands[2])
7903                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7904 {
7905   if (which_alternative == 2)
7906     {
7907       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7908         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7909       return "and{l}\t{%2, %k0|%k0, %2}";
7910     }
7911   return "and{b}\t{%2, %0|%0, %2}";
7912 }
7913   [(set_attr "type" "alu")
7914    (set_attr "mode" "QI,QI,SI")])
7915
7916 (define_insn "*and<mode>_2"
7917   [(set (reg FLAGS_REG)
7918         (compare (and:SWI124
7919                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7920                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7921                  (const_int 0)))
7922    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7923         (and:SWI124 (match_dup 1) (match_dup 2)))]
7924   "ix86_match_ccmode (insn, CCNOmode)
7925    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7926   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7927   [(set_attr "type" "alu")
7928    (set_attr "mode" "<MODE>")])
7929
7930 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7931 (define_insn "*andsi_2_zext"
7932   [(set (reg FLAGS_REG)
7933         (compare (and:SI
7934                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7935                   (match_operand:SI 2 "general_operand" "g"))
7936                  (const_int 0)))
7937    (set (match_operand:DI 0 "register_operand" "=r")
7938         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7939   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7940    && ix86_binary_operator_ok (AND, SImode, operands)"
7941   "and{l}\t{%2, %k0|%k0, %2}"
7942   [(set_attr "type" "alu")
7943    (set_attr "mode" "SI")])
7944
7945 (define_insn "*andqi_2_slp"
7946   [(set (reg FLAGS_REG)
7947         (compare (and:QI
7948                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7949                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7950                  (const_int 0)))
7951    (set (strict_low_part (match_dup 0))
7952         (and:QI (match_dup 0) (match_dup 1)))]
7953   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7954    && ix86_match_ccmode (insn, CCNOmode)
7955    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7956   "and{b}\t{%1, %0|%0, %1}"
7957   [(set_attr "type" "alu1")
7958    (set_attr "mode" "QI")])
7959
7960 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7961 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7962 ;; for a QImode operand, which of course failed.
7963 (define_insn "andqi_ext_0"
7964   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7965                          (const_int 8)
7966                          (const_int 8))
7967         (and:SI
7968           (zero_extract:SI
7969             (match_operand 1 "ext_register_operand" "0")
7970             (const_int 8)
7971             (const_int 8))
7972           (match_operand 2 "const_int_operand" "n")))
7973    (clobber (reg:CC FLAGS_REG))]
7974   ""
7975   "and{b}\t{%2, %h0|%h0, %2}"
7976   [(set_attr "type" "alu")
7977    (set_attr "length_immediate" "1")
7978    (set_attr "modrm" "1")
7979    (set_attr "mode" "QI")])
7980
7981 ;; Generated by peephole translating test to and.  This shows up
7982 ;; often in fp comparisons.
7983 (define_insn "*andqi_ext_0_cc"
7984   [(set (reg FLAGS_REG)
7985         (compare
7986           (and:SI
7987             (zero_extract:SI
7988               (match_operand 1 "ext_register_operand" "0")
7989               (const_int 8)
7990               (const_int 8))
7991             (match_operand 2 "const_int_operand" "n"))
7992           (const_int 0)))
7993    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7994                          (const_int 8)
7995                          (const_int 8))
7996         (and:SI
7997           (zero_extract:SI
7998             (match_dup 1)
7999             (const_int 8)
8000             (const_int 8))
8001           (match_dup 2)))]
8002   "ix86_match_ccmode (insn, CCNOmode)"
8003   "and{b}\t{%2, %h0|%h0, %2}"
8004   [(set_attr "type" "alu")
8005    (set_attr "length_immediate" "1")
8006    (set_attr "modrm" "1")
8007    (set_attr "mode" "QI")])
8008
8009 (define_insn "*andqi_ext_1_rex64"
8010   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8011                          (const_int 8)
8012                          (const_int 8))
8013         (and:SI
8014           (zero_extract:SI
8015             (match_operand 1 "ext_register_operand" "0")
8016             (const_int 8)
8017             (const_int 8))
8018           (zero_extend:SI
8019             (match_operand 2 "ext_register_operand" "Q"))))
8020    (clobber (reg:CC FLAGS_REG))]
8021   "TARGET_64BIT"
8022   "and{b}\t{%2, %h0|%h0, %2}"
8023   [(set_attr "type" "alu")
8024    (set_attr "length_immediate" "0")
8025    (set_attr "mode" "QI")])
8026
8027 (define_insn "*andqi_ext_1"
8028   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8029                          (const_int 8)
8030                          (const_int 8))
8031         (and:SI
8032           (zero_extract:SI
8033             (match_operand 1 "ext_register_operand" "0")
8034             (const_int 8)
8035             (const_int 8))
8036           (zero_extend:SI
8037             (match_operand:QI 2 "general_operand" "Qm"))))
8038    (clobber (reg:CC FLAGS_REG))]
8039   "!TARGET_64BIT"
8040   "and{b}\t{%2, %h0|%h0, %2}"
8041   [(set_attr "type" "alu")
8042    (set_attr "length_immediate" "0")
8043    (set_attr "mode" "QI")])
8044
8045 (define_insn "*andqi_ext_2"
8046   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8047                          (const_int 8)
8048                          (const_int 8))
8049         (and:SI
8050           (zero_extract:SI
8051             (match_operand 1 "ext_register_operand" "%0")
8052             (const_int 8)
8053             (const_int 8))
8054           (zero_extract:SI
8055             (match_operand 2 "ext_register_operand" "Q")
8056             (const_int 8)
8057             (const_int 8))))
8058    (clobber (reg:CC FLAGS_REG))]
8059   ""
8060   "and{b}\t{%h2, %h0|%h0, %h2}"
8061   [(set_attr "type" "alu")
8062    (set_attr "length_immediate" "0")
8063    (set_attr "mode" "QI")])
8064
8065 ;; Convert wide AND instructions with immediate operand to shorter QImode
8066 ;; equivalents when possible.
8067 ;; Don't do the splitting with memory operands, since it introduces risk
8068 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8069 ;; for size, but that can (should?) be handled by generic code instead.
8070 (define_split
8071   [(set (match_operand 0 "register_operand" "")
8072         (and (match_operand 1 "register_operand" "")
8073              (match_operand 2 "const_int_operand" "")))
8074    (clobber (reg:CC FLAGS_REG))]
8075    "reload_completed
8076     && QI_REG_P (operands[0])
8077     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8078     && !(~INTVAL (operands[2]) & ~(255 << 8))
8079     && GET_MODE (operands[0]) != QImode"
8080   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8081                    (and:SI (zero_extract:SI (match_dup 1)
8082                                             (const_int 8) (const_int 8))
8083                            (match_dup 2)))
8084               (clobber (reg:CC FLAGS_REG))])]
8085   "operands[0] = gen_lowpart (SImode, operands[0]);
8086    operands[1] = gen_lowpart (SImode, operands[1]);
8087    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8088
8089 ;; Since AND can be encoded with sign extended immediate, this is only
8090 ;; profitable when 7th bit is not set.
8091 (define_split
8092   [(set (match_operand 0 "register_operand" "")
8093         (and (match_operand 1 "general_operand" "")
8094              (match_operand 2 "const_int_operand" "")))
8095    (clobber (reg:CC FLAGS_REG))]
8096    "reload_completed
8097     && ANY_QI_REG_P (operands[0])
8098     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8099     && !(~INTVAL (operands[2]) & ~255)
8100     && !(INTVAL (operands[2]) & 128)
8101     && GET_MODE (operands[0]) != QImode"
8102   [(parallel [(set (strict_low_part (match_dup 0))
8103                    (and:QI (match_dup 1)
8104                            (match_dup 2)))
8105               (clobber (reg:CC FLAGS_REG))])]
8106   "operands[0] = gen_lowpart (QImode, operands[0]);
8107    operands[1] = gen_lowpart (QImode, operands[1]);
8108    operands[2] = gen_lowpart (QImode, operands[2]);")
8109 \f
8110 ;; Logical inclusive and exclusive OR instructions
8111
8112 ;; %%% This used to optimize known byte-wide and operations to memory.
8113 ;; If this is considered useful, it should be done with splitters.
8114
8115 (define_expand "<code><mode>3"
8116   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8117         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8118                      (match_operand:SWIM 2 "<general_operand>" "")))]
8119   ""
8120   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8121
8122 (define_insn "*<code><mode>_1"
8123   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8124         (any_or:SWI248
8125          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8126          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8127    (clobber (reg:CC FLAGS_REG))]
8128   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8129   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8130   [(set_attr "type" "alu")
8131    (set_attr "mode" "<MODE>")])
8132
8133 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8134 (define_insn "*<code>qi_1"
8135   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8136         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8137                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8138    (clobber (reg:CC FLAGS_REG))]
8139   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8140   "@
8141    <logic>{b}\t{%2, %0|%0, %2}
8142    <logic>{b}\t{%2, %0|%0, %2}
8143    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8144   [(set_attr "type" "alu")
8145    (set_attr "mode" "QI,QI,SI")])
8146
8147 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8148 (define_insn "*<code>si_1_zext"
8149   [(set (match_operand:DI 0 "register_operand" "=r")
8150         (zero_extend:DI
8151          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8152                     (match_operand:SI 2 "general_operand" "g"))))
8153    (clobber (reg:CC FLAGS_REG))]
8154   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8155   "<logic>{l}\t{%2, %k0|%k0, %2}"
8156   [(set_attr "type" "alu")
8157    (set_attr "mode" "SI")])
8158
8159 (define_insn "*<code>si_1_zext_imm"
8160   [(set (match_operand:DI 0 "register_operand" "=r")
8161         (any_or:DI
8162          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8163          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8164    (clobber (reg:CC FLAGS_REG))]
8165   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8166   "<logic>{l}\t{%2, %k0|%k0, %2}"
8167   [(set_attr "type" "alu")
8168    (set_attr "mode" "SI")])
8169
8170 (define_insn "*<code>qi_1_slp"
8171   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8172         (any_or:QI (match_dup 0)
8173                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8174    (clobber (reg:CC FLAGS_REG))]
8175   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8176    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8177   "<logic>{b}\t{%1, %0|%0, %1}"
8178   [(set_attr "type" "alu1")
8179    (set_attr "mode" "QI")])
8180
8181 (define_insn "*<code><mode>_2"
8182   [(set (reg FLAGS_REG)
8183         (compare (any_or:SWI
8184                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8185                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8186                  (const_int 0)))
8187    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8188         (any_or:SWI (match_dup 1) (match_dup 2)))]
8189   "ix86_match_ccmode (insn, CCNOmode)
8190    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8191   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8192   [(set_attr "type" "alu")
8193    (set_attr "mode" "<MODE>")])
8194
8195 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8196 ;; ??? Special case for immediate operand is missing - it is tricky.
8197 (define_insn "*<code>si_2_zext"
8198   [(set (reg FLAGS_REG)
8199         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8200                             (match_operand:SI 2 "general_operand" "g"))
8201                  (const_int 0)))
8202    (set (match_operand:DI 0 "register_operand" "=r")
8203         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8204   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8205    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8206   "<logic>{l}\t{%2, %k0|%k0, %2}"
8207   [(set_attr "type" "alu")
8208    (set_attr "mode" "SI")])
8209
8210 (define_insn "*<code>si_2_zext_imm"
8211   [(set (reg FLAGS_REG)
8212         (compare (any_or:SI
8213                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8214                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8215                  (const_int 0)))
8216    (set (match_operand:DI 0 "register_operand" "=r")
8217         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8218   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8219    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8220   "<logic>{l}\t{%2, %k0|%k0, %2}"
8221   [(set_attr "type" "alu")
8222    (set_attr "mode" "SI")])
8223
8224 (define_insn "*<code>qi_2_slp"
8225   [(set (reg FLAGS_REG)
8226         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8227                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8228                  (const_int 0)))
8229    (set (strict_low_part (match_dup 0))
8230         (any_or:QI (match_dup 0) (match_dup 1)))]
8231   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8232    && ix86_match_ccmode (insn, CCNOmode)
8233    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8234   "<logic>{b}\t{%1, %0|%0, %1}"
8235   [(set_attr "type" "alu1")
8236    (set_attr "mode" "QI")])
8237
8238 (define_insn "*<code><mode>_3"
8239   [(set (reg FLAGS_REG)
8240         (compare (any_or:SWI
8241                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8242                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8243                  (const_int 0)))
8244    (clobber (match_scratch:SWI 0 "=<r>"))]
8245   "ix86_match_ccmode (insn, CCNOmode)
8246    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8247   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "<MODE>")])
8250
8251 (define_insn "*<code>qi_ext_0"
8252   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8253                          (const_int 8)
8254                          (const_int 8))
8255         (any_or:SI
8256           (zero_extract:SI
8257             (match_operand 1 "ext_register_operand" "0")
8258             (const_int 8)
8259             (const_int 8))
8260           (match_operand 2 "const_int_operand" "n")))
8261    (clobber (reg:CC FLAGS_REG))]
8262   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8263   "<logic>{b}\t{%2, %h0|%h0, %2}"
8264   [(set_attr "type" "alu")
8265    (set_attr "length_immediate" "1")
8266    (set_attr "modrm" "1")
8267    (set_attr "mode" "QI")])
8268
8269 (define_insn "*<code>qi_ext_1_rex64"
8270   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8271                          (const_int 8)
8272                          (const_int 8))
8273         (any_or:SI
8274           (zero_extract:SI
8275             (match_operand 1 "ext_register_operand" "0")
8276             (const_int 8)
8277             (const_int 8))
8278           (zero_extend:SI
8279             (match_operand 2 "ext_register_operand" "Q"))))
8280    (clobber (reg:CC FLAGS_REG))]
8281   "TARGET_64BIT
8282    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8283   "<logic>{b}\t{%2, %h0|%h0, %2}"
8284   [(set_attr "type" "alu")
8285    (set_attr "length_immediate" "0")
8286    (set_attr "mode" "QI")])
8287
8288 (define_insn "*<code>qi_ext_1"
8289   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8290                          (const_int 8)
8291                          (const_int 8))
8292         (any_or:SI
8293           (zero_extract:SI
8294             (match_operand 1 "ext_register_operand" "0")
8295             (const_int 8)
8296             (const_int 8))
8297           (zero_extend:SI
8298             (match_operand:QI 2 "general_operand" "Qm"))))
8299    (clobber (reg:CC FLAGS_REG))]
8300   "!TARGET_64BIT
8301    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8302   "<logic>{b}\t{%2, %h0|%h0, %2}"
8303   [(set_attr "type" "alu")
8304    (set_attr "length_immediate" "0")
8305    (set_attr "mode" "QI")])
8306
8307 (define_insn "*<code>qi_ext_2"
8308   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8309                          (const_int 8)
8310                          (const_int 8))
8311         (any_or:SI
8312           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8313                            (const_int 8)
8314                            (const_int 8))
8315           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8316                            (const_int 8)
8317                            (const_int 8))))
8318    (clobber (reg:CC FLAGS_REG))]
8319   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8320   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8321   [(set_attr "type" "alu")
8322    (set_attr "length_immediate" "0")
8323    (set_attr "mode" "QI")])
8324
8325 (define_split
8326   [(set (match_operand 0 "register_operand" "")
8327         (any_or (match_operand 1 "register_operand" "")
8328                 (match_operand 2 "const_int_operand" "")))
8329    (clobber (reg:CC FLAGS_REG))]
8330    "reload_completed
8331     && QI_REG_P (operands[0])
8332     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8333     && !(INTVAL (operands[2]) & ~(255 << 8))
8334     && GET_MODE (operands[0]) != QImode"
8335   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8336                    (any_or:SI (zero_extract:SI (match_dup 1)
8337                                                (const_int 8) (const_int 8))
8338                               (match_dup 2)))
8339               (clobber (reg:CC FLAGS_REG))])]
8340   "operands[0] = gen_lowpart (SImode, operands[0]);
8341    operands[1] = gen_lowpart (SImode, operands[1]);
8342    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8343
8344 ;; Since OR can be encoded with sign extended immediate, this is only
8345 ;; profitable when 7th bit is set.
8346 (define_split
8347   [(set (match_operand 0 "register_operand" "")
8348         (any_or (match_operand 1 "general_operand" "")
8349                 (match_operand 2 "const_int_operand" "")))
8350    (clobber (reg:CC FLAGS_REG))]
8351    "reload_completed
8352     && ANY_QI_REG_P (operands[0])
8353     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8354     && !(INTVAL (operands[2]) & ~255)
8355     && (INTVAL (operands[2]) & 128)
8356     && GET_MODE (operands[0]) != QImode"
8357   [(parallel [(set (strict_low_part (match_dup 0))
8358                    (any_or:QI (match_dup 1)
8359                               (match_dup 2)))
8360               (clobber (reg:CC FLAGS_REG))])]
8361   "operands[0] = gen_lowpart (QImode, operands[0]);
8362    operands[1] = gen_lowpart (QImode, operands[1]);
8363    operands[2] = gen_lowpart (QImode, operands[2]);")
8364
8365 (define_expand "xorqi_cc_ext_1"
8366   [(parallel [
8367      (set (reg:CCNO FLAGS_REG)
8368           (compare:CCNO
8369             (xor:SI
8370               (zero_extract:SI
8371                 (match_operand 1 "ext_register_operand" "")
8372                 (const_int 8)
8373                 (const_int 8))
8374               (match_operand:QI 2 "general_operand" ""))
8375             (const_int 0)))
8376      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8377                            (const_int 8)
8378                            (const_int 8))
8379           (xor:SI
8380             (zero_extract:SI
8381              (match_dup 1)
8382              (const_int 8)
8383              (const_int 8))
8384             (match_dup 2)))])])
8385
8386 (define_insn "*xorqi_cc_ext_1_rex64"
8387   [(set (reg FLAGS_REG)
8388         (compare
8389           (xor:SI
8390             (zero_extract:SI
8391               (match_operand 1 "ext_register_operand" "0")
8392               (const_int 8)
8393               (const_int 8))
8394             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8395           (const_int 0)))
8396    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8397                          (const_int 8)
8398                          (const_int 8))
8399         (xor:SI
8400           (zero_extract:SI
8401            (match_dup 1)
8402            (const_int 8)
8403            (const_int 8))
8404           (match_dup 2)))]
8405   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8406   "xor{b}\t{%2, %h0|%h0, %2}"
8407   [(set_attr "type" "alu")
8408    (set_attr "modrm" "1")
8409    (set_attr "mode" "QI")])
8410
8411 (define_insn "*xorqi_cc_ext_1"
8412   [(set (reg FLAGS_REG)
8413         (compare
8414           (xor:SI
8415             (zero_extract:SI
8416               (match_operand 1 "ext_register_operand" "0")
8417               (const_int 8)
8418               (const_int 8))
8419             (match_operand:QI 2 "general_operand" "qmn"))
8420           (const_int 0)))
8421    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8422                          (const_int 8)
8423                          (const_int 8))
8424         (xor:SI
8425           (zero_extract:SI
8426            (match_dup 1)
8427            (const_int 8)
8428            (const_int 8))
8429           (match_dup 2)))]
8430   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8431   "xor{b}\t{%2, %h0|%h0, %2}"
8432   [(set_attr "type" "alu")
8433    (set_attr "modrm" "1")
8434    (set_attr "mode" "QI")])
8435 \f
8436 ;; Negation instructions
8437
8438 (define_expand "neg<mode>2"
8439   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8440         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8441   ""
8442   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8443
8444 (define_insn_and_split "*neg<dwi>2_doubleword"
8445   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8446         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8447    (clobber (reg:CC FLAGS_REG))]
8448   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8449   "#"
8450   "reload_completed"
8451   [(parallel
8452     [(set (reg:CCZ FLAGS_REG)
8453           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8454      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8455    (parallel
8456     [(set (match_dup 2)
8457           (plus:DWIH (match_dup 3)
8458                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8459                                 (const_int 0))))
8460      (clobber (reg:CC FLAGS_REG))])
8461    (parallel
8462     [(set (match_dup 2)
8463           (neg:DWIH (match_dup 2)))
8464      (clobber (reg:CC FLAGS_REG))])]
8465   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8466
8467 (define_insn "*neg<mode>2_1"
8468   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8469         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8470    (clobber (reg:CC FLAGS_REG))]
8471   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8472   "neg{<imodesuffix>}\t%0"
8473   [(set_attr "type" "negnot")
8474    (set_attr "mode" "<MODE>")])
8475
8476 ;; Combine is quite creative about this pattern.
8477 (define_insn "*negsi2_1_zext"
8478   [(set (match_operand:DI 0 "register_operand" "=r")
8479         (lshiftrt:DI
8480           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8481                              (const_int 32)))
8482         (const_int 32)))
8483    (clobber (reg:CC FLAGS_REG))]
8484   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8485   "neg{l}\t%k0"
8486   [(set_attr "type" "negnot")
8487    (set_attr "mode" "SI")])
8488
8489 ;; The problem with neg is that it does not perform (compare x 0),
8490 ;; it really performs (compare 0 x), which leaves us with the zero
8491 ;; flag being the only useful item.
8492
8493 (define_insn "*neg<mode>2_cmpz"
8494   [(set (reg:CCZ FLAGS_REG)
8495         (compare:CCZ
8496           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8497                    (const_int 0)))
8498    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8499         (neg:SWI (match_dup 1)))]
8500   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8501   "neg{<imodesuffix>}\t%0"
8502   [(set_attr "type" "negnot")
8503    (set_attr "mode" "<MODE>")])
8504
8505 (define_insn "*negsi2_cmpz_zext"
8506   [(set (reg:CCZ FLAGS_REG)
8507         (compare:CCZ
8508           (lshiftrt:DI
8509             (neg:DI (ashift:DI
8510                       (match_operand:DI 1 "register_operand" "0")
8511                       (const_int 32)))
8512             (const_int 32))
8513           (const_int 0)))
8514    (set (match_operand:DI 0 "register_operand" "=r")
8515         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8516                                         (const_int 32)))
8517                      (const_int 32)))]
8518   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8519   "neg{l}\t%k0"
8520   [(set_attr "type" "negnot")
8521    (set_attr "mode" "SI")])
8522
8523 ;; Changing of sign for FP values is doable using integer unit too.
8524
8525 (define_expand "<code><mode>2"
8526   [(set (match_operand:X87MODEF 0 "register_operand" "")
8527         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8528   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8529   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8530
8531 (define_insn "*absneg<mode>2_mixed"
8532   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8533         (match_operator:MODEF 3 "absneg_operator"
8534           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8535    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8536    (clobber (reg:CC FLAGS_REG))]
8537   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8538   "#")
8539
8540 (define_insn "*absneg<mode>2_sse"
8541   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8542         (match_operator:MODEF 3 "absneg_operator"
8543           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8544    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8545    (clobber (reg:CC FLAGS_REG))]
8546   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8547   "#")
8548
8549 (define_insn "*absneg<mode>2_i387"
8550   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8551         (match_operator:X87MODEF 3 "absneg_operator"
8552           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8553    (use (match_operand 2 "" ""))
8554    (clobber (reg:CC FLAGS_REG))]
8555   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8556   "#")
8557
8558 (define_expand "<code>tf2"
8559   [(set (match_operand:TF 0 "register_operand" "")
8560         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8561   "TARGET_SSE2"
8562   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8563
8564 (define_insn "*absnegtf2_sse"
8565   [(set (match_operand:TF 0 "register_operand" "=x,x")
8566         (match_operator:TF 3 "absneg_operator"
8567           [(match_operand:TF 1 "register_operand" "0,x")]))
8568    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8569    (clobber (reg:CC FLAGS_REG))]
8570   "TARGET_SSE2"
8571   "#")
8572
8573 ;; Splitters for fp abs and neg.
8574
8575 (define_split
8576   [(set (match_operand 0 "fp_register_operand" "")
8577         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8578    (use (match_operand 2 "" ""))
8579    (clobber (reg:CC FLAGS_REG))]
8580   "reload_completed"
8581   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8582
8583 (define_split
8584   [(set (match_operand 0 "register_operand" "")
8585         (match_operator 3 "absneg_operator"
8586           [(match_operand 1 "register_operand" "")]))
8587    (use (match_operand 2 "nonimmediate_operand" ""))
8588    (clobber (reg:CC FLAGS_REG))]
8589   "reload_completed && SSE_REG_P (operands[0])"
8590   [(set (match_dup 0) (match_dup 3))]
8591 {
8592   enum machine_mode mode = GET_MODE (operands[0]);
8593   enum machine_mode vmode = GET_MODE (operands[2]);
8594   rtx tmp;
8595
8596   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8597   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8598   if (operands_match_p (operands[0], operands[2]))
8599     {
8600       tmp = operands[1];
8601       operands[1] = operands[2];
8602       operands[2] = tmp;
8603     }
8604   if (GET_CODE (operands[3]) == ABS)
8605     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8606   else
8607     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8608   operands[3] = tmp;
8609 })
8610
8611 (define_split
8612   [(set (match_operand:SF 0 "register_operand" "")
8613         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8614    (use (match_operand:V4SF 2 "" ""))
8615    (clobber (reg:CC FLAGS_REG))]
8616   "reload_completed"
8617   [(parallel [(set (match_dup 0) (match_dup 1))
8618               (clobber (reg:CC FLAGS_REG))])]
8619 {
8620   rtx tmp;
8621   operands[0] = gen_lowpart (SImode, operands[0]);
8622   if (GET_CODE (operands[1]) == ABS)
8623     {
8624       tmp = gen_int_mode (0x7fffffff, SImode);
8625       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8626     }
8627   else
8628     {
8629       tmp = gen_int_mode (0x80000000, SImode);
8630       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8631     }
8632   operands[1] = tmp;
8633 })
8634
8635 (define_split
8636   [(set (match_operand:DF 0 "register_operand" "")
8637         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8638    (use (match_operand 2 "" ""))
8639    (clobber (reg:CC FLAGS_REG))]
8640   "reload_completed"
8641   [(parallel [(set (match_dup 0) (match_dup 1))
8642               (clobber (reg:CC FLAGS_REG))])]
8643 {
8644   rtx tmp;
8645   if (TARGET_64BIT)
8646     {
8647       tmp = gen_lowpart (DImode, operands[0]);
8648       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8649       operands[0] = tmp;
8650
8651       if (GET_CODE (operands[1]) == ABS)
8652         tmp = const0_rtx;
8653       else
8654         tmp = gen_rtx_NOT (DImode, tmp);
8655     }
8656   else
8657     {
8658       operands[0] = gen_highpart (SImode, operands[0]);
8659       if (GET_CODE (operands[1]) == ABS)
8660         {
8661           tmp = gen_int_mode (0x7fffffff, SImode);
8662           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8663         }
8664       else
8665         {
8666           tmp = gen_int_mode (0x80000000, SImode);
8667           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8668         }
8669     }
8670   operands[1] = tmp;
8671 })
8672
8673 (define_split
8674   [(set (match_operand:XF 0 "register_operand" "")
8675         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8676    (use (match_operand 2 "" ""))
8677    (clobber (reg:CC FLAGS_REG))]
8678   "reload_completed"
8679   [(parallel [(set (match_dup 0) (match_dup 1))
8680               (clobber (reg:CC FLAGS_REG))])]
8681 {
8682   rtx tmp;
8683   operands[0] = gen_rtx_REG (SImode,
8684                              true_regnum (operands[0])
8685                              + (TARGET_64BIT ? 1 : 2));
8686   if (GET_CODE (operands[1]) == ABS)
8687     {
8688       tmp = GEN_INT (0x7fff);
8689       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8690     }
8691   else
8692     {
8693       tmp = GEN_INT (0x8000);
8694       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8695     }
8696   operands[1] = tmp;
8697 })
8698
8699 ;; Conditionalize these after reload. If they match before reload, we
8700 ;; lose the clobber and ability to use integer instructions.
8701
8702 (define_insn "*<code><mode>2_1"
8703   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8704         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8705   "TARGET_80387
8706    && (reload_completed
8707        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8708   "f<absneg_mnemonic>"
8709   [(set_attr "type" "fsgn")
8710    (set_attr "mode" "<MODE>")])
8711
8712 (define_insn "*<code>extendsfdf2"
8713   [(set (match_operand:DF 0 "register_operand" "=f")
8714         (absneg:DF (float_extend:DF
8715                      (match_operand:SF 1 "register_operand" "0"))))]
8716   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8717   "f<absneg_mnemonic>"
8718   [(set_attr "type" "fsgn")
8719    (set_attr "mode" "DF")])
8720
8721 (define_insn "*<code>extendsfxf2"
8722   [(set (match_operand:XF 0 "register_operand" "=f")
8723         (absneg:XF (float_extend:XF
8724                      (match_operand:SF 1 "register_operand" "0"))))]
8725   "TARGET_80387"
8726   "f<absneg_mnemonic>"
8727   [(set_attr "type" "fsgn")
8728    (set_attr "mode" "XF")])
8729
8730 (define_insn "*<code>extenddfxf2"
8731   [(set (match_operand:XF 0 "register_operand" "=f")
8732         (absneg:XF (float_extend:XF
8733                      (match_operand:DF 1 "register_operand" "0"))))]
8734   "TARGET_80387"
8735   "f<absneg_mnemonic>"
8736   [(set_attr "type" "fsgn")
8737    (set_attr "mode" "XF")])
8738
8739 ;; Copysign instructions
8740
8741 (define_mode_iterator CSGNMODE [SF DF TF])
8742 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8743
8744 (define_expand "copysign<mode>3"
8745   [(match_operand:CSGNMODE 0 "register_operand" "")
8746    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8747    (match_operand:CSGNMODE 2 "register_operand" "")]
8748   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8749    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8750   "ix86_expand_copysign (operands); DONE;")
8751
8752 (define_insn_and_split "copysign<mode>3_const"
8753   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8754         (unspec:CSGNMODE
8755           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8756            (match_operand:CSGNMODE 2 "register_operand" "0")
8757            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8758           UNSPEC_COPYSIGN))]
8759   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8760    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8761   "#"
8762   "&& reload_completed"
8763   [(const_int 0)]
8764   "ix86_split_copysign_const (operands); DONE;")
8765
8766 (define_insn "copysign<mode>3_var"
8767   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8768         (unspec:CSGNMODE
8769           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8770            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8771            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8772            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8773           UNSPEC_COPYSIGN))
8774    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8775   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8776    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8777   "#")
8778
8779 (define_split
8780   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8781         (unspec:CSGNMODE
8782           [(match_operand:CSGNMODE 2 "register_operand" "")
8783            (match_operand:CSGNMODE 3 "register_operand" "")
8784            (match_operand:<CSGNVMODE> 4 "" "")
8785            (match_operand:<CSGNVMODE> 5 "" "")]
8786           UNSPEC_COPYSIGN))
8787    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8788   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8789     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8790    && reload_completed"
8791   [(const_int 0)]
8792   "ix86_split_copysign_var (operands); DONE;")
8793 \f
8794 ;; One complement instructions
8795
8796 (define_expand "one_cmpl<mode>2"
8797   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8798         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8799   ""
8800   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8801
8802 (define_insn "*one_cmpl<mode>2_1"
8803   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8804         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8805   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8806   "not{<imodesuffix>}\t%0"
8807   [(set_attr "type" "negnot")
8808    (set_attr "mode" "<MODE>")])
8809
8810 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8811 (define_insn "*one_cmplqi2_1"
8812   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8813         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8814   "ix86_unary_operator_ok (NOT, QImode, operands)"
8815   "@
8816    not{b}\t%0
8817    not{l}\t%k0"
8818   [(set_attr "type" "negnot")
8819    (set_attr "mode" "QI,SI")])
8820
8821 ;; ??? Currently never generated - xor is used instead.
8822 (define_insn "*one_cmplsi2_1_zext"
8823   [(set (match_operand:DI 0 "register_operand" "=r")
8824         (zero_extend:DI
8825           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8826   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8827   "not{l}\t%k0"
8828   [(set_attr "type" "negnot")
8829    (set_attr "mode" "SI")])
8830
8831 (define_insn "*one_cmpl<mode>2_2"
8832   [(set (reg FLAGS_REG)
8833         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8834                  (const_int 0)))
8835    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8836         (not:SWI (match_dup 1)))]
8837   "ix86_match_ccmode (insn, CCNOmode)
8838    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8839   "#"
8840   [(set_attr "type" "alu1")
8841    (set_attr "mode" "<MODE>")])
8842
8843 (define_split
8844   [(set (match_operand 0 "flags_reg_operand" "")
8845         (match_operator 2 "compare_operator"
8846           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8847            (const_int 0)]))
8848    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8849         (not:SWI (match_dup 3)))]
8850   "ix86_match_ccmode (insn, CCNOmode)"
8851   [(parallel [(set (match_dup 0)
8852                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8853                                     (const_int 0)]))
8854               (set (match_dup 1)
8855                    (xor:SWI (match_dup 3) (const_int -1)))])])
8856
8857 ;; ??? Currently never generated - xor is used instead.
8858 (define_insn "*one_cmplsi2_2_zext"
8859   [(set (reg FLAGS_REG)
8860         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8861                  (const_int 0)))
8862    (set (match_operand:DI 0 "register_operand" "=r")
8863         (zero_extend:DI (not:SI (match_dup 1))))]
8864   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8865    && ix86_unary_operator_ok (NOT, SImode, operands)"
8866   "#"
8867   [(set_attr "type" "alu1")
8868    (set_attr "mode" "SI")])
8869
8870 (define_split
8871   [(set (match_operand 0 "flags_reg_operand" "")
8872         (match_operator 2 "compare_operator"
8873           [(not:SI (match_operand:SI 3 "register_operand" ""))
8874            (const_int 0)]))
8875    (set (match_operand:DI 1 "register_operand" "")
8876         (zero_extend:DI (not:SI (match_dup 3))))]
8877   "ix86_match_ccmode (insn, CCNOmode)"
8878   [(parallel [(set (match_dup 0)
8879                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8880                                     (const_int 0)]))
8881               (set (match_dup 1)
8882                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8883 \f
8884 ;; Shift instructions
8885
8886 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8887 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8888 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8889 ;; from the assembler input.
8890 ;;
8891 ;; This instruction shifts the target reg/mem as usual, but instead of
8892 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8893 ;; is a left shift double, bits are taken from the high order bits of
8894 ;; reg, else if the insn is a shift right double, bits are taken from the
8895 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8896 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8897 ;;
8898 ;; Since sh[lr]d does not change the `reg' operand, that is done
8899 ;; separately, making all shifts emit pairs of shift double and normal
8900 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8901 ;; support a 63 bit shift, each shift where the count is in a reg expands
8902 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8903 ;;
8904 ;; If the shift count is a constant, we need never emit more than one
8905 ;; shift pair, instead using moves and sign extension for counts greater
8906 ;; than 31.
8907
8908 (define_expand "ashl<mode>3"
8909   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8910         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8911                       (match_operand:QI 2 "nonmemory_operand" "")))]
8912   ""
8913   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8914
8915 (define_insn "*ashl<mode>3_doubleword"
8916   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8917         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8918                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8919    (clobber (reg:CC FLAGS_REG))]
8920   ""
8921   "#"
8922   [(set_attr "type" "multi")])
8923
8924 (define_split
8925   [(set (match_operand:DWI 0 "register_operand" "")
8926         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8927                     (match_operand:QI 2 "nonmemory_operand" "")))
8928    (clobber (reg:CC FLAGS_REG))]
8929   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8930   [(const_int 0)]
8931   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8932
8933 ;; By default we don't ask for a scratch register, because when DWImode
8934 ;; values are manipulated, registers are already at a premium.  But if
8935 ;; we have one handy, we won't turn it away.
8936
8937 (define_peephole2
8938   [(match_scratch:DWIH 3 "r")
8939    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8940                    (ashift:<DWI>
8941                      (match_operand:<DWI> 1 "nonmemory_operand" "")
8942                      (match_operand:QI 2 "nonmemory_operand" "")))
8943               (clobber (reg:CC FLAGS_REG))])
8944    (match_dup 3)]
8945   "TARGET_CMOVE"
8946   [(const_int 0)]
8947   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8948
8949 (define_insn "x86_64_shld"
8950   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8951         (ior:DI (ashift:DI (match_dup 0)
8952                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
8953                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8954                   (minus:QI (const_int 64) (match_dup 2)))))
8955    (clobber (reg:CC FLAGS_REG))]
8956   "TARGET_64BIT"
8957   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8958   [(set_attr "type" "ishift")
8959    (set_attr "prefix_0f" "1")
8960    (set_attr "mode" "DI")
8961    (set_attr "athlon_decode" "vector")
8962    (set_attr "amdfam10_decode" "vector")
8963    (set_attr "bdver1_decode" "vector")])
8964
8965 (define_insn "x86_shld"
8966   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8967         (ior:SI (ashift:SI (match_dup 0)
8968                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
8969                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8970                   (minus:QI (const_int 32) (match_dup 2)))))
8971    (clobber (reg:CC FLAGS_REG))]
8972   ""
8973   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8974   [(set_attr "type" "ishift")
8975    (set_attr "prefix_0f" "1")
8976    (set_attr "mode" "SI")
8977    (set_attr "pent_pair" "np")
8978    (set_attr "athlon_decode" "vector")
8979    (set_attr "amdfam10_decode" "vector")
8980    (set_attr "bdver1_decode" "vector")])
8981
8982 (define_expand "x86_shift<mode>_adj_1"
8983   [(set (reg:CCZ FLAGS_REG)
8984         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8985                              (match_dup 4))
8986                      (const_int 0)))
8987    (set (match_operand:SWI48 0 "register_operand" "")
8988         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8989                             (match_operand:SWI48 1 "register_operand" "")
8990                             (match_dup 0)))
8991    (set (match_dup 1)
8992         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8993                             (match_operand:SWI48 3 "register_operand" "r")
8994                             (match_dup 1)))]
8995   "TARGET_CMOVE"
8996   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8997
8998 (define_expand "x86_shift<mode>_adj_2"
8999   [(use (match_operand:SWI48 0 "register_operand" ""))
9000    (use (match_operand:SWI48 1 "register_operand" ""))
9001    (use (match_operand:QI 2 "register_operand" ""))]
9002   ""
9003 {
9004   rtx label = gen_label_rtx ();
9005   rtx tmp;
9006
9007   emit_insn (gen_testqi_ccz_1 (operands[2],
9008                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9009
9010   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9011   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9012   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9013                               gen_rtx_LABEL_REF (VOIDmode, label),
9014                               pc_rtx);
9015   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9016   JUMP_LABEL (tmp) = label;
9017
9018   emit_move_insn (operands[0], operands[1]);
9019   ix86_expand_clear (operands[1]);
9020
9021   emit_label (label);
9022   LABEL_NUSES (label) = 1;
9023
9024   DONE;
9025 })
9026
9027 ;; Avoid useless masking of count operand.
9028 (define_insn_and_split "*ashl<mode>3_mask"
9029   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9030         (ashift:SWI48
9031           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9032           (subreg:QI
9033             (and:SI
9034               (match_operand:SI 2 "nonimmediate_operand" "c")
9035               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9036    (clobber (reg:CC FLAGS_REG))]
9037   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9038    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9039       == GET_MODE_BITSIZE (<MODE>mode)-1"
9040   "#"
9041   "&& 1"
9042   [(parallel [(set (match_dup 0)
9043                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9044               (clobber (reg:CC FLAGS_REG))])]
9045 {
9046   if (can_create_pseudo_p ())
9047     operands [2] = force_reg (SImode, operands[2]);
9048
9049   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9050 }
9051   [(set_attr "type" "ishift")
9052    (set_attr "mode" "<MODE>")])
9053
9054 (define_insn "*ashl<mode>3_1"
9055   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9056         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9057                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9058    (clobber (reg:CC FLAGS_REG))]
9059   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9060 {
9061   switch (get_attr_type (insn))
9062     {
9063     case TYPE_LEA:
9064       return "#";
9065
9066     case TYPE_ALU:
9067       gcc_assert (operands[2] == const1_rtx);
9068       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9069       return "add{<imodesuffix>}\t%0, %0";
9070
9071     default:
9072       if (operands[2] == const1_rtx
9073           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9074         return "sal{<imodesuffix>}\t%0";
9075       else
9076         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9077     }
9078 }
9079   [(set (attr "type")
9080      (cond [(eq_attr "alternative" "1")
9081               (const_string "lea")
9082             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9083                           (const_int 0))
9084                       (match_operand 0 "register_operand" ""))
9085                  (match_operand 2 "const1_operand" ""))
9086               (const_string "alu")
9087            ]
9088            (const_string "ishift")))
9089    (set (attr "length_immediate")
9090      (if_then_else
9091        (ior (eq_attr "type" "alu")
9092             (and (eq_attr "type" "ishift")
9093                  (and (match_operand 2 "const1_operand" "")
9094                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9095                           (const_int 0)))))
9096        (const_string "0")
9097        (const_string "*")))
9098    (set_attr "mode" "<MODE>")])
9099
9100 (define_insn "*ashlsi3_1_zext"
9101   [(set (match_operand:DI 0 "register_operand" "=r,r")
9102         (zero_extend:DI
9103           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9104                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9105    (clobber (reg:CC FLAGS_REG))]
9106   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9107 {
9108   switch (get_attr_type (insn))
9109     {
9110     case TYPE_LEA:
9111       return "#";
9112
9113     case TYPE_ALU:
9114       gcc_assert (operands[2] == const1_rtx);
9115       return "add{l}\t%k0, %k0";
9116
9117     default:
9118       if (operands[2] == const1_rtx
9119           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9120         return "sal{l}\t%k0";
9121       else
9122         return "sal{l}\t{%2, %k0|%k0, %2}";
9123     }
9124 }
9125   [(set (attr "type")
9126      (cond [(eq_attr "alternative" "1")
9127               (const_string "lea")
9128             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9129                      (const_int 0))
9130                  (match_operand 2 "const1_operand" ""))
9131               (const_string "alu")
9132            ]
9133            (const_string "ishift")))
9134    (set (attr "length_immediate")
9135      (if_then_else
9136        (ior (eq_attr "type" "alu")
9137             (and (eq_attr "type" "ishift")
9138                  (and (match_operand 2 "const1_operand" "")
9139                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9140                           (const_int 0)))))
9141        (const_string "0")
9142        (const_string "*")))
9143    (set_attr "mode" "SI")])
9144
9145 (define_insn "*ashlhi3_1"
9146   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9147         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9148                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9149    (clobber (reg:CC FLAGS_REG))]
9150   "TARGET_PARTIAL_REG_STALL
9151    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9152 {
9153   switch (get_attr_type (insn))
9154     {
9155     case TYPE_ALU:
9156       gcc_assert (operands[2] == const1_rtx);
9157       return "add{w}\t%0, %0";
9158
9159     default:
9160       if (operands[2] == const1_rtx
9161           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9162         return "sal{w}\t%0";
9163       else
9164         return "sal{w}\t{%2, %0|%0, %2}";
9165     }
9166 }
9167   [(set (attr "type")
9168      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9169                           (const_int 0))
9170                       (match_operand 0 "register_operand" ""))
9171                  (match_operand 2 "const1_operand" ""))
9172               (const_string "alu")
9173            ]
9174            (const_string "ishift")))
9175    (set (attr "length_immediate")
9176      (if_then_else
9177        (ior (eq_attr "type" "alu")
9178             (and (eq_attr "type" "ishift")
9179                  (and (match_operand 2 "const1_operand" "")
9180                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9181                           (const_int 0)))))
9182        (const_string "0")
9183        (const_string "*")))
9184    (set_attr "mode" "HI")])
9185
9186 (define_insn "*ashlhi3_1_lea"
9187   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9188         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9189                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9190    (clobber (reg:CC FLAGS_REG))]
9191   "!TARGET_PARTIAL_REG_STALL
9192    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9193 {
9194   switch (get_attr_type (insn))
9195     {
9196     case TYPE_LEA:
9197       return "#";
9198
9199     case TYPE_ALU:
9200       gcc_assert (operands[2] == const1_rtx);
9201       return "add{w}\t%0, %0";
9202
9203     default:
9204       if (operands[2] == const1_rtx
9205           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9206         return "sal{w}\t%0";
9207       else
9208         return "sal{w}\t{%2, %0|%0, %2}";
9209     }
9210 }
9211   [(set (attr "type")
9212      (cond [(eq_attr "alternative" "1")
9213               (const_string "lea")
9214             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9215                           (const_int 0))
9216                       (match_operand 0 "register_operand" ""))
9217                  (match_operand 2 "const1_operand" ""))
9218               (const_string "alu")
9219            ]
9220            (const_string "ishift")))
9221    (set (attr "length_immediate")
9222      (if_then_else
9223        (ior (eq_attr "type" "alu")
9224             (and (eq_attr "type" "ishift")
9225                  (and (match_operand 2 "const1_operand" "")
9226                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9227                           (const_int 0)))))
9228        (const_string "0")
9229        (const_string "*")))
9230    (set_attr "mode" "HI,SI")])
9231
9232 (define_insn "*ashlqi3_1"
9233   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9234         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9235                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9236    (clobber (reg:CC FLAGS_REG))]
9237   "TARGET_PARTIAL_REG_STALL
9238    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9239 {
9240   switch (get_attr_type (insn))
9241     {
9242     case TYPE_ALU:
9243       gcc_assert (operands[2] == const1_rtx);
9244       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9245         return "add{l}\t%k0, %k0";
9246       else
9247         return "add{b}\t%0, %0";
9248
9249     default:
9250       if (operands[2] == const1_rtx
9251           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9252         {
9253           if (get_attr_mode (insn) == MODE_SI)
9254             return "sal{l}\t%k0";
9255           else
9256             return "sal{b}\t%0";
9257         }
9258       else
9259         {
9260           if (get_attr_mode (insn) == MODE_SI)
9261             return "sal{l}\t{%2, %k0|%k0, %2}";
9262           else
9263             return "sal{b}\t{%2, %0|%0, %2}";
9264         }
9265     }
9266 }
9267   [(set (attr "type")
9268      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9269                           (const_int 0))
9270                       (match_operand 0 "register_operand" ""))
9271                  (match_operand 2 "const1_operand" ""))
9272               (const_string "alu")
9273            ]
9274            (const_string "ishift")))
9275    (set (attr "length_immediate")
9276      (if_then_else
9277        (ior (eq_attr "type" "alu")
9278             (and (eq_attr "type" "ishift")
9279                  (and (match_operand 2 "const1_operand" "")
9280                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9281                           (const_int 0)))))
9282        (const_string "0")
9283        (const_string "*")))
9284    (set_attr "mode" "QI,SI")])
9285
9286 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9287 (define_insn "*ashlqi3_1_lea"
9288   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9289         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9290                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9291    (clobber (reg:CC FLAGS_REG))]
9292   "!TARGET_PARTIAL_REG_STALL
9293    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9294 {
9295   switch (get_attr_type (insn))
9296     {
9297     case TYPE_LEA:
9298       return "#";
9299
9300     case TYPE_ALU:
9301       gcc_assert (operands[2] == const1_rtx);
9302       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9303         return "add{l}\t%k0, %k0";
9304       else
9305         return "add{b}\t%0, %0";
9306
9307     default:
9308       if (operands[2] == const1_rtx
9309           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9310         {
9311           if (get_attr_mode (insn) == MODE_SI)
9312             return "sal{l}\t%k0";
9313           else
9314             return "sal{b}\t%0";
9315         }
9316       else
9317         {
9318           if (get_attr_mode (insn) == MODE_SI)
9319             return "sal{l}\t{%2, %k0|%k0, %2}";
9320           else
9321             return "sal{b}\t{%2, %0|%0, %2}";
9322         }
9323     }
9324 }
9325   [(set (attr "type")
9326      (cond [(eq_attr "alternative" "2")
9327               (const_string "lea")
9328             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9329                           (const_int 0))
9330                       (match_operand 0 "register_operand" ""))
9331                  (match_operand 2 "const1_operand" ""))
9332               (const_string "alu")
9333            ]
9334            (const_string "ishift")))
9335    (set (attr "length_immediate")
9336      (if_then_else
9337        (ior (eq_attr "type" "alu")
9338             (and (eq_attr "type" "ishift")
9339                  (and (match_operand 2 "const1_operand" "")
9340                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9341                           (const_int 0)))))
9342        (const_string "0")
9343        (const_string "*")))
9344    (set_attr "mode" "QI,SI,SI")])
9345
9346 (define_insn "*ashlqi3_1_slp"
9347   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9348         (ashift:QI (match_dup 0)
9349                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9350    (clobber (reg:CC FLAGS_REG))]
9351   "(optimize_function_for_size_p (cfun)
9352     || !TARGET_PARTIAL_FLAG_REG_STALL
9353     || (operands[1] == const1_rtx
9354         && (TARGET_SHIFT1
9355             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9356 {
9357   switch (get_attr_type (insn))
9358     {
9359     case TYPE_ALU:
9360       gcc_assert (operands[1] == const1_rtx);
9361       return "add{b}\t%0, %0";
9362
9363     default:
9364       if (operands[1] == const1_rtx
9365           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9366         return "sal{b}\t%0";
9367       else
9368         return "sal{b}\t{%1, %0|%0, %1}";
9369     }
9370 }
9371   [(set (attr "type")
9372      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9373                           (const_int 0))
9374                       (match_operand 0 "register_operand" ""))
9375                  (match_operand 1 "const1_operand" ""))
9376               (const_string "alu")
9377            ]
9378            (const_string "ishift1")))
9379    (set (attr "length_immediate")
9380      (if_then_else
9381        (ior (eq_attr "type" "alu")
9382             (and (eq_attr "type" "ishift1")
9383                  (and (match_operand 1 "const1_operand" "")
9384                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9385                           (const_int 0)))))
9386        (const_string "0")
9387        (const_string "*")))
9388    (set_attr "mode" "QI")])
9389
9390 ;; Convert lea to the lea pattern to avoid flags dependency.
9391 (define_split
9392   [(set (match_operand 0 "register_operand" "")
9393         (ashift (match_operand 1 "index_register_operand" "")
9394                 (match_operand:QI 2 "const_int_operand" "")))
9395    (clobber (reg:CC FLAGS_REG))]
9396   "reload_completed
9397    && true_regnum (operands[0]) != true_regnum (operands[1])"
9398   [(const_int 0)]
9399 {
9400   rtx pat;
9401   enum machine_mode mode = GET_MODE (operands[0]);
9402
9403   if (mode != Pmode)
9404     operands[1] = gen_lowpart (Pmode, operands[1]);
9405   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9406
9407   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9408
9409   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9410     operands[0] = gen_lowpart (SImode, operands[0]);
9411
9412   if (TARGET_64BIT && mode != Pmode)
9413     pat = gen_rtx_SUBREG (SImode, pat, 0);
9414
9415   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9416   DONE;
9417 })
9418
9419 ;; Convert lea to the lea pattern to avoid flags dependency.
9420 (define_split
9421   [(set (match_operand:DI 0 "register_operand" "")
9422         (zero_extend:DI
9423           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9424                      (match_operand:QI 2 "const_int_operand" ""))))
9425    (clobber (reg:CC FLAGS_REG))]
9426   "TARGET_64BIT && reload_completed
9427    && true_regnum (operands[0]) != true_regnum (operands[1])"
9428   [(set (match_dup 0)
9429         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9430 {
9431   operands[1] = gen_lowpart (DImode, operands[1]);
9432   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9433 })
9434
9435 ;; This pattern can't accept a variable shift count, since shifts by
9436 ;; zero don't affect the flags.  We assume that shifts by constant
9437 ;; zero are optimized away.
9438 (define_insn "*ashl<mode>3_cmp"
9439   [(set (reg FLAGS_REG)
9440         (compare
9441           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9442                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9443           (const_int 0)))
9444    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9445         (ashift:SWI (match_dup 1) (match_dup 2)))]
9446   "(optimize_function_for_size_p (cfun)
9447     || !TARGET_PARTIAL_FLAG_REG_STALL
9448     || (operands[2] == const1_rtx
9449         && (TARGET_SHIFT1
9450             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9451    && ix86_match_ccmode (insn, CCGOCmode)
9452    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9453 {
9454   switch (get_attr_type (insn))
9455     {
9456     case TYPE_ALU:
9457       gcc_assert (operands[2] == const1_rtx);
9458       return "add{<imodesuffix>}\t%0, %0";
9459
9460     default:
9461       if (operands[2] == const1_rtx
9462           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9463         return "sal{<imodesuffix>}\t%0";
9464       else
9465         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9466     }
9467 }
9468   [(set (attr "type")
9469      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9470                           (const_int 0))
9471                       (match_operand 0 "register_operand" ""))
9472                  (match_operand 2 "const1_operand" ""))
9473               (const_string "alu")
9474            ]
9475            (const_string "ishift")))
9476    (set (attr "length_immediate")
9477      (if_then_else
9478        (ior (eq_attr "type" "alu")
9479             (and (eq_attr "type" "ishift")
9480                  (and (match_operand 2 "const1_operand" "")
9481                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9482                           (const_int 0)))))
9483        (const_string "0")
9484        (const_string "*")))
9485    (set_attr "mode" "<MODE>")])
9486
9487 (define_insn "*ashlsi3_cmp_zext"
9488   [(set (reg FLAGS_REG)
9489         (compare
9490           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9491                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9492           (const_int 0)))
9493    (set (match_operand:DI 0 "register_operand" "=r")
9494         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9495   "TARGET_64BIT
9496    && (optimize_function_for_size_p (cfun)
9497        || !TARGET_PARTIAL_FLAG_REG_STALL
9498        || (operands[2] == const1_rtx
9499            && (TARGET_SHIFT1
9500                || TARGET_DOUBLE_WITH_ADD)))
9501    && ix86_match_ccmode (insn, CCGOCmode)
9502    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9503 {
9504   switch (get_attr_type (insn))
9505     {
9506     case TYPE_ALU:
9507       gcc_assert (operands[2] == const1_rtx);
9508       return "add{l}\t%k0, %k0";
9509
9510     default:
9511       if (operands[2] == const1_rtx
9512           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513         return "sal{l}\t%k0";
9514       else
9515         return "sal{l}\t{%2, %k0|%k0, %2}";
9516     }
9517 }
9518   [(set (attr "type")
9519      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9520                      (const_int 0))
9521                  (match_operand 2 "const1_operand" ""))
9522               (const_string "alu")
9523            ]
9524            (const_string "ishift")))
9525    (set (attr "length_immediate")
9526      (if_then_else
9527        (ior (eq_attr "type" "alu")
9528             (and (eq_attr "type" "ishift")
9529                  (and (match_operand 2 "const1_operand" "")
9530                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9531                           (const_int 0)))))
9532        (const_string "0")
9533        (const_string "*")))
9534    (set_attr "mode" "SI")])
9535
9536 (define_insn "*ashl<mode>3_cconly"
9537   [(set (reg FLAGS_REG)
9538         (compare
9539           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9540                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9541           (const_int 0)))
9542    (clobber (match_scratch:SWI 0 "=<r>"))]
9543   "(optimize_function_for_size_p (cfun)
9544     || !TARGET_PARTIAL_FLAG_REG_STALL
9545     || (operands[2] == const1_rtx
9546         && (TARGET_SHIFT1
9547             || TARGET_DOUBLE_WITH_ADD)))
9548    && ix86_match_ccmode (insn, CCGOCmode)"
9549 {
9550   switch (get_attr_type (insn))
9551     {
9552     case TYPE_ALU:
9553       gcc_assert (operands[2] == const1_rtx);
9554       return "add{<imodesuffix>}\t%0, %0";
9555
9556     default:
9557       if (operands[2] == const1_rtx
9558           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9559         return "sal{<imodesuffix>}\t%0";
9560       else
9561         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9562     }
9563 }
9564   [(set (attr "type")
9565      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9566                           (const_int 0))
9567                       (match_operand 0 "register_operand" ""))
9568                  (match_operand 2 "const1_operand" ""))
9569               (const_string "alu")
9570            ]
9571            (const_string "ishift")))
9572    (set (attr "length_immediate")
9573      (if_then_else
9574        (ior (eq_attr "type" "alu")
9575             (and (eq_attr "type" "ishift")
9576                  (and (match_operand 2 "const1_operand" "")
9577                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9578                           (const_int 0)))))
9579        (const_string "0")
9580        (const_string "*")))
9581    (set_attr "mode" "<MODE>")])
9582
9583 ;; See comment above `ashl<mode>3' about how this works.
9584
9585 (define_expand "<shiftrt_insn><mode>3"
9586   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9587         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9588                            (match_operand:QI 2 "nonmemory_operand" "")))]
9589   ""
9590   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9591
9592 ;; Avoid useless masking of count operand.
9593 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9594   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9595         (any_shiftrt:SWI48
9596           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9597           (subreg:QI
9598             (and:SI
9599               (match_operand:SI 2 "nonimmediate_operand" "c")
9600               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9601    (clobber (reg:CC FLAGS_REG))]
9602   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9603    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9604       == GET_MODE_BITSIZE (<MODE>mode)-1"
9605   "#"
9606   "&& 1"
9607   [(parallel [(set (match_dup 0)
9608                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9609               (clobber (reg:CC FLAGS_REG))])]
9610 {
9611   if (can_create_pseudo_p ())
9612     operands [2] = force_reg (SImode, operands[2]);
9613
9614   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9615 }
9616   [(set_attr "type" "ishift")
9617    (set_attr "mode" "<MODE>")])
9618
9619 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9620   [(set (match_operand:DWI 0 "register_operand" "=r")
9621         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9622                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9623    (clobber (reg:CC FLAGS_REG))]
9624   ""
9625   "#"
9626   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9627   [(const_int 0)]
9628   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9629   [(set_attr "type" "multi")])
9630
9631 ;; By default we don't ask for a scratch register, because when DWImode
9632 ;; values are manipulated, registers are already at a premium.  But if
9633 ;; we have one handy, we won't turn it away.
9634
9635 (define_peephole2
9636   [(match_scratch:DWIH 3 "r")
9637    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9638                    (any_shiftrt:<DWI>
9639                      (match_operand:<DWI> 1 "register_operand" "")
9640                      (match_operand:QI 2 "nonmemory_operand" "")))
9641               (clobber (reg:CC FLAGS_REG))])
9642    (match_dup 3)]
9643   "TARGET_CMOVE"
9644   [(const_int 0)]
9645   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9646
9647 (define_insn "x86_64_shrd"
9648   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9649         (ior:DI (ashiftrt:DI (match_dup 0)
9650                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9651                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9652                   (minus:QI (const_int 64) (match_dup 2)))))
9653    (clobber (reg:CC FLAGS_REG))]
9654   "TARGET_64BIT"
9655   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9656   [(set_attr "type" "ishift")
9657    (set_attr "prefix_0f" "1")
9658    (set_attr "mode" "DI")
9659    (set_attr "athlon_decode" "vector")
9660    (set_attr "amdfam10_decode" "vector")
9661    (set_attr "bdver1_decode" "vector")])
9662
9663 (define_insn "x86_shrd"
9664   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9665         (ior:SI (ashiftrt:SI (match_dup 0)
9666                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9667                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9668                   (minus:QI (const_int 32) (match_dup 2)))))
9669    (clobber (reg:CC FLAGS_REG))]
9670   ""
9671   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9672   [(set_attr "type" "ishift")
9673    (set_attr "prefix_0f" "1")
9674    (set_attr "mode" "SI")
9675    (set_attr "pent_pair" "np")
9676    (set_attr "athlon_decode" "vector")
9677    (set_attr "amdfam10_decode" "vector")
9678    (set_attr "bdver1_decode" "vector")])
9679
9680 (define_insn "ashrdi3_cvt"
9681   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9682         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9683                      (match_operand:QI 2 "const_int_operand" "")))
9684    (clobber (reg:CC FLAGS_REG))]
9685   "TARGET_64BIT && INTVAL (operands[2]) == 63
9686    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9687    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9688   "@
9689    {cqto|cqo}
9690    sar{q}\t{%2, %0|%0, %2}"
9691   [(set_attr "type" "imovx,ishift")
9692    (set_attr "prefix_0f" "0,*")
9693    (set_attr "length_immediate" "0,*")
9694    (set_attr "modrm" "0,1")
9695    (set_attr "mode" "DI")])
9696
9697 (define_insn "ashrsi3_cvt"
9698   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9699         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9700                      (match_operand:QI 2 "const_int_operand" "")))
9701    (clobber (reg:CC FLAGS_REG))]
9702   "INTVAL (operands[2]) == 31
9703    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9704    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9705   "@
9706    {cltd|cdq}
9707    sar{l}\t{%2, %0|%0, %2}"
9708   [(set_attr "type" "imovx,ishift")
9709    (set_attr "prefix_0f" "0,*")
9710    (set_attr "length_immediate" "0,*")
9711    (set_attr "modrm" "0,1")
9712    (set_attr "mode" "SI")])
9713
9714 (define_insn "*ashrsi3_cvt_zext"
9715   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9716         (zero_extend:DI
9717           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9718                        (match_operand:QI 2 "const_int_operand" ""))))
9719    (clobber (reg:CC FLAGS_REG))]
9720   "TARGET_64BIT && INTVAL (operands[2]) == 31
9721    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9722    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9723   "@
9724    {cltd|cdq}
9725    sar{l}\t{%2, %k0|%k0, %2}"
9726   [(set_attr "type" "imovx,ishift")
9727    (set_attr "prefix_0f" "0,*")
9728    (set_attr "length_immediate" "0,*")
9729    (set_attr "modrm" "0,1")
9730    (set_attr "mode" "SI")])
9731
9732 (define_expand "x86_shift<mode>_adj_3"
9733   [(use (match_operand:SWI48 0 "register_operand" ""))
9734    (use (match_operand:SWI48 1 "register_operand" ""))
9735    (use (match_operand:QI 2 "register_operand" ""))]
9736   ""
9737 {
9738   rtx label = gen_label_rtx ();
9739   rtx tmp;
9740
9741   emit_insn (gen_testqi_ccz_1 (operands[2],
9742                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9743
9744   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9745   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9746   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9747                               gen_rtx_LABEL_REF (VOIDmode, label),
9748                               pc_rtx);
9749   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9750   JUMP_LABEL (tmp) = label;
9751
9752   emit_move_insn (operands[0], operands[1]);
9753   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9754                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9755   emit_label (label);
9756   LABEL_NUSES (label) = 1;
9757
9758   DONE;
9759 })
9760
9761 (define_insn "*<shiftrt_insn><mode>3_1"
9762   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9763         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9764                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9765    (clobber (reg:CC FLAGS_REG))]
9766   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9767 {
9768   if (operands[2] == const1_rtx
9769       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9770     return "<shiftrt>{<imodesuffix>}\t%0";
9771   else
9772     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9773 }
9774   [(set_attr "type" "ishift")
9775    (set (attr "length_immediate")
9776      (if_then_else
9777        (and (match_operand 2 "const1_operand" "")
9778             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9779                 (const_int 0)))
9780        (const_string "0")
9781        (const_string "*")))
9782    (set_attr "mode" "<MODE>")])
9783
9784 (define_insn "*<shiftrt_insn>si3_1_zext"
9785   [(set (match_operand:DI 0 "register_operand" "=r")
9786         (zero_extend:DI
9787           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9788                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9789    (clobber (reg:CC FLAGS_REG))]
9790   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9791 {
9792   if (operands[2] == const1_rtx
9793       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9794     return "<shiftrt>{l}\t%k0";
9795   else
9796     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9797 }
9798   [(set_attr "type" "ishift")
9799    (set (attr "length_immediate")
9800      (if_then_else
9801        (and (match_operand 2 "const1_operand" "")
9802             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9803                 (const_int 0)))
9804        (const_string "0")
9805        (const_string "*")))
9806    (set_attr "mode" "SI")])
9807
9808 (define_insn "*<shiftrt_insn>qi3_1_slp"
9809   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9810         (any_shiftrt:QI (match_dup 0)
9811                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9812    (clobber (reg:CC FLAGS_REG))]
9813   "(optimize_function_for_size_p (cfun)
9814     || !TARGET_PARTIAL_REG_STALL
9815     || (operands[1] == const1_rtx
9816         && TARGET_SHIFT1))"
9817 {
9818   if (operands[1] == const1_rtx
9819       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9820     return "<shiftrt>{b}\t%0";
9821   else
9822     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9823 }
9824   [(set_attr "type" "ishift1")
9825    (set (attr "length_immediate")
9826      (if_then_else
9827        (and (match_operand 1 "const1_operand" "")
9828             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9829                 (const_int 0)))
9830        (const_string "0")
9831        (const_string "*")))
9832    (set_attr "mode" "QI")])
9833
9834 ;; This pattern can't accept a variable shift count, since shifts by
9835 ;; zero don't affect the flags.  We assume that shifts by constant
9836 ;; zero are optimized away.
9837 (define_insn "*<shiftrt_insn><mode>3_cmp"
9838   [(set (reg FLAGS_REG)
9839         (compare
9840           (any_shiftrt:SWI
9841             (match_operand:SWI 1 "nonimmediate_operand" "0")
9842             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9843           (const_int 0)))
9844    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9845         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9846   "(optimize_function_for_size_p (cfun)
9847     || !TARGET_PARTIAL_FLAG_REG_STALL
9848     || (operands[2] == const1_rtx
9849         && TARGET_SHIFT1))
9850    && ix86_match_ccmode (insn, CCGOCmode)
9851    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9852 {
9853   if (operands[2] == const1_rtx
9854       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9855     return "<shiftrt>{<imodesuffix>}\t%0";
9856   else
9857     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9858 }
9859   [(set_attr "type" "ishift")
9860    (set (attr "length_immediate")
9861      (if_then_else
9862        (and (match_operand 2 "const1_operand" "")
9863             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9864                 (const_int 0)))
9865        (const_string "0")
9866        (const_string "*")))
9867    (set_attr "mode" "<MODE>")])
9868
9869 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9870   [(set (reg FLAGS_REG)
9871         (compare
9872           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9873                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9874           (const_int 0)))
9875    (set (match_operand:DI 0 "register_operand" "=r")
9876         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9877   "TARGET_64BIT
9878    && (optimize_function_for_size_p (cfun)
9879        || !TARGET_PARTIAL_FLAG_REG_STALL
9880        || (operands[2] == const1_rtx
9881            && TARGET_SHIFT1))
9882    && ix86_match_ccmode (insn, CCGOCmode)
9883    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9884 {
9885   if (operands[2] == const1_rtx
9886       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9887     return "<shiftrt>{l}\t%k0";
9888   else
9889     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9890 }
9891   [(set_attr "type" "ishift")
9892    (set (attr "length_immediate")
9893      (if_then_else
9894        (and (match_operand 2 "const1_operand" "")
9895             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9896                 (const_int 0)))
9897        (const_string "0")
9898        (const_string "*")))
9899    (set_attr "mode" "SI")])
9900
9901 (define_insn "*<shiftrt_insn><mode>3_cconly"
9902   [(set (reg FLAGS_REG)
9903         (compare
9904           (any_shiftrt:SWI
9905             (match_operand:SWI 1 "register_operand" "0")
9906             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9907           (const_int 0)))
9908    (clobber (match_scratch:SWI 0 "=<r>"))]
9909   "(optimize_function_for_size_p (cfun)
9910     || !TARGET_PARTIAL_FLAG_REG_STALL
9911     || (operands[2] == const1_rtx
9912         && TARGET_SHIFT1))
9913    && ix86_match_ccmode (insn, CCGOCmode)"
9914 {
9915   if (operands[2] == const1_rtx
9916       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9917     return "<shiftrt>{<imodesuffix>}\t%0";
9918   else
9919     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9920 }
9921   [(set_attr "type" "ishift")
9922    (set (attr "length_immediate")
9923      (if_then_else
9924        (and (match_operand 2 "const1_operand" "")
9925             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9926                 (const_int 0)))
9927        (const_string "0")
9928        (const_string "*")))
9929    (set_attr "mode" "<MODE>")])
9930 \f
9931 ;; Rotate instructions
9932
9933 (define_expand "<rotate_insn>ti3"
9934   [(set (match_operand:TI 0 "register_operand" "")
9935         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9936                        (match_operand:QI 2 "nonmemory_operand" "")))]
9937   "TARGET_64BIT"
9938 {
9939   if (const_1_to_63_operand (operands[2], VOIDmode))
9940     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9941                 (operands[0], operands[1], operands[2]));
9942   else
9943     FAIL;
9944
9945   DONE;
9946 })
9947
9948 (define_expand "<rotate_insn>di3"
9949   [(set (match_operand:DI 0 "shiftdi_operand" "")
9950         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9951                        (match_operand:QI 2 "nonmemory_operand" "")))]
9952  ""
9953 {
9954   if (TARGET_64BIT)
9955     ix86_expand_binary_operator (<CODE>, DImode, operands);
9956   else if (const_1_to_31_operand (operands[2], VOIDmode))
9957     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9958                 (operands[0], operands[1], operands[2]));
9959   else
9960     FAIL;
9961
9962   DONE;
9963 })
9964
9965 (define_expand "<rotate_insn><mode>3"
9966   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9967         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9968                             (match_operand:QI 2 "nonmemory_operand" "")))]
9969   ""
9970   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9971
9972 ;; Avoid useless masking of count operand.
9973 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9974   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9975         (any_rotate:SWI48
9976           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9977           (subreg:QI
9978             (and:SI
9979               (match_operand:SI 2 "nonimmediate_operand" "c")
9980               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9981    (clobber (reg:CC FLAGS_REG))]
9982   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9983    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9984       == GET_MODE_BITSIZE (<MODE>mode)-1"
9985   "#"
9986   "&& 1"
9987   [(parallel [(set (match_dup 0)
9988                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9989               (clobber (reg:CC FLAGS_REG))])]
9990 {
9991   if (can_create_pseudo_p ())
9992     operands [2] = force_reg (SImode, operands[2]);
9993
9994   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9995 }
9996   [(set_attr "type" "rotate")
9997    (set_attr "mode" "<MODE>")])
9998
9999 ;; Implement rotation using two double-precision
10000 ;; shift instructions and a scratch register.
10001
10002 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10003  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10004        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10005                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10006   (clobber (reg:CC FLAGS_REG))
10007   (clobber (match_scratch:DWIH 3 "=&r"))]
10008  ""
10009  "#"
10010  "reload_completed"
10011  [(set (match_dup 3) (match_dup 4))
10012   (parallel
10013    [(set (match_dup 4)
10014          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10015                    (lshiftrt:DWIH (match_dup 5)
10016                                   (minus:QI (match_dup 6) (match_dup 2)))))
10017     (clobber (reg:CC FLAGS_REG))])
10018   (parallel
10019    [(set (match_dup 5)
10020          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10021                    (lshiftrt:DWIH (match_dup 3)
10022                                   (minus:QI (match_dup 6) (match_dup 2)))))
10023     (clobber (reg:CC FLAGS_REG))])]
10024 {
10025   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10026
10027   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10028 })
10029
10030 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10031  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10032        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10033                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10034   (clobber (reg:CC FLAGS_REG))
10035   (clobber (match_scratch:DWIH 3 "=&r"))]
10036  ""
10037  "#"
10038  "reload_completed"
10039  [(set (match_dup 3) (match_dup 4))
10040   (parallel
10041    [(set (match_dup 4)
10042          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10043                    (ashift:DWIH (match_dup 5)
10044                                 (minus:QI (match_dup 6) (match_dup 2)))))
10045     (clobber (reg:CC FLAGS_REG))])
10046   (parallel
10047    [(set (match_dup 5)
10048          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10049                    (ashift:DWIH (match_dup 3)
10050                                 (minus:QI (match_dup 6) (match_dup 2)))))
10051     (clobber (reg:CC FLAGS_REG))])]
10052 {
10053   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10054
10055   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10056 })
10057
10058 (define_insn "*<rotate_insn><mode>3_1"
10059   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10060         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10061                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10062    (clobber (reg:CC FLAGS_REG))]
10063   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10064 {
10065   if (operands[2] == const1_rtx
10066       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10067     return "<rotate>{<imodesuffix>}\t%0";
10068   else
10069     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10070 }
10071   [(set_attr "type" "rotate")
10072    (set (attr "length_immediate")
10073      (if_then_else
10074        (and (match_operand 2 "const1_operand" "")
10075             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10076                 (const_int 0)))
10077        (const_string "0")
10078        (const_string "*")))
10079    (set_attr "mode" "<MODE>")])
10080
10081 (define_insn "*<rotate_insn>si3_1_zext"
10082   [(set (match_operand:DI 0 "register_operand" "=r")
10083         (zero_extend:DI
10084           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10085                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10086    (clobber (reg:CC FLAGS_REG))]
10087   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10088 {
10089     if (operands[2] == const1_rtx
10090         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10091     return "<rotate>{l}\t%k0";
10092   else
10093     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10094 }
10095   [(set_attr "type" "rotate")
10096    (set (attr "length_immediate")
10097      (if_then_else
10098        (and (match_operand 2 "const1_operand" "")
10099             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10100                 (const_int 0)))
10101        (const_string "0")
10102        (const_string "*")))
10103    (set_attr "mode" "SI")])
10104
10105 (define_insn "*<rotate_insn>qi3_1_slp"
10106   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10107         (any_rotate:QI (match_dup 0)
10108                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10109    (clobber (reg:CC FLAGS_REG))]
10110   "(optimize_function_for_size_p (cfun)
10111     || !TARGET_PARTIAL_REG_STALL
10112     || (operands[1] == const1_rtx
10113         && TARGET_SHIFT1))"
10114 {
10115   if (operands[1] == const1_rtx
10116       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10117     return "<rotate>{b}\t%0";
10118   else
10119     return "<rotate>{b}\t{%1, %0|%0, %1}";
10120 }
10121   [(set_attr "type" "rotate1")
10122    (set (attr "length_immediate")
10123      (if_then_else
10124        (and (match_operand 1 "const1_operand" "")
10125             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10126                 (const_int 0)))
10127        (const_string "0")
10128        (const_string "*")))
10129    (set_attr "mode" "QI")])
10130
10131 (define_split
10132  [(set (match_operand:HI 0 "register_operand" "")
10133        (any_rotate:HI (match_dup 0) (const_int 8)))
10134   (clobber (reg:CC FLAGS_REG))]
10135  "reload_completed
10136   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10137  [(parallel [(set (strict_low_part (match_dup 0))
10138                   (bswap:HI (match_dup 0)))
10139              (clobber (reg:CC FLAGS_REG))])])
10140 \f
10141 ;; Bit set / bit test instructions
10142
10143 (define_expand "extv"
10144   [(set (match_operand:SI 0 "register_operand" "")
10145         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10146                          (match_operand:SI 2 "const8_operand" "")
10147                          (match_operand:SI 3 "const8_operand" "")))]
10148   ""
10149 {
10150   /* Handle extractions from %ah et al.  */
10151   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10152     FAIL;
10153
10154   /* From mips.md: extract_bit_field doesn't verify that our source
10155      matches the predicate, so check it again here.  */
10156   if (! ext_register_operand (operands[1], VOIDmode))
10157     FAIL;
10158 })
10159
10160 (define_expand "extzv"
10161   [(set (match_operand:SI 0 "register_operand" "")
10162         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10163                          (match_operand:SI 2 "const8_operand" "")
10164                          (match_operand:SI 3 "const8_operand" "")))]
10165   ""
10166 {
10167   /* Handle extractions from %ah et al.  */
10168   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10169     FAIL;
10170
10171   /* From mips.md: extract_bit_field doesn't verify that our source
10172      matches the predicate, so check it again here.  */
10173   if (! ext_register_operand (operands[1], VOIDmode))
10174     FAIL;
10175 })
10176
10177 (define_expand "insv"
10178   [(set (zero_extract (match_operand 0 "register_operand" "")
10179                       (match_operand 1 "const_int_operand" "")
10180                       (match_operand 2 "const_int_operand" ""))
10181         (match_operand 3 "register_operand" ""))]
10182   ""
10183 {
10184   rtx (*gen_mov_insv_1) (rtx, rtx);
10185
10186   if (ix86_expand_pinsr (operands))
10187     DONE;
10188
10189   /* Handle insertions to %ah et al.  */
10190   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10191     FAIL;
10192
10193   /* From mips.md: insert_bit_field doesn't verify that our source
10194      matches the predicate, so check it again here.  */
10195   if (! ext_register_operand (operands[0], VOIDmode))
10196     FAIL;
10197
10198   gen_mov_insv_1 = (TARGET_64BIT
10199                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10200
10201   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10202   DONE;
10203 })
10204
10205 ;; %%% bts, btr, btc, bt.
10206 ;; In general these instructions are *slow* when applied to memory,
10207 ;; since they enforce atomic operation.  When applied to registers,
10208 ;; it depends on the cpu implementation.  They're never faster than
10209 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10210 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10211 ;; within the instruction itself, so operating on bits in the high
10212 ;; 32-bits of a register becomes easier.
10213 ;;
10214 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10215 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10216 ;; negdf respectively, so they can never be disabled entirely.
10217
10218 (define_insn "*btsq"
10219   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10220                          (const_int 1)
10221                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10222         (const_int 1))
10223    (clobber (reg:CC FLAGS_REG))]
10224   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10225   "bts{q}\t{%1, %0|%0, %1}"
10226   [(set_attr "type" "alu1")
10227    (set_attr "prefix_0f" "1")
10228    (set_attr "mode" "DI")])
10229
10230 (define_insn "*btrq"
10231   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10232                          (const_int 1)
10233                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10234         (const_int 0))
10235    (clobber (reg:CC FLAGS_REG))]
10236   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10237   "btr{q}\t{%1, %0|%0, %1}"
10238   [(set_attr "type" "alu1")
10239    (set_attr "prefix_0f" "1")
10240    (set_attr "mode" "DI")])
10241
10242 (define_insn "*btcq"
10243   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10244                          (const_int 1)
10245                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10246         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10247    (clobber (reg:CC FLAGS_REG))]
10248   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10249   "btc{q}\t{%1, %0|%0, %1}"
10250   [(set_attr "type" "alu1")
10251    (set_attr "prefix_0f" "1")
10252    (set_attr "mode" "DI")])
10253
10254 ;; Allow Nocona to avoid these instructions if a register is available.
10255
10256 (define_peephole2
10257   [(match_scratch:DI 2 "r")
10258    (parallel [(set (zero_extract:DI
10259                      (match_operand:DI 0 "register_operand" "")
10260                      (const_int 1)
10261                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10262                    (const_int 1))
10263               (clobber (reg:CC FLAGS_REG))])]
10264   "TARGET_64BIT && !TARGET_USE_BT"
10265   [(const_int 0)]
10266 {
10267   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10268   rtx op1;
10269
10270   if (HOST_BITS_PER_WIDE_INT >= 64)
10271     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10272   else if (i < HOST_BITS_PER_WIDE_INT)
10273     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10274   else
10275     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10276
10277   op1 = immed_double_const (lo, hi, DImode);
10278   if (i >= 31)
10279     {
10280       emit_move_insn (operands[2], op1);
10281       op1 = operands[2];
10282     }
10283
10284   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10285   DONE;
10286 })
10287
10288 (define_peephole2
10289   [(match_scratch:DI 2 "r")
10290    (parallel [(set (zero_extract:DI
10291                      (match_operand:DI 0 "register_operand" "")
10292                      (const_int 1)
10293                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10294                    (const_int 0))
10295               (clobber (reg:CC FLAGS_REG))])]
10296   "TARGET_64BIT && !TARGET_USE_BT"
10297   [(const_int 0)]
10298 {
10299   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10300   rtx op1;
10301
10302   if (HOST_BITS_PER_WIDE_INT >= 64)
10303     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10304   else if (i < HOST_BITS_PER_WIDE_INT)
10305     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10306   else
10307     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10308
10309   op1 = immed_double_const (~lo, ~hi, DImode);
10310   if (i >= 32)
10311     {
10312       emit_move_insn (operands[2], op1);
10313       op1 = operands[2];
10314     }
10315
10316   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10317   DONE;
10318 })
10319
10320 (define_peephole2
10321   [(match_scratch:DI 2 "r")
10322    (parallel [(set (zero_extract:DI
10323                      (match_operand:DI 0 "register_operand" "")
10324                      (const_int 1)
10325                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10326               (not:DI (zero_extract:DI
10327                         (match_dup 0) (const_int 1) (match_dup 1))))
10328               (clobber (reg:CC FLAGS_REG))])]
10329   "TARGET_64BIT && !TARGET_USE_BT"
10330   [(const_int 0)]
10331 {
10332   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10333   rtx op1;
10334
10335   if (HOST_BITS_PER_WIDE_INT >= 64)
10336     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10337   else if (i < HOST_BITS_PER_WIDE_INT)
10338     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10339   else
10340     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10341
10342   op1 = immed_double_const (lo, hi, DImode);
10343   if (i >= 31)
10344     {
10345       emit_move_insn (operands[2], op1);
10346       op1 = operands[2];
10347     }
10348
10349   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10350   DONE;
10351 })
10352
10353 (define_insn "*bt<mode>"
10354   [(set (reg:CCC FLAGS_REG)
10355         (compare:CCC
10356           (zero_extract:SWI48
10357             (match_operand:SWI48 0 "register_operand" "r")
10358             (const_int 1)
10359             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10360           (const_int 0)))]
10361   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10362   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10363   [(set_attr "type" "alu1")
10364    (set_attr "prefix_0f" "1")
10365    (set_attr "mode" "<MODE>")])
10366 \f
10367 ;; Store-flag instructions.
10368
10369 ;; For all sCOND expanders, also expand the compare or test insn that
10370 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10371
10372 (define_insn_and_split "*setcc_di_1"
10373   [(set (match_operand:DI 0 "register_operand" "=q")
10374         (match_operator:DI 1 "ix86_comparison_operator"
10375           [(reg FLAGS_REG) (const_int 0)]))]
10376   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10377   "#"
10378   "&& reload_completed"
10379   [(set (match_dup 2) (match_dup 1))
10380    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10381 {
10382   PUT_MODE (operands[1], QImode);
10383   operands[2] = gen_lowpart (QImode, operands[0]);
10384 })
10385
10386 (define_insn_and_split "*setcc_si_1_and"
10387   [(set (match_operand:SI 0 "register_operand" "=q")
10388         (match_operator:SI 1 "ix86_comparison_operator"
10389           [(reg FLAGS_REG) (const_int 0)]))
10390    (clobber (reg:CC FLAGS_REG))]
10391   "!TARGET_PARTIAL_REG_STALL
10392    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10393   "#"
10394   "&& reload_completed"
10395   [(set (match_dup 2) (match_dup 1))
10396    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10397               (clobber (reg:CC FLAGS_REG))])]
10398 {
10399   PUT_MODE (operands[1], QImode);
10400   operands[2] = gen_lowpart (QImode, operands[0]);
10401 })
10402
10403 (define_insn_and_split "*setcc_si_1_movzbl"
10404   [(set (match_operand:SI 0 "register_operand" "=q")
10405         (match_operator:SI 1 "ix86_comparison_operator"
10406           [(reg FLAGS_REG) (const_int 0)]))]
10407   "!TARGET_PARTIAL_REG_STALL
10408    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10409   "#"
10410   "&& reload_completed"
10411   [(set (match_dup 2) (match_dup 1))
10412    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10413 {
10414   PUT_MODE (operands[1], QImode);
10415   operands[2] = gen_lowpart (QImode, operands[0]);
10416 })
10417
10418 (define_insn "*setcc_qi"
10419   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10420         (match_operator:QI 1 "ix86_comparison_operator"
10421           [(reg FLAGS_REG) (const_int 0)]))]
10422   ""
10423   "set%C1\t%0"
10424   [(set_attr "type" "setcc")
10425    (set_attr "mode" "QI")])
10426
10427 (define_insn "*setcc_qi_slp"
10428   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10429         (match_operator:QI 1 "ix86_comparison_operator"
10430           [(reg FLAGS_REG) (const_int 0)]))]
10431   ""
10432   "set%C1\t%0"
10433   [(set_attr "type" "setcc")
10434    (set_attr "mode" "QI")])
10435
10436 ;; In general it is not safe to assume too much about CCmode registers,
10437 ;; so simplify-rtx stops when it sees a second one.  Under certain
10438 ;; conditions this is safe on x86, so help combine not create
10439 ;;
10440 ;;      seta    %al
10441 ;;      testb   %al, %al
10442 ;;      sete    %al
10443
10444 (define_split
10445   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10446         (ne:QI (match_operator 1 "ix86_comparison_operator"
10447                  [(reg FLAGS_REG) (const_int 0)])
10448             (const_int 0)))]
10449   ""
10450   [(set (match_dup 0) (match_dup 1))]
10451   "PUT_MODE (operands[1], QImode);")
10452
10453 (define_split
10454   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10455         (ne:QI (match_operator 1 "ix86_comparison_operator"
10456                  [(reg FLAGS_REG) (const_int 0)])
10457             (const_int 0)))]
10458   ""
10459   [(set (match_dup 0) (match_dup 1))]
10460   "PUT_MODE (operands[1], QImode);")
10461
10462 (define_split
10463   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10464         (eq:QI (match_operator 1 "ix86_comparison_operator"
10465                  [(reg FLAGS_REG) (const_int 0)])
10466             (const_int 0)))]
10467   ""
10468   [(set (match_dup 0) (match_dup 1))]
10469 {
10470   rtx new_op1 = copy_rtx (operands[1]);
10471   operands[1] = new_op1;
10472   PUT_MODE (new_op1, QImode);
10473   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10474                                              GET_MODE (XEXP (new_op1, 0))));
10475
10476   /* Make sure that (a) the CCmode we have for the flags is strong
10477      enough for the reversed compare or (b) we have a valid FP compare.  */
10478   if (! ix86_comparison_operator (new_op1, VOIDmode))
10479     FAIL;
10480 })
10481
10482 (define_split
10483   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10484         (eq:QI (match_operator 1 "ix86_comparison_operator"
10485                  [(reg FLAGS_REG) (const_int 0)])
10486             (const_int 0)))]
10487   ""
10488   [(set (match_dup 0) (match_dup 1))]
10489 {
10490   rtx new_op1 = copy_rtx (operands[1]);
10491   operands[1] = new_op1;
10492   PUT_MODE (new_op1, QImode);
10493   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10494                                              GET_MODE (XEXP (new_op1, 0))));
10495
10496   /* Make sure that (a) the CCmode we have for the flags is strong
10497      enough for the reversed compare or (b) we have a valid FP compare.  */
10498   if (! ix86_comparison_operator (new_op1, VOIDmode))
10499     FAIL;
10500 })
10501
10502 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10503 ;; subsequent logical operations are used to imitate conditional moves.
10504 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10505 ;; it directly.
10506
10507 (define_insn "setcc_<mode>_sse"
10508   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10509         (match_operator:MODEF 3 "sse_comparison_operator"
10510           [(match_operand:MODEF 1 "register_operand" "0,x")
10511            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10512   "SSE_FLOAT_MODE_P (<MODE>mode)"
10513   "@
10514    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10515    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10516   [(set_attr "isa" "noavx,avx")
10517    (set_attr "type" "ssecmp")
10518    (set_attr "length_immediate" "1")
10519    (set_attr "prefix" "orig,vex")
10520    (set_attr "mode" "<MODE>")])
10521 \f
10522 ;; Basic conditional jump instructions.
10523 ;; We ignore the overflow flag for signed branch instructions.
10524
10525 (define_insn "*jcc_1"
10526   [(set (pc)
10527         (if_then_else (match_operator 1 "ix86_comparison_operator"
10528                                       [(reg FLAGS_REG) (const_int 0)])
10529                       (label_ref (match_operand 0 "" ""))
10530                       (pc)))]
10531   ""
10532   "%+j%C1\t%l0"
10533   [(set_attr "type" "ibr")
10534    (set_attr "modrm" "0")
10535    (set (attr "length")
10536            (if_then_else (and (ge (minus (match_dup 0) (pc))
10537                                   (const_int -126))
10538                               (lt (minus (match_dup 0) (pc))
10539                                   (const_int 128)))
10540              (const_int 2)
10541              (const_int 6)))])
10542
10543 (define_insn "*jcc_2"
10544   [(set (pc)
10545         (if_then_else (match_operator 1 "ix86_comparison_operator"
10546                                       [(reg FLAGS_REG) (const_int 0)])
10547                       (pc)
10548                       (label_ref (match_operand 0 "" ""))))]
10549   ""
10550   "%+j%c1\t%l0"
10551   [(set_attr "type" "ibr")
10552    (set_attr "modrm" "0")
10553    (set (attr "length")
10554            (if_then_else (and (ge (minus (match_dup 0) (pc))
10555                                   (const_int -126))
10556                               (lt (minus (match_dup 0) (pc))
10557                                   (const_int 128)))
10558              (const_int 2)
10559              (const_int 6)))])
10560
10561 ;; In general it is not safe to assume too much about CCmode registers,
10562 ;; so simplify-rtx stops when it sees a second one.  Under certain
10563 ;; conditions this is safe on x86, so help combine not create
10564 ;;
10565 ;;      seta    %al
10566 ;;      testb   %al, %al
10567 ;;      je      Lfoo
10568
10569 (define_split
10570   [(set (pc)
10571         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10572                                       [(reg FLAGS_REG) (const_int 0)])
10573                           (const_int 0))
10574                       (label_ref (match_operand 1 "" ""))
10575                       (pc)))]
10576   ""
10577   [(set (pc)
10578         (if_then_else (match_dup 0)
10579                       (label_ref (match_dup 1))
10580                       (pc)))]
10581   "PUT_MODE (operands[0], VOIDmode);")
10582
10583 (define_split
10584   [(set (pc)
10585         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10586                                       [(reg FLAGS_REG) (const_int 0)])
10587                           (const_int 0))
10588                       (label_ref (match_operand 1 "" ""))
10589                       (pc)))]
10590   ""
10591   [(set (pc)
10592         (if_then_else (match_dup 0)
10593                       (label_ref (match_dup 1))
10594                       (pc)))]
10595 {
10596   rtx new_op0 = copy_rtx (operands[0]);
10597   operands[0] = new_op0;
10598   PUT_MODE (new_op0, VOIDmode);
10599   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10600                                              GET_MODE (XEXP (new_op0, 0))));
10601
10602   /* Make sure that (a) the CCmode we have for the flags is strong
10603      enough for the reversed compare or (b) we have a valid FP compare.  */
10604   if (! ix86_comparison_operator (new_op0, VOIDmode))
10605     FAIL;
10606 })
10607
10608 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10609 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10610 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10611 ;; appropriate modulo of the bit offset value.
10612
10613 (define_insn_and_split "*jcc_bt<mode>"
10614   [(set (pc)
10615         (if_then_else (match_operator 0 "bt_comparison_operator"
10616                         [(zero_extract:SWI48
10617                            (match_operand:SWI48 1 "register_operand" "r")
10618                            (const_int 1)
10619                            (zero_extend:SI
10620                              (match_operand:QI 2 "register_operand" "r")))
10621                          (const_int 0)])
10622                       (label_ref (match_operand 3 "" ""))
10623                       (pc)))
10624    (clobber (reg:CC FLAGS_REG))]
10625   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10626   "#"
10627   "&& 1"
10628   [(set (reg:CCC FLAGS_REG)
10629         (compare:CCC
10630           (zero_extract:SWI48
10631             (match_dup 1)
10632             (const_int 1)
10633             (match_dup 2))
10634           (const_int 0)))
10635    (set (pc)
10636         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10637                       (label_ref (match_dup 3))
10638                       (pc)))]
10639 {
10640   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10641
10642   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10643 })
10644
10645 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10646 ;; also for DImode, this is what combine produces.
10647 (define_insn_and_split "*jcc_bt<mode>_mask"
10648   [(set (pc)
10649         (if_then_else (match_operator 0 "bt_comparison_operator"
10650                         [(zero_extract:SWI48
10651                            (match_operand:SWI48 1 "register_operand" "r")
10652                            (const_int 1)
10653                            (and:SI
10654                              (match_operand:SI 2 "register_operand" "r")
10655                              (match_operand:SI 3 "const_int_operand" "n")))])
10656                       (label_ref (match_operand 4 "" ""))
10657                       (pc)))
10658    (clobber (reg:CC FLAGS_REG))]
10659   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10660    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10661       == GET_MODE_BITSIZE (<MODE>mode)-1"
10662   "#"
10663   "&& 1"
10664   [(set (reg:CCC FLAGS_REG)
10665         (compare:CCC
10666           (zero_extract:SWI48
10667             (match_dup 1)
10668             (const_int 1)
10669             (match_dup 2))
10670           (const_int 0)))
10671    (set (pc)
10672         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10673                       (label_ref (match_dup 4))
10674                       (pc)))]
10675 {
10676   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10677
10678   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10679 })
10680
10681 (define_insn_and_split "*jcc_btsi_1"
10682   [(set (pc)
10683         (if_then_else (match_operator 0 "bt_comparison_operator"
10684                         [(and:SI
10685                            (lshiftrt:SI
10686                              (match_operand:SI 1 "register_operand" "r")
10687                              (match_operand:QI 2 "register_operand" "r"))
10688                            (const_int 1))
10689                          (const_int 0)])
10690                       (label_ref (match_operand 3 "" ""))
10691                       (pc)))
10692    (clobber (reg:CC FLAGS_REG))]
10693   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10694   "#"
10695   "&& 1"
10696   [(set (reg:CCC FLAGS_REG)
10697         (compare:CCC
10698           (zero_extract:SI
10699             (match_dup 1)
10700             (const_int 1)
10701             (match_dup 2))
10702           (const_int 0)))
10703    (set (pc)
10704         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10705                       (label_ref (match_dup 3))
10706                       (pc)))]
10707 {
10708   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10709
10710   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10711 })
10712
10713 ;; avoid useless masking of bit offset operand
10714 (define_insn_and_split "*jcc_btsi_mask_1"
10715   [(set (pc)
10716         (if_then_else
10717           (match_operator 0 "bt_comparison_operator"
10718             [(and:SI
10719                (lshiftrt:SI
10720                  (match_operand:SI 1 "register_operand" "r")
10721                  (subreg:QI
10722                    (and:SI
10723                      (match_operand:SI 2 "register_operand" "r")
10724                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10725                (const_int 1))
10726              (const_int 0)])
10727           (label_ref (match_operand 4 "" ""))
10728           (pc)))
10729    (clobber (reg:CC FLAGS_REG))]
10730   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10731    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10732   "#"
10733   "&& 1"
10734   [(set (reg:CCC FLAGS_REG)
10735         (compare:CCC
10736           (zero_extract:SI
10737             (match_dup 1)
10738             (const_int 1)
10739             (match_dup 2))
10740           (const_int 0)))
10741    (set (pc)
10742         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10743                       (label_ref (match_dup 4))
10744                       (pc)))]
10745   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10746
10747 ;; Define combination compare-and-branch fp compare instructions to help
10748 ;; combine.
10749
10750 (define_insn "*fp_jcc_1_387"
10751   [(set (pc)
10752         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10753                         [(match_operand 1 "register_operand" "f")
10754                          (match_operand 2 "nonimmediate_operand" "fm")])
10755           (label_ref (match_operand 3 "" ""))
10756           (pc)))
10757    (clobber (reg:CCFP FPSR_REG))
10758    (clobber (reg:CCFP FLAGS_REG))
10759    (clobber (match_scratch:HI 4 "=a"))]
10760   "TARGET_80387
10761    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10762    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10763    && SELECT_CC_MODE (GET_CODE (operands[0]),
10764                       operands[1], operands[2]) == CCFPmode
10765    && !TARGET_CMOVE"
10766   "#")
10767
10768 (define_insn "*fp_jcc_1r_387"
10769   [(set (pc)
10770         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10771                         [(match_operand 1 "register_operand" "f")
10772                          (match_operand 2 "nonimmediate_operand" "fm")])
10773           (pc)
10774           (label_ref (match_operand 3 "" ""))))
10775    (clobber (reg:CCFP FPSR_REG))
10776    (clobber (reg:CCFP FLAGS_REG))
10777    (clobber (match_scratch:HI 4 "=a"))]
10778   "TARGET_80387
10779    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10780    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10781    && SELECT_CC_MODE (GET_CODE (operands[0]),
10782                       operands[1], operands[2]) == CCFPmode
10783    && !TARGET_CMOVE"
10784   "#")
10785
10786 (define_insn "*fp_jcc_2_387"
10787   [(set (pc)
10788         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10789                         [(match_operand 1 "register_operand" "f")
10790                          (match_operand 2 "register_operand" "f")])
10791           (label_ref (match_operand 3 "" ""))
10792           (pc)))
10793    (clobber (reg:CCFP FPSR_REG))
10794    (clobber (reg:CCFP FLAGS_REG))
10795    (clobber (match_scratch:HI 4 "=a"))]
10796   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10797    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10798    && !TARGET_CMOVE"
10799   "#")
10800
10801 (define_insn "*fp_jcc_2r_387"
10802   [(set (pc)
10803         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10804                         [(match_operand 1 "register_operand" "f")
10805                          (match_operand 2 "register_operand" "f")])
10806           (pc)
10807           (label_ref (match_operand 3 "" ""))))
10808    (clobber (reg:CCFP FPSR_REG))
10809    (clobber (reg:CCFP FLAGS_REG))
10810    (clobber (match_scratch:HI 4 "=a"))]
10811   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10812    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10813    && !TARGET_CMOVE"
10814   "#")
10815
10816 (define_insn "*fp_jcc_3_387"
10817   [(set (pc)
10818         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10819                         [(match_operand 1 "register_operand" "f")
10820                          (match_operand 2 "const0_operand" "")])
10821           (label_ref (match_operand 3 "" ""))
10822           (pc)))
10823    (clobber (reg:CCFP FPSR_REG))
10824    (clobber (reg:CCFP FLAGS_REG))
10825    (clobber (match_scratch:HI 4 "=a"))]
10826   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10827    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10828    && SELECT_CC_MODE (GET_CODE (operands[0]),
10829                       operands[1], operands[2]) == CCFPmode
10830    && !TARGET_CMOVE"
10831   "#")
10832
10833 (define_split
10834   [(set (pc)
10835         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10836                         [(match_operand 1 "register_operand" "")
10837                          (match_operand 2 "nonimmediate_operand" "")])
10838           (match_operand 3 "" "")
10839           (match_operand 4 "" "")))
10840    (clobber (reg:CCFP FPSR_REG))
10841    (clobber (reg:CCFP FLAGS_REG))]
10842   "reload_completed"
10843   [(const_int 0)]
10844 {
10845   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10846                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10847   DONE;
10848 })
10849
10850 (define_split
10851   [(set (pc)
10852         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10853                         [(match_operand 1 "register_operand" "")
10854                          (match_operand 2 "general_operand" "")])
10855           (match_operand 3 "" "")
10856           (match_operand 4 "" "")))
10857    (clobber (reg:CCFP FPSR_REG))
10858    (clobber (reg:CCFP FLAGS_REG))
10859    (clobber (match_scratch:HI 5 "=a"))]
10860   "reload_completed"
10861   [(const_int 0)]
10862 {
10863   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10864                         operands[3], operands[4], operands[5], NULL_RTX);
10865   DONE;
10866 })
10867
10868 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10869 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10870 ;; with a precedence over other operators and is always put in the first
10871 ;; place. Swap condition and operands to match ficom instruction.
10872
10873 (define_insn "*fp_jcc_4_<mode>_387"
10874   [(set (pc)
10875         (if_then_else
10876           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10877             [(match_operator 1 "float_operator"
10878               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10879              (match_operand 3 "register_operand" "f,f")])
10880           (label_ref (match_operand 4 "" ""))
10881           (pc)))
10882    (clobber (reg:CCFP FPSR_REG))
10883    (clobber (reg:CCFP FLAGS_REG))
10884    (clobber (match_scratch:HI 5 "=a,a"))]
10885   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10886    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10887    && GET_MODE (operands[1]) == GET_MODE (operands[3])
10888    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10889    && !TARGET_CMOVE"
10890   "#")
10891
10892 (define_split
10893   [(set (pc)
10894         (if_then_else
10895           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10896             [(match_operator 1 "float_operator"
10897               [(match_operand:X87MODEI12 2 "memory_operand" "")])
10898              (match_operand 3 "register_operand" "")])
10899           (match_operand 4 "" "")
10900           (match_operand 5 "" "")))
10901    (clobber (reg:CCFP FPSR_REG))
10902    (clobber (reg:CCFP FLAGS_REG))
10903    (clobber (match_scratch:HI 6 "=a"))]
10904   "reload_completed"
10905   [(const_int 0)]
10906 {
10907   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10908
10909   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10910                         operands[3], operands[7],
10911                         operands[4], operands[5], operands[6], NULL_RTX);
10912   DONE;
10913 })
10914
10915 ;; %%% Kill this when reload knows how to do it.
10916 (define_split
10917   [(set (pc)
10918         (if_then_else
10919           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10920             [(match_operator 1 "float_operator"
10921               [(match_operand:X87MODEI12 2 "register_operand" "")])
10922              (match_operand 3 "register_operand" "")])
10923           (match_operand 4 "" "")
10924           (match_operand 5 "" "")))
10925    (clobber (reg:CCFP FPSR_REG))
10926    (clobber (reg:CCFP FLAGS_REG))
10927    (clobber (match_scratch:HI 6 "=a"))]
10928   "reload_completed"
10929   [(const_int 0)]
10930 {
10931   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10932   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10933
10934   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10935                         operands[3], operands[7],
10936                         operands[4], operands[5], operands[6], operands[2]);
10937   DONE;
10938 })
10939 \f
10940 ;; Unconditional and other jump instructions
10941
10942 (define_insn "jump"
10943   [(set (pc)
10944         (label_ref (match_operand 0 "" "")))]
10945   ""
10946   "jmp\t%l0"
10947   [(set_attr "type" "ibr")
10948    (set (attr "length")
10949            (if_then_else (and (ge (minus (match_dup 0) (pc))
10950                                   (const_int -126))
10951                               (lt (minus (match_dup 0) (pc))
10952                                   (const_int 128)))
10953              (const_int 2)
10954              (const_int 5)))
10955    (set_attr "modrm" "0")])
10956
10957 (define_expand "indirect_jump"
10958   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10959   ""
10960   "")
10961
10962 (define_insn "*indirect_jump"
10963   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10964   ""
10965   "jmp\t%A0"
10966   [(set_attr "type" "ibr")
10967    (set_attr "length_immediate" "0")])
10968
10969 (define_expand "tablejump"
10970   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10971               (use (label_ref (match_operand 1 "" "")))])]
10972   ""
10973 {
10974   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10975      relative.  Convert the relative address to an absolute address.  */
10976   if (flag_pic)
10977     {
10978       rtx op0, op1;
10979       enum rtx_code code;
10980
10981       /* We can't use @GOTOFF for text labels on VxWorks;
10982          see gotoff_operand.  */
10983       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10984         {
10985           code = PLUS;
10986           op0 = operands[0];
10987           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10988         }
10989       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10990         {
10991           code = PLUS;
10992           op0 = operands[0];
10993           op1 = pic_offset_table_rtx;
10994         }
10995       else
10996         {
10997           code = MINUS;
10998           op0 = pic_offset_table_rtx;
10999           op1 = operands[0];
11000         }
11001
11002       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11003                                          OPTAB_DIRECT);
11004     }
11005 })
11006
11007 (define_insn "*tablejump_1"
11008   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11009    (use (label_ref (match_operand 1 "" "")))]
11010   ""
11011   "jmp\t%A0"
11012   [(set_attr "type" "ibr")
11013    (set_attr "length_immediate" "0")])
11014 \f
11015 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11016
11017 (define_peephole2
11018   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11019    (set (match_operand:QI 1 "register_operand" "")
11020         (match_operator:QI 2 "ix86_comparison_operator"
11021           [(reg FLAGS_REG) (const_int 0)]))
11022    (set (match_operand 3 "q_regs_operand" "")
11023         (zero_extend (match_dup 1)))]
11024   "(peep2_reg_dead_p (3, operands[1])
11025     || operands_match_p (operands[1], operands[3]))
11026    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11027   [(set (match_dup 4) (match_dup 0))
11028    (set (strict_low_part (match_dup 5))
11029         (match_dup 2))]
11030 {
11031   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11032   operands[5] = gen_lowpart (QImode, operands[3]);
11033   ix86_expand_clear (operands[3]);
11034 })
11035
11036 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11037
11038 (define_peephole2
11039   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11040    (set (match_operand:QI 1 "register_operand" "")
11041         (match_operator:QI 2 "ix86_comparison_operator"
11042           [(reg FLAGS_REG) (const_int 0)]))
11043    (parallel [(set (match_operand 3 "q_regs_operand" "")
11044                    (zero_extend (match_dup 1)))
11045               (clobber (reg:CC FLAGS_REG))])]
11046   "(peep2_reg_dead_p (3, operands[1])
11047     || operands_match_p (operands[1], operands[3]))
11048    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11049   [(set (match_dup 4) (match_dup 0))
11050    (set (strict_low_part (match_dup 5))
11051         (match_dup 2))]
11052 {
11053   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11054   operands[5] = gen_lowpart (QImode, operands[3]);
11055   ix86_expand_clear (operands[3]);
11056 })
11057 \f
11058 ;; Call instructions.
11059
11060 ;; The predicates normally associated with named expanders are not properly
11061 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11062 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11063
11064 ;; P6 processors will jump to the address after the decrement when %esp
11065 ;; is used as a call operand, so they will execute return address as a code.
11066 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11067
11068 ;; Register constraint for call instruction.
11069 (define_mode_attr c [(SI "l") (DI "r")])
11070
11071 ;; Call subroutine returning no value.
11072
11073 (define_expand "call"
11074   [(call (match_operand:QI 0 "" "")
11075          (match_operand 1 "" ""))
11076    (use (match_operand 2 "" ""))]
11077   ""
11078 {
11079   ix86_expand_call (NULL, operands[0], operands[1],
11080                     operands[2], NULL, 0);
11081   DONE;
11082 })
11083
11084 (define_expand "sibcall"
11085   [(call (match_operand:QI 0 "" "")
11086          (match_operand 1 "" ""))
11087    (use (match_operand 2 "" ""))]
11088   ""
11089 {
11090   ix86_expand_call (NULL, operands[0], operands[1],
11091                     operands[2], NULL, 1);
11092   DONE;
11093 })
11094
11095 (define_insn_and_split "*call_vzeroupper"
11096   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11097          (match_operand 1 "" ""))
11098    (unspec [(match_operand 2 "const_int_operand" "")]
11099            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11100   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11101   "#"
11102   "&& reload_completed"
11103   [(const_int 0)]
11104   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11105   [(set_attr "type" "call")])
11106
11107 (define_insn "*call"
11108   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11109          (match_operand 1 "" ""))]
11110   "!SIBLING_CALL_P (insn)"
11111   "* return ix86_output_call_insn (insn, operands[0]);"
11112   [(set_attr "type" "call")])
11113
11114 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11115   [(parallel
11116     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11117            (match_operand 1 "" ""))
11118      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11119      (clobber (reg:TI XMM6_REG))
11120      (clobber (reg:TI XMM7_REG))
11121      (clobber (reg:TI XMM8_REG))
11122      (clobber (reg:TI XMM9_REG))
11123      (clobber (reg:TI XMM10_REG))
11124      (clobber (reg:TI XMM11_REG))
11125      (clobber (reg:TI XMM12_REG))
11126      (clobber (reg:TI XMM13_REG))
11127      (clobber (reg:TI XMM14_REG))
11128      (clobber (reg:TI XMM15_REG))
11129      (clobber (reg:DI SI_REG))
11130      (clobber (reg:DI DI_REG))])
11131    (unspec [(match_operand 2 "const_int_operand" "")]
11132            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11133   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11134   "#"
11135   "&& reload_completed"
11136   [(const_int 0)]
11137   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11138   [(set_attr "type" "call")])
11139
11140 (define_insn "*call_rex64_ms_sysv"
11141   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11142          (match_operand 1 "" ""))
11143    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11144    (clobber (reg:TI XMM6_REG))
11145    (clobber (reg:TI XMM7_REG))
11146    (clobber (reg:TI XMM8_REG))
11147    (clobber (reg:TI XMM9_REG))
11148    (clobber (reg:TI XMM10_REG))
11149    (clobber (reg:TI XMM11_REG))
11150    (clobber (reg:TI XMM12_REG))
11151    (clobber (reg:TI XMM13_REG))
11152    (clobber (reg:TI XMM14_REG))
11153    (clobber (reg:TI XMM15_REG))
11154    (clobber (reg:DI SI_REG))
11155    (clobber (reg:DI DI_REG))]
11156   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11157   "* return ix86_output_call_insn (insn, operands[0]);"
11158   [(set_attr "type" "call")])
11159
11160 (define_insn_and_split "*sibcall_vzeroupper"
11161   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11162          (match_operand 1 "" ""))
11163    (unspec [(match_operand 2 "const_int_operand" "")]
11164            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11165   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11166   "#"
11167   "&& reload_completed"
11168   [(const_int 0)]
11169   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11170   [(set_attr "type" "call")])
11171
11172 (define_insn "*sibcall"
11173   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11174          (match_operand 1 "" ""))]
11175   "SIBLING_CALL_P (insn)"
11176   "* return ix86_output_call_insn (insn, operands[0]);"
11177   [(set_attr "type" "call")])
11178
11179 (define_expand "call_pop"
11180   [(parallel [(call (match_operand:QI 0 "" "")
11181                     (match_operand:SI 1 "" ""))
11182               (set (reg:SI SP_REG)
11183                    (plus:SI (reg:SI SP_REG)
11184                             (match_operand:SI 3 "" "")))])]
11185   "!TARGET_64BIT"
11186 {
11187   ix86_expand_call (NULL, operands[0], operands[1],
11188                     operands[2], operands[3], 0);
11189   DONE;
11190 })
11191
11192 (define_insn_and_split "*call_pop_vzeroupper"
11193   [(parallel
11194     [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11195            (match_operand:SI 1 "" ""))
11196      (set (reg:SI SP_REG)
11197           (plus:SI (reg:SI SP_REG)
11198                    (match_operand:SI 2 "immediate_operand" "i")))])
11199    (unspec [(match_operand 3 "const_int_operand" "")]
11200            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11201   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11202   "#"
11203   "&& reload_completed"
11204   [(const_int 0)]
11205   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11206   [(set_attr "type" "call")])
11207
11208 (define_insn "*call_pop"
11209   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11210          (match_operand 1 "" ""))
11211    (set (reg:SI SP_REG)
11212         (plus:SI (reg:SI SP_REG)
11213                  (match_operand:SI 2 "immediate_operand" "i")))]
11214   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11215   "* return ix86_output_call_insn (insn, operands[0]);"
11216   [(set_attr "type" "call")])
11217
11218 (define_insn_and_split "*sibcall_pop_vzeroupper"
11219  [(parallel
11220    [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11221           (match_operand 1 "" ""))
11222      (set (reg:SI SP_REG)
11223           (plus:SI (reg:SI SP_REG)
11224                    (match_operand:SI 2 "immediate_operand" "i")))])
11225    (unspec [(match_operand 3 "const_int_operand" "")]
11226            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11227   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11228   "#"
11229   "&& reload_completed"
11230   [(const_int 0)]
11231   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11232   [(set_attr "type" "call")])
11233
11234 (define_insn "*sibcall_pop"
11235   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11236          (match_operand 1 "" ""))
11237    (set (reg:SI SP_REG)
11238         (plus:SI (reg:SI SP_REG)
11239                  (match_operand:SI 2 "immediate_operand" "i")))]
11240   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11241   "* return ix86_output_call_insn (insn, operands[0]);"
11242   [(set_attr "type" "call")])
11243
11244 ;; Call subroutine, returning value in operand 0
11245
11246 (define_expand "call_value"
11247   [(set (match_operand 0 "" "")
11248         (call (match_operand:QI 1 "" "")
11249               (match_operand 2 "" "")))
11250    (use (match_operand 3 "" ""))]
11251   ""
11252 {
11253   ix86_expand_call (operands[0], operands[1], operands[2],
11254                     operands[3], NULL, 0);
11255   DONE;
11256 })
11257
11258 (define_expand "sibcall_value"
11259   [(set (match_operand 0 "" "")
11260         (call (match_operand:QI 1 "" "")
11261               (match_operand 2 "" "")))
11262    (use (match_operand 3 "" ""))]
11263   ""
11264 {
11265   ix86_expand_call (operands[0], operands[1], operands[2],
11266                     operands[3], NULL, 1);
11267   DONE;
11268 })
11269
11270 (define_insn_and_split "*call_value_vzeroupper"
11271   [(set (match_operand 0 "" "")
11272         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11273               (match_operand 2 "" "")))
11274    (unspec [(match_operand 3 "const_int_operand" "")]
11275            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11276   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11277   "#"
11278   "&& reload_completed"
11279   [(const_int 0)]
11280   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11281   [(set_attr "type" "callv")])
11282
11283 (define_insn "*call_value"
11284   [(set (match_operand 0 "" "")
11285         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11286               (match_operand 2 "" "")))]
11287   "!SIBLING_CALL_P (insn)"
11288   "* return ix86_output_call_insn (insn, operands[1]);"
11289   [(set_attr "type" "callv")])
11290
11291 (define_insn_and_split "*sibcall_value_vzeroupper"
11292   [(set (match_operand 0 "" "")
11293         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11294               (match_operand 2 "" "")))
11295    (unspec [(match_operand 3 "const_int_operand" "")]
11296            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11297   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11298   "#"
11299   "&& reload_completed"
11300   [(const_int 0)]
11301   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11302   [(set_attr "type" "callv")])
11303
11304 (define_insn "*sibcall_value"
11305   [(set (match_operand 0 "" "")
11306         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11307               (match_operand 2 "" "")))]
11308   "SIBLING_CALL_P (insn)"
11309   "* return ix86_output_call_insn (insn, operands[1]);"
11310   [(set_attr "type" "callv")])
11311
11312 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11313   [(parallel
11314     [(set (match_operand 0 "" "")
11315           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11316                 (match_operand 2 "" "")))
11317      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11318      (clobber (reg:TI XMM6_REG))
11319      (clobber (reg:TI XMM7_REG))
11320      (clobber (reg:TI XMM8_REG))
11321      (clobber (reg:TI XMM9_REG))
11322      (clobber (reg:TI XMM10_REG))
11323      (clobber (reg:TI XMM11_REG))
11324      (clobber (reg:TI XMM12_REG))
11325      (clobber (reg:TI XMM13_REG))
11326      (clobber (reg:TI XMM14_REG))
11327      (clobber (reg:TI XMM15_REG))
11328      (clobber (reg:DI SI_REG))
11329      (clobber (reg:DI DI_REG))])
11330    (unspec [(match_operand 3 "const_int_operand" "")]
11331            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11332   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11333   "#"
11334   "&& reload_completed"
11335   [(const_int 0)]
11336   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11337   [(set_attr "type" "callv")])
11338
11339 (define_insn "*call_value_rex64_ms_sysv"
11340   [(set (match_operand 0 "" "")
11341         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11342               (match_operand 2 "" "")))
11343    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11344    (clobber (reg:TI XMM6_REG))
11345    (clobber (reg:TI XMM7_REG))
11346    (clobber (reg:TI XMM8_REG))
11347    (clobber (reg:TI XMM9_REG))
11348    (clobber (reg:TI XMM10_REG))
11349    (clobber (reg:TI XMM11_REG))
11350    (clobber (reg:TI XMM12_REG))
11351    (clobber (reg:TI XMM13_REG))
11352    (clobber (reg:TI XMM14_REG))
11353    (clobber (reg:TI XMM15_REG))
11354    (clobber (reg:DI SI_REG))
11355    (clobber (reg:DI DI_REG))]
11356   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11357   "* return ix86_output_call_insn (insn, operands[1]);"
11358   [(set_attr "type" "callv")])
11359
11360 (define_expand "call_value_pop"
11361   [(parallel [(set (match_operand 0 "" "")
11362                    (call (match_operand:QI 1 "" "")
11363                          (match_operand:SI 2 "" "")))
11364               (set (reg:SI SP_REG)
11365                    (plus:SI (reg:SI SP_REG)
11366                             (match_operand:SI 4 "" "")))])]
11367   "!TARGET_64BIT"
11368 {
11369   ix86_expand_call (operands[0], operands[1], operands[2],
11370                     operands[3], operands[4], 0);
11371   DONE;
11372 })
11373
11374 (define_insn_and_split "*call_value_pop_vzeroupper"
11375   [(parallel
11376     [(set (match_operand 0 "" "")
11377           (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11378                 (match_operand 2 "" "")))
11379      (set (reg:SI SP_REG)
11380           (plus:SI (reg:SI SP_REG)
11381                    (match_operand:SI 3 "immediate_operand" "i")))])
11382    (unspec [(match_operand 4 "const_int_operand" "")]
11383            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11384   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11385   "#"
11386   "&& reload_completed"
11387   [(const_int 0)]
11388   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11389   [(set_attr "type" "callv")])
11390
11391 (define_insn "*call_value_pop"
11392   [(set (match_operand 0 "" "")
11393         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11394               (match_operand 2 "" "")))
11395    (set (reg:SI SP_REG)
11396         (plus:SI (reg:SI SP_REG)
11397                  (match_operand:SI 3 "immediate_operand" "i")))]
11398   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11399   "* return ix86_output_call_insn (insn, operands[1]);"
11400   [(set_attr "type" "callv")])
11401
11402 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11403  [(parallel
11404    [(set (match_operand 0 "" "")
11405           (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11406                 (match_operand 2 "" "")))
11407      (set (reg:SI SP_REG)
11408           (plus:SI (reg:SI SP_REG)
11409                    (match_operand:SI 3 "immediate_operand" "i")))])
11410    (unspec [(match_operand 4 "const_int_operand" "")]
11411            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11412   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11413   "#"
11414   "&& reload_completed"
11415   [(const_int 0)]
11416   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11417   [(set_attr "type" "callv")])
11418
11419 (define_insn "*sibcall_value_pop"
11420   [(set (match_operand 0 "" "")
11421         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11422               (match_operand 2 "" "")))
11423    (set (reg:SI SP_REG)
11424         (plus:SI (reg:SI SP_REG)
11425                  (match_operand:SI 3 "immediate_operand" "i")))]
11426   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11427   "* return ix86_output_call_insn (insn, operands[1]);"
11428   [(set_attr "type" "callv")])
11429
11430 ;; Call subroutine returning any type.
11431
11432 (define_expand "untyped_call"
11433   [(parallel [(call (match_operand 0 "" "")
11434                     (const_int 0))
11435               (match_operand 1 "" "")
11436               (match_operand 2 "" "")])]
11437   ""
11438 {
11439   int i;
11440
11441   /* In order to give reg-stack an easier job in validating two
11442      coprocessor registers as containing a possible return value,
11443      simply pretend the untyped call returns a complex long double
11444      value. 
11445
11446      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11447      and should have the default ABI.  */
11448
11449   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11450                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11451                     operands[0], const0_rtx,
11452                     GEN_INT ((TARGET_64BIT
11453                               ? (ix86_abi == SYSV_ABI
11454                                  ? X86_64_SSE_REGPARM_MAX
11455                                  : X86_64_MS_SSE_REGPARM_MAX)
11456                               : X86_32_SSE_REGPARM_MAX)
11457                              - 1),
11458                     NULL, 0);
11459
11460   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11461     {
11462       rtx set = XVECEXP (operands[2], 0, i);
11463       emit_move_insn (SET_DEST (set), SET_SRC (set));
11464     }
11465
11466   /* The optimizer does not know that the call sets the function value
11467      registers we stored in the result block.  We avoid problems by
11468      claiming that all hard registers are used and clobbered at this
11469      point.  */
11470   emit_insn (gen_blockage ());
11471
11472   DONE;
11473 })
11474 \f
11475 ;; Prologue and epilogue instructions
11476
11477 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11478 ;; all of memory.  This blocks insns from being moved across this point.
11479
11480 (define_insn "blockage"
11481   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11482   ""
11483   ""
11484   [(set_attr "length" "0")])
11485
11486 ;; Do not schedule instructions accessing memory across this point.
11487
11488 (define_expand "memory_blockage"
11489   [(set (match_dup 0)
11490         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11491   ""
11492 {
11493   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11494   MEM_VOLATILE_P (operands[0]) = 1;
11495 })
11496
11497 (define_insn "*memory_blockage"
11498   [(set (match_operand:BLK 0 "" "")
11499         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11500   ""
11501   ""
11502   [(set_attr "length" "0")])
11503
11504 ;; As USE insns aren't meaningful after reload, this is used instead
11505 ;; to prevent deleting instructions setting registers for PIC code
11506 (define_insn "prologue_use"
11507   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11508   ""
11509   ""
11510   [(set_attr "length" "0")])
11511
11512 ;; Insn emitted into the body of a function to return from a function.
11513 ;; This is only done if the function's epilogue is known to be simple.
11514 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11515
11516 (define_expand "return"
11517   [(return)]
11518   "ix86_can_use_return_insn_p ()"
11519 {
11520   if (crtl->args.pops_args)
11521     {
11522       rtx popc = GEN_INT (crtl->args.pops_args);
11523       emit_jump_insn (gen_return_pop_internal (popc));
11524       DONE;
11525     }
11526 })
11527
11528 (define_insn "return_internal"
11529   [(return)]
11530   "reload_completed"
11531   "ret"
11532   [(set_attr "length" "1")
11533    (set_attr "atom_unit" "jeu")
11534    (set_attr "length_immediate" "0")
11535    (set_attr "modrm" "0")])
11536
11537 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11538 ;; instruction Athlon and K8 have.
11539
11540 (define_insn "return_internal_long"
11541   [(return)
11542    (unspec [(const_int 0)] UNSPEC_REP)]
11543   "reload_completed"
11544   "rep\;ret"
11545   [(set_attr "length" "2")
11546    (set_attr "atom_unit" "jeu")
11547    (set_attr "length_immediate" "0")
11548    (set_attr "prefix_rep" "1")
11549    (set_attr "modrm" "0")])
11550
11551 (define_insn "return_pop_internal"
11552   [(return)
11553    (use (match_operand:SI 0 "const_int_operand" ""))]
11554   "reload_completed"
11555   "ret\t%0"
11556   [(set_attr "length" "3")
11557    (set_attr "atom_unit" "jeu")
11558    (set_attr "length_immediate" "2")
11559    (set_attr "modrm" "0")])
11560
11561 (define_insn "return_indirect_internal"
11562   [(return)
11563    (use (match_operand:SI 0 "register_operand" "r"))]
11564   "reload_completed"
11565   "jmp\t%A0"
11566   [(set_attr "type" "ibr")
11567    (set_attr "length_immediate" "0")])
11568
11569 (define_insn "nop"
11570   [(const_int 0)]
11571   ""
11572   "nop"
11573   [(set_attr "length" "1")
11574    (set_attr "length_immediate" "0")
11575    (set_attr "modrm" "0")])
11576
11577 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11578 (define_insn "nops"
11579   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11580                     UNSPECV_NOPS)]
11581   "reload_completed"
11582 {
11583   int num = INTVAL (operands[0]);
11584
11585   gcc_assert (num >= 1 && num <= 8);
11586
11587   while (num--)
11588     fputs ("\tnop\n", asm_out_file);
11589
11590   return "";
11591 }
11592   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11593    (set_attr "length_immediate" "0")
11594    (set_attr "modrm" "0")])
11595
11596 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11597 ;; branch prediction penalty for the third jump in a 16-byte
11598 ;; block on K8.
11599
11600 (define_insn "pad"
11601   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11602   ""
11603 {
11604 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11605   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11606 #else
11607   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11608      The align insn is used to avoid 3 jump instructions in the row to improve
11609      branch prediction and the benefits hardly outweigh the cost of extra 8
11610      nops on the average inserted by full alignment pseudo operation.  */
11611 #endif
11612   return "";
11613 }
11614   [(set_attr "length" "16")])
11615
11616 (define_expand "prologue"
11617   [(const_int 0)]
11618   ""
11619   "ix86_expand_prologue (); DONE;")
11620
11621 (define_insn "set_got"
11622   [(set (match_operand:SI 0 "register_operand" "=r")
11623         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11624    (clobber (reg:CC FLAGS_REG))]
11625   "!TARGET_64BIT"
11626   "* return output_set_got (operands[0], NULL_RTX);"
11627   [(set_attr "type" "multi")
11628    (set_attr "length" "12")])
11629
11630 (define_insn "set_got_labelled"
11631   [(set (match_operand:SI 0 "register_operand" "=r")
11632         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11633          UNSPEC_SET_GOT))
11634    (clobber (reg:CC FLAGS_REG))]
11635   "!TARGET_64BIT"
11636   "* return output_set_got (operands[0], operands[1]);"
11637   [(set_attr "type" "multi")
11638    (set_attr "length" "12")])
11639
11640 (define_insn "set_got_rex64"
11641   [(set (match_operand:DI 0 "register_operand" "=r")
11642         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11643   "TARGET_64BIT"
11644   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11645   [(set_attr "type" "lea")
11646    (set_attr "length_address" "4")
11647    (set_attr "mode" "DI")])
11648
11649 (define_insn "set_rip_rex64"
11650   [(set (match_operand:DI 0 "register_operand" "=r")
11651         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11652   "TARGET_64BIT"
11653   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11654   [(set_attr "type" "lea")
11655    (set_attr "length_address" "4")
11656    (set_attr "mode" "DI")])
11657
11658 (define_insn "set_got_offset_rex64"
11659   [(set (match_operand:DI 0 "register_operand" "=r")
11660         (unspec:DI
11661           [(label_ref (match_operand 1 "" ""))]
11662           UNSPEC_SET_GOT_OFFSET))]
11663   "TARGET_64BIT"
11664   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11665   [(set_attr "type" "imov")
11666    (set_attr "length_immediate" "0")
11667    (set_attr "length_address" "8")
11668    (set_attr "mode" "DI")])
11669
11670 (define_expand "epilogue"
11671   [(const_int 0)]
11672   ""
11673   "ix86_expand_epilogue (1); DONE;")
11674
11675 (define_expand "sibcall_epilogue"
11676   [(const_int 0)]
11677   ""
11678   "ix86_expand_epilogue (0); DONE;")
11679
11680 (define_expand "eh_return"
11681   [(use (match_operand 0 "register_operand" ""))]
11682   ""
11683 {
11684   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11685
11686   /* Tricky bit: we write the address of the handler to which we will
11687      be returning into someone else's stack frame, one word below the
11688      stack address we wish to restore.  */
11689   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11690   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11691   tmp = gen_rtx_MEM (Pmode, tmp);
11692   emit_move_insn (tmp, ra);
11693
11694   emit_jump_insn (gen_eh_return_internal ());
11695   emit_barrier ();
11696   DONE;
11697 })
11698
11699 (define_insn_and_split "eh_return_internal"
11700   [(eh_return)]
11701   ""
11702   "#"
11703   "epilogue_completed"
11704   [(const_int 0)]
11705   "ix86_expand_epilogue (2); DONE;")
11706
11707 (define_insn "leave"
11708   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11709    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11710    (clobber (mem:BLK (scratch)))]
11711   "!TARGET_64BIT"
11712   "leave"
11713   [(set_attr "type" "leave")])
11714
11715 (define_insn "leave_rex64"
11716   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11717    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11718    (clobber (mem:BLK (scratch)))]
11719   "TARGET_64BIT"
11720   "leave"
11721   [(set_attr "type" "leave")])
11722 \f
11723 ;; Handle -fsplit-stack.
11724
11725 (define_expand "split_stack_prologue"
11726   [(const_int 0)]
11727   ""
11728 {
11729   ix86_expand_split_stack_prologue ();
11730   DONE;
11731 })
11732
11733 ;; In order to support the call/return predictor, we use a return
11734 ;; instruction which the middle-end doesn't see.
11735 (define_insn "split_stack_return"
11736   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11737                      UNSPECV_SPLIT_STACK_RETURN)]
11738   ""
11739 {
11740   if (operands[0] == const0_rtx)
11741     return "ret";
11742   else
11743     return "ret\t%0";
11744 }
11745   [(set_attr "atom_unit" "jeu")
11746    (set_attr "modrm" "0")
11747    (set (attr "length")
11748         (if_then_else (match_operand:SI 0 "const0_operand" "")
11749                       (const_int 1)
11750                       (const_int 3)))
11751    (set (attr "length_immediate")
11752         (if_then_else (match_operand:SI 0 "const0_operand" "")
11753                       (const_int 0)
11754                       (const_int 2)))])
11755
11756 ;; If there are operand 0 bytes available on the stack, jump to
11757 ;; operand 1.
11758
11759 (define_expand "split_stack_space_check"
11760   [(set (pc) (if_then_else
11761               (ltu (minus (reg SP_REG)
11762                           (match_operand 0 "register_operand" ""))
11763                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11764               (label_ref (match_operand 1 "" ""))
11765               (pc)))]
11766   ""
11767 {
11768   rtx reg, size, limit;
11769
11770   reg = gen_reg_rtx (Pmode);
11771   size = force_reg (Pmode, operands[0]);
11772   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11773   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11774                           UNSPEC_STACK_CHECK);
11775   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11776   ix86_expand_branch (GEU, reg, limit, operands[1]);
11777
11778   DONE;
11779 })
11780 \f
11781 ;; Bit manipulation instructions.
11782
11783 (define_expand "ffs<mode>2"
11784   [(set (match_dup 2) (const_int -1))
11785    (parallel [(set (reg:CCZ FLAGS_REG)
11786                    (compare:CCZ
11787                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11788                      (const_int 0)))
11789               (set (match_operand:SWI48 0 "register_operand" "")
11790                    (ctz:SWI48 (match_dup 1)))])
11791    (set (match_dup 0) (if_then_else:SWI48
11792                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11793                         (match_dup 2)
11794                         (match_dup 0)))
11795    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11796               (clobber (reg:CC FLAGS_REG))])]
11797   ""
11798 {
11799   if (<MODE>mode == SImode && !TARGET_CMOVE)
11800     {
11801       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11802       DONE;
11803     }
11804   operands[2] = gen_reg_rtx (<MODE>mode);
11805 })
11806
11807 (define_insn_and_split "ffssi2_no_cmove"
11808   [(set (match_operand:SI 0 "register_operand" "=r")
11809         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11810    (clobber (match_scratch:SI 2 "=&q"))
11811    (clobber (reg:CC FLAGS_REG))]
11812   "!TARGET_CMOVE"
11813   "#"
11814   "&& reload_completed"
11815   [(parallel [(set (reg:CCZ FLAGS_REG)
11816                    (compare:CCZ (match_dup 1) (const_int 0)))
11817               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11818    (set (strict_low_part (match_dup 3))
11819         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11820    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11821               (clobber (reg:CC FLAGS_REG))])
11822    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11823               (clobber (reg:CC FLAGS_REG))])
11824    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11825               (clobber (reg:CC FLAGS_REG))])]
11826 {
11827   operands[3] = gen_lowpart (QImode, operands[2]);
11828   ix86_expand_clear (operands[2]);
11829 })
11830
11831 (define_insn "*ffs<mode>_1"
11832   [(set (reg:CCZ FLAGS_REG)
11833         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11834                      (const_int 0)))
11835    (set (match_operand:SWI48 0 "register_operand" "=r")
11836         (ctz:SWI48 (match_dup 1)))]
11837   ""
11838   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11839   [(set_attr "type" "alu1")
11840    (set_attr "prefix_0f" "1")
11841    (set_attr "mode" "<MODE>")])
11842
11843 (define_insn "ctz<mode>2"
11844   [(set (match_operand:SWI248 0 "register_operand" "=r")
11845         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11846    (clobber (reg:CC FLAGS_REG))]
11847   ""
11848 {
11849   if (TARGET_BMI)
11850     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11851   else
11852     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11853 }
11854   [(set_attr "type" "alu1")
11855    (set_attr "prefix_0f" "1")
11856    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11857    (set_attr "mode" "<MODE>")])
11858
11859 (define_expand "clz<mode>2"
11860   [(parallel
11861      [(set (match_operand:SWI248 0 "register_operand" "")
11862            (minus:SWI248
11863              (match_dup 2)
11864              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11865       (clobber (reg:CC FLAGS_REG))])
11866    (parallel
11867      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11868       (clobber (reg:CC FLAGS_REG))])]
11869   ""
11870 {
11871   if (TARGET_ABM)
11872     {
11873       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11874       DONE;
11875     }
11876   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11877 })
11878
11879 (define_insn "clz<mode>2_abm"
11880   [(set (match_operand:SWI248 0 "register_operand" "=r")
11881         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11882    (clobber (reg:CC FLAGS_REG))]
11883   "TARGET_ABM || TARGET_BMI"
11884   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11885   [(set_attr "prefix_rep" "1")
11886    (set_attr "type" "bitmanip")
11887    (set_attr "mode" "<MODE>")])
11888
11889 ;; BMI instructions.
11890 (define_insn "*bmi_andn_<mode>"
11891   [(set (match_operand:SWI48 0 "register_operand" "=r")
11892         (and:SWI48
11893           (not:SWI48
11894             (match_operand:SWI48 1 "register_operand" "r"))
11895             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11896    (clobber (reg:CC FLAGS_REG))]
11897   "TARGET_BMI"
11898   "andn\t{%2, %1, %0|%0, %1, %2}"
11899   [(set_attr "type" "bitmanip")
11900    (set_attr "mode" "<MODE>")])
11901
11902 (define_insn "bmi_bextr_<mode>"
11903   [(set (match_operand:SWI48 0 "register_operand" "=r")
11904         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11905                        (match_operand:SWI48 2 "register_operand" "r")]
11906                        UNSPEC_BEXTR))
11907    (clobber (reg:CC FLAGS_REG))]
11908   "TARGET_BMI"
11909   "bextr\t{%2, %1, %0|%0, %1, %2}"
11910   [(set_attr "type" "bitmanip")
11911    (set_attr "mode" "<MODE>")])
11912
11913 (define_insn "*bmi_blsi_<mode>"
11914   [(set (match_operand:SWI48 0 "register_operand" "=r")
11915         (and:SWI48
11916           (neg:SWI48
11917             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11918           (match_dup 1)))
11919    (clobber (reg:CC FLAGS_REG))]
11920   "TARGET_BMI"
11921   "blsi\t{%1, %0|%0, %1}"
11922   [(set_attr "type" "bitmanip")
11923    (set_attr "mode" "<MODE>")])
11924
11925 (define_insn "*bmi_blsmsk_<mode>"
11926   [(set (match_operand:SWI48 0 "register_operand" "=r")
11927         (xor:SWI48
11928           (plus:SWI48
11929             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11930             (const_int -1))
11931           (match_dup 1)))
11932    (clobber (reg:CC FLAGS_REG))]
11933   "TARGET_BMI"
11934   "blsmsk\t{%1, %0|%0, %1}"
11935   [(set_attr "type" "bitmanip")
11936    (set_attr "mode" "<MODE>")])
11937
11938 (define_insn "*bmi_blsr_<mode>"
11939   [(set (match_operand:SWI48 0 "register_operand" "=r")
11940         (and:SWI48
11941           (plus:SWI48
11942             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11943             (const_int -1))
11944           (match_dup 1)))
11945    (clobber (reg:CC FLAGS_REG))]
11946    "TARGET_BMI"
11947    "blsr\t{%1, %0|%0, %1}"
11948   [(set_attr "type" "bitmanip")
11949    (set_attr "mode" "<MODE>")])
11950
11951 ;; TBM instructions.
11952 (define_insn "tbm_bextri_<mode>"
11953   [(set (match_operand:SWI48 0 "register_operand" "=r")
11954         (zero_extract:SWI48
11955           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11956           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11957           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11958    (clobber (reg:CC FLAGS_REG))]
11959    "TARGET_TBM"
11960 {
11961   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11962   return "bextr\t{%2, %1, %0|%0, %1, %2}";
11963 }
11964   [(set_attr "type" "bitmanip")
11965    (set_attr "mode" "<MODE>")])
11966
11967 (define_insn "*tbm_blcfill_<mode>"
11968   [(set (match_operand:SWI48 0 "register_operand" "=r")
11969         (and:SWI48
11970           (plus:SWI48
11971             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11972             (const_int 1))
11973           (match_dup 1)))
11974    (clobber (reg:CC FLAGS_REG))]
11975    "TARGET_TBM"
11976    "blcfill\t{%1, %0|%0, %1}"
11977   [(set_attr "type" "bitmanip")
11978    (set_attr "mode" "<MODE>")])
11979
11980 (define_insn "*tbm_blci_<mode>"
11981   [(set (match_operand:SWI48 0 "register_operand" "=r")
11982         (ior:SWI48
11983           (not:SWI48
11984             (plus:SWI48
11985               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11986               (const_int 1)))
11987           (match_dup 1)))
11988    (clobber (reg:CC FLAGS_REG))]
11989    "TARGET_TBM"
11990    "blci\t{%1, %0|%0, %1}"
11991   [(set_attr "type" "bitmanip")
11992    (set_attr "mode" "<MODE>")])
11993
11994 (define_insn "*tbm_blcic_<mode>"
11995   [(set (match_operand:SWI48 0 "register_operand" "=r")
11996         (and:SWI48
11997           (plus:SWI48
11998             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11999             (const_int 1))
12000           (not:SWI48
12001             (match_dup 1))))
12002    (clobber (reg:CC FLAGS_REG))]
12003    "TARGET_TBM"
12004    "blcic\t{%1, %0|%0, %1}"
12005   [(set_attr "type" "bitmanip")
12006    (set_attr "mode" "<MODE>")])
12007
12008 (define_insn "*tbm_blcmsk_<mode>"
12009   [(set (match_operand:SWI48 0 "register_operand" "=r")
12010         (xor:SWI48
12011           (plus:SWI48
12012             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12013             (const_int 1))
12014           (match_dup 1)))
12015    (clobber (reg:CC FLAGS_REG))]
12016    "TARGET_TBM"
12017    "blcmsk\t{%1, %0|%0, %1}"
12018   [(set_attr "type" "bitmanip")
12019    (set_attr "mode" "<MODE>")])
12020
12021 (define_insn "*tbm_blcs_<mode>"
12022   [(set (match_operand:SWI48 0 "register_operand" "=r")
12023         (ior:SWI48
12024           (plus:SWI48
12025             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12026             (const_int 1))
12027           (match_dup 1)))
12028    (clobber (reg:CC FLAGS_REG))]
12029    "TARGET_TBM"
12030    "blcs\t{%1, %0|%0, %1}"
12031   [(set_attr "type" "bitmanip")
12032    (set_attr "mode" "<MODE>")])
12033
12034 (define_insn "*tbm_blsfill_<mode>"
12035   [(set (match_operand:SWI48 0 "register_operand" "=r")
12036         (ior:SWI48
12037           (plus:SWI48
12038             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12039             (const_int -1))
12040           (match_dup 1)))
12041    (clobber (reg:CC FLAGS_REG))]
12042    "TARGET_TBM"
12043    "blsfill\t{%1, %0|%0, %1}"
12044   [(set_attr "type" "bitmanip")
12045    (set_attr "mode" "<MODE>")])
12046
12047 (define_insn "*tbm_blsic_<mode>"
12048   [(set (match_operand:SWI48 0 "register_operand" "=r")
12049         (ior:SWI48
12050           (plus:SWI48
12051             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12052             (const_int -1))
12053           (not:SWI48
12054             (match_dup 1))))
12055    (clobber (reg:CC FLAGS_REG))]
12056    "TARGET_TBM"
12057    "blsic\t{%1, %0|%0, %1}"
12058   [(set_attr "type" "bitmanip")
12059    (set_attr "mode" "<MODE>")])
12060
12061 (define_insn "*tbm_t1mskc_<mode>"
12062   [(set (match_operand:SWI48 0 "register_operand" "=r")
12063         (ior:SWI48
12064           (plus:SWI48
12065             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12066             (const_int 1))
12067           (not:SWI48
12068             (match_dup 1))))
12069    (clobber (reg:CC FLAGS_REG))]
12070    "TARGET_TBM"
12071    "t1mskc\t{%1, %0|%0, %1}"
12072   [(set_attr "type" "bitmanip")
12073    (set_attr "mode" "<MODE>")])
12074
12075 (define_insn "*tbm_tzmsk_<mode>"
12076   [(set (match_operand:SWI48 0 "register_operand" "=r")
12077         (and:SWI48
12078           (plus:SWI48
12079             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12080             (const_int -1))
12081           (not:SWI48
12082             (match_dup 1))))
12083    (clobber (reg:CC FLAGS_REG))]
12084    "TARGET_TBM"
12085    "tzmsk\t{%1, %0|%0, %1}"
12086   [(set_attr "type" "bitmanip")
12087    (set_attr "mode" "<MODE>")])
12088
12089 (define_insn "bsr_rex64"
12090   [(set (match_operand:DI 0 "register_operand" "=r")
12091         (minus:DI (const_int 63)
12092                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12093    (clobber (reg:CC FLAGS_REG))]
12094   "TARGET_64BIT"
12095   "bsr{q}\t{%1, %0|%0, %1}"
12096   [(set_attr "type" "alu1")
12097    (set_attr "prefix_0f" "1")
12098    (set_attr "mode" "DI")])
12099
12100 (define_insn "bsr"
12101   [(set (match_operand:SI 0 "register_operand" "=r")
12102         (minus:SI (const_int 31)
12103                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12104    (clobber (reg:CC FLAGS_REG))]
12105   ""
12106   "bsr{l}\t{%1, %0|%0, %1}"
12107   [(set_attr "type" "alu1")
12108    (set_attr "prefix_0f" "1")
12109    (set_attr "mode" "SI")])
12110
12111 (define_insn "*bsrhi"
12112   [(set (match_operand:HI 0 "register_operand" "=r")
12113         (minus:HI (const_int 15)
12114                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12115    (clobber (reg:CC FLAGS_REG))]
12116   ""
12117   "bsr{w}\t{%1, %0|%0, %1}"
12118   [(set_attr "type" "alu1")
12119    (set_attr "prefix_0f" "1")
12120    (set_attr "mode" "HI")])
12121
12122 (define_insn "popcount<mode>2"
12123   [(set (match_operand:SWI248 0 "register_operand" "=r")
12124         (popcount:SWI248
12125           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12126    (clobber (reg:CC FLAGS_REG))]
12127   "TARGET_POPCNT"
12128 {
12129 #if TARGET_MACHO
12130   return "popcnt\t{%1, %0|%0, %1}";
12131 #else
12132   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12133 #endif
12134 }
12135   [(set_attr "prefix_rep" "1")
12136    (set_attr "type" "bitmanip")
12137    (set_attr "mode" "<MODE>")])
12138
12139 (define_insn "*popcount<mode>2_cmp"
12140   [(set (reg FLAGS_REG)
12141         (compare
12142           (popcount:SWI248
12143             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12144           (const_int 0)))
12145    (set (match_operand:SWI248 0 "register_operand" "=r")
12146         (popcount:SWI248 (match_dup 1)))]
12147   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12148 {
12149 #if TARGET_MACHO
12150   return "popcnt\t{%1, %0|%0, %1}";
12151 #else
12152   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12153 #endif
12154 }
12155   [(set_attr "prefix_rep" "1")
12156    (set_attr "type" "bitmanip")
12157    (set_attr "mode" "<MODE>")])
12158
12159 (define_insn "*popcountsi2_cmp_zext"
12160   [(set (reg FLAGS_REG)
12161         (compare
12162           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12163           (const_int 0)))
12164    (set (match_operand:DI 0 "register_operand" "=r")
12165         (zero_extend:DI(popcount:SI (match_dup 1))))]
12166   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12167 {
12168 #if TARGET_MACHO
12169   return "popcnt\t{%1, %0|%0, %1}";
12170 #else
12171   return "popcnt{l}\t{%1, %0|%0, %1}";
12172 #endif
12173 }
12174   [(set_attr "prefix_rep" "1")
12175    (set_attr "type" "bitmanip")
12176    (set_attr "mode" "SI")])
12177
12178 (define_expand "bswap<mode>2"
12179   [(set (match_operand:SWI48 0 "register_operand" "")
12180         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12181   ""
12182 {
12183   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12184     {
12185       rtx x = operands[0];
12186
12187       emit_move_insn (x, operands[1]);
12188       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12189       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12190       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12191       DONE;
12192     }
12193 })
12194
12195 (define_insn "*bswap<mode>2_movbe"
12196   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12197         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12198   "TARGET_MOVBE
12199    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12200   "@
12201     bswap\t%0
12202     movbe\t{%1, %0|%0, %1}
12203     movbe\t{%1, %0|%0, %1}"
12204   [(set_attr "type" "bitmanip,imov,imov")
12205    (set_attr "modrm" "0,1,1")
12206    (set_attr "prefix_0f" "*,1,1")
12207    (set_attr "prefix_extra" "*,1,1")
12208    (set_attr "mode" "<MODE>")])
12209
12210 (define_insn "*bswap<mode>2_1"
12211   [(set (match_operand:SWI48 0 "register_operand" "=r")
12212         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12213   "TARGET_BSWAP"
12214   "bswap\t%0"
12215   [(set_attr "type" "bitmanip")
12216    (set_attr "modrm" "0")
12217    (set_attr "mode" "<MODE>")])
12218
12219 (define_insn "*bswaphi_lowpart_1"
12220   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12221         (bswap:HI (match_dup 0)))
12222    (clobber (reg:CC FLAGS_REG))]
12223   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12224   "@
12225     xchg{b}\t{%h0, %b0|%b0, %h0}
12226     rol{w}\t{$8, %0|%0, 8}"
12227   [(set_attr "length" "2,4")
12228    (set_attr "mode" "QI,HI")])
12229
12230 (define_insn "bswaphi_lowpart"
12231   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12232         (bswap:HI (match_dup 0)))
12233    (clobber (reg:CC FLAGS_REG))]
12234   ""
12235   "rol{w}\t{$8, %0|%0, 8}"
12236   [(set_attr "length" "4")
12237    (set_attr "mode" "HI")])
12238
12239 (define_expand "paritydi2"
12240   [(set (match_operand:DI 0 "register_operand" "")
12241         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12242   "! TARGET_POPCNT"
12243 {
12244   rtx scratch = gen_reg_rtx (QImode);
12245   rtx cond;
12246
12247   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12248                                 NULL_RTX, operands[1]));
12249
12250   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12251                          gen_rtx_REG (CCmode, FLAGS_REG),
12252                          const0_rtx);
12253   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12254
12255   if (TARGET_64BIT)
12256     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12257   else
12258     {
12259       rtx tmp = gen_reg_rtx (SImode);
12260
12261       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12262       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12263     }
12264   DONE;
12265 })
12266
12267 (define_expand "paritysi2"
12268   [(set (match_operand:SI 0 "register_operand" "")
12269         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12270   "! TARGET_POPCNT"
12271 {
12272   rtx scratch = gen_reg_rtx (QImode);
12273   rtx cond;
12274
12275   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12276
12277   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12278                          gen_rtx_REG (CCmode, FLAGS_REG),
12279                          const0_rtx);
12280   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12281
12282   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12283   DONE;
12284 })
12285
12286 (define_insn_and_split "paritydi2_cmp"
12287   [(set (reg:CC FLAGS_REG)
12288         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12289                    UNSPEC_PARITY))
12290    (clobber (match_scratch:DI 0 "=r"))
12291    (clobber (match_scratch:SI 1 "=&r"))
12292    (clobber (match_scratch:HI 2 "=Q"))]
12293   "! TARGET_POPCNT"
12294   "#"
12295   "&& reload_completed"
12296   [(parallel
12297      [(set (match_dup 1)
12298            (xor:SI (match_dup 1) (match_dup 4)))
12299       (clobber (reg:CC FLAGS_REG))])
12300    (parallel
12301      [(set (reg:CC FLAGS_REG)
12302            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12303       (clobber (match_dup 1))
12304       (clobber (match_dup 2))])]
12305 {
12306   operands[4] = gen_lowpart (SImode, operands[3]);
12307
12308   if (TARGET_64BIT)
12309     {
12310       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12311       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12312     }
12313   else
12314     operands[1] = gen_highpart (SImode, operands[3]);
12315 })
12316
12317 (define_insn_and_split "paritysi2_cmp"
12318   [(set (reg:CC FLAGS_REG)
12319         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12320                    UNSPEC_PARITY))
12321    (clobber (match_scratch:SI 0 "=r"))
12322    (clobber (match_scratch:HI 1 "=&Q"))]
12323   "! TARGET_POPCNT"
12324   "#"
12325   "&& reload_completed"
12326   [(parallel
12327      [(set (match_dup 1)
12328            (xor:HI (match_dup 1) (match_dup 3)))
12329       (clobber (reg:CC FLAGS_REG))])
12330    (parallel
12331      [(set (reg:CC FLAGS_REG)
12332            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12333       (clobber (match_dup 1))])]
12334 {
12335   operands[3] = gen_lowpart (HImode, operands[2]);
12336
12337   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12338   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12339 })
12340
12341 (define_insn "*parityhi2_cmp"
12342   [(set (reg:CC FLAGS_REG)
12343         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12344                    UNSPEC_PARITY))
12345    (clobber (match_scratch:HI 0 "=Q"))]
12346   "! TARGET_POPCNT"
12347   "xor{b}\t{%h0, %b0|%b0, %h0}"
12348   [(set_attr "length" "2")
12349    (set_attr "mode" "HI")])
12350 \f
12351 ;; Thread-local storage patterns for ELF.
12352 ;;
12353 ;; Note that these code sequences must appear exactly as shown
12354 ;; in order to allow linker relaxation.
12355
12356 (define_insn "*tls_global_dynamic_32_gnu"
12357   [(set (match_operand:SI 0 "register_operand" "=a")
12358         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12359                     (match_operand:SI 2 "tls_symbolic_operand" "")
12360                     (match_operand:SI 3 "constant_call_address_operand" "z")]
12361                     UNSPEC_TLS_GD))
12362    (clobber (match_scratch:SI 4 "=d"))
12363    (clobber (match_scratch:SI 5 "=c"))
12364    (clobber (reg:CC FLAGS_REG))]
12365   "!TARGET_64BIT && TARGET_GNU_TLS"
12366   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12367   [(set_attr "type" "multi")
12368    (set_attr "length" "12")])
12369
12370 (define_expand "tls_global_dynamic_32"
12371   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12372                    (unspec:SI
12373                     [(match_operand:SI 2 "register_operand" "")
12374                      (match_operand:SI 1 "tls_symbolic_operand" "")
12375                      (match_operand:SI 3 "constant_call_address_operand" "")]
12376                     UNSPEC_TLS_GD))
12377               (clobber (match_scratch:SI 4 ""))
12378               (clobber (match_scratch:SI 5 ""))
12379               (clobber (reg:CC FLAGS_REG))])])
12380
12381 (define_insn "*tls_global_dynamic_64"
12382   [(set (match_operand:DI 0 "register_operand" "=a")
12383         (call:DI
12384           (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12385           (match_operand:DI 3 "" "")))
12386    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12387               UNSPEC_TLS_GD)]
12388   "TARGET_64BIT"
12389   { 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"; }
12390   [(set_attr "type" "multi")
12391    (set_attr "length" "16")])
12392
12393 (define_expand "tls_global_dynamic_64"
12394   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12395                    (call:DI
12396                      (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12397                      (const_int 0)))
12398               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12399                          UNSPEC_TLS_GD)])])
12400
12401 (define_insn "*tls_local_dynamic_base_32_gnu"
12402   [(set (match_operand:SI 0 "register_operand" "=a")
12403         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12404                     (match_operand:SI 2 "constant_call_address_operand" "z")]
12405                    UNSPEC_TLS_LD_BASE))
12406    (clobber (match_scratch:SI 3 "=d"))
12407    (clobber (match_scratch:SI 4 "=c"))
12408    (clobber (reg:CC FLAGS_REG))]
12409   "!TARGET_64BIT && TARGET_GNU_TLS"
12410   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12411   [(set_attr "type" "multi")
12412    (set_attr "length" "11")])
12413
12414 (define_expand "tls_local_dynamic_base_32"
12415   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12416                    (unspec:SI [(match_operand:SI 1 "register_operand" "")
12417                                (match_operand:SI 2 "constant_call_address_operand" "")]
12418                               UNSPEC_TLS_LD_BASE))
12419               (clobber (match_scratch:SI 3 ""))
12420               (clobber (match_scratch:SI 4 ""))
12421               (clobber (reg:CC FLAGS_REG))])])
12422
12423 (define_insn "*tls_local_dynamic_base_64"
12424   [(set (match_operand:DI 0 "register_operand" "=a")
12425         (call:DI (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12426                  (match_operand:DI 2 "" "")))
12427    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12428   "TARGET_64BIT"
12429   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12430   [(set_attr "type" "multi")
12431    (set_attr "length" "12")])
12432
12433 (define_expand "tls_local_dynamic_base_64"
12434   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12435                    (call:DI
12436                      (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12437                      (const_int 0)))
12438               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12439
12440 ;; Local dynamic of a single variable is a lose.  Show combine how
12441 ;; to convert that back to global dynamic.
12442
12443 (define_insn_and_split "*tls_local_dynamic_32_once"
12444   [(set (match_operand:SI 0 "register_operand" "=a")
12445         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12446                              (match_operand:SI 2 "constant_call_address_operand" "z")]
12447                             UNSPEC_TLS_LD_BASE)
12448                  (const:SI (unspec:SI
12449                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12450                             UNSPEC_DTPOFF))))
12451    (clobber (match_scratch:SI 4 "=d"))
12452    (clobber (match_scratch:SI 5 "=c"))
12453    (clobber (reg:CC FLAGS_REG))]
12454   ""
12455   "#"
12456   ""
12457   [(parallel [(set (match_dup 0)
12458                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12459                               UNSPEC_TLS_GD))
12460               (clobber (match_dup 4))
12461               (clobber (match_dup 5))
12462               (clobber (reg:CC FLAGS_REG))])])
12463
12464 ;; Segment register for the thread base ptr load
12465 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12466
12467 ;; Load and add the thread base pointer from %gs:0.
12468 (define_insn "*load_tp_<mode>"
12469   [(set (match_operand:P 0 "register_operand" "=r")
12470         (unspec:P [(const_int 0)] UNSPEC_TP))]
12471   ""
12472   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12473   [(set_attr "type" "imov")
12474    (set_attr "modrm" "0")
12475    (set_attr "length" "7")
12476    (set_attr "memory" "load")
12477    (set_attr "imm_disp" "false")])
12478
12479 (define_insn "*add_tp_<mode>"
12480   [(set (match_operand:P 0 "register_operand" "=r")
12481         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12482                 (match_operand:P 1 "register_operand" "0")))
12483    (clobber (reg:CC FLAGS_REG))]
12484   ""
12485   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12486   [(set_attr "type" "alu")
12487    (set_attr "modrm" "0")
12488    (set_attr "length" "7")
12489    (set_attr "memory" "load")
12490    (set_attr "imm_disp" "false")])
12491
12492 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12493 ;; %rax as destination of the initial executable code sequence.
12494 (define_insn "tls_initial_exec_64_sun"
12495   [(set (match_operand:DI 0 "register_operand" "=a")
12496         (unspec:DI
12497          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12498          UNSPEC_TLS_IE_SUN))
12499    (clobber (reg:CC FLAGS_REG))]
12500   "TARGET_64BIT && TARGET_SUN_TLS"
12501   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}\n\tadd{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"
12502   [(set_attr "type" "multi")])
12503
12504 ;; GNU2 TLS patterns can be split.
12505
12506 (define_expand "tls_dynamic_gnu2_32"
12507   [(set (match_dup 3)
12508         (plus:SI (match_operand:SI 2 "register_operand" "")
12509                  (const:SI
12510                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12511                              UNSPEC_TLSDESC))))
12512    (parallel
12513     [(set (match_operand:SI 0 "register_operand" "")
12514           (unspec:SI [(match_dup 1) (match_dup 3)
12515                       (match_dup 2) (reg:SI SP_REG)]
12516                       UNSPEC_TLSDESC))
12517      (clobber (reg:CC FLAGS_REG))])]
12518   "!TARGET_64BIT && TARGET_GNU2_TLS"
12519 {
12520   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12521   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12522 })
12523
12524 (define_insn "*tls_dynamic_lea_32"
12525   [(set (match_operand:SI 0 "register_operand" "=r")
12526         (plus:SI (match_operand:SI 1 "register_operand" "b")
12527                  (const:SI
12528                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12529                               UNSPEC_TLSDESC))))]
12530   "!TARGET_64BIT && TARGET_GNU2_TLS"
12531   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12532   [(set_attr "type" "lea")
12533    (set_attr "mode" "SI")
12534    (set_attr "length" "6")
12535    (set_attr "length_address" "4")])
12536
12537 (define_insn "*tls_dynamic_call_32"
12538   [(set (match_operand:SI 0 "register_operand" "=a")
12539         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12540                     (match_operand:SI 2 "register_operand" "0")
12541                     ;; we have to make sure %ebx still points to the GOT
12542                     (match_operand:SI 3 "register_operand" "b")
12543                     (reg:SI SP_REG)]
12544                    UNSPEC_TLSDESC))
12545    (clobber (reg:CC FLAGS_REG))]
12546   "!TARGET_64BIT && TARGET_GNU2_TLS"
12547   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12548   [(set_attr "type" "call")
12549    (set_attr "length" "2")
12550    (set_attr "length_address" "0")])
12551
12552 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12553   [(set (match_operand:SI 0 "register_operand" "=&a")
12554         (plus:SI
12555          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12556                      (match_operand:SI 4 "" "")
12557                      (match_operand:SI 2 "register_operand" "b")
12558                      (reg:SI SP_REG)]
12559                     UNSPEC_TLSDESC)
12560          (const:SI (unspec:SI
12561                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12562                     UNSPEC_DTPOFF))))
12563    (clobber (reg:CC FLAGS_REG))]
12564   "!TARGET_64BIT && TARGET_GNU2_TLS"
12565   "#"
12566   ""
12567   [(set (match_dup 0) (match_dup 5))]
12568 {
12569   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12570   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12571 })
12572
12573 (define_expand "tls_dynamic_gnu2_64"
12574   [(set (match_dup 2)
12575         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12576                    UNSPEC_TLSDESC))
12577    (parallel
12578     [(set (match_operand:DI 0 "register_operand" "")
12579           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12580                      UNSPEC_TLSDESC))
12581      (clobber (reg:CC FLAGS_REG))])]
12582   "TARGET_64BIT && TARGET_GNU2_TLS"
12583 {
12584   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12585   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12586 })
12587
12588 (define_insn "*tls_dynamic_lea_64"
12589   [(set (match_operand:DI 0 "register_operand" "=r")
12590         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12591                    UNSPEC_TLSDESC))]
12592   "TARGET_64BIT && TARGET_GNU2_TLS"
12593   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12594   [(set_attr "type" "lea")
12595    (set_attr "mode" "DI")
12596    (set_attr "length" "7")
12597    (set_attr "length_address" "4")])
12598
12599 (define_insn "*tls_dynamic_call_64"
12600   [(set (match_operand:DI 0 "register_operand" "=a")
12601         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12602                     (match_operand:DI 2 "register_operand" "0")
12603                     (reg:DI SP_REG)]
12604                    UNSPEC_TLSDESC))
12605    (clobber (reg:CC FLAGS_REG))]
12606   "TARGET_64BIT && TARGET_GNU2_TLS"
12607   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12608   [(set_attr "type" "call")
12609    (set_attr "length" "2")
12610    (set_attr "length_address" "0")])
12611
12612 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12613   [(set (match_operand:DI 0 "register_operand" "=&a")
12614         (plus:DI
12615          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12616                      (match_operand:DI 3 "" "")
12617                      (reg:DI SP_REG)]
12618                     UNSPEC_TLSDESC)
12619          (const:DI (unspec:DI
12620                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12621                     UNSPEC_DTPOFF))))
12622    (clobber (reg:CC FLAGS_REG))]
12623   "TARGET_64BIT && TARGET_GNU2_TLS"
12624   "#"
12625   ""
12626   [(set (match_dup 0) (match_dup 4))]
12627 {
12628   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12629   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12630 })
12631 \f
12632 ;; These patterns match the binary 387 instructions for addM3, subM3,
12633 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12634 ;; SFmode.  The first is the normal insn, the second the same insn but
12635 ;; with one operand a conversion, and the third the same insn but with
12636 ;; the other operand a conversion.  The conversion may be SFmode or
12637 ;; SImode if the target mode DFmode, but only SImode if the target mode
12638 ;; is SFmode.
12639
12640 ;; Gcc is slightly more smart about handling normal two address instructions
12641 ;; so use special patterns for add and mull.
12642
12643 (define_insn "*fop_<mode>_comm_mixed"
12644   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12645         (match_operator:MODEF 3 "binary_fp_operator"
12646           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12647            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12648   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12649    && COMMUTATIVE_ARITH_P (operands[3])
12650    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12651   "* return output_387_binary_op (insn, operands);"
12652   [(set (attr "type")
12653         (if_then_else (eq_attr "alternative" "1,2")
12654            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12655               (const_string "ssemul")
12656               (const_string "sseadd"))
12657            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12658               (const_string "fmul")
12659               (const_string "fop"))))
12660    (set_attr "isa" "base,noavx,avx")
12661    (set_attr "prefix" "orig,orig,vex")
12662    (set_attr "mode" "<MODE>")])
12663
12664 (define_insn "*fop_<mode>_comm_sse"
12665   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12666         (match_operator:MODEF 3 "binary_fp_operator"
12667           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12668            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12669   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12670    && COMMUTATIVE_ARITH_P (operands[3])
12671    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12672   "* return output_387_binary_op (insn, operands);"
12673   [(set (attr "type")
12674         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12675            (const_string "ssemul")
12676            (const_string "sseadd")))
12677    (set_attr "isa" "noavx,avx")
12678    (set_attr "prefix" "orig,vex")
12679    (set_attr "mode" "<MODE>")])
12680
12681 (define_insn "*fop_<mode>_comm_i387"
12682   [(set (match_operand:MODEF 0 "register_operand" "=f")
12683         (match_operator:MODEF 3 "binary_fp_operator"
12684           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12685            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12686   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12687    && COMMUTATIVE_ARITH_P (operands[3])
12688    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12689   "* return output_387_binary_op (insn, operands);"
12690   [(set (attr "type")
12691         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12692            (const_string "fmul")
12693            (const_string "fop")))
12694    (set_attr "mode" "<MODE>")])
12695
12696 (define_insn "*fop_<mode>_1_mixed"
12697   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12698         (match_operator:MODEF 3 "binary_fp_operator"
12699           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12700            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12701   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12702    && !COMMUTATIVE_ARITH_P (operands[3])
12703    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12704   "* return output_387_binary_op (insn, operands);"
12705   [(set (attr "type")
12706         (cond [(and (eq_attr "alternative" "2,3")
12707                     (match_operand:MODEF 3 "mult_operator" ""))
12708                  (const_string "ssemul")
12709                (and (eq_attr "alternative" "2,3")
12710                     (match_operand:MODEF 3 "div_operator" ""))
12711                  (const_string "ssediv")
12712                (eq_attr "alternative" "2,3")
12713                  (const_string "sseadd")
12714                (match_operand:MODEF 3 "mult_operator" "")
12715                  (const_string "fmul")
12716                (match_operand:MODEF 3 "div_operator" "")
12717                  (const_string "fdiv")
12718               ]
12719               (const_string "fop")))
12720    (set_attr "isa" "base,base,noavx,avx")
12721    (set_attr "prefix" "orig,orig,orig,vex")
12722    (set_attr "mode" "<MODE>")])
12723
12724 (define_insn "*rcpsf2_sse"
12725   [(set (match_operand:SF 0 "register_operand" "=x")
12726         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12727                    UNSPEC_RCP))]
12728   "TARGET_SSE_MATH"
12729   "%vrcpss\t{%1, %d0|%d0, %1}"
12730   [(set_attr "type" "sse")
12731    (set_attr "atom_sse_attr" "rcp")
12732    (set_attr "prefix" "maybe_vex")
12733    (set_attr "mode" "SF")])
12734
12735 (define_insn "*fop_<mode>_1_sse"
12736   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12737         (match_operator:MODEF 3 "binary_fp_operator"
12738           [(match_operand:MODEF 1 "register_operand" "0,x")
12739            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12740   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12741    && !COMMUTATIVE_ARITH_P (operands[3])"
12742   "* return output_387_binary_op (insn, operands);"
12743   [(set (attr "type")
12744         (cond [(match_operand:MODEF 3 "mult_operator" "")
12745                  (const_string "ssemul")
12746                (match_operand:MODEF 3 "div_operator" "")
12747                  (const_string "ssediv")
12748               ]
12749               (const_string "sseadd")))
12750    (set_attr "isa" "noavx,avx")
12751    (set_attr "prefix" "orig,vex")
12752    (set_attr "mode" "<MODE>")])
12753
12754 ;; This pattern is not fully shadowed by the pattern above.
12755 (define_insn "*fop_<mode>_1_i387"
12756   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12757         (match_operator:MODEF 3 "binary_fp_operator"
12758           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12759            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12760   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12761    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12762    && !COMMUTATIVE_ARITH_P (operands[3])
12763    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12764   "* return output_387_binary_op (insn, operands);"
12765   [(set (attr "type")
12766         (cond [(match_operand:MODEF 3 "mult_operator" "")
12767                  (const_string "fmul")
12768                (match_operand:MODEF 3 "div_operator" "")
12769                  (const_string "fdiv")
12770               ]
12771               (const_string "fop")))
12772    (set_attr "mode" "<MODE>")])
12773
12774 ;; ??? Add SSE splitters for these!
12775 (define_insn "*fop_<MODEF:mode>_2_i387"
12776   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12777         (match_operator:MODEF 3 "binary_fp_operator"
12778           [(float:MODEF
12779              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12780            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12781   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12782    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12783    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12784   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12785   [(set (attr "type")
12786         (cond [(match_operand:MODEF 3 "mult_operator" "")
12787                  (const_string "fmul")
12788                (match_operand:MODEF 3 "div_operator" "")
12789                  (const_string "fdiv")
12790               ]
12791               (const_string "fop")))
12792    (set_attr "fp_int_src" "true")
12793    (set_attr "mode" "<X87MODEI12:MODE>")])
12794
12795 (define_insn "*fop_<MODEF:mode>_3_i387"
12796   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12797         (match_operator:MODEF 3 "binary_fp_operator"
12798           [(match_operand:MODEF 1 "register_operand" "0,0")
12799            (float:MODEF
12800              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12801   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12802    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12803    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12804   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12805   [(set (attr "type")
12806         (cond [(match_operand:MODEF 3 "mult_operator" "")
12807                  (const_string "fmul")
12808                (match_operand:MODEF 3 "div_operator" "")
12809                  (const_string "fdiv")
12810               ]
12811               (const_string "fop")))
12812    (set_attr "fp_int_src" "true")
12813    (set_attr "mode" "<MODE>")])
12814
12815 (define_insn "*fop_df_4_i387"
12816   [(set (match_operand:DF 0 "register_operand" "=f,f")
12817         (match_operator:DF 3 "binary_fp_operator"
12818            [(float_extend:DF
12819              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12820             (match_operand:DF 2 "register_operand" "0,f")]))]
12821   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12822    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12823    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12824   "* return output_387_binary_op (insn, operands);"
12825   [(set (attr "type")
12826         (cond [(match_operand:DF 3 "mult_operator" "")
12827                  (const_string "fmul")
12828                (match_operand:DF 3 "div_operator" "")
12829                  (const_string "fdiv")
12830               ]
12831               (const_string "fop")))
12832    (set_attr "mode" "SF")])
12833
12834 (define_insn "*fop_df_5_i387"
12835   [(set (match_operand:DF 0 "register_operand" "=f,f")
12836         (match_operator:DF 3 "binary_fp_operator"
12837           [(match_operand:DF 1 "register_operand" "0,f")
12838            (float_extend:DF
12839             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12840   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12841    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12842   "* return output_387_binary_op (insn, operands);"
12843   [(set (attr "type")
12844         (cond [(match_operand:DF 3 "mult_operator" "")
12845                  (const_string "fmul")
12846                (match_operand:DF 3 "div_operator" "")
12847                  (const_string "fdiv")
12848               ]
12849               (const_string "fop")))
12850    (set_attr "mode" "SF")])
12851
12852 (define_insn "*fop_df_6_i387"
12853   [(set (match_operand:DF 0 "register_operand" "=f,f")
12854         (match_operator:DF 3 "binary_fp_operator"
12855           [(float_extend:DF
12856             (match_operand:SF 1 "register_operand" "0,f"))
12857            (float_extend:DF
12858             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12859   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12860    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12861   "* return output_387_binary_op (insn, operands);"
12862   [(set (attr "type")
12863         (cond [(match_operand:DF 3 "mult_operator" "")
12864                  (const_string "fmul")
12865                (match_operand:DF 3 "div_operator" "")
12866                  (const_string "fdiv")
12867               ]
12868               (const_string "fop")))
12869    (set_attr "mode" "SF")])
12870
12871 (define_insn "*fop_xf_comm_i387"
12872   [(set (match_operand:XF 0 "register_operand" "=f")
12873         (match_operator:XF 3 "binary_fp_operator"
12874                         [(match_operand:XF 1 "register_operand" "%0")
12875                          (match_operand:XF 2 "register_operand" "f")]))]
12876   "TARGET_80387
12877    && COMMUTATIVE_ARITH_P (operands[3])"
12878   "* return output_387_binary_op (insn, operands);"
12879   [(set (attr "type")
12880         (if_then_else (match_operand:XF 3 "mult_operator" "")
12881            (const_string "fmul")
12882            (const_string "fop")))
12883    (set_attr "mode" "XF")])
12884
12885 (define_insn "*fop_xf_1_i387"
12886   [(set (match_operand:XF 0 "register_operand" "=f,f")
12887         (match_operator:XF 3 "binary_fp_operator"
12888                         [(match_operand:XF 1 "register_operand" "0,f")
12889                          (match_operand:XF 2 "register_operand" "f,0")]))]
12890   "TARGET_80387
12891    && !COMMUTATIVE_ARITH_P (operands[3])"
12892   "* return output_387_binary_op (insn, operands);"
12893   [(set (attr "type")
12894         (cond [(match_operand:XF 3 "mult_operator" "")
12895                  (const_string "fmul")
12896                (match_operand:XF 3 "div_operator" "")
12897                  (const_string "fdiv")
12898               ]
12899               (const_string "fop")))
12900    (set_attr "mode" "XF")])
12901
12902 (define_insn "*fop_xf_2_i387"
12903   [(set (match_operand:XF 0 "register_operand" "=f,f")
12904         (match_operator:XF 3 "binary_fp_operator"
12905           [(float:XF
12906              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12907            (match_operand:XF 2 "register_operand" "0,0")]))]
12908   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12909   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12910   [(set (attr "type")
12911         (cond [(match_operand:XF 3 "mult_operator" "")
12912                  (const_string "fmul")
12913                (match_operand:XF 3 "div_operator" "")
12914                  (const_string "fdiv")
12915               ]
12916               (const_string "fop")))
12917    (set_attr "fp_int_src" "true")
12918    (set_attr "mode" "<MODE>")])
12919
12920 (define_insn "*fop_xf_3_i387"
12921   [(set (match_operand:XF 0 "register_operand" "=f,f")
12922         (match_operator:XF 3 "binary_fp_operator"
12923           [(match_operand:XF 1 "register_operand" "0,0")
12924            (float:XF
12925              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12926   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12927   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12928   [(set (attr "type")
12929         (cond [(match_operand:XF 3 "mult_operator" "")
12930                  (const_string "fmul")
12931                (match_operand:XF 3 "div_operator" "")
12932                  (const_string "fdiv")
12933               ]
12934               (const_string "fop")))
12935    (set_attr "fp_int_src" "true")
12936    (set_attr "mode" "<MODE>")])
12937
12938 (define_insn "*fop_xf_4_i387"
12939   [(set (match_operand:XF 0 "register_operand" "=f,f")
12940         (match_operator:XF 3 "binary_fp_operator"
12941            [(float_extend:XF
12942               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12943             (match_operand:XF 2 "register_operand" "0,f")]))]
12944   "TARGET_80387"
12945   "* return output_387_binary_op (insn, operands);"
12946   [(set (attr "type")
12947         (cond [(match_operand:XF 3 "mult_operator" "")
12948                  (const_string "fmul")
12949                (match_operand:XF 3 "div_operator" "")
12950                  (const_string "fdiv")
12951               ]
12952               (const_string "fop")))
12953    (set_attr "mode" "<MODE>")])
12954
12955 (define_insn "*fop_xf_5_i387"
12956   [(set (match_operand:XF 0 "register_operand" "=f,f")
12957         (match_operator:XF 3 "binary_fp_operator"
12958           [(match_operand:XF 1 "register_operand" "0,f")
12959            (float_extend:XF
12960              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12961   "TARGET_80387"
12962   "* return output_387_binary_op (insn, operands);"
12963   [(set (attr "type")
12964         (cond [(match_operand:XF 3 "mult_operator" "")
12965                  (const_string "fmul")
12966                (match_operand:XF 3 "div_operator" "")
12967                  (const_string "fdiv")
12968               ]
12969               (const_string "fop")))
12970    (set_attr "mode" "<MODE>")])
12971
12972 (define_insn "*fop_xf_6_i387"
12973   [(set (match_operand:XF 0 "register_operand" "=f,f")
12974         (match_operator:XF 3 "binary_fp_operator"
12975           [(float_extend:XF
12976              (match_operand:MODEF 1 "register_operand" "0,f"))
12977            (float_extend:XF
12978              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12979   "TARGET_80387"
12980   "* return output_387_binary_op (insn, operands);"
12981   [(set (attr "type")
12982         (cond [(match_operand:XF 3 "mult_operator" "")
12983                  (const_string "fmul")
12984                (match_operand:XF 3 "div_operator" "")
12985                  (const_string "fdiv")
12986               ]
12987               (const_string "fop")))
12988    (set_attr "mode" "<MODE>")])
12989
12990 (define_split
12991   [(set (match_operand 0 "register_operand" "")
12992         (match_operator 3 "binary_fp_operator"
12993            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12994             (match_operand 2 "register_operand" "")]))]
12995   "reload_completed
12996    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12997    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12998   [(const_int 0)]
12999 {
13000   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13001   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13002   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13003                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13004                                           GET_MODE (operands[3]),
13005                                           operands[4],
13006                                           operands[2])));
13007   ix86_free_from_memory (GET_MODE (operands[1]));
13008   DONE;
13009 })
13010
13011 (define_split
13012   [(set (match_operand 0 "register_operand" "")
13013         (match_operator 3 "binary_fp_operator"
13014            [(match_operand 1 "register_operand" "")
13015             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13016   "reload_completed
13017    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13018    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13019   [(const_int 0)]
13020 {
13021   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13022   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13023   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13024                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13025                                           GET_MODE (operands[3]),
13026                                           operands[1],
13027                                           operands[4])));
13028   ix86_free_from_memory (GET_MODE (operands[2]));
13029   DONE;
13030 })
13031 \f
13032 ;; FPU special functions.
13033
13034 ;; This pattern implements a no-op XFmode truncation for
13035 ;; all fancy i386 XFmode math functions.
13036
13037 (define_insn "truncxf<mode>2_i387_noop_unspec"
13038   [(set (match_operand:MODEF 0 "register_operand" "=f")
13039         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13040         UNSPEC_TRUNC_NOOP))]
13041   "TARGET_USE_FANCY_MATH_387"
13042   "* return output_387_reg_move (insn, operands);"
13043   [(set_attr "type" "fmov")
13044    (set_attr "mode" "<MODE>")])
13045
13046 (define_insn "sqrtxf2"
13047   [(set (match_operand:XF 0 "register_operand" "=f")
13048         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13049   "TARGET_USE_FANCY_MATH_387"
13050   "fsqrt"
13051   [(set_attr "type" "fpspc")
13052    (set_attr "mode" "XF")
13053    (set_attr "athlon_decode" "direct")
13054    (set_attr "amdfam10_decode" "direct")
13055    (set_attr "bdver1_decode" "direct")])
13056
13057 (define_insn "sqrt_extend<mode>xf2_i387"
13058   [(set (match_operand:XF 0 "register_operand" "=f")
13059         (sqrt:XF
13060           (float_extend:XF
13061             (match_operand:MODEF 1 "register_operand" "0"))))]
13062   "TARGET_USE_FANCY_MATH_387"
13063   "fsqrt"
13064   [(set_attr "type" "fpspc")
13065    (set_attr "mode" "XF")
13066    (set_attr "athlon_decode" "direct")
13067    (set_attr "amdfam10_decode" "direct")
13068    (set_attr "bdver1_decode" "direct")])
13069
13070 (define_insn "*rsqrtsf2_sse"
13071   [(set (match_operand:SF 0 "register_operand" "=x")
13072         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13073                    UNSPEC_RSQRT))]
13074   "TARGET_SSE_MATH"
13075   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13076   [(set_attr "type" "sse")
13077    (set_attr "atom_sse_attr" "rcp")
13078    (set_attr "prefix" "maybe_vex")
13079    (set_attr "mode" "SF")])
13080
13081 (define_expand "rsqrtsf2"
13082   [(set (match_operand:SF 0 "register_operand" "")
13083         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13084                    UNSPEC_RSQRT))]
13085   "TARGET_SSE_MATH"
13086 {
13087   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13088   DONE;
13089 })
13090
13091 (define_insn "*sqrt<mode>2_sse"
13092   [(set (match_operand:MODEF 0 "register_operand" "=x")
13093         (sqrt:MODEF
13094           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13095   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13096   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13097   [(set_attr "type" "sse")
13098    (set_attr "atom_sse_attr" "sqrt")
13099    (set_attr "prefix" "maybe_vex")
13100    (set_attr "mode" "<MODE>")
13101    (set_attr "athlon_decode" "*")
13102    (set_attr "amdfam10_decode" "*")
13103    (set_attr "bdver1_decode" "*")])
13104
13105 (define_expand "sqrt<mode>2"
13106   [(set (match_operand:MODEF 0 "register_operand" "")
13107         (sqrt:MODEF
13108           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13109   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13110    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13111 {
13112   if (<MODE>mode == SFmode
13113       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13114       && flag_finite_math_only && !flag_trapping_math
13115       && flag_unsafe_math_optimizations)
13116     {
13117       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13118       DONE;
13119     }
13120
13121   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13122     {
13123       rtx op0 = gen_reg_rtx (XFmode);
13124       rtx op1 = force_reg (<MODE>mode, operands[1]);
13125
13126       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13127       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13128       DONE;
13129    }
13130 })
13131
13132 (define_insn "fpremxf4_i387"
13133   [(set (match_operand:XF 0 "register_operand" "=f")
13134         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13135                     (match_operand:XF 3 "register_operand" "1")]
13136                    UNSPEC_FPREM_F))
13137    (set (match_operand:XF 1 "register_operand" "=u")
13138         (unspec:XF [(match_dup 2) (match_dup 3)]
13139                    UNSPEC_FPREM_U))
13140    (set (reg:CCFP FPSR_REG)
13141         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13142                      UNSPEC_C2_FLAG))]
13143   "TARGET_USE_FANCY_MATH_387"
13144   "fprem"
13145   [(set_attr "type" "fpspc")
13146    (set_attr "mode" "XF")])
13147
13148 (define_expand "fmodxf3"
13149   [(use (match_operand:XF 0 "register_operand" ""))
13150    (use (match_operand:XF 1 "general_operand" ""))
13151    (use (match_operand:XF 2 "general_operand" ""))]
13152   "TARGET_USE_FANCY_MATH_387"
13153 {
13154   rtx label = gen_label_rtx ();
13155
13156   rtx op1 = gen_reg_rtx (XFmode);
13157   rtx op2 = gen_reg_rtx (XFmode);
13158
13159   emit_move_insn (op2, operands[2]);
13160   emit_move_insn (op1, operands[1]);
13161
13162   emit_label (label);
13163   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13164   ix86_emit_fp_unordered_jump (label);
13165   LABEL_NUSES (label) = 1;
13166
13167   emit_move_insn (operands[0], op1);
13168   DONE;
13169 })
13170
13171 (define_expand "fmod<mode>3"
13172   [(use (match_operand:MODEF 0 "register_operand" ""))
13173    (use (match_operand:MODEF 1 "general_operand" ""))
13174    (use (match_operand:MODEF 2 "general_operand" ""))]
13175   "TARGET_USE_FANCY_MATH_387"
13176 {
13177   rtx (*gen_truncxf) (rtx, rtx);
13178
13179   rtx label = gen_label_rtx ();
13180
13181   rtx op1 = gen_reg_rtx (XFmode);
13182   rtx op2 = gen_reg_rtx (XFmode);
13183
13184   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13185   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13186
13187   emit_label (label);
13188   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13189   ix86_emit_fp_unordered_jump (label);
13190   LABEL_NUSES (label) = 1;
13191
13192   /* Truncate the result properly for strict SSE math.  */
13193   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13194       && !TARGET_MIX_SSE_I387)
13195     gen_truncxf = gen_truncxf<mode>2;
13196   else
13197     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13198
13199   emit_insn (gen_truncxf (operands[0], op1));
13200   DONE;
13201 })
13202
13203 (define_insn "fprem1xf4_i387"
13204   [(set (match_operand:XF 0 "register_operand" "=f")
13205         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13206                     (match_operand:XF 3 "register_operand" "1")]
13207                    UNSPEC_FPREM1_F))
13208    (set (match_operand:XF 1 "register_operand" "=u")
13209         (unspec:XF [(match_dup 2) (match_dup 3)]
13210                    UNSPEC_FPREM1_U))
13211    (set (reg:CCFP FPSR_REG)
13212         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13213                      UNSPEC_C2_FLAG))]
13214   "TARGET_USE_FANCY_MATH_387"
13215   "fprem1"
13216   [(set_attr "type" "fpspc")
13217    (set_attr "mode" "XF")])
13218
13219 (define_expand "remainderxf3"
13220   [(use (match_operand:XF 0 "register_operand" ""))
13221    (use (match_operand:XF 1 "general_operand" ""))
13222    (use (match_operand:XF 2 "general_operand" ""))]
13223   "TARGET_USE_FANCY_MATH_387"
13224 {
13225   rtx label = gen_label_rtx ();
13226
13227   rtx op1 = gen_reg_rtx (XFmode);
13228   rtx op2 = gen_reg_rtx (XFmode);
13229
13230   emit_move_insn (op2, operands[2]);
13231   emit_move_insn (op1, operands[1]);
13232
13233   emit_label (label);
13234   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13235   ix86_emit_fp_unordered_jump (label);
13236   LABEL_NUSES (label) = 1;
13237
13238   emit_move_insn (operands[0], op1);
13239   DONE;
13240 })
13241
13242 (define_expand "remainder<mode>3"
13243   [(use (match_operand:MODEF 0 "register_operand" ""))
13244    (use (match_operand:MODEF 1 "general_operand" ""))
13245    (use (match_operand:MODEF 2 "general_operand" ""))]
13246   "TARGET_USE_FANCY_MATH_387"
13247 {
13248   rtx (*gen_truncxf) (rtx, rtx);
13249
13250   rtx label = gen_label_rtx ();
13251
13252   rtx op1 = gen_reg_rtx (XFmode);
13253   rtx op2 = gen_reg_rtx (XFmode);
13254
13255   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13256   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13257
13258   emit_label (label);
13259
13260   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13261   ix86_emit_fp_unordered_jump (label);
13262   LABEL_NUSES (label) = 1;
13263
13264   /* Truncate the result properly for strict SSE math.  */
13265   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13266       && !TARGET_MIX_SSE_I387)
13267     gen_truncxf = gen_truncxf<mode>2;
13268   else
13269     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13270
13271   emit_insn (gen_truncxf (operands[0], op1));
13272   DONE;
13273 })
13274
13275 (define_insn "*sinxf2_i387"
13276   [(set (match_operand:XF 0 "register_operand" "=f")
13277         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13278   "TARGET_USE_FANCY_MATH_387
13279    && flag_unsafe_math_optimizations"
13280   "fsin"
13281   [(set_attr "type" "fpspc")
13282    (set_attr "mode" "XF")])
13283
13284 (define_insn "*sin_extend<mode>xf2_i387"
13285   [(set (match_operand:XF 0 "register_operand" "=f")
13286         (unspec:XF [(float_extend:XF
13287                       (match_operand:MODEF 1 "register_operand" "0"))]
13288                    UNSPEC_SIN))]
13289   "TARGET_USE_FANCY_MATH_387
13290    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13291        || TARGET_MIX_SSE_I387)
13292    && flag_unsafe_math_optimizations"
13293   "fsin"
13294   [(set_attr "type" "fpspc")
13295    (set_attr "mode" "XF")])
13296
13297 (define_insn "*cosxf2_i387"
13298   [(set (match_operand:XF 0 "register_operand" "=f")
13299         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13300   "TARGET_USE_FANCY_MATH_387
13301    && flag_unsafe_math_optimizations"
13302   "fcos"
13303   [(set_attr "type" "fpspc")
13304    (set_attr "mode" "XF")])
13305
13306 (define_insn "*cos_extend<mode>xf2_i387"
13307   [(set (match_operand:XF 0 "register_operand" "=f")
13308         (unspec:XF [(float_extend:XF
13309                       (match_operand:MODEF 1 "register_operand" "0"))]
13310                    UNSPEC_COS))]
13311   "TARGET_USE_FANCY_MATH_387
13312    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13313        || TARGET_MIX_SSE_I387)
13314    && flag_unsafe_math_optimizations"
13315   "fcos"
13316   [(set_attr "type" "fpspc")
13317    (set_attr "mode" "XF")])
13318
13319 ;; When sincos pattern is defined, sin and cos builtin functions will be
13320 ;; expanded to sincos pattern with one of its outputs left unused.
13321 ;; CSE pass will figure out if two sincos patterns can be combined,
13322 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13323 ;; depending on the unused output.
13324
13325 (define_insn "sincosxf3"
13326   [(set (match_operand:XF 0 "register_operand" "=f")
13327         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13328                    UNSPEC_SINCOS_COS))
13329    (set (match_operand:XF 1 "register_operand" "=u")
13330         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13331   "TARGET_USE_FANCY_MATH_387
13332    && flag_unsafe_math_optimizations"
13333   "fsincos"
13334   [(set_attr "type" "fpspc")
13335    (set_attr "mode" "XF")])
13336
13337 (define_split
13338   [(set (match_operand:XF 0 "register_operand" "")
13339         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13340                    UNSPEC_SINCOS_COS))
13341    (set (match_operand:XF 1 "register_operand" "")
13342         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13343   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13344    && can_create_pseudo_p ()"
13345   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13346
13347 (define_split
13348   [(set (match_operand:XF 0 "register_operand" "")
13349         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13350                    UNSPEC_SINCOS_COS))
13351    (set (match_operand:XF 1 "register_operand" "")
13352         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13353   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13354    && can_create_pseudo_p ()"
13355   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13356
13357 (define_insn "sincos_extend<mode>xf3_i387"
13358   [(set (match_operand:XF 0 "register_operand" "=f")
13359         (unspec:XF [(float_extend:XF
13360                       (match_operand:MODEF 2 "register_operand" "0"))]
13361                    UNSPEC_SINCOS_COS))
13362    (set (match_operand:XF 1 "register_operand" "=u")
13363         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13364   "TARGET_USE_FANCY_MATH_387
13365    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13366        || TARGET_MIX_SSE_I387)
13367    && flag_unsafe_math_optimizations"
13368   "fsincos"
13369   [(set_attr "type" "fpspc")
13370    (set_attr "mode" "XF")])
13371
13372 (define_split
13373   [(set (match_operand:XF 0 "register_operand" "")
13374         (unspec:XF [(float_extend:XF
13375                       (match_operand:MODEF 2 "register_operand" ""))]
13376                    UNSPEC_SINCOS_COS))
13377    (set (match_operand:XF 1 "register_operand" "")
13378         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13379   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13380    && can_create_pseudo_p ()"
13381   [(set (match_dup 1)
13382         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13383
13384 (define_split
13385   [(set (match_operand:XF 0 "register_operand" "")
13386         (unspec:XF [(float_extend:XF
13387                       (match_operand:MODEF 2 "register_operand" ""))]
13388                    UNSPEC_SINCOS_COS))
13389    (set (match_operand:XF 1 "register_operand" "")
13390         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13391   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13392    && can_create_pseudo_p ()"
13393   [(set (match_dup 0)
13394         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13395
13396 (define_expand "sincos<mode>3"
13397   [(use (match_operand:MODEF 0 "register_operand" ""))
13398    (use (match_operand:MODEF 1 "register_operand" ""))
13399    (use (match_operand:MODEF 2 "register_operand" ""))]
13400   "TARGET_USE_FANCY_MATH_387
13401    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13402        || TARGET_MIX_SSE_I387)
13403    && flag_unsafe_math_optimizations"
13404 {
13405   rtx op0 = gen_reg_rtx (XFmode);
13406   rtx op1 = gen_reg_rtx (XFmode);
13407
13408   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13409   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13410   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13411   DONE;
13412 })
13413
13414 (define_insn "fptanxf4_i387"
13415   [(set (match_operand:XF 0 "register_operand" "=f")
13416         (match_operand:XF 3 "const_double_operand" "F"))
13417    (set (match_operand:XF 1 "register_operand" "=u")
13418         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13419                    UNSPEC_TAN))]
13420   "TARGET_USE_FANCY_MATH_387
13421    && flag_unsafe_math_optimizations
13422    && standard_80387_constant_p (operands[3]) == 2"
13423   "fptan"
13424   [(set_attr "type" "fpspc")
13425    (set_attr "mode" "XF")])
13426
13427 (define_insn "fptan_extend<mode>xf4_i387"
13428   [(set (match_operand:MODEF 0 "register_operand" "=f")
13429         (match_operand:MODEF 3 "const_double_operand" "F"))
13430    (set (match_operand:XF 1 "register_operand" "=u")
13431         (unspec:XF [(float_extend:XF
13432                       (match_operand:MODEF 2 "register_operand" "0"))]
13433                    UNSPEC_TAN))]
13434   "TARGET_USE_FANCY_MATH_387
13435    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13436        || TARGET_MIX_SSE_I387)
13437    && flag_unsafe_math_optimizations
13438    && standard_80387_constant_p (operands[3]) == 2"
13439   "fptan"
13440   [(set_attr "type" "fpspc")
13441    (set_attr "mode" "XF")])
13442
13443 (define_expand "tanxf2"
13444   [(use (match_operand:XF 0 "register_operand" ""))
13445    (use (match_operand:XF 1 "register_operand" ""))]
13446   "TARGET_USE_FANCY_MATH_387
13447    && flag_unsafe_math_optimizations"
13448 {
13449   rtx one = gen_reg_rtx (XFmode);
13450   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13451
13452   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13453   DONE;
13454 })
13455
13456 (define_expand "tan<mode>2"
13457   [(use (match_operand:MODEF 0 "register_operand" ""))
13458    (use (match_operand:MODEF 1 "register_operand" ""))]
13459   "TARGET_USE_FANCY_MATH_387
13460    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13461        || TARGET_MIX_SSE_I387)
13462    && flag_unsafe_math_optimizations"
13463 {
13464   rtx op0 = gen_reg_rtx (XFmode);
13465
13466   rtx one = gen_reg_rtx (<MODE>mode);
13467   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13468
13469   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13470                                              operands[1], op2));
13471   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13472   DONE;
13473 })
13474
13475 (define_insn "*fpatanxf3_i387"
13476   [(set (match_operand:XF 0 "register_operand" "=f")
13477         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13478                     (match_operand:XF 2 "register_operand" "u")]
13479                    UNSPEC_FPATAN))
13480    (clobber (match_scratch:XF 3 "=2"))]
13481   "TARGET_USE_FANCY_MATH_387
13482    && flag_unsafe_math_optimizations"
13483   "fpatan"
13484   [(set_attr "type" "fpspc")
13485    (set_attr "mode" "XF")])
13486
13487 (define_insn "fpatan_extend<mode>xf3_i387"
13488   [(set (match_operand:XF 0 "register_operand" "=f")
13489         (unspec:XF [(float_extend:XF
13490                       (match_operand:MODEF 1 "register_operand" "0"))
13491                     (float_extend:XF
13492                       (match_operand:MODEF 2 "register_operand" "u"))]
13493                    UNSPEC_FPATAN))
13494    (clobber (match_scratch:XF 3 "=2"))]
13495   "TARGET_USE_FANCY_MATH_387
13496    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13497        || TARGET_MIX_SSE_I387)
13498    && flag_unsafe_math_optimizations"
13499   "fpatan"
13500   [(set_attr "type" "fpspc")
13501    (set_attr "mode" "XF")])
13502
13503 (define_expand "atan2xf3"
13504   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13505                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13506                                (match_operand:XF 1 "register_operand" "")]
13507                               UNSPEC_FPATAN))
13508               (clobber (match_scratch:XF 3 ""))])]
13509   "TARGET_USE_FANCY_MATH_387
13510    && flag_unsafe_math_optimizations")
13511
13512 (define_expand "atan2<mode>3"
13513   [(use (match_operand:MODEF 0 "register_operand" ""))
13514    (use (match_operand:MODEF 1 "register_operand" ""))
13515    (use (match_operand:MODEF 2 "register_operand" ""))]
13516   "TARGET_USE_FANCY_MATH_387
13517    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13518        || TARGET_MIX_SSE_I387)
13519    && flag_unsafe_math_optimizations"
13520 {
13521   rtx op0 = gen_reg_rtx (XFmode);
13522
13523   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13524   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13525   DONE;
13526 })
13527
13528 (define_expand "atanxf2"
13529   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13530                    (unspec:XF [(match_dup 2)
13531                                (match_operand:XF 1 "register_operand" "")]
13532                               UNSPEC_FPATAN))
13533               (clobber (match_scratch:XF 3 ""))])]
13534   "TARGET_USE_FANCY_MATH_387
13535    && flag_unsafe_math_optimizations"
13536 {
13537   operands[2] = gen_reg_rtx (XFmode);
13538   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13539 })
13540
13541 (define_expand "atan<mode>2"
13542   [(use (match_operand:MODEF 0 "register_operand" ""))
13543    (use (match_operand:MODEF 1 "register_operand" ""))]
13544   "TARGET_USE_FANCY_MATH_387
13545    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13546        || TARGET_MIX_SSE_I387)
13547    && flag_unsafe_math_optimizations"
13548 {
13549   rtx op0 = gen_reg_rtx (XFmode);
13550
13551   rtx op2 = gen_reg_rtx (<MODE>mode);
13552   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13553
13554   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13555   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13556   DONE;
13557 })
13558
13559 (define_expand "asinxf2"
13560   [(set (match_dup 2)
13561         (mult:XF (match_operand:XF 1 "register_operand" "")
13562                  (match_dup 1)))
13563    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13564    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13565    (parallel [(set (match_operand:XF 0 "register_operand" "")
13566                    (unspec:XF [(match_dup 5) (match_dup 1)]
13567                               UNSPEC_FPATAN))
13568               (clobber (match_scratch:XF 6 ""))])]
13569   "TARGET_USE_FANCY_MATH_387
13570    && flag_unsafe_math_optimizations"
13571 {
13572   int i;
13573
13574   if (optimize_insn_for_size_p ())
13575     FAIL;
13576
13577   for (i = 2; i < 6; i++)
13578     operands[i] = gen_reg_rtx (XFmode);
13579
13580   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13581 })
13582
13583 (define_expand "asin<mode>2"
13584   [(use (match_operand:MODEF 0 "register_operand" ""))
13585    (use (match_operand:MODEF 1 "general_operand" ""))]
13586  "TARGET_USE_FANCY_MATH_387
13587    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13588        || TARGET_MIX_SSE_I387)
13589    && flag_unsafe_math_optimizations"
13590 {
13591   rtx op0 = gen_reg_rtx (XFmode);
13592   rtx op1 = gen_reg_rtx (XFmode);
13593
13594   if (optimize_insn_for_size_p ())
13595     FAIL;
13596
13597   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13598   emit_insn (gen_asinxf2 (op0, op1));
13599   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13600   DONE;
13601 })
13602
13603 (define_expand "acosxf2"
13604   [(set (match_dup 2)
13605         (mult:XF (match_operand:XF 1 "register_operand" "")
13606                  (match_dup 1)))
13607    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13608    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13609    (parallel [(set (match_operand:XF 0 "register_operand" "")
13610                    (unspec:XF [(match_dup 1) (match_dup 5)]
13611                               UNSPEC_FPATAN))
13612               (clobber (match_scratch:XF 6 ""))])]
13613   "TARGET_USE_FANCY_MATH_387
13614    && flag_unsafe_math_optimizations"
13615 {
13616   int i;
13617
13618   if (optimize_insn_for_size_p ())
13619     FAIL;
13620
13621   for (i = 2; i < 6; i++)
13622     operands[i] = gen_reg_rtx (XFmode);
13623
13624   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13625 })
13626
13627 (define_expand "acos<mode>2"
13628   [(use (match_operand:MODEF 0 "register_operand" ""))
13629    (use (match_operand:MODEF 1 "general_operand" ""))]
13630  "TARGET_USE_FANCY_MATH_387
13631    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13632        || TARGET_MIX_SSE_I387)
13633    && flag_unsafe_math_optimizations"
13634 {
13635   rtx op0 = gen_reg_rtx (XFmode);
13636   rtx op1 = gen_reg_rtx (XFmode);
13637
13638   if (optimize_insn_for_size_p ())
13639     FAIL;
13640
13641   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13642   emit_insn (gen_acosxf2 (op0, op1));
13643   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13644   DONE;
13645 })
13646
13647 (define_insn "fyl2xxf3_i387"
13648   [(set (match_operand:XF 0 "register_operand" "=f")
13649         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13650                     (match_operand:XF 2 "register_operand" "u")]
13651                    UNSPEC_FYL2X))
13652    (clobber (match_scratch:XF 3 "=2"))]
13653   "TARGET_USE_FANCY_MATH_387
13654    && flag_unsafe_math_optimizations"
13655   "fyl2x"
13656   [(set_attr "type" "fpspc")
13657    (set_attr "mode" "XF")])
13658
13659 (define_insn "fyl2x_extend<mode>xf3_i387"
13660   [(set (match_operand:XF 0 "register_operand" "=f")
13661         (unspec:XF [(float_extend:XF
13662                       (match_operand:MODEF 1 "register_operand" "0"))
13663                     (match_operand:XF 2 "register_operand" "u")]
13664                    UNSPEC_FYL2X))
13665    (clobber (match_scratch:XF 3 "=2"))]
13666   "TARGET_USE_FANCY_MATH_387
13667    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13668        || TARGET_MIX_SSE_I387)
13669    && flag_unsafe_math_optimizations"
13670   "fyl2x"
13671   [(set_attr "type" "fpspc")
13672    (set_attr "mode" "XF")])
13673
13674 (define_expand "logxf2"
13675   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13676                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13677                                (match_dup 2)] UNSPEC_FYL2X))
13678               (clobber (match_scratch:XF 3 ""))])]
13679   "TARGET_USE_FANCY_MATH_387
13680    && flag_unsafe_math_optimizations"
13681 {
13682   operands[2] = gen_reg_rtx (XFmode);
13683   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13684 })
13685
13686 (define_expand "log<mode>2"
13687   [(use (match_operand:MODEF 0 "register_operand" ""))
13688    (use (match_operand:MODEF 1 "register_operand" ""))]
13689   "TARGET_USE_FANCY_MATH_387
13690    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13691        || TARGET_MIX_SSE_I387)
13692    && flag_unsafe_math_optimizations"
13693 {
13694   rtx op0 = gen_reg_rtx (XFmode);
13695
13696   rtx op2 = gen_reg_rtx (XFmode);
13697   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13698
13699   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13700   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13701   DONE;
13702 })
13703
13704 (define_expand "log10xf2"
13705   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13706                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13707                                (match_dup 2)] UNSPEC_FYL2X))
13708               (clobber (match_scratch:XF 3 ""))])]
13709   "TARGET_USE_FANCY_MATH_387
13710    && flag_unsafe_math_optimizations"
13711 {
13712   operands[2] = gen_reg_rtx (XFmode);
13713   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13714 })
13715
13716 (define_expand "log10<mode>2"
13717   [(use (match_operand:MODEF 0 "register_operand" ""))
13718    (use (match_operand:MODEF 1 "register_operand" ""))]
13719   "TARGET_USE_FANCY_MATH_387
13720    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13721        || TARGET_MIX_SSE_I387)
13722    && flag_unsafe_math_optimizations"
13723 {
13724   rtx op0 = gen_reg_rtx (XFmode);
13725
13726   rtx op2 = gen_reg_rtx (XFmode);
13727   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13728
13729   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13730   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13731   DONE;
13732 })
13733
13734 (define_expand "log2xf2"
13735   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13736                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13737                                (match_dup 2)] UNSPEC_FYL2X))
13738               (clobber (match_scratch:XF 3 ""))])]
13739   "TARGET_USE_FANCY_MATH_387
13740    && flag_unsafe_math_optimizations"
13741 {
13742   operands[2] = gen_reg_rtx (XFmode);
13743   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13744 })
13745
13746 (define_expand "log2<mode>2"
13747   [(use (match_operand:MODEF 0 "register_operand" ""))
13748    (use (match_operand:MODEF 1 "register_operand" ""))]
13749   "TARGET_USE_FANCY_MATH_387
13750    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13751        || TARGET_MIX_SSE_I387)
13752    && flag_unsafe_math_optimizations"
13753 {
13754   rtx op0 = gen_reg_rtx (XFmode);
13755
13756   rtx op2 = gen_reg_rtx (XFmode);
13757   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13758
13759   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13760   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13761   DONE;
13762 })
13763
13764 (define_insn "fyl2xp1xf3_i387"
13765   [(set (match_operand:XF 0 "register_operand" "=f")
13766         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13767                     (match_operand:XF 2 "register_operand" "u")]
13768                    UNSPEC_FYL2XP1))
13769    (clobber (match_scratch:XF 3 "=2"))]
13770   "TARGET_USE_FANCY_MATH_387
13771    && flag_unsafe_math_optimizations"
13772   "fyl2xp1"
13773   [(set_attr "type" "fpspc")
13774    (set_attr "mode" "XF")])
13775
13776 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13777   [(set (match_operand:XF 0 "register_operand" "=f")
13778         (unspec:XF [(float_extend:XF
13779                       (match_operand:MODEF 1 "register_operand" "0"))
13780                     (match_operand:XF 2 "register_operand" "u")]
13781                    UNSPEC_FYL2XP1))
13782    (clobber (match_scratch:XF 3 "=2"))]
13783   "TARGET_USE_FANCY_MATH_387
13784    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13785        || TARGET_MIX_SSE_I387)
13786    && flag_unsafe_math_optimizations"
13787   "fyl2xp1"
13788   [(set_attr "type" "fpspc")
13789    (set_attr "mode" "XF")])
13790
13791 (define_expand "log1pxf2"
13792   [(use (match_operand:XF 0 "register_operand" ""))
13793    (use (match_operand:XF 1 "register_operand" ""))]
13794   "TARGET_USE_FANCY_MATH_387
13795    && flag_unsafe_math_optimizations"
13796 {
13797   if (optimize_insn_for_size_p ())
13798     FAIL;
13799
13800   ix86_emit_i387_log1p (operands[0], operands[1]);
13801   DONE;
13802 })
13803
13804 (define_expand "log1p<mode>2"
13805   [(use (match_operand:MODEF 0 "register_operand" ""))
13806    (use (match_operand:MODEF 1 "register_operand" ""))]
13807   "TARGET_USE_FANCY_MATH_387
13808    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13809        || TARGET_MIX_SSE_I387)
13810    && flag_unsafe_math_optimizations"
13811 {
13812   rtx op0;
13813
13814   if (optimize_insn_for_size_p ())
13815     FAIL;
13816
13817   op0 = gen_reg_rtx (XFmode);
13818
13819   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13820
13821   ix86_emit_i387_log1p (op0, operands[1]);
13822   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13823   DONE;
13824 })
13825
13826 (define_insn "fxtractxf3_i387"
13827   [(set (match_operand:XF 0 "register_operand" "=f")
13828         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13829                    UNSPEC_XTRACT_FRACT))
13830    (set (match_operand:XF 1 "register_operand" "=u")
13831         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13832   "TARGET_USE_FANCY_MATH_387
13833    && flag_unsafe_math_optimizations"
13834   "fxtract"
13835   [(set_attr "type" "fpspc")
13836    (set_attr "mode" "XF")])
13837
13838 (define_insn "fxtract_extend<mode>xf3_i387"
13839   [(set (match_operand:XF 0 "register_operand" "=f")
13840         (unspec:XF [(float_extend:XF
13841                       (match_operand:MODEF 2 "register_operand" "0"))]
13842                    UNSPEC_XTRACT_FRACT))
13843    (set (match_operand:XF 1 "register_operand" "=u")
13844         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13845   "TARGET_USE_FANCY_MATH_387
13846    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13847        || TARGET_MIX_SSE_I387)
13848    && flag_unsafe_math_optimizations"
13849   "fxtract"
13850   [(set_attr "type" "fpspc")
13851    (set_attr "mode" "XF")])
13852
13853 (define_expand "logbxf2"
13854   [(parallel [(set (match_dup 2)
13855                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13856                               UNSPEC_XTRACT_FRACT))
13857               (set (match_operand:XF 0 "register_operand" "")
13858                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13859   "TARGET_USE_FANCY_MATH_387
13860    && flag_unsafe_math_optimizations"
13861   "operands[2] = gen_reg_rtx (XFmode);")
13862
13863 (define_expand "logb<mode>2"
13864   [(use (match_operand:MODEF 0 "register_operand" ""))
13865    (use (match_operand:MODEF 1 "register_operand" ""))]
13866   "TARGET_USE_FANCY_MATH_387
13867    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13868        || TARGET_MIX_SSE_I387)
13869    && flag_unsafe_math_optimizations"
13870 {
13871   rtx op0 = gen_reg_rtx (XFmode);
13872   rtx op1 = gen_reg_rtx (XFmode);
13873
13874   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13875   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13876   DONE;
13877 })
13878
13879 (define_expand "ilogbxf2"
13880   [(use (match_operand:SI 0 "register_operand" ""))
13881    (use (match_operand:XF 1 "register_operand" ""))]
13882   "TARGET_USE_FANCY_MATH_387
13883    && flag_unsafe_math_optimizations"
13884 {
13885   rtx op0, op1;
13886
13887   if (optimize_insn_for_size_p ())
13888     FAIL;
13889
13890   op0 = gen_reg_rtx (XFmode);
13891   op1 = gen_reg_rtx (XFmode);
13892
13893   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13894   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13895   DONE;
13896 })
13897
13898 (define_expand "ilogb<mode>2"
13899   [(use (match_operand:SI 0 "register_operand" ""))
13900    (use (match_operand:MODEF 1 "register_operand" ""))]
13901   "TARGET_USE_FANCY_MATH_387
13902    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13903        || TARGET_MIX_SSE_I387)
13904    && flag_unsafe_math_optimizations"
13905 {
13906   rtx op0, op1;
13907
13908   if (optimize_insn_for_size_p ())
13909     FAIL;
13910
13911   op0 = gen_reg_rtx (XFmode);
13912   op1 = gen_reg_rtx (XFmode);
13913
13914   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13915   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13916   DONE;
13917 })
13918
13919 (define_insn "*f2xm1xf2_i387"
13920   [(set (match_operand:XF 0 "register_operand" "=f")
13921         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13922                    UNSPEC_F2XM1))]
13923   "TARGET_USE_FANCY_MATH_387
13924    && flag_unsafe_math_optimizations"
13925   "f2xm1"
13926   [(set_attr "type" "fpspc")
13927    (set_attr "mode" "XF")])
13928
13929 (define_insn "*fscalexf4_i387"
13930   [(set (match_operand:XF 0 "register_operand" "=f")
13931         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13932                     (match_operand:XF 3 "register_operand" "1")]
13933                    UNSPEC_FSCALE_FRACT))
13934    (set (match_operand:XF 1 "register_operand" "=u")
13935         (unspec:XF [(match_dup 2) (match_dup 3)]
13936                    UNSPEC_FSCALE_EXP))]
13937   "TARGET_USE_FANCY_MATH_387
13938    && flag_unsafe_math_optimizations"
13939   "fscale"
13940   [(set_attr "type" "fpspc")
13941    (set_attr "mode" "XF")])
13942
13943 (define_expand "expNcorexf3"
13944   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13945                                (match_operand:XF 2 "register_operand" "")))
13946    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13947    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13948    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13949    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13950    (parallel [(set (match_operand:XF 0 "register_operand" "")
13951                    (unspec:XF [(match_dup 8) (match_dup 4)]
13952                               UNSPEC_FSCALE_FRACT))
13953               (set (match_dup 9)
13954                    (unspec:XF [(match_dup 8) (match_dup 4)]
13955                               UNSPEC_FSCALE_EXP))])]
13956   "TARGET_USE_FANCY_MATH_387
13957    && flag_unsafe_math_optimizations"
13958 {
13959   int i;
13960
13961   if (optimize_insn_for_size_p ())
13962     FAIL;
13963
13964   for (i = 3; i < 10; i++)
13965     operands[i] = gen_reg_rtx (XFmode);
13966
13967   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
13968 })
13969
13970 (define_expand "expxf2"
13971   [(use (match_operand:XF 0 "register_operand" ""))
13972    (use (match_operand:XF 1 "register_operand" ""))]
13973   "TARGET_USE_FANCY_MATH_387
13974    && flag_unsafe_math_optimizations"
13975 {
13976   rtx op2;
13977
13978   if (optimize_insn_for_size_p ())
13979     FAIL;
13980
13981   op2 = gen_reg_rtx (XFmode);
13982   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13983
13984   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13985   DONE;
13986 })
13987
13988 (define_expand "exp<mode>2"
13989   [(use (match_operand:MODEF 0 "register_operand" ""))
13990    (use (match_operand:MODEF 1 "general_operand" ""))]
13991  "TARGET_USE_FANCY_MATH_387
13992    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13993        || TARGET_MIX_SSE_I387)
13994    && flag_unsafe_math_optimizations"
13995 {
13996   rtx op0, op1;
13997
13998   if (optimize_insn_for_size_p ())
13999     FAIL;
14000
14001   op0 = gen_reg_rtx (XFmode);
14002   op1 = gen_reg_rtx (XFmode);
14003
14004   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14005   emit_insn (gen_expxf2 (op0, op1));
14006   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14007   DONE;
14008 })
14009
14010 (define_expand "exp10xf2"
14011   [(use (match_operand:XF 0 "register_operand" ""))
14012    (use (match_operand:XF 1 "register_operand" ""))]
14013   "TARGET_USE_FANCY_MATH_387
14014    && flag_unsafe_math_optimizations"
14015 {
14016   rtx op2;
14017
14018   if (optimize_insn_for_size_p ())
14019     FAIL;
14020
14021   op2 = gen_reg_rtx (XFmode);
14022   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14023
14024   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14025   DONE;
14026 })
14027
14028 (define_expand "exp10<mode>2"
14029   [(use (match_operand:MODEF 0 "register_operand" ""))
14030    (use (match_operand:MODEF 1 "general_operand" ""))]
14031  "TARGET_USE_FANCY_MATH_387
14032    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14033        || TARGET_MIX_SSE_I387)
14034    && flag_unsafe_math_optimizations"
14035 {
14036   rtx op0, op1;
14037
14038   if (optimize_insn_for_size_p ())
14039     FAIL;
14040
14041   op0 = gen_reg_rtx (XFmode);
14042   op1 = gen_reg_rtx (XFmode);
14043
14044   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14045   emit_insn (gen_exp10xf2 (op0, op1));
14046   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14047   DONE;
14048 })
14049
14050 (define_expand "exp2xf2"
14051   [(use (match_operand:XF 0 "register_operand" ""))
14052    (use (match_operand:XF 1 "register_operand" ""))]
14053   "TARGET_USE_FANCY_MATH_387
14054    && flag_unsafe_math_optimizations"
14055 {
14056   rtx op2;
14057
14058   if (optimize_insn_for_size_p ())
14059     FAIL;
14060
14061   op2 = gen_reg_rtx (XFmode);
14062   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14063
14064   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14065   DONE;
14066 })
14067
14068 (define_expand "exp2<mode>2"
14069   [(use (match_operand:MODEF 0 "register_operand" ""))
14070    (use (match_operand:MODEF 1 "general_operand" ""))]
14071  "TARGET_USE_FANCY_MATH_387
14072    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14073        || TARGET_MIX_SSE_I387)
14074    && flag_unsafe_math_optimizations"
14075 {
14076   rtx op0, op1;
14077
14078   if (optimize_insn_for_size_p ())
14079     FAIL;
14080
14081   op0 = gen_reg_rtx (XFmode);
14082   op1 = gen_reg_rtx (XFmode);
14083
14084   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14085   emit_insn (gen_exp2xf2 (op0, op1));
14086   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14087   DONE;
14088 })
14089
14090 (define_expand "expm1xf2"
14091   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14092                                (match_dup 2)))
14093    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14094    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14095    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14096    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14097    (parallel [(set (match_dup 7)
14098                    (unspec:XF [(match_dup 6) (match_dup 4)]
14099                               UNSPEC_FSCALE_FRACT))
14100               (set (match_dup 8)
14101                    (unspec:XF [(match_dup 6) (match_dup 4)]
14102                               UNSPEC_FSCALE_EXP))])
14103    (parallel [(set (match_dup 10)
14104                    (unspec:XF [(match_dup 9) (match_dup 8)]
14105                               UNSPEC_FSCALE_FRACT))
14106               (set (match_dup 11)
14107                    (unspec:XF [(match_dup 9) (match_dup 8)]
14108                               UNSPEC_FSCALE_EXP))])
14109    (set (match_dup 12) (minus:XF (match_dup 10)
14110                                  (float_extend:XF (match_dup 13))))
14111    (set (match_operand:XF 0 "register_operand" "")
14112         (plus:XF (match_dup 12) (match_dup 7)))]
14113   "TARGET_USE_FANCY_MATH_387
14114    && flag_unsafe_math_optimizations"
14115 {
14116   int i;
14117
14118   if (optimize_insn_for_size_p ())
14119     FAIL;
14120
14121   for (i = 2; i < 13; i++)
14122     operands[i] = gen_reg_rtx (XFmode);
14123
14124   operands[13]
14125     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14126
14127   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14128 })
14129
14130 (define_expand "expm1<mode>2"
14131   [(use (match_operand:MODEF 0 "register_operand" ""))
14132    (use (match_operand:MODEF 1 "general_operand" ""))]
14133  "TARGET_USE_FANCY_MATH_387
14134    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14135        || TARGET_MIX_SSE_I387)
14136    && flag_unsafe_math_optimizations"
14137 {
14138   rtx op0, op1;
14139
14140   if (optimize_insn_for_size_p ())
14141     FAIL;
14142
14143   op0 = gen_reg_rtx (XFmode);
14144   op1 = gen_reg_rtx (XFmode);
14145
14146   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14147   emit_insn (gen_expm1xf2 (op0, op1));
14148   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14149   DONE;
14150 })
14151
14152 (define_expand "ldexpxf3"
14153   [(set (match_dup 3)
14154         (float:XF (match_operand:SI 2 "register_operand" "")))
14155    (parallel [(set (match_operand:XF 0 " register_operand" "")
14156                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14157                                (match_dup 3)]
14158                               UNSPEC_FSCALE_FRACT))
14159               (set (match_dup 4)
14160                    (unspec:XF [(match_dup 1) (match_dup 3)]
14161                               UNSPEC_FSCALE_EXP))])]
14162   "TARGET_USE_FANCY_MATH_387
14163    && flag_unsafe_math_optimizations"
14164 {
14165   if (optimize_insn_for_size_p ())
14166     FAIL;
14167
14168   operands[3] = gen_reg_rtx (XFmode);
14169   operands[4] = gen_reg_rtx (XFmode);
14170 })
14171
14172 (define_expand "ldexp<mode>3"
14173   [(use (match_operand:MODEF 0 "register_operand" ""))
14174    (use (match_operand:MODEF 1 "general_operand" ""))
14175    (use (match_operand:SI 2 "register_operand" ""))]
14176  "TARGET_USE_FANCY_MATH_387
14177    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14178        || TARGET_MIX_SSE_I387)
14179    && flag_unsafe_math_optimizations"
14180 {
14181   rtx op0, op1;
14182
14183   if (optimize_insn_for_size_p ())
14184     FAIL;
14185
14186   op0 = gen_reg_rtx (XFmode);
14187   op1 = gen_reg_rtx (XFmode);
14188
14189   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14190   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14191   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14192   DONE;
14193 })
14194
14195 (define_expand "scalbxf3"
14196   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14197                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14198                                (match_operand:XF 2 "register_operand" "")]
14199                               UNSPEC_FSCALE_FRACT))
14200               (set (match_dup 3)
14201                    (unspec:XF [(match_dup 1) (match_dup 2)]
14202                               UNSPEC_FSCALE_EXP))])]
14203   "TARGET_USE_FANCY_MATH_387
14204    && flag_unsafe_math_optimizations"
14205 {
14206   if (optimize_insn_for_size_p ())
14207     FAIL;
14208
14209   operands[3] = gen_reg_rtx (XFmode);
14210 })
14211
14212 (define_expand "scalb<mode>3"
14213   [(use (match_operand:MODEF 0 "register_operand" ""))
14214    (use (match_operand:MODEF 1 "general_operand" ""))
14215    (use (match_operand:MODEF 2 "general_operand" ""))]
14216  "TARGET_USE_FANCY_MATH_387
14217    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14218        || TARGET_MIX_SSE_I387)
14219    && flag_unsafe_math_optimizations"
14220 {
14221   rtx op0, op1, op2;
14222
14223   if (optimize_insn_for_size_p ())
14224     FAIL;
14225
14226   op0 = gen_reg_rtx (XFmode);
14227   op1 = gen_reg_rtx (XFmode);
14228   op2 = gen_reg_rtx (XFmode);
14229
14230   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14231   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14232   emit_insn (gen_scalbxf3 (op0, op1, op2));
14233   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14234   DONE;
14235 })
14236
14237 (define_expand "significandxf2"
14238   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14239                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14240                               UNSPEC_XTRACT_FRACT))
14241               (set (match_dup 2)
14242                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14243   "TARGET_USE_FANCY_MATH_387
14244    && flag_unsafe_math_optimizations"
14245   "operands[2] = gen_reg_rtx (XFmode);")
14246
14247 (define_expand "significand<mode>2"
14248   [(use (match_operand:MODEF 0 "register_operand" ""))
14249    (use (match_operand:MODEF 1 "register_operand" ""))]
14250   "TARGET_USE_FANCY_MATH_387
14251    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14252        || TARGET_MIX_SSE_I387)
14253    && flag_unsafe_math_optimizations"
14254 {
14255   rtx op0 = gen_reg_rtx (XFmode);
14256   rtx op1 = gen_reg_rtx (XFmode);
14257
14258   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14259   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14260   DONE;
14261 })
14262 \f
14263
14264 (define_insn "sse4_1_round<mode>2"
14265   [(set (match_operand:MODEF 0 "register_operand" "=x")
14266         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14267                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14268                       UNSPEC_ROUND))]
14269   "TARGET_ROUND"
14270   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14271   [(set_attr "type" "ssecvt")
14272    (set_attr "prefix_extra" "1")
14273    (set_attr "prefix" "maybe_vex")
14274    (set_attr "mode" "<MODE>")])
14275
14276 (define_insn "rintxf2"
14277   [(set (match_operand:XF 0 "register_operand" "=f")
14278         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14279                    UNSPEC_FRNDINT))]
14280   "TARGET_USE_FANCY_MATH_387
14281    && flag_unsafe_math_optimizations"
14282   "frndint"
14283   [(set_attr "type" "fpspc")
14284    (set_attr "mode" "XF")])
14285
14286 (define_expand "rint<mode>2"
14287   [(use (match_operand:MODEF 0 "register_operand" ""))
14288    (use (match_operand:MODEF 1 "register_operand" ""))]
14289   "(TARGET_USE_FANCY_MATH_387
14290     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14291         || TARGET_MIX_SSE_I387)
14292     && flag_unsafe_math_optimizations)
14293    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14294        && !flag_trapping_math)"
14295 {
14296   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14297       && !flag_trapping_math)
14298     {
14299       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14300         FAIL;
14301       if (TARGET_ROUND)
14302         emit_insn (gen_sse4_1_round<mode>2
14303                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14304       else
14305         ix86_expand_rint (operand0, operand1);
14306     }
14307   else
14308     {
14309       rtx op0 = gen_reg_rtx (XFmode);
14310       rtx op1 = gen_reg_rtx (XFmode);
14311
14312       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14313       emit_insn (gen_rintxf2 (op0, op1));
14314
14315       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14316     }
14317   DONE;
14318 })
14319
14320 (define_expand "round<mode>2"
14321   [(match_operand:MODEF 0 "register_operand" "")
14322    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14323   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14324    && !flag_trapping_math && !flag_rounding_math"
14325 {
14326   if (optimize_insn_for_size_p ())
14327     FAIL;
14328   if (TARGET_64BIT || (<MODE>mode != DFmode))
14329     ix86_expand_round (operand0, operand1);
14330   else
14331     ix86_expand_rounddf_32 (operand0, operand1);
14332   DONE;
14333 })
14334
14335 (define_insn_and_split "*fistdi2_1"
14336   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14337         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14338                    UNSPEC_FIST))]
14339   "TARGET_USE_FANCY_MATH_387
14340    && can_create_pseudo_p ()"
14341   "#"
14342   "&& 1"
14343   [(const_int 0)]
14344 {
14345   if (memory_operand (operands[0], VOIDmode))
14346     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14347   else
14348     {
14349       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14350       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14351                                          operands[2]));
14352     }
14353   DONE;
14354 }
14355   [(set_attr "type" "fpspc")
14356    (set_attr "mode" "DI")])
14357
14358 (define_insn "fistdi2"
14359   [(set (match_operand:DI 0 "memory_operand" "=m")
14360         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14361                    UNSPEC_FIST))
14362    (clobber (match_scratch:XF 2 "=&1f"))]
14363   "TARGET_USE_FANCY_MATH_387"
14364   "* return output_fix_trunc (insn, operands, 0);"
14365   [(set_attr "type" "fpspc")
14366    (set_attr "mode" "DI")])
14367
14368 (define_insn "fistdi2_with_temp"
14369   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14370         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14371                    UNSPEC_FIST))
14372    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14373    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14374   "TARGET_USE_FANCY_MATH_387"
14375   "#"
14376   [(set_attr "type" "fpspc")
14377    (set_attr "mode" "DI")])
14378
14379 (define_split
14380   [(set (match_operand:DI 0 "register_operand" "")
14381         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14382                    UNSPEC_FIST))
14383    (clobber (match_operand:DI 2 "memory_operand" ""))
14384    (clobber (match_scratch 3 ""))]
14385   "reload_completed"
14386   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14387               (clobber (match_dup 3))])
14388    (set (match_dup 0) (match_dup 2))])
14389
14390 (define_split
14391   [(set (match_operand:DI 0 "memory_operand" "")
14392         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14393                    UNSPEC_FIST))
14394    (clobber (match_operand:DI 2 "memory_operand" ""))
14395    (clobber (match_scratch 3 ""))]
14396   "reload_completed"
14397   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14398               (clobber (match_dup 3))])])
14399
14400 (define_insn_and_split "*fist<mode>2_1"
14401   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14402         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14403                            UNSPEC_FIST))]
14404   "TARGET_USE_FANCY_MATH_387
14405    && can_create_pseudo_p ()"
14406   "#"
14407   "&& 1"
14408   [(const_int 0)]
14409 {
14410   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14411   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14412                                         operands[2]));
14413   DONE;
14414 }
14415   [(set_attr "type" "fpspc")
14416    (set_attr "mode" "<MODE>")])
14417
14418 (define_insn "fist<mode>2"
14419   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14420         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14421                            UNSPEC_FIST))]
14422   "TARGET_USE_FANCY_MATH_387"
14423   "* return output_fix_trunc (insn, operands, 0);"
14424   [(set_attr "type" "fpspc")
14425    (set_attr "mode" "<MODE>")])
14426
14427 (define_insn "fist<mode>2_with_temp"
14428   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14429         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14430                            UNSPEC_FIST))
14431    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14432   "TARGET_USE_FANCY_MATH_387"
14433   "#"
14434   [(set_attr "type" "fpspc")
14435    (set_attr "mode" "<MODE>")])
14436
14437 (define_split
14438   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14439         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14440                            UNSPEC_FIST))
14441    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14442   "reload_completed"
14443   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14444    (set (match_dup 0) (match_dup 2))])
14445
14446 (define_split
14447   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14448         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14449                            UNSPEC_FIST))
14450    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14451   "reload_completed"
14452   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14453
14454 (define_expand "lrintxf<mode>2"
14455   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14456      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14457                       UNSPEC_FIST))]
14458   "TARGET_USE_FANCY_MATH_387")
14459
14460 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14461   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14462      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14463                         UNSPEC_FIX_NOTRUNC))]
14464   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14465    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14466
14467 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14468   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14469    (match_operand:MODEF 1 "register_operand" "")]
14470   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14471    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14472    && !flag_trapping_math && !flag_rounding_math"
14473 {
14474   if (optimize_insn_for_size_p ())
14475     FAIL;
14476   ix86_expand_lround (operand0, operand1);
14477   DONE;
14478 })
14479
14480 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14481 (define_insn_and_split "frndintxf2_floor"
14482   [(set (match_operand:XF 0 "register_operand" "")
14483         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14484          UNSPEC_FRNDINT_FLOOR))
14485    (clobber (reg:CC FLAGS_REG))]
14486   "TARGET_USE_FANCY_MATH_387
14487    && flag_unsafe_math_optimizations
14488    && can_create_pseudo_p ()"
14489   "#"
14490   "&& 1"
14491   [(const_int 0)]
14492 {
14493   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14494
14495   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14496   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14497
14498   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14499                                         operands[2], operands[3]));
14500   DONE;
14501 }
14502   [(set_attr "type" "frndint")
14503    (set_attr "i387_cw" "floor")
14504    (set_attr "mode" "XF")])
14505
14506 (define_insn "frndintxf2_floor_i387"
14507   [(set (match_operand:XF 0 "register_operand" "=f")
14508         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14509          UNSPEC_FRNDINT_FLOOR))
14510    (use (match_operand:HI 2 "memory_operand" "m"))
14511    (use (match_operand:HI 3 "memory_operand" "m"))]
14512   "TARGET_USE_FANCY_MATH_387
14513    && flag_unsafe_math_optimizations"
14514   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14515   [(set_attr "type" "frndint")
14516    (set_attr "i387_cw" "floor")
14517    (set_attr "mode" "XF")])
14518
14519 (define_expand "floorxf2"
14520   [(use (match_operand:XF 0 "register_operand" ""))
14521    (use (match_operand:XF 1 "register_operand" ""))]
14522   "TARGET_USE_FANCY_MATH_387
14523    && flag_unsafe_math_optimizations"
14524 {
14525   if (optimize_insn_for_size_p ())
14526     FAIL;
14527   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14528   DONE;
14529 })
14530
14531 (define_expand "floor<mode>2"
14532   [(use (match_operand:MODEF 0 "register_operand" ""))
14533    (use (match_operand:MODEF 1 "register_operand" ""))]
14534   "(TARGET_USE_FANCY_MATH_387
14535     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14536         || TARGET_MIX_SSE_I387)
14537     && flag_unsafe_math_optimizations)
14538    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14539        && !flag_trapping_math)"
14540 {
14541   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14542       && !flag_trapping_math
14543       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14544     {
14545       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14546         FAIL;
14547       if (TARGET_ROUND)
14548         emit_insn (gen_sse4_1_round<mode>2
14549                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14550       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14551         ix86_expand_floorceil (operand0, operand1, true);
14552       else
14553         ix86_expand_floorceildf_32 (operand0, operand1, true);
14554     }
14555   else
14556     {
14557       rtx op0, op1;
14558
14559       if (optimize_insn_for_size_p ())
14560         FAIL;
14561
14562       op0 = gen_reg_rtx (XFmode);
14563       op1 = gen_reg_rtx (XFmode);
14564       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14565       emit_insn (gen_frndintxf2_floor (op0, op1));
14566
14567       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14568     }
14569   DONE;
14570 })
14571
14572 (define_insn_and_split "*fist<mode>2_floor_1"
14573   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14574         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14575          UNSPEC_FIST_FLOOR))
14576    (clobber (reg:CC FLAGS_REG))]
14577   "TARGET_USE_FANCY_MATH_387
14578    && flag_unsafe_math_optimizations
14579    && can_create_pseudo_p ()"
14580   "#"
14581   "&& 1"
14582   [(const_int 0)]
14583 {
14584   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14585
14586   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14587   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14588   if (memory_operand (operands[0], VOIDmode))
14589     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14590                                       operands[2], operands[3]));
14591   else
14592     {
14593       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14594       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14595                                                   operands[2], operands[3],
14596                                                   operands[4]));
14597     }
14598   DONE;
14599 }
14600   [(set_attr "type" "fistp")
14601    (set_attr "i387_cw" "floor")
14602    (set_attr "mode" "<MODE>")])
14603
14604 (define_insn "fistdi2_floor"
14605   [(set (match_operand:DI 0 "memory_operand" "=m")
14606         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14607          UNSPEC_FIST_FLOOR))
14608    (use (match_operand:HI 2 "memory_operand" "m"))
14609    (use (match_operand:HI 3 "memory_operand" "m"))
14610    (clobber (match_scratch:XF 4 "=&1f"))]
14611   "TARGET_USE_FANCY_MATH_387
14612    && flag_unsafe_math_optimizations"
14613   "* return output_fix_trunc (insn, operands, 0);"
14614   [(set_attr "type" "fistp")
14615    (set_attr "i387_cw" "floor")
14616    (set_attr "mode" "DI")])
14617
14618 (define_insn "fistdi2_floor_with_temp"
14619   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14620         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14621          UNSPEC_FIST_FLOOR))
14622    (use (match_operand:HI 2 "memory_operand" "m,m"))
14623    (use (match_operand:HI 3 "memory_operand" "m,m"))
14624    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14625    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14626   "TARGET_USE_FANCY_MATH_387
14627    && flag_unsafe_math_optimizations"
14628   "#"
14629   [(set_attr "type" "fistp")
14630    (set_attr "i387_cw" "floor")
14631    (set_attr "mode" "DI")])
14632
14633 (define_split
14634   [(set (match_operand:DI 0 "register_operand" "")
14635         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14636          UNSPEC_FIST_FLOOR))
14637    (use (match_operand:HI 2 "memory_operand" ""))
14638    (use (match_operand:HI 3 "memory_operand" ""))
14639    (clobber (match_operand:DI 4 "memory_operand" ""))
14640    (clobber (match_scratch 5 ""))]
14641   "reload_completed"
14642   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14643               (use (match_dup 2))
14644               (use (match_dup 3))
14645               (clobber (match_dup 5))])
14646    (set (match_dup 0) (match_dup 4))])
14647
14648 (define_split
14649   [(set (match_operand:DI 0 "memory_operand" "")
14650         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14651          UNSPEC_FIST_FLOOR))
14652    (use (match_operand:HI 2 "memory_operand" ""))
14653    (use (match_operand:HI 3 "memory_operand" ""))
14654    (clobber (match_operand:DI 4 "memory_operand" ""))
14655    (clobber (match_scratch 5 ""))]
14656   "reload_completed"
14657   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14658               (use (match_dup 2))
14659               (use (match_dup 3))
14660               (clobber (match_dup 5))])])
14661
14662 (define_insn "fist<mode>2_floor"
14663   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14664         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14665          UNSPEC_FIST_FLOOR))
14666    (use (match_operand:HI 2 "memory_operand" "m"))
14667    (use (match_operand:HI 3 "memory_operand" "m"))]
14668   "TARGET_USE_FANCY_MATH_387
14669    && flag_unsafe_math_optimizations"
14670   "* return output_fix_trunc (insn, operands, 0);"
14671   [(set_attr "type" "fistp")
14672    (set_attr "i387_cw" "floor")
14673    (set_attr "mode" "<MODE>")])
14674
14675 (define_insn "fist<mode>2_floor_with_temp"
14676   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14677         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14678          UNSPEC_FIST_FLOOR))
14679    (use (match_operand:HI 2 "memory_operand" "m,m"))
14680    (use (match_operand:HI 3 "memory_operand" "m,m"))
14681    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14682   "TARGET_USE_FANCY_MATH_387
14683    && flag_unsafe_math_optimizations"
14684   "#"
14685   [(set_attr "type" "fistp")
14686    (set_attr "i387_cw" "floor")
14687    (set_attr "mode" "<MODE>")])
14688
14689 (define_split
14690   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14691         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14692          UNSPEC_FIST_FLOOR))
14693    (use (match_operand:HI 2 "memory_operand" ""))
14694    (use (match_operand:HI 3 "memory_operand" ""))
14695    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14696   "reload_completed"
14697   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14698                                   UNSPEC_FIST_FLOOR))
14699               (use (match_dup 2))
14700               (use (match_dup 3))])
14701    (set (match_dup 0) (match_dup 4))])
14702
14703 (define_split
14704   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14705         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14706          UNSPEC_FIST_FLOOR))
14707    (use (match_operand:HI 2 "memory_operand" ""))
14708    (use (match_operand:HI 3 "memory_operand" ""))
14709    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14710   "reload_completed"
14711   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14712                                   UNSPEC_FIST_FLOOR))
14713               (use (match_dup 2))
14714               (use (match_dup 3))])])
14715
14716 (define_expand "lfloorxf<mode>2"
14717   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14718                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14719                     UNSPEC_FIST_FLOOR))
14720               (clobber (reg:CC FLAGS_REG))])]
14721   "TARGET_USE_FANCY_MATH_387
14722    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14723    && flag_unsafe_math_optimizations")
14724
14725 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14726   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14727    (match_operand:MODEF 1 "register_operand" "")]
14728   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14729    && !flag_trapping_math"
14730 {
14731   if (TARGET_64BIT && optimize_insn_for_size_p ())
14732     FAIL;
14733   ix86_expand_lfloorceil (operand0, operand1, true);
14734   DONE;
14735 })
14736
14737 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14738 (define_insn_and_split "frndintxf2_ceil"
14739   [(set (match_operand:XF 0 "register_operand" "")
14740         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14741          UNSPEC_FRNDINT_CEIL))
14742    (clobber (reg:CC FLAGS_REG))]
14743   "TARGET_USE_FANCY_MATH_387
14744    && flag_unsafe_math_optimizations
14745    && can_create_pseudo_p ()"
14746   "#"
14747   "&& 1"
14748   [(const_int 0)]
14749 {
14750   ix86_optimize_mode_switching[I387_CEIL] = 1;
14751
14752   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14753   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14754
14755   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14756                                        operands[2], operands[3]));
14757   DONE;
14758 }
14759   [(set_attr "type" "frndint")
14760    (set_attr "i387_cw" "ceil")
14761    (set_attr "mode" "XF")])
14762
14763 (define_insn "frndintxf2_ceil_i387"
14764   [(set (match_operand:XF 0 "register_operand" "=f")
14765         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14766          UNSPEC_FRNDINT_CEIL))
14767    (use (match_operand:HI 2 "memory_operand" "m"))
14768    (use (match_operand:HI 3 "memory_operand" "m"))]
14769   "TARGET_USE_FANCY_MATH_387
14770    && flag_unsafe_math_optimizations"
14771   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14772   [(set_attr "type" "frndint")
14773    (set_attr "i387_cw" "ceil")
14774    (set_attr "mode" "XF")])
14775
14776 (define_expand "ceilxf2"
14777   [(use (match_operand:XF 0 "register_operand" ""))
14778    (use (match_operand:XF 1 "register_operand" ""))]
14779   "TARGET_USE_FANCY_MATH_387
14780    && flag_unsafe_math_optimizations"
14781 {
14782   if (optimize_insn_for_size_p ())
14783     FAIL;
14784   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14785   DONE;
14786 })
14787
14788 (define_expand "ceil<mode>2"
14789   [(use (match_operand:MODEF 0 "register_operand" ""))
14790    (use (match_operand:MODEF 1 "register_operand" ""))]
14791   "(TARGET_USE_FANCY_MATH_387
14792     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14793         || TARGET_MIX_SSE_I387)
14794     && flag_unsafe_math_optimizations)
14795    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14796        && !flag_trapping_math)"
14797 {
14798   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14799       && !flag_trapping_math
14800       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14801     {
14802       if (TARGET_ROUND)
14803         emit_insn (gen_sse4_1_round<mode>2
14804                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14805       else if (optimize_insn_for_size_p ())
14806         FAIL;
14807       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14808         ix86_expand_floorceil (operand0, operand1, false);
14809       else
14810         ix86_expand_floorceildf_32 (operand0, operand1, false);
14811     }
14812   else
14813     {
14814       rtx op0, op1;
14815
14816       if (optimize_insn_for_size_p ())
14817         FAIL;
14818
14819       op0 = gen_reg_rtx (XFmode);
14820       op1 = gen_reg_rtx (XFmode);
14821       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14822       emit_insn (gen_frndintxf2_ceil (op0, op1));
14823
14824       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14825     }
14826   DONE;
14827 })
14828
14829 (define_insn_and_split "*fist<mode>2_ceil_1"
14830   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14831         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14832          UNSPEC_FIST_CEIL))
14833    (clobber (reg:CC FLAGS_REG))]
14834   "TARGET_USE_FANCY_MATH_387
14835    && flag_unsafe_math_optimizations
14836    && can_create_pseudo_p ()"
14837   "#"
14838   "&& 1"
14839   [(const_int 0)]
14840 {
14841   ix86_optimize_mode_switching[I387_CEIL] = 1;
14842
14843   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14844   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14845   if (memory_operand (operands[0], VOIDmode))
14846     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14847                                      operands[2], operands[3]));
14848   else
14849     {
14850       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14851       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14852                                                  operands[2], operands[3],
14853                                                  operands[4]));
14854     }
14855   DONE;
14856 }
14857   [(set_attr "type" "fistp")
14858    (set_attr "i387_cw" "ceil")
14859    (set_attr "mode" "<MODE>")])
14860
14861 (define_insn "fistdi2_ceil"
14862   [(set (match_operand:DI 0 "memory_operand" "=m")
14863         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14864          UNSPEC_FIST_CEIL))
14865    (use (match_operand:HI 2 "memory_operand" "m"))
14866    (use (match_operand:HI 3 "memory_operand" "m"))
14867    (clobber (match_scratch:XF 4 "=&1f"))]
14868   "TARGET_USE_FANCY_MATH_387
14869    && flag_unsafe_math_optimizations"
14870   "* return output_fix_trunc (insn, operands, 0);"
14871   [(set_attr "type" "fistp")
14872    (set_attr "i387_cw" "ceil")
14873    (set_attr "mode" "DI")])
14874
14875 (define_insn "fistdi2_ceil_with_temp"
14876   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14877         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14878          UNSPEC_FIST_CEIL))
14879    (use (match_operand:HI 2 "memory_operand" "m,m"))
14880    (use (match_operand:HI 3 "memory_operand" "m,m"))
14881    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14882    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14883   "TARGET_USE_FANCY_MATH_387
14884    && flag_unsafe_math_optimizations"
14885   "#"
14886   [(set_attr "type" "fistp")
14887    (set_attr "i387_cw" "ceil")
14888    (set_attr "mode" "DI")])
14889
14890 (define_split
14891   [(set (match_operand:DI 0 "register_operand" "")
14892         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14893          UNSPEC_FIST_CEIL))
14894    (use (match_operand:HI 2 "memory_operand" ""))
14895    (use (match_operand:HI 3 "memory_operand" ""))
14896    (clobber (match_operand:DI 4 "memory_operand" ""))
14897    (clobber (match_scratch 5 ""))]
14898   "reload_completed"
14899   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14900               (use (match_dup 2))
14901               (use (match_dup 3))
14902               (clobber (match_dup 5))])
14903    (set (match_dup 0) (match_dup 4))])
14904
14905 (define_split
14906   [(set (match_operand:DI 0 "memory_operand" "")
14907         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14908          UNSPEC_FIST_CEIL))
14909    (use (match_operand:HI 2 "memory_operand" ""))
14910    (use (match_operand:HI 3 "memory_operand" ""))
14911    (clobber (match_operand:DI 4 "memory_operand" ""))
14912    (clobber (match_scratch 5 ""))]
14913   "reload_completed"
14914   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14915               (use (match_dup 2))
14916               (use (match_dup 3))
14917               (clobber (match_dup 5))])])
14918
14919 (define_insn "fist<mode>2_ceil"
14920   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14921         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14922          UNSPEC_FIST_CEIL))
14923    (use (match_operand:HI 2 "memory_operand" "m"))
14924    (use (match_operand:HI 3 "memory_operand" "m"))]
14925   "TARGET_USE_FANCY_MATH_387
14926    && flag_unsafe_math_optimizations"
14927   "* return output_fix_trunc (insn, operands, 0);"
14928   [(set_attr "type" "fistp")
14929    (set_attr "i387_cw" "ceil")
14930    (set_attr "mode" "<MODE>")])
14931
14932 (define_insn "fist<mode>2_ceil_with_temp"
14933   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14934         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14935          UNSPEC_FIST_CEIL))
14936    (use (match_operand:HI 2 "memory_operand" "m,m"))
14937    (use (match_operand:HI 3 "memory_operand" "m,m"))
14938    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14939   "TARGET_USE_FANCY_MATH_387
14940    && flag_unsafe_math_optimizations"
14941   "#"
14942   [(set_attr "type" "fistp")
14943    (set_attr "i387_cw" "ceil")
14944    (set_attr "mode" "<MODE>")])
14945
14946 (define_split
14947   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14948         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14949          UNSPEC_FIST_CEIL))
14950    (use (match_operand:HI 2 "memory_operand" ""))
14951    (use (match_operand:HI 3 "memory_operand" ""))
14952    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14953   "reload_completed"
14954   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14955                                   UNSPEC_FIST_CEIL))
14956               (use (match_dup 2))
14957               (use (match_dup 3))])
14958    (set (match_dup 0) (match_dup 4))])
14959
14960 (define_split
14961   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14962         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14963          UNSPEC_FIST_CEIL))
14964    (use (match_operand:HI 2 "memory_operand" ""))
14965    (use (match_operand:HI 3 "memory_operand" ""))
14966    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14967   "reload_completed"
14968   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14969                                   UNSPEC_FIST_CEIL))
14970               (use (match_dup 2))
14971               (use (match_dup 3))])])
14972
14973 (define_expand "lceilxf<mode>2"
14974   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14975                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14976                     UNSPEC_FIST_CEIL))
14977               (clobber (reg:CC FLAGS_REG))])]
14978   "TARGET_USE_FANCY_MATH_387
14979    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14980    && flag_unsafe_math_optimizations")
14981
14982 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14983   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14984    (match_operand:MODEF 1 "register_operand" "")]
14985   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14986    && !flag_trapping_math"
14987 {
14988   ix86_expand_lfloorceil (operand0, operand1, false);
14989   DONE;
14990 })
14991
14992 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14993 (define_insn_and_split "frndintxf2_trunc"
14994   [(set (match_operand:XF 0 "register_operand" "")
14995         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14996          UNSPEC_FRNDINT_TRUNC))
14997    (clobber (reg:CC FLAGS_REG))]
14998   "TARGET_USE_FANCY_MATH_387
14999    && flag_unsafe_math_optimizations
15000    && can_create_pseudo_p ()"
15001   "#"
15002   "&& 1"
15003   [(const_int 0)]
15004 {
15005   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15006
15007   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15008   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15009
15010   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15011                                         operands[2], operands[3]));
15012   DONE;
15013 }
15014   [(set_attr "type" "frndint")
15015    (set_attr "i387_cw" "trunc")
15016    (set_attr "mode" "XF")])
15017
15018 (define_insn "frndintxf2_trunc_i387"
15019   [(set (match_operand:XF 0 "register_operand" "=f")
15020         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15021          UNSPEC_FRNDINT_TRUNC))
15022    (use (match_operand:HI 2 "memory_operand" "m"))
15023    (use (match_operand:HI 3 "memory_operand" "m"))]
15024   "TARGET_USE_FANCY_MATH_387
15025    && flag_unsafe_math_optimizations"
15026   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15027   [(set_attr "type" "frndint")
15028    (set_attr "i387_cw" "trunc")
15029    (set_attr "mode" "XF")])
15030
15031 (define_expand "btruncxf2"
15032   [(use (match_operand:XF 0 "register_operand" ""))
15033    (use (match_operand:XF 1 "register_operand" ""))]
15034   "TARGET_USE_FANCY_MATH_387
15035    && flag_unsafe_math_optimizations"
15036 {
15037   if (optimize_insn_for_size_p ())
15038     FAIL;
15039   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15040   DONE;
15041 })
15042
15043 (define_expand "btrunc<mode>2"
15044   [(use (match_operand:MODEF 0 "register_operand" ""))
15045    (use (match_operand:MODEF 1 "register_operand" ""))]
15046   "(TARGET_USE_FANCY_MATH_387
15047     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15048         || TARGET_MIX_SSE_I387)
15049     && flag_unsafe_math_optimizations)
15050    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15051        && !flag_trapping_math)"
15052 {
15053   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15054       && !flag_trapping_math
15055       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15056     {
15057       if (TARGET_ROUND)
15058         emit_insn (gen_sse4_1_round<mode>2
15059                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15060       else if (optimize_insn_for_size_p ())
15061         FAIL;
15062       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15063         ix86_expand_trunc (operand0, operand1);
15064       else
15065         ix86_expand_truncdf_32 (operand0, operand1);
15066     }
15067   else
15068     {
15069       rtx op0, op1;
15070
15071       if (optimize_insn_for_size_p ())
15072         FAIL;
15073
15074       op0 = gen_reg_rtx (XFmode);
15075       op1 = gen_reg_rtx (XFmode);
15076       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15077       emit_insn (gen_frndintxf2_trunc (op0, op1));
15078
15079       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15080     }
15081   DONE;
15082 })
15083
15084 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15085 (define_insn_and_split "frndintxf2_mask_pm"
15086   [(set (match_operand:XF 0 "register_operand" "")
15087         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15088          UNSPEC_FRNDINT_MASK_PM))
15089    (clobber (reg:CC FLAGS_REG))]
15090   "TARGET_USE_FANCY_MATH_387
15091    && flag_unsafe_math_optimizations
15092    && can_create_pseudo_p ()"
15093   "#"
15094   "&& 1"
15095   [(const_int 0)]
15096 {
15097   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15098
15099   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15100   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15101
15102   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15103                                           operands[2], operands[3]));
15104   DONE;
15105 }
15106   [(set_attr "type" "frndint")
15107    (set_attr "i387_cw" "mask_pm")
15108    (set_attr "mode" "XF")])
15109
15110 (define_insn "frndintxf2_mask_pm_i387"
15111   [(set (match_operand:XF 0 "register_operand" "=f")
15112         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15113          UNSPEC_FRNDINT_MASK_PM))
15114    (use (match_operand:HI 2 "memory_operand" "m"))
15115    (use (match_operand:HI 3 "memory_operand" "m"))]
15116   "TARGET_USE_FANCY_MATH_387
15117    && flag_unsafe_math_optimizations"
15118   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15119   [(set_attr "type" "frndint")
15120    (set_attr "i387_cw" "mask_pm")
15121    (set_attr "mode" "XF")])
15122
15123 (define_expand "nearbyintxf2"
15124   [(use (match_operand:XF 0 "register_operand" ""))
15125    (use (match_operand:XF 1 "register_operand" ""))]
15126   "TARGET_USE_FANCY_MATH_387
15127    && flag_unsafe_math_optimizations"
15128 {
15129   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15130   DONE;
15131 })
15132
15133 (define_expand "nearbyint<mode>2"
15134   [(use (match_operand:MODEF 0 "register_operand" ""))
15135    (use (match_operand:MODEF 1 "register_operand" ""))]
15136   "TARGET_USE_FANCY_MATH_387
15137    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15138        || TARGET_MIX_SSE_I387)
15139    && flag_unsafe_math_optimizations"
15140 {
15141   rtx op0 = gen_reg_rtx (XFmode);
15142   rtx op1 = gen_reg_rtx (XFmode);
15143
15144   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15145   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15146
15147   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15148   DONE;
15149 })
15150
15151 (define_insn "fxam<mode>2_i387"
15152   [(set (match_operand:HI 0 "register_operand" "=a")
15153         (unspec:HI
15154           [(match_operand:X87MODEF 1 "register_operand" "f")]
15155           UNSPEC_FXAM))]
15156   "TARGET_USE_FANCY_MATH_387"
15157   "fxam\n\tfnstsw\t%0"
15158   [(set_attr "type" "multi")
15159    (set_attr "length" "4")
15160    (set_attr "unit" "i387")
15161    (set_attr "mode" "<MODE>")])
15162
15163 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15164   [(set (match_operand:HI 0 "register_operand" "")
15165         (unspec:HI
15166           [(match_operand:MODEF 1 "memory_operand" "")]
15167           UNSPEC_FXAM_MEM))]
15168   "TARGET_USE_FANCY_MATH_387
15169    && can_create_pseudo_p ()"
15170   "#"
15171   "&& 1"
15172   [(set (match_dup 2)(match_dup 1))
15173    (set (match_dup 0)
15174         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15175 {
15176   operands[2] = gen_reg_rtx (<MODE>mode);
15177
15178   MEM_VOLATILE_P (operands[1]) = 1;
15179 }
15180   [(set_attr "type" "multi")
15181    (set_attr "unit" "i387")
15182    (set_attr "mode" "<MODE>")])
15183
15184 (define_expand "isinfxf2"
15185   [(use (match_operand:SI 0 "register_operand" ""))
15186    (use (match_operand:XF 1 "register_operand" ""))]
15187   "TARGET_USE_FANCY_MATH_387
15188    && TARGET_C99_FUNCTIONS"
15189 {
15190   rtx mask = GEN_INT (0x45);
15191   rtx val = GEN_INT (0x05);
15192
15193   rtx cond;
15194
15195   rtx scratch = gen_reg_rtx (HImode);
15196   rtx res = gen_reg_rtx (QImode);
15197
15198   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15199
15200   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15201   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15202   cond = gen_rtx_fmt_ee (EQ, QImode,
15203                          gen_rtx_REG (CCmode, FLAGS_REG),
15204                          const0_rtx);
15205   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15206   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15207   DONE;
15208 })
15209
15210 (define_expand "isinf<mode>2"
15211   [(use (match_operand:SI 0 "register_operand" ""))
15212    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15213   "TARGET_USE_FANCY_MATH_387
15214    && TARGET_C99_FUNCTIONS
15215    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15216 {
15217   rtx mask = GEN_INT (0x45);
15218   rtx val = GEN_INT (0x05);
15219
15220   rtx cond;
15221
15222   rtx scratch = gen_reg_rtx (HImode);
15223   rtx res = gen_reg_rtx (QImode);
15224
15225   /* Remove excess precision by forcing value through memory. */
15226   if (memory_operand (operands[1], VOIDmode))
15227     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15228   else
15229     {
15230       enum ix86_stack_slot slot = (virtuals_instantiated
15231                                    ? SLOT_TEMP
15232                                    : SLOT_VIRTUAL);
15233       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15234
15235       emit_move_insn (temp, operands[1]);
15236       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15237     }
15238
15239   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15240   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15241   cond = gen_rtx_fmt_ee (EQ, QImode,
15242                          gen_rtx_REG (CCmode, FLAGS_REG),
15243                          const0_rtx);
15244   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15245   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15246   DONE;
15247 })
15248
15249 (define_expand "signbitxf2"
15250   [(use (match_operand:SI 0 "register_operand" ""))
15251    (use (match_operand:XF 1 "register_operand" ""))]
15252   "TARGET_USE_FANCY_MATH_387"
15253 {
15254   rtx scratch = gen_reg_rtx (HImode);
15255
15256   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15257   emit_insn (gen_andsi3 (operands[0],
15258              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15259   DONE;
15260 })
15261
15262 (define_insn "movmsk_df"
15263   [(set (match_operand:SI 0 "register_operand" "=r")
15264         (unspec:SI
15265           [(match_operand:DF 1 "register_operand" "x")]
15266           UNSPEC_MOVMSK))]
15267   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15268   "%vmovmskpd\t{%1, %0|%0, %1}"
15269   [(set_attr "type" "ssemov")
15270    (set_attr "prefix" "maybe_vex")
15271    (set_attr "mode" "DF")])
15272
15273 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15274 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15275 (define_expand "signbitdf2"
15276   [(use (match_operand:SI 0 "register_operand" ""))
15277    (use (match_operand:DF 1 "register_operand" ""))]
15278   "TARGET_USE_FANCY_MATH_387
15279    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15280 {
15281   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15282     {
15283       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15284       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15285     }
15286   else
15287     {
15288       rtx scratch = gen_reg_rtx (HImode);
15289
15290       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15291       emit_insn (gen_andsi3 (operands[0],
15292                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15293     }
15294   DONE;
15295 })
15296
15297 (define_expand "signbitsf2"
15298   [(use (match_operand:SI 0 "register_operand" ""))
15299    (use (match_operand:SF 1 "register_operand" ""))]
15300   "TARGET_USE_FANCY_MATH_387
15301    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15302 {
15303   rtx scratch = gen_reg_rtx (HImode);
15304
15305   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15306   emit_insn (gen_andsi3 (operands[0],
15307              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15308   DONE;
15309 })
15310 \f
15311 ;; Block operation instructions
15312
15313 (define_insn "cld"
15314   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15315   ""
15316   "cld"
15317   [(set_attr "length" "1")
15318    (set_attr "length_immediate" "0")
15319    (set_attr "modrm" "0")])
15320
15321 (define_expand "movmem<mode>"
15322   [(use (match_operand:BLK 0 "memory_operand" ""))
15323    (use (match_operand:BLK 1 "memory_operand" ""))
15324    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15325    (use (match_operand:SWI48 3 "const_int_operand" ""))
15326    (use (match_operand:SI 4 "const_int_operand" ""))
15327    (use (match_operand:SI 5 "const_int_operand" ""))]
15328   ""
15329 {
15330  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15331                          operands[4], operands[5]))
15332    DONE;
15333  else
15334    FAIL;
15335 })
15336
15337 ;; Most CPUs don't like single string operations
15338 ;; Handle this case here to simplify previous expander.
15339
15340 (define_expand "strmov"
15341   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15342    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15343    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15344               (clobber (reg:CC FLAGS_REG))])
15345    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15346               (clobber (reg:CC FLAGS_REG))])]
15347   ""
15348 {
15349   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15350
15351   /* If .md ever supports :P for Pmode, these can be directly
15352      in the pattern above.  */
15353   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15354   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15355
15356   /* Can't use this if the user has appropriated esi or edi.  */
15357   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15358       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15359     {
15360       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15361                                       operands[2], operands[3],
15362                                       operands[5], operands[6]));
15363       DONE;
15364     }
15365
15366   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15367 })
15368
15369 (define_expand "strmov_singleop"
15370   [(parallel [(set (match_operand 1 "memory_operand" "")
15371                    (match_operand 3 "memory_operand" ""))
15372               (set (match_operand 0 "register_operand" "")
15373                    (match_operand 4 "" ""))
15374               (set (match_operand 2 "register_operand" "")
15375                    (match_operand 5 "" ""))])]
15376   ""
15377   "ix86_current_function_needs_cld = 1;")
15378
15379 (define_insn "*strmovdi_rex_1"
15380   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15381         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15382    (set (match_operand:DI 0 "register_operand" "=D")
15383         (plus:DI (match_dup 2)
15384                  (const_int 8)))
15385    (set (match_operand:DI 1 "register_operand" "=S")
15386         (plus:DI (match_dup 3)
15387                  (const_int 8)))]
15388   "TARGET_64BIT"
15389   "movsq"
15390   [(set_attr "type" "str")
15391    (set_attr "memory" "both")
15392    (set_attr "mode" "DI")])
15393
15394 (define_insn "*strmovsi_1"
15395   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15396         (mem:SI (match_operand:P 3 "register_operand" "1")))
15397    (set (match_operand:P 0 "register_operand" "=D")
15398         (plus:P (match_dup 2)
15399                 (const_int 4)))
15400    (set (match_operand:P 1 "register_operand" "=S")
15401         (plus:P (match_dup 3)
15402                 (const_int 4)))]
15403   ""
15404   "movs{l|d}"
15405   [(set_attr "type" "str")
15406    (set_attr "memory" "both")
15407    (set_attr "mode" "SI")])
15408
15409 (define_insn "*strmovhi_1"
15410   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15411         (mem:HI (match_operand:P 3 "register_operand" "1")))
15412    (set (match_operand:P 0 "register_operand" "=D")
15413         (plus:P (match_dup 2)
15414                 (const_int 2)))
15415    (set (match_operand:P 1 "register_operand" "=S")
15416         (plus:P (match_dup 3)
15417                 (const_int 2)))]
15418   ""
15419   "movsw"
15420   [(set_attr "type" "str")
15421    (set_attr "memory" "both")
15422    (set_attr "mode" "HI")])
15423
15424 (define_insn "*strmovqi_1"
15425   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15426         (mem:QI (match_operand:P 3 "register_operand" "1")))
15427    (set (match_operand:P 0 "register_operand" "=D")
15428         (plus:P (match_dup 2)
15429                 (const_int 1)))
15430    (set (match_operand:P 1 "register_operand" "=S")
15431         (plus:P (match_dup 3)
15432                 (const_int 1)))]
15433   ""
15434   "movsb"
15435   [(set_attr "type" "str")
15436    (set_attr "memory" "both")
15437    (set (attr "prefix_rex")
15438         (if_then_else
15439           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15440           (const_string "0")
15441           (const_string "*")))
15442    (set_attr "mode" "QI")])
15443
15444 (define_expand "rep_mov"
15445   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15446               (set (match_operand 0 "register_operand" "")
15447                    (match_operand 5 "" ""))
15448               (set (match_operand 2 "register_operand" "")
15449                    (match_operand 6 "" ""))
15450               (set (match_operand 1 "memory_operand" "")
15451                    (match_operand 3 "memory_operand" ""))
15452               (use (match_dup 4))])]
15453   ""
15454   "ix86_current_function_needs_cld = 1;")
15455
15456 (define_insn "*rep_movdi_rex64"
15457   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15458    (set (match_operand:DI 0 "register_operand" "=D")
15459         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15460                             (const_int 3))
15461                  (match_operand:DI 3 "register_operand" "0")))
15462    (set (match_operand:DI 1 "register_operand" "=S")
15463         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15464                  (match_operand:DI 4 "register_operand" "1")))
15465    (set (mem:BLK (match_dup 3))
15466         (mem:BLK (match_dup 4)))
15467    (use (match_dup 5))]
15468   "TARGET_64BIT"
15469   "rep{%;} movsq"
15470   [(set_attr "type" "str")
15471    (set_attr "prefix_rep" "1")
15472    (set_attr "memory" "both")
15473    (set_attr "mode" "DI")])
15474
15475 (define_insn "*rep_movsi"
15476   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15477    (set (match_operand:P 0 "register_operand" "=D")
15478         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15479                           (const_int 2))
15480                  (match_operand:P 3 "register_operand" "0")))
15481    (set (match_operand:P 1 "register_operand" "=S")
15482         (plus:P (ashift:P (match_dup 5) (const_int 2))
15483                 (match_operand:P 4 "register_operand" "1")))
15484    (set (mem:BLK (match_dup 3))
15485         (mem:BLK (match_dup 4)))
15486    (use (match_dup 5))]
15487   ""
15488   "rep{%;} movs{l|d}"
15489   [(set_attr "type" "str")
15490    (set_attr "prefix_rep" "1")
15491    (set_attr "memory" "both")
15492    (set_attr "mode" "SI")])
15493
15494 (define_insn "*rep_movqi"
15495   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15496    (set (match_operand:P 0 "register_operand" "=D")
15497         (plus:P (match_operand:P 3 "register_operand" "0")
15498                 (match_operand:P 5 "register_operand" "2")))
15499    (set (match_operand:P 1 "register_operand" "=S")
15500         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15501    (set (mem:BLK (match_dup 3))
15502         (mem:BLK (match_dup 4)))
15503    (use (match_dup 5))]
15504   ""
15505   "rep{%;} movsb"
15506   [(set_attr "type" "str")
15507    (set_attr "prefix_rep" "1")
15508    (set_attr "memory" "both")
15509    (set_attr "mode" "QI")])
15510
15511 (define_expand "setmem<mode>"
15512    [(use (match_operand:BLK 0 "memory_operand" ""))
15513     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15514     (use (match_operand:QI 2 "nonmemory_operand" ""))
15515     (use (match_operand 3 "const_int_operand" ""))
15516     (use (match_operand:SI 4 "const_int_operand" ""))
15517     (use (match_operand:SI 5 "const_int_operand" ""))]
15518   ""
15519 {
15520  if (ix86_expand_setmem (operands[0], operands[1],
15521                          operands[2], operands[3],
15522                          operands[4], operands[5]))
15523    DONE;
15524  else
15525    FAIL;
15526 })
15527
15528 ;; Most CPUs don't like single string operations
15529 ;; Handle this case here to simplify previous expander.
15530
15531 (define_expand "strset"
15532   [(set (match_operand 1 "memory_operand" "")
15533         (match_operand 2 "register_operand" ""))
15534    (parallel [(set (match_operand 0 "register_operand" "")
15535                    (match_dup 3))
15536               (clobber (reg:CC FLAGS_REG))])]
15537   ""
15538 {
15539   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15540     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15541
15542   /* If .md ever supports :P for Pmode, this can be directly
15543      in the pattern above.  */
15544   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15545                               GEN_INT (GET_MODE_SIZE (GET_MODE
15546                                                       (operands[2]))));
15547   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15548     {
15549       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15550                                       operands[3]));
15551       DONE;
15552     }
15553 })
15554
15555 (define_expand "strset_singleop"
15556   [(parallel [(set (match_operand 1 "memory_operand" "")
15557                    (match_operand 2 "register_operand" ""))
15558               (set (match_operand 0 "register_operand" "")
15559                    (match_operand 3 "" ""))])]
15560   ""
15561   "ix86_current_function_needs_cld = 1;")
15562
15563 (define_insn "*strsetdi_rex_1"
15564   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15565         (match_operand:DI 2 "register_operand" "a"))
15566    (set (match_operand:DI 0 "register_operand" "=D")
15567         (plus:DI (match_dup 1)
15568                  (const_int 8)))]
15569   "TARGET_64BIT"
15570   "stosq"
15571   [(set_attr "type" "str")
15572    (set_attr "memory" "store")
15573    (set_attr "mode" "DI")])
15574
15575 (define_insn "*strsetsi_1"
15576   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15577         (match_operand:SI 2 "register_operand" "a"))
15578    (set (match_operand:P 0 "register_operand" "=D")
15579         (plus:P (match_dup 1)
15580                 (const_int 4)))]
15581   ""
15582   "stos{l|d}"
15583   [(set_attr "type" "str")
15584    (set_attr "memory" "store")
15585    (set_attr "mode" "SI")])
15586
15587 (define_insn "*strsethi_1"
15588   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15589         (match_operand:HI 2 "register_operand" "a"))
15590    (set (match_operand:P 0 "register_operand" "=D")
15591         (plus:P (match_dup 1)
15592                 (const_int 2)))]
15593   ""
15594   "stosw"
15595   [(set_attr "type" "str")
15596    (set_attr "memory" "store")
15597    (set_attr "mode" "HI")])
15598
15599 (define_insn "*strsetqi_1"
15600   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15601         (match_operand:QI 2 "register_operand" "a"))
15602    (set (match_operand:P 0 "register_operand" "=D")
15603         (plus:P (match_dup 1)
15604                 (const_int 1)))]
15605   ""
15606   "stosb"
15607   [(set_attr "type" "str")
15608    (set_attr "memory" "store")
15609    (set (attr "prefix_rex")
15610         (if_then_else
15611           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15612           (const_string "0")
15613           (const_string "*")))
15614    (set_attr "mode" "QI")])
15615
15616 (define_expand "rep_stos"
15617   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15618               (set (match_operand 0 "register_operand" "")
15619                    (match_operand 4 "" ""))
15620               (set (match_operand 2 "memory_operand" "") (const_int 0))
15621               (use (match_operand 3 "register_operand" ""))
15622               (use (match_dup 1))])]
15623   ""
15624   "ix86_current_function_needs_cld = 1;")
15625
15626 (define_insn "*rep_stosdi_rex64"
15627   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15628    (set (match_operand:DI 0 "register_operand" "=D")
15629         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15630                             (const_int 3))
15631                  (match_operand:DI 3 "register_operand" "0")))
15632    (set (mem:BLK (match_dup 3))
15633         (const_int 0))
15634    (use (match_operand:DI 2 "register_operand" "a"))
15635    (use (match_dup 4))]
15636   "TARGET_64BIT"
15637   "rep{%;} stosq"
15638   [(set_attr "type" "str")
15639    (set_attr "prefix_rep" "1")
15640    (set_attr "memory" "store")
15641    (set_attr "mode" "DI")])
15642
15643 (define_insn "*rep_stossi"
15644   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15645    (set (match_operand:P 0 "register_operand" "=D")
15646         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15647                           (const_int 2))
15648                  (match_operand:P 3 "register_operand" "0")))
15649    (set (mem:BLK (match_dup 3))
15650         (const_int 0))
15651    (use (match_operand:SI 2 "register_operand" "a"))
15652    (use (match_dup 4))]
15653   ""
15654   "rep{%;} stos{l|d}"
15655   [(set_attr "type" "str")
15656    (set_attr "prefix_rep" "1")
15657    (set_attr "memory" "store")
15658    (set_attr "mode" "SI")])
15659
15660 (define_insn "*rep_stosqi"
15661   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15662    (set (match_operand:P 0 "register_operand" "=D")
15663         (plus:P (match_operand:P 3 "register_operand" "0")
15664                 (match_operand:P 4 "register_operand" "1")))
15665    (set (mem:BLK (match_dup 3))
15666         (const_int 0))
15667    (use (match_operand:QI 2 "register_operand" "a"))
15668    (use (match_dup 4))]
15669   ""
15670   "rep{%;} stosb"
15671   [(set_attr "type" "str")
15672    (set_attr "prefix_rep" "1")
15673    (set_attr "memory" "store")
15674    (set (attr "prefix_rex")
15675         (if_then_else
15676           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15677           (const_string "0")
15678           (const_string "*")))
15679    (set_attr "mode" "QI")])
15680
15681 (define_expand "cmpstrnsi"
15682   [(set (match_operand:SI 0 "register_operand" "")
15683         (compare:SI (match_operand:BLK 1 "general_operand" "")
15684                     (match_operand:BLK 2 "general_operand" "")))
15685    (use (match_operand 3 "general_operand" ""))
15686    (use (match_operand 4 "immediate_operand" ""))]
15687   ""
15688 {
15689   rtx addr1, addr2, out, outlow, count, countreg, align;
15690
15691   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15692     FAIL;
15693
15694   /* Can't use this if the user has appropriated esi or edi.  */
15695   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15696     FAIL;
15697
15698   out = operands[0];
15699   if (!REG_P (out))
15700     out = gen_reg_rtx (SImode);
15701
15702   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15703   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15704   if (addr1 != XEXP (operands[1], 0))
15705     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15706   if (addr2 != XEXP (operands[2], 0))
15707     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15708
15709   count = operands[3];
15710   countreg = ix86_zero_extend_to_Pmode (count);
15711
15712   /* %%% Iff we are testing strict equality, we can use known alignment
15713      to good advantage.  This may be possible with combine, particularly
15714      once cc0 is dead.  */
15715   align = operands[4];
15716
15717   if (CONST_INT_P (count))
15718     {
15719       if (INTVAL (count) == 0)
15720         {
15721           emit_move_insn (operands[0], const0_rtx);
15722           DONE;
15723         }
15724       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15725                                      operands[1], operands[2]));
15726     }
15727   else
15728     {
15729       rtx (*gen_cmp) (rtx, rtx);
15730
15731       gen_cmp = (TARGET_64BIT
15732                  ? gen_cmpdi_1 : gen_cmpsi_1);
15733
15734       emit_insn (gen_cmp (countreg, countreg));
15735       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15736                                   operands[1], operands[2]));
15737     }
15738
15739   outlow = gen_lowpart (QImode, out);
15740   emit_insn (gen_cmpintqi (outlow));
15741   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15742
15743   if (operands[0] != out)
15744     emit_move_insn (operands[0], out);
15745
15746   DONE;
15747 })
15748
15749 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15750
15751 (define_expand "cmpintqi"
15752   [(set (match_dup 1)
15753         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15754    (set (match_dup 2)
15755         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15756    (parallel [(set (match_operand:QI 0 "register_operand" "")
15757                    (minus:QI (match_dup 1)
15758                              (match_dup 2)))
15759               (clobber (reg:CC FLAGS_REG))])]
15760   ""
15761 {
15762   operands[1] = gen_reg_rtx (QImode);
15763   operands[2] = gen_reg_rtx (QImode);
15764 })
15765
15766 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15767 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15768
15769 (define_expand "cmpstrnqi_nz_1"
15770   [(parallel [(set (reg:CC FLAGS_REG)
15771                    (compare:CC (match_operand 4 "memory_operand" "")
15772                                (match_operand 5 "memory_operand" "")))
15773               (use (match_operand 2 "register_operand" ""))
15774               (use (match_operand:SI 3 "immediate_operand" ""))
15775               (clobber (match_operand 0 "register_operand" ""))
15776               (clobber (match_operand 1 "register_operand" ""))
15777               (clobber (match_dup 2))])]
15778   ""
15779   "ix86_current_function_needs_cld = 1;")
15780
15781 (define_insn "*cmpstrnqi_nz_1"
15782   [(set (reg:CC FLAGS_REG)
15783         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15784                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15785    (use (match_operand:P 6 "register_operand" "2"))
15786    (use (match_operand:SI 3 "immediate_operand" "i"))
15787    (clobber (match_operand:P 0 "register_operand" "=S"))
15788    (clobber (match_operand:P 1 "register_operand" "=D"))
15789    (clobber (match_operand:P 2 "register_operand" "=c"))]
15790   ""
15791   "repz{%;} cmpsb"
15792   [(set_attr "type" "str")
15793    (set_attr "mode" "QI")
15794    (set (attr "prefix_rex")
15795         (if_then_else
15796           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15797           (const_string "0")
15798           (const_string "*")))
15799    (set_attr "prefix_rep" "1")])
15800
15801 ;; The same, but the count is not known to not be zero.
15802
15803 (define_expand "cmpstrnqi_1"
15804   [(parallel [(set (reg:CC FLAGS_REG)
15805                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15806                                      (const_int 0))
15807                   (compare:CC (match_operand 4 "memory_operand" "")
15808                               (match_operand 5 "memory_operand" ""))
15809                   (const_int 0)))
15810               (use (match_operand:SI 3 "immediate_operand" ""))
15811               (use (reg:CC FLAGS_REG))
15812               (clobber (match_operand 0 "register_operand" ""))
15813               (clobber (match_operand 1 "register_operand" ""))
15814               (clobber (match_dup 2))])]
15815   ""
15816   "ix86_current_function_needs_cld = 1;")
15817
15818 (define_insn "*cmpstrnqi_1"
15819   [(set (reg:CC FLAGS_REG)
15820         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15821                              (const_int 0))
15822           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15823                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15824           (const_int 0)))
15825    (use (match_operand:SI 3 "immediate_operand" "i"))
15826    (use (reg:CC FLAGS_REG))
15827    (clobber (match_operand:P 0 "register_operand" "=S"))
15828    (clobber (match_operand:P 1 "register_operand" "=D"))
15829    (clobber (match_operand:P 2 "register_operand" "=c"))]
15830   ""
15831   "repz{%;} cmpsb"
15832   [(set_attr "type" "str")
15833    (set_attr "mode" "QI")
15834    (set (attr "prefix_rex")
15835         (if_then_else
15836           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15837           (const_string "0")
15838           (const_string "*")))
15839    (set_attr "prefix_rep" "1")])
15840
15841 (define_expand "strlen<mode>"
15842   [(set (match_operand:SWI48x 0 "register_operand" "")
15843         (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15844                         (match_operand:QI 2 "immediate_operand" "")
15845                         (match_operand 3 "immediate_operand" "")]
15846                        UNSPEC_SCAS))]
15847   ""
15848 {
15849  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15850    DONE;
15851  else
15852    FAIL;
15853 })
15854
15855 (define_expand "strlenqi_1"
15856   [(parallel [(set (match_operand 0 "register_operand" "")
15857                    (match_operand 2 "" ""))
15858               (clobber (match_operand 1 "register_operand" ""))
15859               (clobber (reg:CC FLAGS_REG))])]
15860   ""
15861   "ix86_current_function_needs_cld = 1;")
15862
15863 (define_insn "*strlenqi_1"
15864   [(set (match_operand:P 0 "register_operand" "=&c")
15865         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15866                    (match_operand:QI 2 "register_operand" "a")
15867                    (match_operand:P 3 "immediate_operand" "i")
15868                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15869    (clobber (match_operand:P 1 "register_operand" "=D"))
15870    (clobber (reg:CC FLAGS_REG))]
15871   ""
15872   "repnz{%;} scasb"
15873   [(set_attr "type" "str")
15874    (set_attr "mode" "QI")
15875    (set (attr "prefix_rex")
15876         (if_then_else
15877           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15878           (const_string "0")
15879           (const_string "*")))
15880    (set_attr "prefix_rep" "1")])
15881
15882 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15883 ;; handled in combine, but it is not currently up to the task.
15884 ;; When used for their truth value, the cmpstrn* expanders generate
15885 ;; code like this:
15886 ;;
15887 ;;   repz cmpsb
15888 ;;   seta       %al
15889 ;;   setb       %dl
15890 ;;   cmpb       %al, %dl
15891 ;;   jcc        label
15892 ;;
15893 ;; The intermediate three instructions are unnecessary.
15894
15895 ;; This one handles cmpstrn*_nz_1...
15896 (define_peephole2
15897   [(parallel[
15898      (set (reg:CC FLAGS_REG)
15899           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15900                       (mem:BLK (match_operand 5 "register_operand" ""))))
15901      (use (match_operand 6 "register_operand" ""))
15902      (use (match_operand:SI 3 "immediate_operand" ""))
15903      (clobber (match_operand 0 "register_operand" ""))
15904      (clobber (match_operand 1 "register_operand" ""))
15905      (clobber (match_operand 2 "register_operand" ""))])
15906    (set (match_operand:QI 7 "register_operand" "")
15907         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15908    (set (match_operand:QI 8 "register_operand" "")
15909         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15910    (set (reg FLAGS_REG)
15911         (compare (match_dup 7) (match_dup 8)))
15912   ]
15913   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15914   [(parallel[
15915      (set (reg:CC FLAGS_REG)
15916           (compare:CC (mem:BLK (match_dup 4))
15917                       (mem:BLK (match_dup 5))))
15918      (use (match_dup 6))
15919      (use (match_dup 3))
15920      (clobber (match_dup 0))
15921      (clobber (match_dup 1))
15922      (clobber (match_dup 2))])])
15923
15924 ;; ...and this one handles cmpstrn*_1.
15925 (define_peephole2
15926   [(parallel[
15927      (set (reg:CC FLAGS_REG)
15928           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15929                                (const_int 0))
15930             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15931                         (mem:BLK (match_operand 5 "register_operand" "")))
15932             (const_int 0)))
15933      (use (match_operand:SI 3 "immediate_operand" ""))
15934      (use (reg:CC FLAGS_REG))
15935      (clobber (match_operand 0 "register_operand" ""))
15936      (clobber (match_operand 1 "register_operand" ""))
15937      (clobber (match_operand 2 "register_operand" ""))])
15938    (set (match_operand:QI 7 "register_operand" "")
15939         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15940    (set (match_operand:QI 8 "register_operand" "")
15941         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15942    (set (reg FLAGS_REG)
15943         (compare (match_dup 7) (match_dup 8)))
15944   ]
15945   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15946   [(parallel[
15947      (set (reg:CC FLAGS_REG)
15948           (if_then_else:CC (ne (match_dup 6)
15949                                (const_int 0))
15950             (compare:CC (mem:BLK (match_dup 4))
15951                         (mem:BLK (match_dup 5)))
15952             (const_int 0)))
15953      (use (match_dup 3))
15954      (use (reg:CC FLAGS_REG))
15955      (clobber (match_dup 0))
15956      (clobber (match_dup 1))
15957      (clobber (match_dup 2))])])
15958 \f
15959 ;; Conditional move instructions.
15960
15961 (define_expand "mov<mode>cc"
15962   [(set (match_operand:SWIM 0 "register_operand" "")
15963         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15964                            (match_operand:SWIM 2 "general_operand" "")
15965                            (match_operand:SWIM 3 "general_operand" "")))]
15966   ""
15967   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15968
15969 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15970 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15971 ;; So just document what we're doing explicitly.
15972
15973 (define_expand "x86_mov<mode>cc_0_m1"
15974   [(parallel
15975     [(set (match_operand:SWI48 0 "register_operand" "")
15976           (if_then_else:SWI48
15977             (match_operator:SWI48 2 "ix86_carry_flag_operator"
15978              [(match_operand 1 "flags_reg_operand" "")
15979               (const_int 0)])
15980             (const_int -1)
15981             (const_int 0)))
15982      (clobber (reg:CC FLAGS_REG))])])
15983
15984 (define_insn "*x86_mov<mode>cc_0_m1"
15985   [(set (match_operand:SWI48 0 "register_operand" "=r")
15986         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15987                              [(reg FLAGS_REG) (const_int 0)])
15988           (const_int -1)
15989           (const_int 0)))
15990    (clobber (reg:CC FLAGS_REG))]
15991   ""
15992   "sbb{<imodesuffix>}\t%0, %0"
15993   ; Since we don't have the proper number of operands for an alu insn,
15994   ; fill in all the blanks.
15995   [(set_attr "type" "alu")
15996    (set_attr "use_carry" "1")
15997    (set_attr "pent_pair" "pu")
15998    (set_attr "memory" "none")
15999    (set_attr "imm_disp" "false")
16000    (set_attr "mode" "<MODE>")
16001    (set_attr "length_immediate" "0")])
16002
16003 (define_insn "*x86_mov<mode>cc_0_m1_se"
16004   [(set (match_operand:SWI48 0 "register_operand" "=r")
16005         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16006                              [(reg FLAGS_REG) (const_int 0)])
16007                             (const_int 1)
16008                             (const_int 0)))
16009    (clobber (reg:CC FLAGS_REG))]
16010   ""
16011   "sbb{<imodesuffix>}\t%0, %0"
16012   [(set_attr "type" "alu")
16013    (set_attr "use_carry" "1")
16014    (set_attr "pent_pair" "pu")
16015    (set_attr "memory" "none")
16016    (set_attr "imm_disp" "false")
16017    (set_attr "mode" "<MODE>")
16018    (set_attr "length_immediate" "0")])
16019
16020 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16021   [(set (match_operand:SWI48 0 "register_operand" "=r")
16022         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16023                     [(reg FLAGS_REG) (const_int 0)])))]
16024   ""
16025   "sbb{<imodesuffix>}\t%0, %0"
16026   [(set_attr "type" "alu")
16027    (set_attr "use_carry" "1")
16028    (set_attr "pent_pair" "pu")
16029    (set_attr "memory" "none")
16030    (set_attr "imm_disp" "false")
16031    (set_attr "mode" "<MODE>")
16032    (set_attr "length_immediate" "0")])
16033
16034 (define_insn "*mov<mode>cc_noc"
16035   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16036         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16037                                [(reg FLAGS_REG) (const_int 0)])
16038           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16039           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16040   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16041   "@
16042    cmov%O2%C1\t{%2, %0|%0, %2}
16043    cmov%O2%c1\t{%3, %0|%0, %3}"
16044   [(set_attr "type" "icmov")
16045    (set_attr "mode" "<MODE>")])
16046
16047 (define_insn_and_split "*movqicc_noc"
16048   [(set (match_operand:QI 0 "register_operand" "=r,r")
16049         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16050                            [(match_operand 4 "flags_reg_operand" "")
16051                             (const_int 0)])
16052                       (match_operand:QI 2 "register_operand" "r,0")
16053                       (match_operand:QI 3 "register_operand" "0,r")))]
16054   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16055   "#"
16056   "&& reload_completed"
16057   [(set (match_dup 0)
16058         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16059                       (match_dup 2)
16060                       (match_dup 3)))]
16061   "operands[0] = gen_lowpart (SImode, operands[0]);
16062    operands[2] = gen_lowpart (SImode, operands[2]);
16063    operands[3] = gen_lowpart (SImode, operands[3]);"
16064   [(set_attr "type" "icmov")
16065    (set_attr "mode" "SI")])
16066
16067 (define_expand "mov<mode>cc"
16068   [(set (match_operand:X87MODEF 0 "register_operand" "")
16069         (if_then_else:X87MODEF
16070           (match_operand 1 "ix86_fp_comparison_operator" "")
16071           (match_operand:X87MODEF 2 "register_operand" "")
16072           (match_operand:X87MODEF 3 "register_operand" "")))]
16073   "(TARGET_80387 && TARGET_CMOVE)
16074    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16075   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16076
16077 (define_insn "*movxfcc_1"
16078   [(set (match_operand:XF 0 "register_operand" "=f,f")
16079         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16080                                 [(reg FLAGS_REG) (const_int 0)])
16081                       (match_operand:XF 2 "register_operand" "f,0")
16082                       (match_operand:XF 3 "register_operand" "0,f")))]
16083   "TARGET_80387 && TARGET_CMOVE"
16084   "@
16085    fcmov%F1\t{%2, %0|%0, %2}
16086    fcmov%f1\t{%3, %0|%0, %3}"
16087   [(set_attr "type" "fcmov")
16088    (set_attr "mode" "XF")])
16089
16090 (define_insn "*movdfcc_1_rex64"
16091   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16092         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16093                                 [(reg FLAGS_REG) (const_int 0)])
16094                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16095                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16096   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16097    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16098   "@
16099    fcmov%F1\t{%2, %0|%0, %2}
16100    fcmov%f1\t{%3, %0|%0, %3}
16101    cmov%O2%C1\t{%2, %0|%0, %2}
16102    cmov%O2%c1\t{%3, %0|%0, %3}"
16103   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16104    (set_attr "mode" "DF,DF,DI,DI")])
16105
16106 (define_insn "*movdfcc_1"
16107   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16108         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16109                                 [(reg FLAGS_REG) (const_int 0)])
16110                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16111                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16112   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16113    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16114   "@
16115    fcmov%F1\t{%2, %0|%0, %2}
16116    fcmov%f1\t{%3, %0|%0, %3}
16117    #
16118    #"
16119   [(set_attr "type" "fcmov,fcmov,multi,multi")
16120    (set_attr "mode" "DF,DF,DI,DI")])
16121
16122 (define_split
16123   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16124         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16125                                 [(match_operand 4 "flags_reg_operand" "")
16126                                  (const_int 0)])
16127                       (match_operand:DF 2 "nonimmediate_operand" "")
16128                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16129   "!TARGET_64BIT && reload_completed"
16130   [(set (match_dup 2)
16131         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16132                       (match_dup 5)
16133                       (match_dup 6)))
16134    (set (match_dup 3)
16135         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16136                       (match_dup 7)
16137                       (match_dup 8)))]
16138 {
16139   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16140   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16141 })
16142
16143 (define_insn "*movsfcc_1_387"
16144   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16145         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16146                                 [(reg FLAGS_REG) (const_int 0)])
16147                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16148                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16149   "TARGET_80387 && TARGET_CMOVE
16150    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16151   "@
16152    fcmov%F1\t{%2, %0|%0, %2}
16153    fcmov%f1\t{%3, %0|%0, %3}
16154    cmov%O2%C1\t{%2, %0|%0, %2}
16155    cmov%O2%c1\t{%3, %0|%0, %3}"
16156   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16157    (set_attr "mode" "SF,SF,SI,SI")])
16158
16159 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16160 ;; the scalar versions to have only XMM registers as operands.
16161
16162 ;; XOP conditional move
16163 (define_insn "*xop_pcmov_<mode>"
16164   [(set (match_operand:MODEF 0 "register_operand" "=x")
16165         (if_then_else:MODEF
16166           (match_operand:MODEF 1 "register_operand" "x")
16167           (match_operand:MODEF 2 "register_operand" "x")
16168           (match_operand:MODEF 3 "register_operand" "x")))]
16169   "TARGET_XOP"
16170   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16171   [(set_attr "type" "sse4arg")])
16172
16173 ;; These versions of the min/max patterns are intentionally ignorant of
16174 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16175 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16176 ;; are undefined in this condition, we're certain this is correct.
16177
16178 (define_insn "<code><mode>3"
16179   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16180         (smaxmin:MODEF
16181           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16182           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16183   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16184   "@
16185    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16186    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16187   [(set_attr "isa" "noavx,avx")
16188    (set_attr "prefix" "orig,vex")
16189    (set_attr "type" "sseadd")
16190    (set_attr "mode" "<MODE>")])
16191
16192 ;; These versions of the min/max patterns implement exactly the operations
16193 ;;   min = (op1 < op2 ? op1 : op2)
16194 ;;   max = (!(op1 < op2) ? op1 : op2)
16195 ;; Their operands are not commutative, and thus they may be used in the
16196 ;; presence of -0.0 and NaN.
16197
16198 (define_insn "*ieee_smin<mode>3"
16199   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16200         (unspec:MODEF
16201           [(match_operand:MODEF 1 "register_operand" "0,x")
16202            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16203          UNSPEC_IEEE_MIN))]
16204   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16205   "@
16206    min<ssemodesuffix>\t{%2, %0|%0, %2}
16207    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16208   [(set_attr "isa" "noavx,avx")
16209    (set_attr "prefix" "orig,vex")
16210    (set_attr "type" "sseadd")
16211    (set_attr "mode" "<MODE>")])
16212
16213 (define_insn "*ieee_smax<mode>3"
16214   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16215         (unspec:MODEF
16216           [(match_operand:MODEF 1 "register_operand" "0,x")
16217            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16218          UNSPEC_IEEE_MAX))]
16219   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16220   "@
16221    max<ssemodesuffix>\t{%2, %0|%0, %2}
16222    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16223   [(set_attr "isa" "noavx,avx")
16224    (set_attr "prefix" "orig,vex")
16225    (set_attr "type" "sseadd")
16226    (set_attr "mode" "<MODE>")])
16227
16228 ;; Make two stack loads independent:
16229 ;;   fld aa              fld aa
16230 ;;   fld %st(0)     ->   fld bb
16231 ;;   fmul bb             fmul %st(1), %st
16232 ;;
16233 ;; Actually we only match the last two instructions for simplicity.
16234 (define_peephole2
16235   [(set (match_operand 0 "fp_register_operand" "")
16236         (match_operand 1 "fp_register_operand" ""))
16237    (set (match_dup 0)
16238         (match_operator 2 "binary_fp_operator"
16239            [(match_dup 0)
16240             (match_operand 3 "memory_operand" "")]))]
16241   "REGNO (operands[0]) != REGNO (operands[1])"
16242   [(set (match_dup 0) (match_dup 3))
16243    (set (match_dup 0) (match_dup 4))]
16244
16245   ;; The % modifier is not operational anymore in peephole2's, so we have to
16246   ;; swap the operands manually in the case of addition and multiplication.
16247   "if (COMMUTATIVE_ARITH_P (operands[2]))
16248      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16249                                    GET_MODE (operands[2]),
16250                                    operands[0], operands[1]);
16251    else
16252      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16253                                    GET_MODE (operands[2]),
16254                                    operands[1], operands[0]);")
16255
16256 ;; Conditional addition patterns
16257 (define_expand "add<mode>cc"
16258   [(match_operand:SWI 0 "register_operand" "")
16259    (match_operand 1 "ordered_comparison_operator" "")
16260    (match_operand:SWI 2 "register_operand" "")
16261    (match_operand:SWI 3 "const_int_operand" "")]
16262   ""
16263   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16264 \f
16265 ;; Misc patterns (?)
16266
16267 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16268 ;; Otherwise there will be nothing to keep
16269 ;;
16270 ;; [(set (reg ebp) (reg esp))]
16271 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16272 ;;  (clobber (eflags)]
16273 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16274 ;;
16275 ;; in proper program order.
16276
16277 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16278   [(set (match_operand:P 0 "register_operand" "=r,r")
16279         (plus:P (match_operand:P 1 "register_operand" "0,r")
16280                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16281    (clobber (reg:CC FLAGS_REG))
16282    (clobber (mem:BLK (scratch)))]
16283   ""
16284 {
16285   switch (get_attr_type (insn))
16286     {
16287     case TYPE_IMOV:
16288       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16289
16290     case TYPE_ALU:
16291       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16292       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16293         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16294
16295       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16296
16297     default:
16298       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16299       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16300     }
16301 }
16302   [(set (attr "type")
16303         (cond [(and (eq_attr "alternative" "0")
16304                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16305                  (const_string "alu")
16306                (match_operand:<MODE> 2 "const0_operand" "")
16307                  (const_string "imov")
16308               ]
16309               (const_string "lea")))
16310    (set (attr "length_immediate")
16311         (cond [(eq_attr "type" "imov")
16312                  (const_string "0")
16313                (and (eq_attr "type" "alu")
16314                     (match_operand 2 "const128_operand" ""))
16315                  (const_string "1")
16316               ]
16317               (const_string "*")))
16318    (set_attr "mode" "<MODE>")])
16319
16320 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16321   [(set (match_operand:P 0 "register_operand" "=r")
16322         (minus:P (match_operand:P 1 "register_operand" "0")
16323                  (match_operand:P 2 "register_operand" "r")))
16324    (clobber (reg:CC FLAGS_REG))
16325    (clobber (mem:BLK (scratch)))]
16326   ""
16327   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16328   [(set_attr "type" "alu")
16329    (set_attr "mode" "<MODE>")])
16330
16331 (define_insn "allocate_stack_worker_probe_<mode>"
16332   [(set (match_operand:P 0 "register_operand" "=a")
16333         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16334                             UNSPECV_STACK_PROBE))
16335    (clobber (reg:CC FLAGS_REG))]
16336   "ix86_target_stack_probe ()"
16337   "call\t___chkstk_ms"
16338   [(set_attr "type" "multi")
16339    (set_attr "length" "5")])
16340
16341 (define_expand "allocate_stack"
16342   [(match_operand 0 "register_operand" "")
16343    (match_operand 1 "general_operand" "")]
16344   "ix86_target_stack_probe ()"
16345 {
16346   rtx x;
16347
16348 #ifndef CHECK_STACK_LIMIT
16349 #define CHECK_STACK_LIMIT 0
16350 #endif
16351
16352   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16353       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16354     {
16355       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16356                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16357       if (x != stack_pointer_rtx)
16358         emit_move_insn (stack_pointer_rtx, x);
16359     }
16360   else
16361     {
16362       x = copy_to_mode_reg (Pmode, operands[1]);
16363       if (TARGET_64BIT)
16364         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16365       else
16366         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16367       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16368                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16369       if (x != stack_pointer_rtx)
16370         emit_move_insn (stack_pointer_rtx, x);
16371     }
16372
16373   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16374   DONE;
16375 })
16376
16377 ;; Use IOR for stack probes, this is shorter.
16378 (define_expand "probe_stack"
16379   [(match_operand 0 "memory_operand" "")]
16380   ""
16381 {
16382   rtx (*gen_ior3) (rtx, rtx, rtx);
16383
16384   gen_ior3 = (GET_MODE (operands[0]) == DImode
16385               ? gen_iordi3 : gen_iorsi3);
16386
16387   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16388   DONE;
16389 })
16390
16391 (define_insn "adjust_stack_and_probe<mode>"
16392   [(set (match_operand:P 0 "register_operand" "=r")
16393         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16394                             UNSPECV_PROBE_STACK_RANGE))
16395    (set (reg:P SP_REG)
16396         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16397    (clobber (reg:CC FLAGS_REG))
16398    (clobber (mem:BLK (scratch)))]
16399   ""
16400   "* return output_adjust_stack_and_probe (operands[0]);"
16401   [(set_attr "type" "multi")])
16402
16403 (define_insn "probe_stack_range<mode>"
16404   [(set (match_operand:P 0 "register_operand" "=r")
16405         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16406                             (match_operand:P 2 "const_int_operand" "n")]
16407                             UNSPECV_PROBE_STACK_RANGE))
16408    (clobber (reg:CC FLAGS_REG))]
16409   ""
16410   "* return output_probe_stack_range (operands[0], operands[2]);"
16411   [(set_attr "type" "multi")])
16412
16413 (define_expand "builtin_setjmp_receiver"
16414   [(label_ref (match_operand 0 "" ""))]
16415   "!TARGET_64BIT && flag_pic"
16416 {
16417 #if TARGET_MACHO
16418   if (TARGET_MACHO)
16419     {
16420       rtx xops[3];
16421       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16422       rtx label_rtx = gen_label_rtx ();
16423       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16424       xops[0] = xops[1] = picreg;
16425       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16426       ix86_expand_binary_operator (MINUS, SImode, xops);
16427     }
16428   else
16429 #endif
16430     emit_insn (gen_set_got (pic_offset_table_rtx));
16431   DONE;
16432 })
16433 \f
16434 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16435
16436 (define_split
16437   [(set (match_operand 0 "register_operand" "")
16438         (match_operator 3 "promotable_binary_operator"
16439            [(match_operand 1 "register_operand" "")
16440             (match_operand 2 "aligned_operand" "")]))
16441    (clobber (reg:CC FLAGS_REG))]
16442   "! TARGET_PARTIAL_REG_STALL && reload_completed
16443    && ((GET_MODE (operands[0]) == HImode
16444         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16445             /* ??? next two lines just !satisfies_constraint_K (...) */
16446             || !CONST_INT_P (operands[2])
16447             || satisfies_constraint_K (operands[2])))
16448        || (GET_MODE (operands[0]) == QImode
16449            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16450   [(parallel [(set (match_dup 0)
16451                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16452               (clobber (reg:CC FLAGS_REG))])]
16453   "operands[0] = gen_lowpart (SImode, operands[0]);
16454    operands[1] = gen_lowpart (SImode, operands[1]);
16455    if (GET_CODE (operands[3]) != ASHIFT)
16456      operands[2] = gen_lowpart (SImode, operands[2]);
16457    PUT_MODE (operands[3], SImode);")
16458
16459 ; Promote the QImode tests, as i386 has encoding of the AND
16460 ; instruction with 32-bit sign-extended immediate and thus the
16461 ; instruction size is unchanged, except in the %eax case for
16462 ; which it is increased by one byte, hence the ! optimize_size.
16463 (define_split
16464   [(set (match_operand 0 "flags_reg_operand" "")
16465         (match_operator 2 "compare_operator"
16466           [(and (match_operand 3 "aligned_operand" "")
16467                 (match_operand 4 "const_int_operand" ""))
16468            (const_int 0)]))
16469    (set (match_operand 1 "register_operand" "")
16470         (and (match_dup 3) (match_dup 4)))]
16471   "! TARGET_PARTIAL_REG_STALL && reload_completed
16472    && optimize_insn_for_speed_p ()
16473    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16474        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16475    /* Ensure that the operand will remain sign-extended immediate.  */
16476    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16477   [(parallel [(set (match_dup 0)
16478                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16479                                     (const_int 0)]))
16480               (set (match_dup 1)
16481                    (and:SI (match_dup 3) (match_dup 4)))])]
16482 {
16483   operands[4]
16484     = gen_int_mode (INTVAL (operands[4])
16485                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16486   operands[1] = gen_lowpart (SImode, operands[1]);
16487   operands[3] = gen_lowpart (SImode, operands[3]);
16488 })
16489
16490 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16491 ; the TEST instruction with 32-bit sign-extended immediate and thus
16492 ; the instruction size would at least double, which is not what we
16493 ; want even with ! optimize_size.
16494 (define_split
16495   [(set (match_operand 0 "flags_reg_operand" "")
16496         (match_operator 1 "compare_operator"
16497           [(and (match_operand:HI 2 "aligned_operand" "")
16498                 (match_operand:HI 3 "const_int_operand" ""))
16499            (const_int 0)]))]
16500   "! TARGET_PARTIAL_REG_STALL && reload_completed
16501    && ! TARGET_FAST_PREFIX
16502    && optimize_insn_for_speed_p ()
16503    /* Ensure that the operand will remain sign-extended immediate.  */
16504    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16505   [(set (match_dup 0)
16506         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16507                          (const_int 0)]))]
16508 {
16509   operands[3]
16510     = gen_int_mode (INTVAL (operands[3])
16511                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16512   operands[2] = gen_lowpart (SImode, operands[2]);
16513 })
16514
16515 (define_split
16516   [(set (match_operand 0 "register_operand" "")
16517         (neg (match_operand 1 "register_operand" "")))
16518    (clobber (reg:CC FLAGS_REG))]
16519   "! TARGET_PARTIAL_REG_STALL && reload_completed
16520    && (GET_MODE (operands[0]) == HImode
16521        || (GET_MODE (operands[0]) == QImode
16522            && (TARGET_PROMOTE_QImode
16523                || optimize_insn_for_size_p ())))"
16524   [(parallel [(set (match_dup 0)
16525                    (neg:SI (match_dup 1)))
16526               (clobber (reg:CC FLAGS_REG))])]
16527   "operands[0] = gen_lowpart (SImode, operands[0]);
16528    operands[1] = gen_lowpart (SImode, operands[1]);")
16529
16530 (define_split
16531   [(set (match_operand 0 "register_operand" "")
16532         (not (match_operand 1 "register_operand" "")))]
16533   "! TARGET_PARTIAL_REG_STALL && reload_completed
16534    && (GET_MODE (operands[0]) == HImode
16535        || (GET_MODE (operands[0]) == QImode
16536            && (TARGET_PROMOTE_QImode
16537                || optimize_insn_for_size_p ())))"
16538   [(set (match_dup 0)
16539         (not:SI (match_dup 1)))]
16540   "operands[0] = gen_lowpart (SImode, operands[0]);
16541    operands[1] = gen_lowpart (SImode, operands[1]);")
16542
16543 (define_split
16544   [(set (match_operand 0 "register_operand" "")
16545         (if_then_else (match_operator 1 "ordered_comparison_operator"
16546                                 [(reg FLAGS_REG) (const_int 0)])
16547                       (match_operand 2 "register_operand" "")
16548                       (match_operand 3 "register_operand" "")))]
16549   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16550    && (GET_MODE (operands[0]) == HImode
16551        || (GET_MODE (operands[0]) == QImode
16552            && (TARGET_PROMOTE_QImode
16553                || optimize_insn_for_size_p ())))"
16554   [(set (match_dup 0)
16555         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16556   "operands[0] = gen_lowpart (SImode, operands[0]);
16557    operands[2] = gen_lowpart (SImode, operands[2]);
16558    operands[3] = gen_lowpart (SImode, operands[3]);")
16559 \f
16560 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16561 ;; transform a complex memory operation into two memory to register operations.
16562
16563 ;; Don't push memory operands
16564 (define_peephole2
16565   [(set (match_operand:SWI 0 "push_operand" "")
16566         (match_operand:SWI 1 "memory_operand" ""))
16567    (match_scratch:SWI 2 "<r>")]
16568   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16569    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16570   [(set (match_dup 2) (match_dup 1))
16571    (set (match_dup 0) (match_dup 2))])
16572
16573 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16574 ;; SImode pushes.
16575 (define_peephole2
16576   [(set (match_operand:SF 0 "push_operand" "")
16577         (match_operand:SF 1 "memory_operand" ""))
16578    (match_scratch:SF 2 "r")]
16579   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16580    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16581   [(set (match_dup 2) (match_dup 1))
16582    (set (match_dup 0) (match_dup 2))])
16583
16584 ;; Don't move an immediate directly to memory when the instruction
16585 ;; gets too big.
16586 (define_peephole2
16587   [(match_scratch:SWI124 1 "<r>")
16588    (set (match_operand:SWI124 0 "memory_operand" "")
16589         (const_int 0))]
16590   "optimize_insn_for_speed_p ()
16591    && !TARGET_USE_MOV0
16592    && TARGET_SPLIT_LONG_MOVES
16593    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16594    && peep2_regno_dead_p (0, FLAGS_REG)"
16595   [(parallel [(set (match_dup 2) (const_int 0))
16596               (clobber (reg:CC FLAGS_REG))])
16597    (set (match_dup 0) (match_dup 1))]
16598   "operands[2] = gen_lowpart (SImode, operands[1]);")
16599
16600 (define_peephole2
16601   [(match_scratch:SWI124 2 "<r>")
16602    (set (match_operand:SWI124 0 "memory_operand" "")
16603         (match_operand:SWI124 1 "immediate_operand" ""))]
16604   "optimize_insn_for_speed_p ()
16605    && TARGET_SPLIT_LONG_MOVES
16606    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16607   [(set (match_dup 2) (match_dup 1))
16608    (set (match_dup 0) (match_dup 2))])
16609
16610 ;; Don't compare memory with zero, load and use a test instead.
16611 (define_peephole2
16612   [(set (match_operand 0 "flags_reg_operand" "")
16613         (match_operator 1 "compare_operator"
16614           [(match_operand:SI 2 "memory_operand" "")
16615            (const_int 0)]))
16616    (match_scratch:SI 3 "r")]
16617   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16618   [(set (match_dup 3) (match_dup 2))
16619    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16620
16621 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16622 ;; Don't split NOTs with a displacement operand, because resulting XOR
16623 ;; will not be pairable anyway.
16624 ;;
16625 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16626 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16627 ;; so this split helps here as well.
16628 ;;
16629 ;; Note: Can't do this as a regular split because we can't get proper
16630 ;; lifetime information then.
16631
16632 (define_peephole2
16633   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16634         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16635   "optimize_insn_for_speed_p ()
16636    && ((TARGET_NOT_UNPAIRABLE
16637         && (!MEM_P (operands[0])
16638             || !memory_displacement_operand (operands[0], <MODE>mode)))
16639        || (TARGET_NOT_VECTORMODE
16640            && long_memory_operand (operands[0], <MODE>mode)))
16641    && peep2_regno_dead_p (0, FLAGS_REG)"
16642   [(parallel [(set (match_dup 0)
16643                    (xor:SWI124 (match_dup 1) (const_int -1)))
16644               (clobber (reg:CC FLAGS_REG))])])
16645
16646 ;; Non pairable "test imm, reg" instructions can be translated to
16647 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16648 ;; byte opcode instead of two, have a short form for byte operands),
16649 ;; so do it for other CPUs as well.  Given that the value was dead,
16650 ;; this should not create any new dependencies.  Pass on the sub-word
16651 ;; versions if we're concerned about partial register stalls.
16652
16653 (define_peephole2
16654   [(set (match_operand 0 "flags_reg_operand" "")
16655         (match_operator 1 "compare_operator"
16656           [(and:SI (match_operand:SI 2 "register_operand" "")
16657                    (match_operand:SI 3 "immediate_operand" ""))
16658            (const_int 0)]))]
16659   "ix86_match_ccmode (insn, CCNOmode)
16660    && (true_regnum (operands[2]) != AX_REG
16661        || satisfies_constraint_K (operands[3]))
16662    && peep2_reg_dead_p (1, operands[2])"
16663   [(parallel
16664      [(set (match_dup 0)
16665            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16666                             (const_int 0)]))
16667       (set (match_dup 2)
16668            (and:SI (match_dup 2) (match_dup 3)))])])
16669
16670 ;; We don't need to handle HImode case, because it will be promoted to SImode
16671 ;; on ! TARGET_PARTIAL_REG_STALL
16672
16673 (define_peephole2
16674   [(set (match_operand 0 "flags_reg_operand" "")
16675         (match_operator 1 "compare_operator"
16676           [(and:QI (match_operand:QI 2 "register_operand" "")
16677                    (match_operand:QI 3 "immediate_operand" ""))
16678            (const_int 0)]))]
16679   "! TARGET_PARTIAL_REG_STALL
16680    && ix86_match_ccmode (insn, CCNOmode)
16681    && true_regnum (operands[2]) != AX_REG
16682    && peep2_reg_dead_p (1, operands[2])"
16683   [(parallel
16684      [(set (match_dup 0)
16685            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16686                             (const_int 0)]))
16687       (set (match_dup 2)
16688            (and:QI (match_dup 2) (match_dup 3)))])])
16689
16690 (define_peephole2
16691   [(set (match_operand 0 "flags_reg_operand" "")
16692         (match_operator 1 "compare_operator"
16693           [(and:SI
16694              (zero_extract:SI
16695                (match_operand 2 "ext_register_operand" "")
16696                (const_int 8)
16697                (const_int 8))
16698              (match_operand 3 "const_int_operand" ""))
16699            (const_int 0)]))]
16700   "! TARGET_PARTIAL_REG_STALL
16701    && ix86_match_ccmode (insn, CCNOmode)
16702    && true_regnum (operands[2]) != AX_REG
16703    && peep2_reg_dead_p (1, operands[2])"
16704   [(parallel [(set (match_dup 0)
16705                    (match_op_dup 1
16706                      [(and:SI
16707                         (zero_extract:SI
16708                           (match_dup 2)
16709                           (const_int 8)
16710                           (const_int 8))
16711                         (match_dup 3))
16712                       (const_int 0)]))
16713               (set (zero_extract:SI (match_dup 2)
16714                                     (const_int 8)
16715                                     (const_int 8))
16716                    (and:SI
16717                      (zero_extract:SI
16718                        (match_dup 2)
16719                        (const_int 8)
16720                        (const_int 8))
16721                      (match_dup 3)))])])
16722
16723 ;; Don't do logical operations with memory inputs.
16724 (define_peephole2
16725   [(match_scratch:SI 2 "r")
16726    (parallel [(set (match_operand:SI 0 "register_operand" "")
16727                    (match_operator:SI 3 "arith_or_logical_operator"
16728                      [(match_dup 0)
16729                       (match_operand:SI 1 "memory_operand" "")]))
16730               (clobber (reg:CC FLAGS_REG))])]
16731   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16732   [(set (match_dup 2) (match_dup 1))
16733    (parallel [(set (match_dup 0)
16734                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16735               (clobber (reg:CC FLAGS_REG))])])
16736
16737 (define_peephole2
16738   [(match_scratch:SI 2 "r")
16739    (parallel [(set (match_operand:SI 0 "register_operand" "")
16740                    (match_operator:SI 3 "arith_or_logical_operator"
16741                      [(match_operand:SI 1 "memory_operand" "")
16742                       (match_dup 0)]))
16743               (clobber (reg:CC FLAGS_REG))])]
16744   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16745   [(set (match_dup 2) (match_dup 1))
16746    (parallel [(set (match_dup 0)
16747                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16748               (clobber (reg:CC FLAGS_REG))])])
16749
16750 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16751 ;; refers to the destination of the load!
16752
16753 (define_peephole2
16754   [(set (match_operand:SI 0 "register_operand" "")
16755         (match_operand:SI 1 "register_operand" ""))
16756    (parallel [(set (match_dup 0)
16757                    (match_operator:SI 3 "commutative_operator"
16758                      [(match_dup 0)
16759                       (match_operand:SI 2 "memory_operand" "")]))
16760               (clobber (reg:CC FLAGS_REG))])]
16761   "REGNO (operands[0]) != REGNO (operands[1])
16762    && GENERAL_REGNO_P (REGNO (operands[0]))
16763    && GENERAL_REGNO_P (REGNO (operands[1]))"
16764   [(set (match_dup 0) (match_dup 4))
16765    (parallel [(set (match_dup 0)
16766                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16767               (clobber (reg:CC FLAGS_REG))])]
16768   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16769
16770 (define_peephole2
16771   [(set (match_operand 0 "register_operand" "")
16772         (match_operand 1 "register_operand" ""))
16773    (set (match_dup 0)
16774                    (match_operator 3 "commutative_operator"
16775                      [(match_dup 0)
16776                       (match_operand 2 "memory_operand" "")]))]
16777   "REGNO (operands[0]) != REGNO (operands[1])
16778    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16779        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16780   [(set (match_dup 0) (match_dup 2))
16781    (set (match_dup 0)
16782         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16783
16784 ; Don't do logical operations with memory outputs
16785 ;
16786 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16787 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16788 ; the same decoder scheduling characteristics as the original.
16789
16790 (define_peephole2
16791   [(match_scratch:SI 2 "r")
16792    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16793                    (match_operator:SI 3 "arith_or_logical_operator"
16794                      [(match_dup 0)
16795                       (match_operand:SI 1 "nonmemory_operand" "")]))
16796               (clobber (reg:CC FLAGS_REG))])]
16797   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16798    /* Do not split stack checking probes.  */
16799    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16800   [(set (match_dup 2) (match_dup 0))
16801    (parallel [(set (match_dup 2)
16802                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16803               (clobber (reg:CC FLAGS_REG))])
16804    (set (match_dup 0) (match_dup 2))])
16805
16806 (define_peephole2
16807   [(match_scratch:SI 2 "r")
16808    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16809                    (match_operator:SI 3 "arith_or_logical_operator"
16810                      [(match_operand:SI 1 "nonmemory_operand" "")
16811                       (match_dup 0)]))
16812               (clobber (reg:CC FLAGS_REG))])]
16813   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16814    /* Do not split stack checking probes.  */
16815    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16816   [(set (match_dup 2) (match_dup 0))
16817    (parallel [(set (match_dup 2)
16818                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16819               (clobber (reg:CC FLAGS_REG))])
16820    (set (match_dup 0) (match_dup 2))])
16821
16822 ;; Attempt to always use XOR for zeroing registers.
16823 (define_peephole2
16824   [(set (match_operand 0 "register_operand" "")
16825         (match_operand 1 "const0_operand" ""))]
16826   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16827    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16828    && GENERAL_REG_P (operands[0])
16829    && peep2_regno_dead_p (0, FLAGS_REG)"
16830   [(parallel [(set (match_dup 0) (const_int 0))
16831               (clobber (reg:CC FLAGS_REG))])]
16832   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16833
16834 (define_peephole2
16835   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16836         (const_int 0))]
16837   "(GET_MODE (operands[0]) == QImode
16838     || GET_MODE (operands[0]) == HImode)
16839    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16840    && peep2_regno_dead_p (0, FLAGS_REG)"
16841   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16842               (clobber (reg:CC FLAGS_REG))])])
16843
16844 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16845 (define_peephole2
16846   [(set (match_operand:SWI248 0 "register_operand" "")
16847         (const_int -1))]
16848   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16849    && peep2_regno_dead_p (0, FLAGS_REG)"
16850   [(parallel [(set (match_dup 0) (const_int -1))
16851               (clobber (reg:CC FLAGS_REG))])]
16852 {
16853   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16854     operands[0] = gen_lowpart (SImode, operands[0]);
16855 })
16856
16857 ;; Attempt to convert simple lea to add/shift.
16858 ;; These can be created by move expanders.
16859
16860 (define_peephole2
16861   [(set (match_operand:SWI48 0 "register_operand" "")
16862         (plus:SWI48 (match_dup 0)
16863                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16864   "peep2_regno_dead_p (0, FLAGS_REG)"
16865   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16866               (clobber (reg:CC FLAGS_REG))])])
16867
16868 (define_peephole2
16869   [(set (match_operand:SI 0 "register_operand" "")
16870         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16871                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16872   "TARGET_64BIT
16873    && peep2_regno_dead_p (0, FLAGS_REG)
16874    && REGNO (operands[0]) == REGNO (operands[1])"
16875   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16876               (clobber (reg:CC FLAGS_REG))])]
16877   "operands[2] = gen_lowpart (SImode, operands[2]);")
16878
16879 (define_peephole2
16880   [(set (match_operand:SWI48 0 "register_operand" "")
16881         (mult:SWI48 (match_dup 0)
16882                     (match_operand:SWI48 1 "const_int_operand" "")))]
16883   "exact_log2 (INTVAL (operands[1])) >= 0
16884    && peep2_regno_dead_p (0, FLAGS_REG)"
16885   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16886               (clobber (reg:CC FLAGS_REG))])]
16887   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16888
16889 (define_peephole2
16890   [(set (match_operand:SI 0 "register_operand" "")
16891         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16892                    (match_operand:DI 2 "const_int_operand" "")) 0))]
16893   "TARGET_64BIT
16894    && exact_log2 (INTVAL (operands[2])) >= 0
16895    && REGNO (operands[0]) == REGNO (operands[1])
16896    && peep2_regno_dead_p (0, FLAGS_REG)"
16897   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16898               (clobber (reg:CC FLAGS_REG))])]
16899   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16900
16901 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16902 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16903 ;; On many CPUs it is also faster, since special hardware to avoid esp
16904 ;; dependencies is present.
16905
16906 ;; While some of these conversions may be done using splitters, we use
16907 ;; peepholes in order to allow combine_stack_adjustments pass to see
16908 ;; nonobfuscated RTL.
16909
16910 ;; Convert prologue esp subtractions to push.
16911 ;; We need register to push.  In order to keep verify_flow_info happy we have
16912 ;; two choices
16913 ;; - use scratch and clobber it in order to avoid dependencies
16914 ;; - use already live register
16915 ;; We can't use the second way right now, since there is no reliable way how to
16916 ;; verify that given register is live.  First choice will also most likely in
16917 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16918 ;; call clobbered registers are dead.  We may want to use base pointer as an
16919 ;; alternative when no register is available later.
16920
16921 (define_peephole2
16922   [(match_scratch:P 1 "r")
16923    (parallel [(set (reg:P SP_REG)
16924                    (plus:P (reg:P SP_REG)
16925                            (match_operand:P 0 "const_int_operand" "")))
16926               (clobber (reg:CC FLAGS_REG))
16927               (clobber (mem:BLK (scratch)))])]
16928   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16929    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16930   [(clobber (match_dup 1))
16931    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16932               (clobber (mem:BLK (scratch)))])])
16933
16934 (define_peephole2
16935   [(match_scratch:P 1 "r")
16936    (parallel [(set (reg:P SP_REG)
16937                    (plus:P (reg:P SP_REG)
16938                            (match_operand:P 0 "const_int_operand" "")))
16939               (clobber (reg:CC FLAGS_REG))
16940               (clobber (mem:BLK (scratch)))])]
16941   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16942    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16943   [(clobber (match_dup 1))
16944    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16945    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16946               (clobber (mem:BLK (scratch)))])])
16947
16948 ;; Convert esp subtractions to push.
16949 (define_peephole2
16950   [(match_scratch:P 1 "r")
16951    (parallel [(set (reg:P SP_REG)
16952                    (plus:P (reg:P SP_REG)
16953                            (match_operand:P 0 "const_int_operand" "")))
16954               (clobber (reg:CC FLAGS_REG))])]
16955   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16956    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16957   [(clobber (match_dup 1))
16958    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16959
16960 (define_peephole2
16961   [(match_scratch:P 1 "r")
16962    (parallel [(set (reg:P SP_REG)
16963                    (plus:P (reg:P SP_REG)
16964                            (match_operand:P 0 "const_int_operand" "")))
16965               (clobber (reg:CC FLAGS_REG))])]
16966   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16967    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16968   [(clobber (match_dup 1))
16969    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16970    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16971
16972 ;; Convert epilogue deallocator to pop.
16973 (define_peephole2
16974   [(match_scratch:P 1 "r")
16975    (parallel [(set (reg:P SP_REG)
16976                    (plus:P (reg:P SP_REG)
16977                            (match_operand:P 0 "const_int_operand" "")))
16978               (clobber (reg:CC FLAGS_REG))
16979               (clobber (mem:BLK (scratch)))])]
16980   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16981    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16982   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16983               (clobber (mem:BLK (scratch)))])])
16984
16985 ;; Two pops case is tricky, since pop causes dependency
16986 ;; on destination register.  We use two registers if available.
16987 (define_peephole2
16988   [(match_scratch:P 1 "r")
16989    (match_scratch:P 2 "r")
16990    (parallel [(set (reg:P SP_REG)
16991                    (plus:P (reg:P SP_REG)
16992                            (match_operand:P 0 "const_int_operand" "")))
16993               (clobber (reg:CC FLAGS_REG))
16994               (clobber (mem:BLK (scratch)))])]
16995   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16996    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16997   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16998               (clobber (mem:BLK (scratch)))])
16999    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17000
17001 (define_peephole2
17002   [(match_scratch:P 1 "r")
17003    (parallel [(set (reg:P SP_REG)
17004                    (plus:P (reg:P SP_REG)
17005                            (match_operand:P 0 "const_int_operand" "")))
17006               (clobber (reg:CC FLAGS_REG))
17007               (clobber (mem:BLK (scratch)))])]
17008   "optimize_insn_for_size_p ()
17009    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17010   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17011               (clobber (mem:BLK (scratch)))])
17012    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17013
17014 ;; Convert esp additions to pop.
17015 (define_peephole2
17016   [(match_scratch:P 1 "r")
17017    (parallel [(set (reg:P SP_REG)
17018                    (plus:P (reg:P SP_REG)
17019                            (match_operand:P 0 "const_int_operand" "")))
17020               (clobber (reg:CC FLAGS_REG))])]
17021   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17022   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17023
17024 ;; Two pops case is tricky, since pop causes dependency
17025 ;; on destination register.  We use two registers if available.
17026 (define_peephole2
17027   [(match_scratch:P 1 "r")
17028    (match_scratch:P 2 "r")
17029    (parallel [(set (reg:P SP_REG)
17030                    (plus:P (reg:P SP_REG)
17031                            (match_operand:P 0 "const_int_operand" "")))
17032               (clobber (reg:CC FLAGS_REG))])]
17033   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17034   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17035    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17036
17037 (define_peephole2
17038   [(match_scratch:P 1 "r")
17039    (parallel [(set (reg:P SP_REG)
17040                    (plus:P (reg:P SP_REG)
17041                            (match_operand:P 0 "const_int_operand" "")))
17042               (clobber (reg:CC FLAGS_REG))])]
17043   "optimize_insn_for_size_p ()
17044    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17045   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17046    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17047 \f
17048 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17049 ;; required and register dies.  Similarly for 128 to -128.
17050 (define_peephole2
17051   [(set (match_operand 0 "flags_reg_operand" "")
17052         (match_operator 1 "compare_operator"
17053           [(match_operand 2 "register_operand" "")
17054            (match_operand 3 "const_int_operand" "")]))]
17055   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17056      && incdec_operand (operands[3], GET_MODE (operands[3])))
17057     || (!TARGET_FUSE_CMP_AND_BRANCH
17058         && INTVAL (operands[3]) == 128))
17059    && ix86_match_ccmode (insn, CCGCmode)
17060    && peep2_reg_dead_p (1, operands[2])"
17061   [(parallel [(set (match_dup 0)
17062                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17063               (clobber (match_dup 2))])])
17064 \f
17065 ;; Convert imul by three, five and nine into lea
17066 (define_peephole2
17067   [(parallel
17068     [(set (match_operand:SWI48 0 "register_operand" "")
17069           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17070                       (match_operand:SWI48 2 "const_int_operand" "")))
17071      (clobber (reg:CC FLAGS_REG))])]
17072   "INTVAL (operands[2]) == 3
17073    || INTVAL (operands[2]) == 5
17074    || INTVAL (operands[2]) == 9"
17075   [(set (match_dup 0)
17076         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17077                     (match_dup 1)))]
17078   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17079
17080 (define_peephole2
17081   [(parallel
17082     [(set (match_operand:SWI48 0 "register_operand" "")
17083           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17084                       (match_operand:SWI48 2 "const_int_operand" "")))
17085      (clobber (reg:CC FLAGS_REG))])]
17086   "optimize_insn_for_speed_p ()
17087    && (INTVAL (operands[2]) == 3
17088        || INTVAL (operands[2]) == 5
17089        || INTVAL (operands[2]) == 9)"
17090   [(set (match_dup 0) (match_dup 1))
17091    (set (match_dup 0)
17092         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17093                     (match_dup 0)))]
17094   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17095
17096 ;; imul $32bit_imm, mem, reg is vector decoded, while
17097 ;; imul $32bit_imm, reg, reg is direct decoded.
17098 (define_peephole2
17099   [(match_scratch:SWI48 3 "r")
17100    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17101                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17102                                (match_operand:SWI48 2 "immediate_operand" "")))
17103               (clobber (reg:CC FLAGS_REG))])]
17104   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17105    && !satisfies_constraint_K (operands[2])"
17106   [(set (match_dup 3) (match_dup 1))
17107    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17108               (clobber (reg:CC FLAGS_REG))])])
17109
17110 (define_peephole2
17111   [(match_scratch:SI 3 "r")
17112    (parallel [(set (match_operand:DI 0 "register_operand" "")
17113                    (zero_extend:DI
17114                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17115                               (match_operand:SI 2 "immediate_operand" ""))))
17116               (clobber (reg:CC FLAGS_REG))])]
17117   "TARGET_64BIT
17118    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17119    && !satisfies_constraint_K (operands[2])"
17120   [(set (match_dup 3) (match_dup 1))
17121    (parallel [(set (match_dup 0)
17122                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17123               (clobber (reg:CC FLAGS_REG))])])
17124
17125 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17126 ;; Convert it into imul reg, reg
17127 ;; It would be better to force assembler to encode instruction using long
17128 ;; immediate, but there is apparently no way to do so.
17129 (define_peephole2
17130   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17131                    (mult:SWI248
17132                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17133                     (match_operand:SWI248 2 "const_int_operand" "")))
17134               (clobber (reg:CC FLAGS_REG))])
17135    (match_scratch:SWI248 3 "r")]
17136   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17137    && satisfies_constraint_K (operands[2])"
17138   [(set (match_dup 3) (match_dup 2))
17139    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17140               (clobber (reg:CC FLAGS_REG))])]
17141 {
17142   if (!rtx_equal_p (operands[0], operands[1]))
17143     emit_move_insn (operands[0], operands[1]);
17144 })
17145
17146 ;; After splitting up read-modify operations, array accesses with memory
17147 ;; operands might end up in form:
17148 ;;  sall    $2, %eax
17149 ;;  movl    4(%esp), %edx
17150 ;;  addl    %edx, %eax
17151 ;; instead of pre-splitting:
17152 ;;  sall    $2, %eax
17153 ;;  addl    4(%esp), %eax
17154 ;; Turn it into:
17155 ;;  movl    4(%esp), %edx
17156 ;;  leal    (%edx,%eax,4), %eax
17157
17158 (define_peephole2
17159   [(match_scratch:P 5 "r")
17160    (parallel [(set (match_operand 0 "register_operand" "")
17161                    (ashift (match_operand 1 "register_operand" "")
17162                            (match_operand 2 "const_int_operand" "")))
17163                (clobber (reg:CC FLAGS_REG))])
17164    (parallel [(set (match_operand 3 "register_operand" "")
17165                    (plus (match_dup 0)
17166                          (match_operand 4 "x86_64_general_operand" "")))
17167                    (clobber (reg:CC FLAGS_REG))])]
17168   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17169    /* Validate MODE for lea.  */
17170    && ((!TARGET_PARTIAL_REG_STALL
17171         && (GET_MODE (operands[0]) == QImode
17172             || GET_MODE (operands[0]) == HImode))
17173        || GET_MODE (operands[0]) == SImode
17174        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17175    && (rtx_equal_p (operands[0], operands[3])
17176        || peep2_reg_dead_p (2, operands[0]))
17177    /* We reorder load and the shift.  */
17178    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17179   [(set (match_dup 5) (match_dup 4))
17180    (set (match_dup 0) (match_dup 1))]
17181 {
17182   enum machine_mode op1mode = GET_MODE (operands[1]);
17183   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17184   int scale = 1 << INTVAL (operands[2]);
17185   rtx index = gen_lowpart (Pmode, operands[1]);
17186   rtx base = gen_lowpart (Pmode, operands[5]);
17187   rtx dest = gen_lowpart (mode, operands[3]);
17188
17189   operands[1] = gen_rtx_PLUS (Pmode, base,
17190                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17191   operands[5] = base;
17192   if (mode != Pmode)
17193     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17194   if (op1mode != Pmode)
17195     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17196   operands[0] = dest;
17197 })
17198 \f
17199 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17200 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17201 ;; caught for use by garbage collectors and the like.  Using an insn that
17202 ;; maps to SIGILL makes it more likely the program will rightfully die.
17203 ;; Keeping with tradition, "6" is in honor of #UD.
17204 (define_insn "trap"
17205   [(trap_if (const_int 1) (const_int 6))]
17206   ""
17207   { return ASM_SHORT "0x0b0f"; }
17208   [(set_attr "length" "2")])
17209
17210 (define_expand "prefetch"
17211   [(prefetch (match_operand 0 "address_operand" "")
17212              (match_operand:SI 1 "const_int_operand" "")
17213              (match_operand:SI 2 "const_int_operand" ""))]
17214   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17215 {
17216   int rw = INTVAL (operands[1]);
17217   int locality = INTVAL (operands[2]);
17218
17219   gcc_assert (rw == 0 || rw == 1);
17220   gcc_assert (locality >= 0 && locality <= 3);
17221   gcc_assert (GET_MODE (operands[0]) == Pmode
17222               || GET_MODE (operands[0]) == VOIDmode);
17223
17224   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17225      supported by SSE counterpart or the SSE prefetch is not available
17226      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17227      of locality.  */
17228   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17229     operands[2] = GEN_INT (3);
17230   else
17231     operands[1] = const0_rtx;
17232 })
17233
17234 (define_insn "*prefetch_sse_<mode>"
17235   [(prefetch (match_operand:P 0 "address_operand" "p")
17236              (const_int 0)
17237              (match_operand:SI 1 "const_int_operand" ""))]
17238   "TARGET_PREFETCH_SSE"
17239 {
17240   static const char * const patterns[4] = {
17241    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17242   };
17243
17244   int locality = INTVAL (operands[1]);
17245   gcc_assert (locality >= 0 && locality <= 3);
17246
17247   return patterns[locality];
17248 }
17249   [(set_attr "type" "sse")
17250    (set_attr "atom_sse_attr" "prefetch")
17251    (set (attr "length_address")
17252         (symbol_ref "memory_address_length (operands[0])"))
17253    (set_attr "memory" "none")])
17254
17255 (define_insn "*prefetch_3dnow_<mode>"
17256   [(prefetch (match_operand:P 0 "address_operand" "p")
17257              (match_operand:SI 1 "const_int_operand" "n")
17258              (const_int 3))]
17259   "TARGET_3DNOW"
17260 {
17261   if (INTVAL (operands[1]) == 0)
17262     return "prefetch\t%a0";
17263   else
17264     return "prefetchw\t%a0";
17265 }
17266   [(set_attr "type" "mmx")
17267    (set (attr "length_address")
17268         (symbol_ref "memory_address_length (operands[0])"))
17269    (set_attr "memory" "none")])
17270
17271 (define_expand "stack_protect_set"
17272   [(match_operand 0 "memory_operand" "")
17273    (match_operand 1 "memory_operand" "")]
17274   ""
17275 {
17276   rtx (*insn)(rtx, rtx);
17277
17278 #ifdef TARGET_THREAD_SSP_OFFSET
17279   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17280   insn = (TARGET_64BIT
17281           ? gen_stack_tls_protect_set_di
17282           : gen_stack_tls_protect_set_si);
17283 #else
17284   insn = (TARGET_64BIT
17285           ? gen_stack_protect_set_di
17286           : gen_stack_protect_set_si);
17287 #endif
17288
17289   emit_insn (insn (operands[0], operands[1]));
17290   DONE;
17291 })
17292
17293 (define_insn "stack_protect_set_<mode>"
17294   [(set (match_operand:P 0 "memory_operand" "=m")
17295         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17296    (set (match_scratch:P 2 "=&r") (const_int 0))
17297    (clobber (reg:CC FLAGS_REG))]
17298   ""
17299   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17300   [(set_attr "type" "multi")])
17301
17302 (define_insn "stack_tls_protect_set_<mode>"
17303   [(set (match_operand:P 0 "memory_operand" "=m")
17304         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17305                   UNSPEC_SP_TLS_SET))
17306    (set (match_scratch:P 2 "=&r") (const_int 0))
17307    (clobber (reg:CC FLAGS_REG))]
17308   ""
17309   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17310   [(set_attr "type" "multi")])
17311
17312 (define_expand "stack_protect_test"
17313   [(match_operand 0 "memory_operand" "")
17314    (match_operand 1 "memory_operand" "")
17315    (match_operand 2 "" "")]
17316   ""
17317 {
17318   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17319
17320   rtx (*insn)(rtx, rtx, rtx);
17321
17322 #ifdef TARGET_THREAD_SSP_OFFSET
17323   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17324   insn = (TARGET_64BIT
17325           ? gen_stack_tls_protect_test_di
17326           : gen_stack_tls_protect_test_si);
17327 #else
17328   insn = (TARGET_64BIT
17329           ? gen_stack_protect_test_di
17330           : gen_stack_protect_test_si);
17331 #endif
17332
17333   emit_insn (insn (flags, operands[0], operands[1]));
17334
17335   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17336                                   flags, const0_rtx, operands[2]));
17337   DONE;
17338 })
17339
17340 (define_insn "stack_protect_test_<mode>"
17341   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17342         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17343                      (match_operand:P 2 "memory_operand" "m")]
17344                     UNSPEC_SP_TEST))
17345    (clobber (match_scratch:P 3 "=&r"))]
17346   ""
17347   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17348   [(set_attr "type" "multi")])
17349
17350 (define_insn "stack_tls_protect_test_<mode>"
17351   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17352         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17353                      (match_operand:P 2 "const_int_operand" "i")]
17354                     UNSPEC_SP_TLS_TEST))
17355    (clobber (match_scratch:P 3 "=r"))]
17356   ""
17357   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17358   [(set_attr "type" "multi")])
17359
17360 (define_insn "sse4_2_crc32<mode>"
17361   [(set (match_operand:SI 0 "register_operand" "=r")
17362         (unspec:SI
17363           [(match_operand:SI 1 "register_operand" "0")
17364            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17365           UNSPEC_CRC32))]
17366   "TARGET_SSE4_2 || TARGET_CRC32"
17367   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17368   [(set_attr "type" "sselog1")
17369    (set_attr "prefix_rep" "1")
17370    (set_attr "prefix_extra" "1")
17371    (set (attr "prefix_data16")
17372      (if_then_else (match_operand:HI 2 "" "")
17373        (const_string "1")
17374        (const_string "*")))
17375    (set (attr "prefix_rex")
17376      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17377        (const_string "1")
17378        (const_string "*")))
17379    (set_attr "mode" "SI")])
17380
17381 (define_insn "sse4_2_crc32di"
17382   [(set (match_operand:DI 0 "register_operand" "=r")
17383         (unspec:DI
17384           [(match_operand:DI 1 "register_operand" "0")
17385            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17386           UNSPEC_CRC32))]
17387   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17388   "crc32{q}\t{%2, %0|%0, %2}"
17389   [(set_attr "type" "sselog1")
17390    (set_attr "prefix_rep" "1")
17391    (set_attr "prefix_extra" "1")
17392    (set_attr "mode" "DI")])
17393
17394 (define_expand "rdpmc"
17395   [(match_operand:DI 0 "register_operand" "")
17396    (match_operand:SI 1 "register_operand" "")]
17397   ""
17398 {
17399   rtx reg = gen_reg_rtx (DImode);
17400   rtx si;
17401
17402   /* Force operand 1 into ECX.  */
17403   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17404   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17405   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17406                                 UNSPECV_RDPMC);
17407
17408   if (TARGET_64BIT)
17409     {
17410       rtvec vec = rtvec_alloc (2);
17411       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17412       rtx upper = gen_reg_rtx (DImode);
17413       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17414                                         gen_rtvec (1, const0_rtx),
17415                                         UNSPECV_RDPMC);
17416       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17417       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17418       emit_insn (load);
17419       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17420                                    NULL, 1, OPTAB_DIRECT);
17421       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17422                                  OPTAB_DIRECT);
17423     }
17424   else
17425     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17426   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17427   DONE;
17428 })
17429
17430 (define_insn "*rdpmc"
17431   [(set (match_operand:DI 0 "register_operand" "=A")
17432         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17433                             UNSPECV_RDPMC))]
17434   "!TARGET_64BIT"
17435   "rdpmc"
17436   [(set_attr "type" "other")
17437    (set_attr "length" "2")])
17438
17439 (define_insn "*rdpmc_rex64"
17440   [(set (match_operand:DI 0 "register_operand" "=a")
17441         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17442                             UNSPECV_RDPMC))
17443   (set (match_operand:DI 1 "register_operand" "=d")
17444        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17445   "TARGET_64BIT"
17446   "rdpmc"
17447   [(set_attr "type" "other")
17448    (set_attr "length" "2")])
17449
17450 (define_expand "rdtsc"
17451   [(set (match_operand:DI 0 "register_operand" "")
17452         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17453   ""
17454 {
17455   if (TARGET_64BIT)
17456     {
17457       rtvec vec = rtvec_alloc (2);
17458       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17459       rtx upper = gen_reg_rtx (DImode);
17460       rtx lower = gen_reg_rtx (DImode);
17461       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17462                                          gen_rtvec (1, const0_rtx),
17463                                          UNSPECV_RDTSC);
17464       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17465       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17466       emit_insn (load);
17467       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17468                                    NULL, 1, OPTAB_DIRECT);
17469       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17470                                    OPTAB_DIRECT);
17471       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17472       DONE;
17473     }
17474 })
17475
17476 (define_insn "*rdtsc"
17477   [(set (match_operand:DI 0 "register_operand" "=A")
17478         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17479   "!TARGET_64BIT"
17480   "rdtsc"
17481   [(set_attr "type" "other")
17482    (set_attr "length" "2")])
17483
17484 (define_insn "*rdtsc_rex64"
17485   [(set (match_operand:DI 0 "register_operand" "=a")
17486         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17487    (set (match_operand:DI 1 "register_operand" "=d")
17488         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17489   "TARGET_64BIT"
17490   "rdtsc"
17491   [(set_attr "type" "other")
17492    (set_attr "length" "2")])
17493
17494 (define_expand "rdtscp"
17495   [(match_operand:DI 0 "register_operand" "")
17496    (match_operand:SI 1 "memory_operand" "")]
17497   ""
17498 {
17499   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17500                                     gen_rtvec (1, const0_rtx),
17501                                     UNSPECV_RDTSCP);
17502   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17503                                     gen_rtvec (1, const0_rtx),
17504                                     UNSPECV_RDTSCP);
17505   rtx reg = gen_reg_rtx (DImode);
17506   rtx tmp = gen_reg_rtx (SImode);
17507
17508   if (TARGET_64BIT)
17509     {
17510       rtvec vec = rtvec_alloc (3);
17511       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17512       rtx upper = gen_reg_rtx (DImode);
17513       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17514       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17515       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17516       emit_insn (load);
17517       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17518                                    NULL, 1, OPTAB_DIRECT);
17519       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17520                                  OPTAB_DIRECT);
17521     }
17522   else
17523     {
17524       rtvec vec = rtvec_alloc (2);
17525       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17526       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17527       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17528       emit_insn (load);
17529     }
17530   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17531   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17532   DONE;
17533 })
17534
17535 (define_insn "*rdtscp"
17536   [(set (match_operand:DI 0 "register_operand" "=A")
17537         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17538    (set (match_operand:SI 1 "register_operand" "=c")
17539         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17540   "!TARGET_64BIT"
17541   "rdtscp"
17542   [(set_attr "type" "other")
17543    (set_attr "length" "3")])
17544
17545 (define_insn "*rdtscp_rex64"
17546   [(set (match_operand:DI 0 "register_operand" "=a")
17547         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17548    (set (match_operand:DI 1 "register_operand" "=d")
17549         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17550    (set (match_operand:SI 2 "register_operand" "=c")
17551         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17552   "TARGET_64BIT"
17553   "rdtscp"
17554   [(set_attr "type" "other")
17555    (set_attr "length" "3")])
17556
17557 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17558 ;;
17559 ;; LWP instructions
17560 ;;
17561 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17562
17563 (define_expand "lwp_llwpcb"
17564   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17565                     UNSPECV_LLWP_INTRINSIC)]
17566   "TARGET_LWP")
17567
17568 (define_insn "*lwp_llwpcb<mode>1"
17569   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17570                     UNSPECV_LLWP_INTRINSIC)]
17571   "TARGET_LWP"
17572   "llwpcb\t%0"
17573   [(set_attr "type" "lwp")
17574    (set_attr "mode" "<MODE>")
17575    (set_attr "length" "5")])
17576
17577 (define_expand "lwp_slwpcb"
17578   [(set (match_operand 0 "register_operand" "=r")
17579         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17580   "TARGET_LWP"
17581 {
17582   rtx (*insn)(rtx);
17583
17584   insn = (TARGET_64BIT
17585           ? gen_lwp_slwpcbdi
17586           : gen_lwp_slwpcbsi);
17587
17588   emit_insn (insn (operands[0]));
17589   DONE;
17590 })
17591
17592 (define_insn "lwp_slwpcb<mode>"
17593   [(set (match_operand:P 0 "register_operand" "=r")
17594         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17595   "TARGET_LWP"
17596   "slwpcb\t%0"
17597   [(set_attr "type" "lwp")
17598    (set_attr "mode" "<MODE>")
17599    (set_attr "length" "5")])
17600
17601 (define_expand "lwp_lwpval<mode>3"
17602   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17603                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17604                      (match_operand:SI 3 "const_int_operand" "i")]
17605                     UNSPECV_LWPVAL_INTRINSIC)]
17606   "TARGET_LWP"
17607   "/* Avoid unused variable warning.  */
17608    (void) operand0;")
17609
17610 (define_insn "*lwp_lwpval<mode>3_1"
17611   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17612                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17613                      (match_operand:SI 2 "const_int_operand" "i")]
17614                     UNSPECV_LWPVAL_INTRINSIC)]
17615   "TARGET_LWP"
17616   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17617   [(set_attr "type" "lwp")
17618    (set_attr "mode" "<MODE>")
17619    (set (attr "length")
17620         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17621
17622 (define_expand "lwp_lwpins<mode>3"
17623   [(set (reg:CCC FLAGS_REG)
17624         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17625                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17626                               (match_operand:SI 3 "const_int_operand" "i")]
17627                              UNSPECV_LWPINS_INTRINSIC))
17628    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17629         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17630   "TARGET_LWP")
17631
17632 (define_insn "*lwp_lwpins<mode>3_1"
17633   [(set (reg:CCC FLAGS_REG)
17634         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17635                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17636                               (match_operand:SI 2 "const_int_operand" "i")]
17637                              UNSPECV_LWPINS_INTRINSIC))]
17638   "TARGET_LWP"
17639   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17640   [(set_attr "type" "lwp")
17641    (set_attr "mode" "<MODE>")
17642    (set (attr "length")
17643         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17644
17645 (define_insn "rdfsbase<mode>"
17646   [(set (match_operand:SWI48 0 "register_operand" "=r")
17647         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17648   "TARGET_64BIT && TARGET_FSGSBASE"
17649   "rdfsbase %0"
17650   [(set_attr "type" "other")
17651    (set_attr "prefix_extra" "2")])
17652
17653 (define_insn "rdgsbase<mode>"
17654   [(set (match_operand:SWI48 0 "register_operand" "=r")
17655         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17656   "TARGET_64BIT && TARGET_FSGSBASE"
17657   "rdgsbase %0"
17658   [(set_attr "type" "other")
17659    (set_attr "prefix_extra" "2")])
17660
17661 (define_insn "wrfsbase<mode>"
17662   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17663                     UNSPECV_WRFSBASE)]
17664   "TARGET_64BIT && TARGET_FSGSBASE"
17665   "wrfsbase %0"
17666   [(set_attr "type" "other")
17667    (set_attr "prefix_extra" "2")])
17668
17669 (define_insn "wrgsbase<mode>"
17670   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17671                     UNSPECV_WRGSBASE)]
17672   "TARGET_64BIT && TARGET_FSGSBASE"
17673   "wrgsbase %0"
17674   [(set_attr "type" "other")
17675    (set_attr "prefix_extra" "2")])
17676
17677 (define_insn "rdrand<mode>_1"
17678   [(set (match_operand:SWI248 0 "register_operand" "=r")
17679         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17680    (set (reg:CCC FLAGS_REG)
17681         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17682   "TARGET_RDRND"
17683   "rdrand\t%0"
17684   [(set_attr "type" "other")
17685    (set_attr "prefix_extra" "1")])
17686
17687 (include "mmx.md")
17688 (include "sse.md")
17689 (include "sync.md")