OSDN Git Service

278bd77a3662599ba648b37e6681f93a4fcd3062
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- 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
80   ;; Prologue support
81   UNSPEC_STACK_ALLOC
82   UNSPEC_SET_GOT
83   UNSPEC_REG_SAVE
84   UNSPEC_DEF_CFA
85   UNSPEC_SET_RIP
86   UNSPEC_SET_GOT_OFFSET
87   UNSPEC_MEMORY_BLOCKAGE
88   UNSPEC_STACK_CHECK
89
90   ;; TLS support
91   UNSPEC_TP
92   UNSPEC_TLS_GD
93   UNSPEC_TLS_LD_BASE
94   UNSPEC_TLSDESC
95
96   ;; Other random patterns
97   UNSPEC_SCAS
98   UNSPEC_FNSTSW
99   UNSPEC_SAHF
100   UNSPEC_PARITY
101   UNSPEC_FSTCW
102   UNSPEC_ADD_CARRY
103   UNSPEC_FLDCW
104   UNSPEC_REP
105   UNSPEC_LD_MPIC        ; load_macho_picbase
106   UNSPEC_TRUNC_NOOP
107   UNSPEC_DIV_ALREADY_SPLIT
108   UNSPEC_CALL_NEEDS_VZEROUPPER
109
110   ;; For SSE/MMX support:
111   UNSPEC_FIX_NOTRUNC
112   UNSPEC_MASKMOV
113   UNSPEC_MOVMSK
114   UNSPEC_MOVNT
115   UNSPEC_MOVU
116   UNSPEC_RCP
117   UNSPEC_RSQRT
118   UNSPEC_SFENCE
119   UNSPEC_PFRCP
120   UNSPEC_PFRCPIT1
121   UNSPEC_PFRCPIT2
122   UNSPEC_PFRSQRT
123   UNSPEC_PFRSQIT1
124   UNSPEC_MFENCE
125   UNSPEC_LFENCE
126   UNSPEC_PSADBW
127   UNSPEC_LDDQU
128   UNSPEC_MS_TO_SYSV_CALL
129
130   ;; Generic math support
131   UNSPEC_COPYSIGN
132   UNSPEC_IEEE_MIN       ; not commutative
133   UNSPEC_IEEE_MAX       ; not commutative
134
135   ;; x87 Floating point
136   UNSPEC_SIN
137   UNSPEC_COS
138   UNSPEC_FPATAN
139   UNSPEC_FYL2X
140   UNSPEC_FYL2XP1
141   UNSPEC_FRNDINT
142   UNSPEC_FIST
143   UNSPEC_F2XM1
144   UNSPEC_TAN
145   UNSPEC_FXAM
146
147   ;; x87 Rounding
148   UNSPEC_FRNDINT_FLOOR
149   UNSPEC_FRNDINT_CEIL
150   UNSPEC_FRNDINT_TRUNC
151   UNSPEC_FRNDINT_MASK_PM
152   UNSPEC_FIST_FLOOR
153   UNSPEC_FIST_CEIL
154
155   ;; x87 Double output FP
156   UNSPEC_SINCOS_COS
157   UNSPEC_SINCOS_SIN
158   UNSPEC_XTRACT_FRACT
159   UNSPEC_XTRACT_EXP
160   UNSPEC_FSCALE_FRACT
161   UNSPEC_FSCALE_EXP
162   UNSPEC_FPREM_F
163   UNSPEC_FPREM_U
164   UNSPEC_FPREM1_F
165   UNSPEC_FPREM1_U
166
167   UNSPEC_C2_FLAG
168   UNSPEC_FXAM_MEM
169
170   ;; SSP patterns
171   UNSPEC_SP_SET
172   UNSPEC_SP_TEST
173   UNSPEC_SP_TLS_SET
174   UNSPEC_SP_TLS_TEST
175
176   ;; SSSE3
177   UNSPEC_PSHUFB
178   UNSPEC_PSIGN
179   UNSPEC_PALIGNR
180
181   ;; For SSE4A support
182   UNSPEC_EXTRQI
183   UNSPEC_EXTRQ
184   UNSPEC_INSERTQI
185   UNSPEC_INSERTQ
186
187   ;; For SSE4.1 support
188   UNSPEC_BLENDV
189   UNSPEC_INSERTPS
190   UNSPEC_DP
191   UNSPEC_MOVNTDQA
192   UNSPEC_MPSADBW
193   UNSPEC_PHMINPOSUW
194   UNSPEC_PTEST
195   UNSPEC_ROUND
196
197   ;; For SSE4.2 support
198   UNSPEC_CRC32
199   UNSPEC_PCMPESTR
200   UNSPEC_PCMPISTR
201
202   ;; For FMA4 support
203   UNSPEC_FMADDSUB
204   UNSPEC_XOP_UNSIGNED_CMP
205   UNSPEC_XOP_TRUEFALSE
206   UNSPEC_XOP_PERMUTE
207   UNSPEC_FRCZ
208
209   ;; For AES support
210   UNSPEC_AESENC
211   UNSPEC_AESENCLAST
212   UNSPEC_AESDEC
213   UNSPEC_AESDECLAST
214   UNSPEC_AESIMC
215   UNSPEC_AESKEYGENASSIST
216
217   ;; For PCLMUL support
218   UNSPEC_PCLMUL
219
220   ;; For AVX support
221   UNSPEC_PCMP
222   UNSPEC_VPERMIL
223   UNSPEC_VPERMIL2
224   UNSPEC_VPERMIL2F128
225   UNSPEC_MASKLOAD
226   UNSPEC_MASKSTORE
227   UNSPEC_CAST
228   UNSPEC_VTESTP
229   UNSPEC_VCVTPH2PS
230   UNSPEC_VCVTPS2PH
231 ])
232
233 (define_c_enum "unspecv" [
234   UNSPECV_BLOCKAGE
235   UNSPECV_STACK_PROBE
236   UNSPECV_PROBE_STACK_RANGE
237   UNSPECV_EMMS
238   UNSPECV_LDMXCSR
239   UNSPECV_STMXCSR
240   UNSPECV_FEMMS
241   UNSPECV_CLFLUSH
242   UNSPECV_ALIGN
243   UNSPECV_MONITOR
244   UNSPECV_MWAIT
245   UNSPECV_CMPXCHG
246   UNSPECV_XCHG
247   UNSPECV_LOCK
248   UNSPECV_PROLOGUE_USE
249   UNSPECV_CLD
250   UNSPECV_NOPS
251   UNSPECV_VZEROALL
252   UNSPECV_VZEROUPPER
253   UNSPECV_RDTSC
254   UNSPECV_RDTSCP
255   UNSPECV_RDPMC
256   UNSPECV_LLWP_INTRINSIC
257   UNSPECV_SLWP_INTRINSIC
258   UNSPECV_LWPVAL_INTRINSIC
259   UNSPECV_LWPINS_INTRINSIC
260   UNSPECV_RDFSBASE
261   UNSPECV_RDGSBASE
262   UNSPECV_WRFSBASE
263   UNSPECV_WRGSBASE
264   UNSPECV_RDRAND
265   UNSPECV_SPLIT_STACK_RETURN
266 ])
267
268 ;; Constants to represent pcomtrue/pcomfalse variants
269 (define_constants
270   [(PCOM_FALSE                  0)
271    (PCOM_TRUE                   1)
272    (COM_FALSE_S                 2)
273    (COM_FALSE_P                 3)
274    (COM_TRUE_S                  4)
275    (COM_TRUE_P                  5)
276   ])
277
278 ;; Constants used in the XOP pperm instruction
279 (define_constants
280   [(PPERM_SRC                   0x00)   /* copy source */
281    (PPERM_INVERT                0x20)   /* invert source */
282    (PPERM_REVERSE               0x40)   /* bit reverse source */
283    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
284    (PPERM_ZERO                  0x80)   /* all 0's */
285    (PPERM_ONES                  0xa0)   /* all 1's */
286    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
287    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
288    (PPERM_SRC1                  0x00)   /* use first source byte */
289    (PPERM_SRC2                  0x10)   /* use second source byte */
290    ])
291
292 ;; Registers by name.
293 (define_constants
294   [(AX_REG                       0)
295    (DX_REG                       1)
296    (CX_REG                       2)
297    (BX_REG                       3)
298    (SI_REG                       4)
299    (DI_REG                       5)
300    (BP_REG                       6)
301    (SP_REG                       7)
302    (ST0_REG                      8)
303    (ST1_REG                      9)
304    (ST2_REG                     10)
305    (ST3_REG                     11)
306    (ST4_REG                     12)
307    (ST5_REG                     13)
308    (ST6_REG                     14)
309    (ST7_REG                     15)
310    (FLAGS_REG                   17)
311    (FPSR_REG                    18)
312    (FPCR_REG                    19)
313    (XMM0_REG                    21)
314    (XMM1_REG                    22)
315    (XMM2_REG                    23)
316    (XMM3_REG                    24)
317    (XMM4_REG                    25)
318    (XMM5_REG                    26)
319    (XMM6_REG                    27)
320    (XMM7_REG                    28)
321    (MM0_REG                     29)
322    (MM1_REG                     30)
323    (MM2_REG                     31)
324    (MM3_REG                     32)
325    (MM4_REG                     33)
326    (MM5_REG                     34)
327    (MM6_REG                     35)
328    (MM7_REG                     36)
329    (R8_REG                      37)
330    (R9_REG                      38)
331    (R10_REG                     39)
332    (R11_REG                     40)
333    (R12_REG                     41)
334    (R13_REG                     42)
335    (XMM8_REG                    45)
336    (XMM9_REG                    46)
337    (XMM10_REG                   47)
338    (XMM11_REG                   48)
339    (XMM12_REG                   49)
340    (XMM13_REG                   50)
341    (XMM14_REG                   51)
342    (XMM15_REG                   52)
343   ])
344
345 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
346 ;; from i386.c.
347
348 ;; In C guard expressions, put expressions which may be compile-time
349 ;; constants first.  This allows for better optimization.  For
350 ;; example, write "TARGET_64BIT && reload_completed", not
351 ;; "reload_completed && TARGET_64BIT".
352
353 \f
354 ;; Processor type.
355 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
356                     generic64,amdfam10,bdver1"
357   (const (symbol_ref "ix86_schedule")))
358
359 ;; A basic instruction type.  Refinements due to arguments to be
360 ;; provided in other attributes.
361 (define_attr "type"
362   "other,multi,
363    alu,alu1,negnot,imov,imovx,lea,
364    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
365    icmp,test,ibr,setcc,icmov,
366    push,pop,call,callv,leave,
367    str,bitmanip,
368    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
369    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
370    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
371    ssemuladd,sse4arg,lwp,
372    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
373   (const_string "other"))
374
375 ;; Main data type used by the insn
376 (define_attr "mode"
377   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
378   (const_string "unknown"))
379
380 ;; The CPU unit operations uses.
381 (define_attr "unit" "integer,i387,sse,mmx,unknown"
382   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
383            (const_string "i387")
384          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
385                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
386                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
387            (const_string "sse")
388          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
389            (const_string "mmx")
390          (eq_attr "type" "other")
391            (const_string "unknown")]
392          (const_string "integer")))
393
394 ;; The (bounding maximum) length of an instruction immediate.
395 (define_attr "length_immediate" ""
396   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
397                           bitmanip")
398            (const_int 0)
399          (eq_attr "unit" "i387,sse,mmx")
400            (const_int 0)
401          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
402                           imul,icmp,push,pop")
403            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
404          (eq_attr "type" "imov,test")
405            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
406          (eq_attr "type" "call")
407            (if_then_else (match_operand 0 "constant_call_address_operand" "")
408              (const_int 4)
409              (const_int 0))
410          (eq_attr "type" "callv")
411            (if_then_else (match_operand 1 "constant_call_address_operand" "")
412              (const_int 4)
413              (const_int 0))
414          ;; We don't know the size before shorten_branches.  Expect
415          ;; the instruction to fit for better scheduling.
416          (eq_attr "type" "ibr")
417            (const_int 1)
418          ]
419          (symbol_ref "/* Update immediate_length and other attributes! */
420                       gcc_unreachable (),1")))
421
422 ;; The (bounding maximum) length of an instruction address.
423 (define_attr "length_address" ""
424   (cond [(eq_attr "type" "str,other,multi,fxch")
425            (const_int 0)
426          (and (eq_attr "type" "call")
427               (match_operand 0 "constant_call_address_operand" ""))
428              (const_int 0)
429          (and (eq_attr "type" "callv")
430               (match_operand 1 "constant_call_address_operand" ""))
431              (const_int 0)
432          ]
433          (symbol_ref "ix86_attr_length_address_default (insn)")))
434
435 ;; Set when length prefix is used.
436 (define_attr "prefix_data16" ""
437   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
438            (const_int 0)
439          (eq_attr "mode" "HI")
440            (const_int 1)
441          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
442            (const_int 1)
443         ]
444         (const_int 0)))
445
446 ;; Set when string REP prefix is used.
447 (define_attr "prefix_rep" ""
448   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
449            (const_int 0)
450          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
451            (const_int 1)
452         ]
453         (const_int 0)))
454
455 ;; Set when 0f opcode prefix is used.
456 (define_attr "prefix_0f" ""
457   (if_then_else
458     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
459          (eq_attr "unit" "sse,mmx"))
460     (const_int 1)
461     (const_int 0)))
462
463 ;; Set when REX opcode prefix is used.
464 (define_attr "prefix_rex" ""
465   (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
466            (const_int 0)
467          (and (eq_attr "mode" "DI")
468               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
469                    (eq_attr "unit" "!mmx")))
470            (const_int 1)
471          (and (eq_attr "mode" "QI")
472               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
473                   (const_int 0)))
474            (const_int 1)
475          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
476              (const_int 0))
477            (const_int 1)
478          (and (eq_attr "type" "imovx")
479               (match_operand:QI 1 "ext_QIreg_operand" ""))
480            (const_int 1)
481         ]
482         (const_int 0)))
483
484 ;; There are also additional prefixes in 3DNOW, SSSE3.
485 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
486 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
487 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
488 (define_attr "prefix_extra" ""
489   (cond [(eq_attr "type" "ssemuladd,sse4arg")
490            (const_int 2)
491          (eq_attr "type" "sseiadd1,ssecvt1")
492            (const_int 1)
493         ]
494         (const_int 0)))
495
496 ;; Prefix used: original, VEX or maybe VEX.
497 (define_attr "prefix" "orig,vex,maybe_vex"
498   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
499     (const_string "vex")
500     (const_string "orig")))
501
502 ;; VEX W bit is used.
503 (define_attr "prefix_vex_w" "" (const_int 0))
504
505 ;; The length of VEX prefix
506 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
507 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
508 ;; still prefix_0f 1, with prefix_extra 1.
509 (define_attr "length_vex" ""
510   (if_then_else (and (eq_attr "prefix_0f" "1")
511                      (eq_attr "prefix_extra" "0"))
512     (if_then_else (eq_attr "prefix_vex_w" "1")
513       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
514       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
515     (if_then_else (eq_attr "prefix_vex_w" "1")
516       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
517       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
518
519 ;; Set when modrm byte is used.
520 (define_attr "modrm" ""
521   (cond [(eq_attr "type" "str,leave")
522            (const_int 0)
523          (eq_attr "unit" "i387")
524            (const_int 0)
525          (and (eq_attr "type" "incdec")
526               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
527                    (ior (match_operand:SI 1 "register_operand" "")
528                         (match_operand:HI 1 "register_operand" ""))))
529            (const_int 0)
530          (and (eq_attr "type" "push")
531               (not (match_operand 1 "memory_operand" "")))
532            (const_int 0)
533          (and (eq_attr "type" "pop")
534               (not (match_operand 0 "memory_operand" "")))
535            (const_int 0)
536          (and (eq_attr "type" "imov")
537               (and (not (eq_attr "mode" "DI"))
538                    (ior (and (match_operand 0 "register_operand" "")
539                              (match_operand 1 "immediate_operand" ""))
540                         (ior (and (match_operand 0 "ax_reg_operand" "")
541                                   (match_operand 1 "memory_displacement_only_operand" ""))
542                              (and (match_operand 0 "memory_displacement_only_operand" "")
543                                   (match_operand 1 "ax_reg_operand" ""))))))
544            (const_int 0)
545          (and (eq_attr "type" "call")
546               (match_operand 0 "constant_call_address_operand" ""))
547              (const_int 0)
548          (and (eq_attr "type" "callv")
549               (match_operand 1 "constant_call_address_operand" ""))
550              (const_int 0)
551          (and (eq_attr "type" "alu,alu1,icmp,test")
552               (match_operand 0 "ax_reg_operand" ""))
553              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
554          ]
555          (const_int 1)))
556
557 ;; The (bounding maximum) length of an instruction in bytes.
558 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
559 ;; Later we may want to split them and compute proper length as for
560 ;; other insns.
561 (define_attr "length" ""
562   (cond [(eq_attr "type" "other,multi,fistp,frndint")
563            (const_int 16)
564          (eq_attr "type" "fcmp")
565            (const_int 4)
566          (eq_attr "unit" "i387")
567            (plus (const_int 2)
568                  (plus (attr "prefix_data16")
569                        (attr "length_address")))
570          (ior (eq_attr "prefix" "vex")
571               (and (eq_attr "prefix" "maybe_vex")
572                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
573            (plus (attr "length_vex")
574                  (plus (attr "length_immediate")
575                        (plus (attr "modrm")
576                              (attr "length_address"))))]
577          (plus (plus (attr "modrm")
578                      (plus (attr "prefix_0f")
579                            (plus (attr "prefix_rex")
580                                  (plus (attr "prefix_extra")
581                                        (const_int 1)))))
582                (plus (attr "prefix_rep")
583                      (plus (attr "prefix_data16")
584                            (plus (attr "length_immediate")
585                                  (attr "length_address")))))))
586
587 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
588 ;; `store' if there is a simple memory reference therein, or `unknown'
589 ;; if the instruction is complex.
590
591 (define_attr "memory" "none,load,store,both,unknown"
592   (cond [(eq_attr "type" "other,multi,str,lwp")
593            (const_string "unknown")
594          (eq_attr "type" "lea,fcmov,fpspc")
595            (const_string "none")
596          (eq_attr "type" "fistp,leave")
597            (const_string "both")
598          (eq_attr "type" "frndint")
599            (const_string "load")
600          (eq_attr "type" "push")
601            (if_then_else (match_operand 1 "memory_operand" "")
602              (const_string "both")
603              (const_string "store"))
604          (eq_attr "type" "pop")
605            (if_then_else (match_operand 0 "memory_operand" "")
606              (const_string "both")
607              (const_string "load"))
608          (eq_attr "type" "setcc")
609            (if_then_else (match_operand 0 "memory_operand" "")
610              (const_string "store")
611              (const_string "none"))
612          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
613            (if_then_else (ior (match_operand 0 "memory_operand" "")
614                               (match_operand 1 "memory_operand" ""))
615              (const_string "load")
616              (const_string "none"))
617          (eq_attr "type" "ibr")
618            (if_then_else (match_operand 0 "memory_operand" "")
619              (const_string "load")
620              (const_string "none"))
621          (eq_attr "type" "call")
622            (if_then_else (match_operand 0 "constant_call_address_operand" "")
623              (const_string "none")
624              (const_string "load"))
625          (eq_attr "type" "callv")
626            (if_then_else (match_operand 1 "constant_call_address_operand" "")
627              (const_string "none")
628              (const_string "load"))
629          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
630               (match_operand 1 "memory_operand" ""))
631            (const_string "both")
632          (and (match_operand 0 "memory_operand" "")
633               (match_operand 1 "memory_operand" ""))
634            (const_string "both")
635          (match_operand 0 "memory_operand" "")
636            (const_string "store")
637          (match_operand 1 "memory_operand" "")
638            (const_string "load")
639          (and (eq_attr "type"
640                  "!alu1,negnot,ishift1,
641                    imov,imovx,icmp,test,bitmanip,
642                    fmov,fcmp,fsgn,
643                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
644                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
645               (match_operand 2 "memory_operand" ""))
646            (const_string "load")
647          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
648               (match_operand 3 "memory_operand" ""))
649            (const_string "load")
650         ]
651         (const_string "none")))
652
653 ;; Indicates if an instruction has both an immediate and a displacement.
654
655 (define_attr "imm_disp" "false,true,unknown"
656   (cond [(eq_attr "type" "other,multi")
657            (const_string "unknown")
658          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
659               (and (match_operand 0 "memory_displacement_operand" "")
660                    (match_operand 1 "immediate_operand" "")))
661            (const_string "true")
662          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
663               (and (match_operand 0 "memory_displacement_operand" "")
664                    (match_operand 2 "immediate_operand" "")))
665            (const_string "true")
666         ]
667         (const_string "false")))
668
669 ;; Indicates if an FP operation has an integer source.
670
671 (define_attr "fp_int_src" "false,true"
672   (const_string "false"))
673
674 ;; Defines rounding mode of an FP operation.
675
676 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
677   (const_string "any"))
678
679 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
680 (define_attr "use_carry" "0,1" (const_string "0"))
681
682 ;; Define attribute to indicate unaligned ssemov insns
683 (define_attr "movu" "0,1" (const_string "0"))
684
685 ;; Describe a user's asm statement.
686 (define_asm_attributes
687   [(set_attr "length" "128")
688    (set_attr "type" "multi")])
689
690 (define_code_iterator plusminus [plus minus])
691
692 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
693
694 ;; Base name for define_insn
695 (define_code_attr plusminus_insn
696   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
697    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
698
699 ;; Base name for insn mnemonic.
700 (define_code_attr plusminus_mnemonic
701   [(plus "add") (ss_plus "adds") (us_plus "addus")
702    (minus "sub") (ss_minus "subs") (us_minus "subus")])
703 (define_code_attr plusminus_carry_mnemonic
704   [(plus "adc") (minus "sbb")])
705
706 ;; Mark commutative operators as such in constraints.
707 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
708                         (minus "") (ss_minus "") (us_minus "")])
709
710 ;; Mapping of signed max and min
711 (define_code_iterator smaxmin [smax smin])
712
713 ;; Mapping of unsigned max and min
714 (define_code_iterator umaxmin [umax umin])
715
716 ;; Base name for integer and FP insn mnemonic
717 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
718                               (umax "maxu") (umin "minu")])
719 (define_code_attr maxmin_float [(smax "max") (smin "min")])
720
721 ;; Mapping of logic operators
722 (define_code_iterator any_logic [and ior xor])
723 (define_code_iterator any_or [ior xor])
724
725 ;; Base name for insn mnemonic.
726 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
727
728 ;; Mapping of shift-right operators
729 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730
731 ;; Base name for define_insn
732 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
733
734 ;; Base name for insn mnemonic.
735 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
736
737 ;; Mapping of rotate operators
738 (define_code_iterator any_rotate [rotate rotatert])
739
740 ;; Base name for define_insn
741 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
742
743 ;; Base name for insn mnemonic.
744 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
745
746 ;; Mapping of abs neg operators
747 (define_code_iterator absneg [abs neg])
748
749 ;; Base name for x87 insn mnemonic.
750 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
751
752 ;; Used in signed and unsigned widening multiplications.
753 (define_code_iterator any_extend [sign_extend zero_extend])
754
755 ;; Various insn prefixes for signed and unsigned operations.
756 (define_code_attr u [(sign_extend "") (zero_extend "u")
757                      (div "") (udiv "u")])
758 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
759
760 ;; Used in signed and unsigned divisions.
761 (define_code_iterator any_div [div udiv])
762
763 ;; Instruction prefix for signed and unsigned operations.
764 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
765                              (div "i") (udiv "")])
766
767 ;; 64bit single word integer modes.
768 (define_mode_iterator SWI1248x [QI HI SI DI])
769
770 ;; 64bit single word integer modes without QImode and HImode.
771 (define_mode_iterator SWI48x [SI DI])
772
773 ;; Single word integer modes.
774 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
775
776 ;; Single word integer modes without SImode and DImode.
777 (define_mode_iterator SWI12 [QI HI])
778
779 ;; Single word integer modes without DImode.
780 (define_mode_iterator SWI124 [QI HI SI])
781
782 ;; Single word integer modes without QImode and DImode.
783 (define_mode_iterator SWI24 [HI SI])
784
785 ;; Single word integer modes without QImode.
786 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
787
788 ;; Single word integer modes without QImode and HImode.
789 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
790
791 ;; All math-dependant single and double word integer modes.
792 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
793                              (HI "TARGET_HIMODE_MATH")
794                              SI DI (TI "TARGET_64BIT")])
795
796 ;; Math-dependant single word integer modes.
797 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
798                             (HI "TARGET_HIMODE_MATH")
799                             SI (DI "TARGET_64BIT")])
800
801 ;; Math-dependant single word integer modes without DImode.
802 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
803                                (HI "TARGET_HIMODE_MATH")
804                                SI])
805
806 ;; Math-dependant single word integer modes without QImode.
807 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
808                                SI (DI "TARGET_64BIT")])
809
810 ;; Double word integer modes.
811 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
812                            (TI "TARGET_64BIT")])
813
814 ;; Double word integer modes as mode attribute.
815 (define_mode_attr DWI [(SI "DI") (DI "TI")])
816 (define_mode_attr dwi [(SI "di") (DI "ti")])
817
818 ;; Half mode for double word integer modes.
819 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
820                             (DI "TARGET_64BIT")])
821
822 ;; Instruction suffix for integer modes.
823 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
824
825 ;; Pointer size prefix for integer modes (Intel asm dialect)
826 (define_mode_attr iptrsize [(QI "BYTE")
827                             (HI "WORD")
828                             (SI "DWORD")
829                             (DI "QWORD")])
830
831 ;; Register class for integer modes.
832 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
833
834 ;; Immediate operand constraint for integer modes.
835 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
836
837 ;; General operand constraint for word modes.
838 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
839
840 ;; Immediate operand constraint for double integer modes.
841 (define_mode_attr di [(SI "iF") (DI "e")])
842
843 ;; Immediate operand constraint for shifts.
844 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
845
846 ;; General operand predicate for integer modes.
847 (define_mode_attr general_operand
848         [(QI "general_operand")
849          (HI "general_operand")
850          (SI "general_operand")
851          (DI "x86_64_general_operand")
852          (TI "x86_64_general_operand")])
853
854 ;; General sign/zero extend operand predicate for integer modes.
855 (define_mode_attr general_szext_operand
856         [(QI "general_operand")
857          (HI "general_operand")
858          (SI "general_operand")
859          (DI "x86_64_szext_general_operand")])
860
861 ;; Immediate operand predicate for integer modes.
862 (define_mode_attr immediate_operand
863         [(QI "immediate_operand")
864          (HI "immediate_operand")
865          (SI "immediate_operand")
866          (DI "x86_64_immediate_operand")])
867
868 ;; Nonmemory operand predicate for integer modes.
869 (define_mode_attr nonmemory_operand
870         [(QI "nonmemory_operand")
871          (HI "nonmemory_operand")
872          (SI "nonmemory_operand")
873          (DI "x86_64_nonmemory_operand")])
874
875 ;; Operand predicate for shifts.
876 (define_mode_attr shift_operand
877         [(QI "nonimmediate_operand")
878          (HI "nonimmediate_operand")
879          (SI "nonimmediate_operand")
880          (DI "shiftdi_operand")
881          (TI "register_operand")])
882
883 ;; Operand predicate for shift argument.
884 (define_mode_attr shift_immediate_operand
885         [(QI "const_1_to_31_operand")
886          (HI "const_1_to_31_operand")
887          (SI "const_1_to_31_operand")
888          (DI "const_1_to_63_operand")])
889
890 ;; Input operand predicate for arithmetic left shifts.
891 (define_mode_attr ashl_input_operand
892         [(QI "nonimmediate_operand")
893          (HI "nonimmediate_operand")
894          (SI "nonimmediate_operand")
895          (DI "ashldi_input_operand")
896          (TI "reg_or_pm1_operand")])
897
898 ;; SSE and x87 SFmode and DFmode floating point modes
899 (define_mode_iterator MODEF [SF DF])
900
901 ;; All x87 floating point modes
902 (define_mode_iterator X87MODEF [SF DF XF])
903
904 ;; All integer modes handled by x87 fisttp operator.
905 (define_mode_iterator X87MODEI [HI SI DI])
906
907 ;; All integer modes handled by integer x87 operators.
908 (define_mode_iterator X87MODEI12 [HI SI])
909
910 ;; All integer modes handled by SSE cvtts?2si* operators.
911 (define_mode_iterator SSEMODEI24 [SI DI])
912
913 ;; SSE asm suffix for floating point modes
914 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
915
916 ;; SSE vector mode corresponding to a scalar mode
917 (define_mode_attr ssevecmode
918   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
919
920 ;; Instruction suffix for REX 64bit operators.
921 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
922
923 ;; This mode iterator allows :P to be used for patterns that operate on
924 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
925 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
926 \f
927 ;; Scheduling descriptions
928
929 (include "pentium.md")
930 (include "ppro.md")
931 (include "k6.md")
932 (include "athlon.md")
933 (include "bdver1.md")
934 (include "geode.md")
935 (include "atom.md")
936
937 \f
938 ;; Operand and operator predicates and constraints
939
940 (include "predicates.md")
941 (include "constraints.md")
942
943 \f
944 ;; Compare and branch/compare and store instructions.
945
946 (define_expand "cbranch<mode>4"
947   [(set (reg:CC FLAGS_REG)
948         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
949                     (match_operand:SDWIM 2 "<general_operand>" "")))
950    (set (pc) (if_then_else
951                (match_operator 0 "ordered_comparison_operator"
952                 [(reg:CC FLAGS_REG) (const_int 0)])
953                (label_ref (match_operand 3 "" ""))
954                (pc)))]
955   ""
956 {
957   if (MEM_P (operands[1]) && MEM_P (operands[2]))
958     operands[1] = force_reg (<MODE>mode, operands[1]);
959   ix86_expand_branch (GET_CODE (operands[0]),
960                       operands[1], operands[2], operands[3]);
961   DONE;
962 })
963
964 (define_expand "cstore<mode>4"
965   [(set (reg:CC FLAGS_REG)
966         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
967                     (match_operand:SWIM 3 "<general_operand>" "")))
968    (set (match_operand:QI 0 "register_operand" "")
969         (match_operator 1 "ordered_comparison_operator"
970           [(reg:CC FLAGS_REG) (const_int 0)]))]
971   ""
972 {
973   if (MEM_P (operands[2]) && MEM_P (operands[3]))
974     operands[2] = force_reg (<MODE>mode, operands[2]);
975   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
976                      operands[2], operands[3]);
977   DONE;
978 })
979
980 (define_expand "cmp<mode>_1"
981   [(set (reg:CC FLAGS_REG)
982         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
983                     (match_operand:SWI48 1 "<general_operand>" "")))])
984
985 (define_insn "*cmp<mode>_ccno_1"
986   [(set (reg FLAGS_REG)
987         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
988                  (match_operand:SWI 1 "const0_operand" "")))]
989   "ix86_match_ccmode (insn, CCNOmode)"
990   "@
991    test{<imodesuffix>}\t%0, %0
992    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
993   [(set_attr "type" "test,icmp")
994    (set_attr "length_immediate" "0,1")
995    (set_attr "mode" "<MODE>")])
996
997 (define_insn "*cmp<mode>_1"
998   [(set (reg FLAGS_REG)
999         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1000                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1001   "ix86_match_ccmode (insn, CCmode)"
1002   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1003   [(set_attr "type" "icmp")
1004    (set_attr "mode" "<MODE>")])
1005
1006 (define_insn "*cmp<mode>_minus_1"
1007   [(set (reg FLAGS_REG)
1008         (compare
1009           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1010                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1011           (const_int 0)))]
1012   "ix86_match_ccmode (insn, CCGOCmode)"
1013   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1014   [(set_attr "type" "icmp")
1015    (set_attr "mode" "<MODE>")])
1016
1017 (define_insn "*cmpqi_ext_1"
1018   [(set (reg FLAGS_REG)
1019         (compare
1020           (match_operand:QI 0 "general_operand" "Qm")
1021           (subreg:QI
1022             (zero_extract:SI
1023               (match_operand 1 "ext_register_operand" "Q")
1024               (const_int 8)
1025               (const_int 8)) 0)))]
1026   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1027   "cmp{b}\t{%h1, %0|%0, %h1}"
1028   [(set_attr "type" "icmp")
1029    (set_attr "mode" "QI")])
1030
1031 (define_insn "*cmpqi_ext_1_rex64"
1032   [(set (reg FLAGS_REG)
1033         (compare
1034           (match_operand:QI 0 "register_operand" "Q")
1035           (subreg:QI
1036             (zero_extract:SI
1037               (match_operand 1 "ext_register_operand" "Q")
1038               (const_int 8)
1039               (const_int 8)) 0)))]
1040   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1041   "cmp{b}\t{%h1, %0|%0, %h1}"
1042   [(set_attr "type" "icmp")
1043    (set_attr "mode" "QI")])
1044
1045 (define_insn "*cmpqi_ext_2"
1046   [(set (reg FLAGS_REG)
1047         (compare
1048           (subreg:QI
1049             (zero_extract:SI
1050               (match_operand 0 "ext_register_operand" "Q")
1051               (const_int 8)
1052               (const_int 8)) 0)
1053           (match_operand:QI 1 "const0_operand" "")))]
1054   "ix86_match_ccmode (insn, CCNOmode)"
1055   "test{b}\t%h0, %h0"
1056   [(set_attr "type" "test")
1057    (set_attr "length_immediate" "0")
1058    (set_attr "mode" "QI")])
1059
1060 (define_expand "cmpqi_ext_3"
1061   [(set (reg:CC FLAGS_REG)
1062         (compare:CC
1063           (subreg:QI
1064             (zero_extract:SI
1065               (match_operand 0 "ext_register_operand" "")
1066               (const_int 8)
1067               (const_int 8)) 0)
1068           (match_operand:QI 1 "immediate_operand" "")))])
1069
1070 (define_insn "*cmpqi_ext_3_insn"
1071   [(set (reg FLAGS_REG)
1072         (compare
1073           (subreg:QI
1074             (zero_extract:SI
1075               (match_operand 0 "ext_register_operand" "Q")
1076               (const_int 8)
1077               (const_int 8)) 0)
1078           (match_operand:QI 1 "general_operand" "Qmn")))]
1079   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1080   "cmp{b}\t{%1, %h0|%h0, %1}"
1081   [(set_attr "type" "icmp")
1082    (set_attr "modrm" "1")
1083    (set_attr "mode" "QI")])
1084
1085 (define_insn "*cmpqi_ext_3_insn_rex64"
1086   [(set (reg FLAGS_REG)
1087         (compare
1088           (subreg:QI
1089             (zero_extract:SI
1090               (match_operand 0 "ext_register_operand" "Q")
1091               (const_int 8)
1092               (const_int 8)) 0)
1093           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1094   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1095   "cmp{b}\t{%1, %h0|%h0, %1}"
1096   [(set_attr "type" "icmp")
1097    (set_attr "modrm" "1")
1098    (set_attr "mode" "QI")])
1099
1100 (define_insn "*cmpqi_ext_4"
1101   [(set (reg FLAGS_REG)
1102         (compare
1103           (subreg:QI
1104             (zero_extract:SI
1105               (match_operand 0 "ext_register_operand" "Q")
1106               (const_int 8)
1107               (const_int 8)) 0)
1108           (subreg:QI
1109             (zero_extract:SI
1110               (match_operand 1 "ext_register_operand" "Q")
1111               (const_int 8)
1112               (const_int 8)) 0)))]
1113   "ix86_match_ccmode (insn, CCmode)"
1114   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1115   [(set_attr "type" "icmp")
1116    (set_attr "mode" "QI")])
1117
1118 ;; These implement float point compares.
1119 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1120 ;; which would allow mix and match FP modes on the compares.  Which is what
1121 ;; the old patterns did, but with many more of them.
1122
1123 (define_expand "cbranchxf4"
1124   [(set (reg:CC FLAGS_REG)
1125         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1126                     (match_operand:XF 2 "nonmemory_operand" "")))
1127    (set (pc) (if_then_else
1128               (match_operator 0 "ix86_fp_comparison_operator"
1129                [(reg:CC FLAGS_REG)
1130                 (const_int 0)])
1131               (label_ref (match_operand 3 "" ""))
1132               (pc)))]
1133   "TARGET_80387"
1134 {
1135   ix86_expand_branch (GET_CODE (operands[0]),
1136                       operands[1], operands[2], operands[3]);
1137   DONE;
1138 })
1139
1140 (define_expand "cstorexf4"
1141   [(set (reg:CC FLAGS_REG)
1142         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1143                     (match_operand:XF 3 "nonmemory_operand" "")))
1144    (set (match_operand:QI 0 "register_operand" "")
1145               (match_operator 1 "ix86_fp_comparison_operator"
1146                [(reg:CC FLAGS_REG)
1147                 (const_int 0)]))]
1148   "TARGET_80387"
1149 {
1150   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1151                      operands[2], operands[3]);
1152   DONE;
1153 })
1154
1155 (define_expand "cbranch<mode>4"
1156   [(set (reg:CC FLAGS_REG)
1157         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1158                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1159    (set (pc) (if_then_else
1160               (match_operator 0 "ix86_fp_comparison_operator"
1161                [(reg:CC FLAGS_REG)
1162                 (const_int 0)])
1163               (label_ref (match_operand 3 "" ""))
1164               (pc)))]
1165   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1166 {
1167   ix86_expand_branch (GET_CODE (operands[0]),
1168                       operands[1], operands[2], operands[3]);
1169   DONE;
1170 })
1171
1172 (define_expand "cstore<mode>4"
1173   [(set (reg:CC FLAGS_REG)
1174         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1175                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1176    (set (match_operand:QI 0 "register_operand" "")
1177               (match_operator 1 "ix86_fp_comparison_operator"
1178                [(reg:CC FLAGS_REG)
1179                 (const_int 0)]))]
1180   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1181 {
1182   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1183                      operands[2], operands[3]);
1184   DONE;
1185 })
1186
1187 (define_expand "cbranchcc4"
1188   [(set (pc) (if_then_else
1189               (match_operator 0 "comparison_operator"
1190                [(match_operand 1 "flags_reg_operand" "")
1191                 (match_operand 2 "const0_operand" "")])
1192               (label_ref (match_operand 3 "" ""))
1193               (pc)))]
1194   ""
1195 {
1196   ix86_expand_branch (GET_CODE (operands[0]),
1197                       operands[1], operands[2], operands[3]);
1198   DONE;
1199 })
1200
1201 (define_expand "cstorecc4"
1202   [(set (match_operand:QI 0 "register_operand" "")
1203               (match_operator 1 "comparison_operator"
1204                [(match_operand 2 "flags_reg_operand" "")
1205                 (match_operand 3 "const0_operand" "")]))]
1206   ""
1207 {
1208   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1209                      operands[2], operands[3]);
1210   DONE;
1211 })
1212
1213
1214 ;; FP compares, step 1:
1215 ;; Set the FP condition codes.
1216 ;;
1217 ;; CCFPmode     compare with exceptions
1218 ;; CCFPUmode    compare with no exceptions
1219
1220 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1221 ;; used to manage the reg stack popping would not be preserved.
1222
1223 (define_insn "*cmpfp_0"
1224   [(set (match_operand:HI 0 "register_operand" "=a")
1225         (unspec:HI
1226           [(compare:CCFP
1227              (match_operand 1 "register_operand" "f")
1228              (match_operand 2 "const0_operand" ""))]
1229         UNSPEC_FNSTSW))]
1230   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1231    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1232   "* return output_fp_compare (insn, operands, 0, 0);"
1233   [(set_attr "type" "multi")
1234    (set_attr "unit" "i387")
1235    (set (attr "mode")
1236      (cond [(match_operand:SF 1 "" "")
1237               (const_string "SF")
1238             (match_operand:DF 1 "" "")
1239               (const_string "DF")
1240            ]
1241            (const_string "XF")))])
1242
1243 (define_insn_and_split "*cmpfp_0_cc"
1244   [(set (reg:CCFP FLAGS_REG)
1245         (compare:CCFP
1246           (match_operand 1 "register_operand" "f")
1247           (match_operand 2 "const0_operand" "")))
1248    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1249   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1250    && TARGET_SAHF && !TARGET_CMOVE
1251    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1252   "#"
1253   "&& reload_completed"
1254   [(set (match_dup 0)
1255         (unspec:HI
1256           [(compare:CCFP (match_dup 1)(match_dup 2))]
1257         UNSPEC_FNSTSW))
1258    (set (reg:CC FLAGS_REG)
1259         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1260   ""
1261   [(set_attr "type" "multi")
1262    (set_attr "unit" "i387")
1263    (set (attr "mode")
1264      (cond [(match_operand:SF 1 "" "")
1265               (const_string "SF")
1266             (match_operand:DF 1 "" "")
1267               (const_string "DF")
1268            ]
1269            (const_string "XF")))])
1270
1271 (define_insn "*cmpfp_xf"
1272   [(set (match_operand:HI 0 "register_operand" "=a")
1273         (unspec:HI
1274           [(compare:CCFP
1275              (match_operand:XF 1 "register_operand" "f")
1276              (match_operand:XF 2 "register_operand" "f"))]
1277           UNSPEC_FNSTSW))]
1278   "TARGET_80387"
1279   "* return output_fp_compare (insn, operands, 0, 0);"
1280   [(set_attr "type" "multi")
1281    (set_attr "unit" "i387")
1282    (set_attr "mode" "XF")])
1283
1284 (define_insn_and_split "*cmpfp_xf_cc"
1285   [(set (reg:CCFP FLAGS_REG)
1286         (compare:CCFP
1287           (match_operand:XF 1 "register_operand" "f")
1288           (match_operand:XF 2 "register_operand" "f")))
1289    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1290   "TARGET_80387
1291    && TARGET_SAHF && !TARGET_CMOVE"
1292   "#"
1293   "&& reload_completed"
1294   [(set (match_dup 0)
1295         (unspec:HI
1296           [(compare:CCFP (match_dup 1)(match_dup 2))]
1297         UNSPEC_FNSTSW))
1298    (set (reg:CC FLAGS_REG)
1299         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1300   ""
1301   [(set_attr "type" "multi")
1302    (set_attr "unit" "i387")
1303    (set_attr "mode" "XF")])
1304
1305 (define_insn "*cmpfp_<mode>"
1306   [(set (match_operand:HI 0 "register_operand" "=a")
1307         (unspec:HI
1308           [(compare:CCFP
1309              (match_operand:MODEF 1 "register_operand" "f")
1310              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1311           UNSPEC_FNSTSW))]
1312   "TARGET_80387"
1313   "* return output_fp_compare (insn, operands, 0, 0);"
1314   [(set_attr "type" "multi")
1315    (set_attr "unit" "i387")
1316    (set_attr "mode" "<MODE>")])
1317
1318 (define_insn_and_split "*cmpfp_<mode>_cc"
1319   [(set (reg:CCFP FLAGS_REG)
1320         (compare:CCFP
1321           (match_operand:MODEF 1 "register_operand" "f")
1322           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1323    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1324   "TARGET_80387
1325    && TARGET_SAHF && !TARGET_CMOVE"
1326   "#"
1327   "&& reload_completed"
1328   [(set (match_dup 0)
1329         (unspec:HI
1330           [(compare:CCFP (match_dup 1)(match_dup 2))]
1331         UNSPEC_FNSTSW))
1332    (set (reg:CC FLAGS_REG)
1333         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1334   ""
1335   [(set_attr "type" "multi")
1336    (set_attr "unit" "i387")
1337    (set_attr "mode" "<MODE>")])
1338
1339 (define_insn "*cmpfp_u"
1340   [(set (match_operand:HI 0 "register_operand" "=a")
1341         (unspec:HI
1342           [(compare:CCFPU
1343              (match_operand 1 "register_operand" "f")
1344              (match_operand 2 "register_operand" "f"))]
1345           UNSPEC_FNSTSW))]
1346   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1347    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1348   "* return output_fp_compare (insn, operands, 0, 1);"
1349   [(set_attr "type" "multi")
1350    (set_attr "unit" "i387")
1351    (set (attr "mode")
1352      (cond [(match_operand:SF 1 "" "")
1353               (const_string "SF")
1354             (match_operand:DF 1 "" "")
1355               (const_string "DF")
1356            ]
1357            (const_string "XF")))])
1358
1359 (define_insn_and_split "*cmpfp_u_cc"
1360   [(set (reg:CCFPU FLAGS_REG)
1361         (compare:CCFPU
1362           (match_operand 1 "register_operand" "f")
1363           (match_operand 2 "register_operand" "f")))
1364    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1365   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1366    && TARGET_SAHF && !TARGET_CMOVE
1367    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1368   "#"
1369   "&& reload_completed"
1370   [(set (match_dup 0)
1371         (unspec:HI
1372           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1373         UNSPEC_FNSTSW))
1374    (set (reg:CC FLAGS_REG)
1375         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1376   ""
1377   [(set_attr "type" "multi")
1378    (set_attr "unit" "i387")
1379    (set (attr "mode")
1380      (cond [(match_operand:SF 1 "" "")
1381               (const_string "SF")
1382             (match_operand:DF 1 "" "")
1383               (const_string "DF")
1384            ]
1385            (const_string "XF")))])
1386
1387 (define_insn "*cmpfp_<mode>"
1388   [(set (match_operand:HI 0 "register_operand" "=a")
1389         (unspec:HI
1390           [(compare:CCFP
1391              (match_operand 1 "register_operand" "f")
1392              (match_operator 3 "float_operator"
1393                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1394           UNSPEC_FNSTSW))]
1395   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1396    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1397    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1398   "* return output_fp_compare (insn, operands, 0, 0);"
1399   [(set_attr "type" "multi")
1400    (set_attr "unit" "i387")
1401    (set_attr "fp_int_src" "true")
1402    (set_attr "mode" "<MODE>")])
1403
1404 (define_insn_and_split "*cmpfp_<mode>_cc"
1405   [(set (reg:CCFP FLAGS_REG)
1406         (compare:CCFP
1407           (match_operand 1 "register_operand" "f")
1408           (match_operator 3 "float_operator"
1409             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1410    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1411   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1412    && TARGET_SAHF && !TARGET_CMOVE
1413    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1414    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1415   "#"
1416   "&& reload_completed"
1417   [(set (match_dup 0)
1418         (unspec:HI
1419           [(compare:CCFP
1420              (match_dup 1)
1421              (match_op_dup 3 [(match_dup 2)]))]
1422         UNSPEC_FNSTSW))
1423    (set (reg:CC FLAGS_REG)
1424         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1425   ""
1426   [(set_attr "type" "multi")
1427    (set_attr "unit" "i387")
1428    (set_attr "fp_int_src" "true")
1429    (set_attr "mode" "<MODE>")])
1430
1431 ;; FP compares, step 2
1432 ;; Move the fpsw to ax.
1433
1434 (define_insn "x86_fnstsw_1"
1435   [(set (match_operand:HI 0 "register_operand" "=a")
1436         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1437   "TARGET_80387"
1438   "fnstsw\t%0"
1439   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1440    (set_attr "mode" "SI")
1441    (set_attr "unit" "i387")])
1442
1443 ;; FP compares, step 3
1444 ;; Get ax into flags, general case.
1445
1446 (define_insn "x86_sahf_1"
1447   [(set (reg:CC FLAGS_REG)
1448         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1449                    UNSPEC_SAHF))]
1450   "TARGET_SAHF"
1451 {
1452 #ifndef HAVE_AS_IX86_SAHF
1453   if (TARGET_64BIT)
1454     return ASM_BYTE "0x9e";
1455   else
1456 #endif
1457   return "sahf";
1458 }
1459   [(set_attr "length" "1")
1460    (set_attr "athlon_decode" "vector")
1461    (set_attr "amdfam10_decode" "direct")
1462    (set_attr "bdver1_decode" "direct")
1463    (set_attr "mode" "SI")])
1464
1465 ;; Pentium Pro can do steps 1 through 3 in one go.
1466 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1467 (define_insn "*cmpfp_i_mixed"
1468   [(set (reg:CCFP FLAGS_REG)
1469         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1470                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1471   "TARGET_MIX_SSE_I387
1472    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1473    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1474   "* return output_fp_compare (insn, operands, 1, 0);"
1475   [(set_attr "type" "fcmp,ssecomi")
1476    (set_attr "prefix" "orig,maybe_vex")
1477    (set (attr "mode")
1478      (if_then_else (match_operand:SF 1 "" "")
1479         (const_string "SF")
1480         (const_string "DF")))
1481    (set (attr "prefix_rep")
1482         (if_then_else (eq_attr "type" "ssecomi")
1483                       (const_string "0")
1484                       (const_string "*")))
1485    (set (attr "prefix_data16")
1486         (cond [(eq_attr "type" "fcmp")
1487                  (const_string "*")
1488                (eq_attr "mode" "DF")
1489                  (const_string "1")
1490               ]
1491               (const_string "0")))
1492    (set_attr "athlon_decode" "vector")
1493    (set_attr "amdfam10_decode" "direct")
1494    (set_attr "bdver1_decode" "double")])
1495
1496 (define_insn "*cmpfp_i_sse"
1497   [(set (reg:CCFP FLAGS_REG)
1498         (compare:CCFP (match_operand 0 "register_operand" "x")
1499                       (match_operand 1 "nonimmediate_operand" "xm")))]
1500   "TARGET_SSE_MATH
1501    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503   "* return output_fp_compare (insn, operands, 1, 0);"
1504   [(set_attr "type" "ssecomi")
1505    (set_attr "prefix" "maybe_vex")
1506    (set (attr "mode")
1507      (if_then_else (match_operand:SF 1 "" "")
1508         (const_string "SF")
1509         (const_string "DF")))
1510    (set_attr "prefix_rep" "0")
1511    (set (attr "prefix_data16")
1512         (if_then_else (eq_attr "mode" "DF")
1513                       (const_string "1")
1514                       (const_string "0")))
1515    (set_attr "athlon_decode" "vector")
1516    (set_attr "amdfam10_decode" "direct")
1517    (set_attr "bdver1_decode" "double")])
1518
1519 (define_insn "*cmpfp_i_i387"
1520   [(set (reg:CCFP FLAGS_REG)
1521         (compare:CCFP (match_operand 0 "register_operand" "f")
1522                       (match_operand 1 "register_operand" "f")))]
1523   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1524    && TARGET_CMOVE
1525    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1526    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1527   "* return output_fp_compare (insn, operands, 1, 0);"
1528   [(set_attr "type" "fcmp")
1529    (set (attr "mode")
1530      (cond [(match_operand:SF 1 "" "")
1531               (const_string "SF")
1532             (match_operand:DF 1 "" "")
1533               (const_string "DF")
1534            ]
1535            (const_string "XF")))
1536    (set_attr "athlon_decode" "vector")
1537    (set_attr "amdfam10_decode" "direct")
1538    (set_attr "bdver1_decode" "double")])
1539
1540 (define_insn "*cmpfp_iu_mixed"
1541   [(set (reg:CCFPU FLAGS_REG)
1542         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1543                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1544   "TARGET_MIX_SSE_I387
1545    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1546    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1547   "* return output_fp_compare (insn, operands, 1, 1);"
1548   [(set_attr "type" "fcmp,ssecomi")
1549    (set_attr "prefix" "orig,maybe_vex")
1550    (set (attr "mode")
1551      (if_then_else (match_operand:SF 1 "" "")
1552         (const_string "SF")
1553         (const_string "DF")))
1554    (set (attr "prefix_rep")
1555         (if_then_else (eq_attr "type" "ssecomi")
1556                       (const_string "0")
1557                       (const_string "*")))
1558    (set (attr "prefix_data16")
1559         (cond [(eq_attr "type" "fcmp")
1560                  (const_string "*")
1561                (eq_attr "mode" "DF")
1562                  (const_string "1")
1563               ]
1564               (const_string "0")))
1565    (set_attr "athlon_decode" "vector")
1566    (set_attr "amdfam10_decode" "direct")
1567    (set_attr "bdver1_decode" "double")])
1568
1569 (define_insn "*cmpfp_iu_sse"
1570   [(set (reg:CCFPU FLAGS_REG)
1571         (compare:CCFPU (match_operand 0 "register_operand" "x")
1572                        (match_operand 1 "nonimmediate_operand" "xm")))]
1573   "TARGET_SSE_MATH
1574    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1575    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576   "* return output_fp_compare (insn, operands, 1, 1);"
1577   [(set_attr "type" "ssecomi")
1578    (set_attr "prefix" "maybe_vex")
1579    (set (attr "mode")
1580      (if_then_else (match_operand:SF 1 "" "")
1581         (const_string "SF")
1582         (const_string "DF")))
1583    (set_attr "prefix_rep" "0")
1584    (set (attr "prefix_data16")
1585         (if_then_else (eq_attr "mode" "DF")
1586                       (const_string "1")
1587                       (const_string "0")))
1588    (set_attr "athlon_decode" "vector")
1589    (set_attr "amdfam10_decode" "direct")
1590    (set_attr "bdver1_decode" "double")])
1591
1592 (define_insn "*cmpfp_iu_387"
1593   [(set (reg:CCFPU FLAGS_REG)
1594         (compare:CCFPU (match_operand 0 "register_operand" "f")
1595                        (match_operand 1 "register_operand" "f")))]
1596   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1597    && TARGET_CMOVE
1598    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1599    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1600   "* return output_fp_compare (insn, operands, 1, 1);"
1601   [(set_attr "type" "fcmp")
1602    (set (attr "mode")
1603      (cond [(match_operand:SF 1 "" "")
1604               (const_string "SF")
1605             (match_operand:DF 1 "" "")
1606               (const_string "DF")
1607            ]
1608            (const_string "XF")))
1609    (set_attr "athlon_decode" "vector")
1610    (set_attr "amdfam10_decode" "direct")
1611    (set_attr "bdver1_decode" "direct")])
1612 \f
1613 ;; Push/pop instructions.
1614
1615 (define_insn "*push<mode>2"
1616   [(set (match_operand:DWI 0 "push_operand" "=<")
1617         (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1618   ""
1619   "#")
1620
1621 (define_split
1622   [(set (match_operand:TI 0 "push_operand" "")
1623         (match_operand:TI 1 "general_operand" ""))]
1624   "TARGET_64BIT && reload_completed
1625    && !SSE_REG_P (operands[1])"
1626   [(const_int 0)]
1627   "ix86_split_long_move (operands); DONE;")
1628
1629 (define_insn "*pushdi2_rex64"
1630   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1631         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1632   "TARGET_64BIT"
1633   "@
1634    push{q}\t%1
1635    #"
1636   [(set_attr "type" "push,multi")
1637    (set_attr "mode" "DI")])
1638
1639 ;; Convert impossible pushes of immediate to existing instructions.
1640 ;; First try to get scratch register and go through it.  In case this
1641 ;; fails, push sign extended lower part first and then overwrite
1642 ;; upper part by 32bit move.
1643 (define_peephole2
1644   [(match_scratch:DI 2 "r")
1645    (set (match_operand:DI 0 "push_operand" "")
1646         (match_operand:DI 1 "immediate_operand" ""))]
1647   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1648    && !x86_64_immediate_operand (operands[1], DImode)"
1649   [(set (match_dup 2) (match_dup 1))
1650    (set (match_dup 0) (match_dup 2))])
1651
1652 ;; We need to define this as both peepholer and splitter for case
1653 ;; peephole2 pass is not run.
1654 ;; "&& 1" is needed to keep it from matching the previous pattern.
1655 (define_peephole2
1656   [(set (match_operand:DI 0 "push_operand" "")
1657         (match_operand:DI 1 "immediate_operand" ""))]
1658   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1659    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1660   [(set (match_dup 0) (match_dup 1))
1661    (set (match_dup 2) (match_dup 3))]
1662 {
1663   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1664
1665   operands[1] = gen_lowpart (DImode, operands[2]);
1666   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1667                                                    GEN_INT (4)));
1668 })
1669
1670 (define_split
1671   [(set (match_operand:DI 0 "push_operand" "")
1672         (match_operand:DI 1 "immediate_operand" ""))]
1673   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1674                     ? epilogue_completed : reload_completed)
1675    && !symbolic_operand (operands[1], DImode)
1676    && !x86_64_immediate_operand (operands[1], DImode)"
1677   [(set (match_dup 0) (match_dup 1))
1678    (set (match_dup 2) (match_dup 3))]
1679 {
1680   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1681
1682   operands[1] = gen_lowpart (DImode, operands[2]);
1683   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1684                                                    GEN_INT (4)));
1685 })
1686
1687 (define_split
1688   [(set (match_operand:DI 0 "push_operand" "")
1689         (match_operand:DI 1 "general_operand" ""))]
1690   "!TARGET_64BIT && reload_completed
1691    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1692   [(const_int 0)]
1693   "ix86_split_long_move (operands); DONE;")
1694
1695 (define_insn "*pushsi2"
1696   [(set (match_operand:SI 0 "push_operand" "=<")
1697         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1698   "!TARGET_64BIT"
1699   "push{l}\t%1"
1700   [(set_attr "type" "push")
1701    (set_attr "mode" "SI")])
1702
1703 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1704 ;; "push a byte/word".  But actually we use pushl, which has the effect
1705 ;; of rounding the amount pushed up to a word.
1706
1707 ;; For TARGET_64BIT we always round up to 8 bytes.
1708 (define_insn "*push<mode>2_rex64"
1709   [(set (match_operand:SWI124 0 "push_operand" "=X")
1710         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1711   "TARGET_64BIT"
1712   "push{q}\t%q1"
1713   [(set_attr "type" "push")
1714    (set_attr "mode" "DI")])
1715
1716 (define_insn "*push<mode>2"
1717   [(set (match_operand:SWI12 0 "push_operand" "=X")
1718         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1719   "!TARGET_64BIT"
1720   "push{l}\t%k1"
1721   [(set_attr "type" "push")
1722    (set_attr "mode" "SI")])
1723
1724 (define_insn "*push<mode>2_prologue"
1725   [(set (match_operand:P 0 "push_operand" "=<")
1726         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1727    (clobber (mem:BLK (scratch)))]
1728   ""
1729   "push{<imodesuffix>}\t%1"
1730   [(set_attr "type" "push")
1731    (set_attr "mode" "<MODE>")])
1732
1733 (define_insn "*pop<mode>1"
1734   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1735         (match_operand:P 1 "pop_operand" ">"))]
1736   ""
1737   "pop{<imodesuffix>}\t%0"
1738   [(set_attr "type" "pop")
1739    (set_attr "mode" "<MODE>")])
1740
1741 (define_insn "*pop<mode>1_epilogue"
1742   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1743         (match_operand:P 1 "pop_operand" ">"))
1744    (clobber (mem:BLK (scratch)))]
1745   ""
1746   "pop{<imodesuffix>}\t%0"
1747   [(set_attr "type" "pop")
1748    (set_attr "mode" "<MODE>")])
1749 \f
1750 ;; Move instructions.
1751
1752 (define_expand "movoi"
1753   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1754         (match_operand:OI 1 "general_operand" ""))]
1755   "TARGET_AVX"
1756   "ix86_expand_move (OImode, operands); DONE;")
1757
1758 (define_expand "movti"
1759   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1760         (match_operand:TI 1 "nonimmediate_operand" ""))]
1761   "TARGET_64BIT || TARGET_SSE"
1762 {
1763   if (TARGET_64BIT)
1764     ix86_expand_move (TImode, operands);
1765   else if (push_operand (operands[0], TImode))
1766     ix86_expand_push (TImode, operands[1]);
1767   else
1768     ix86_expand_vector_move (TImode, operands);
1769   DONE;
1770 })
1771
1772 ;; This expands to what emit_move_complex would generate if we didn't
1773 ;; have a movti pattern.  Having this avoids problems with reload on
1774 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1775 ;; to have around all the time.
1776 (define_expand "movcdi"
1777   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1778         (match_operand:CDI 1 "general_operand" ""))]
1779   ""
1780 {
1781   if (push_operand (operands[0], CDImode))
1782     emit_move_complex_push (CDImode, operands[0], operands[1]);
1783   else
1784     emit_move_complex_parts (operands[0], operands[1]);
1785   DONE;
1786 })
1787
1788 (define_expand "mov<mode>"
1789   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1790         (match_operand:SWI1248x 1 "general_operand" ""))]
1791   ""
1792   "ix86_expand_move (<MODE>mode, operands); DONE;")
1793
1794 (define_insn "*mov<mode>_xor"
1795   [(set (match_operand:SWI48 0 "register_operand" "=r")
1796         (match_operand:SWI48 1 "const0_operand" ""))
1797    (clobber (reg:CC FLAGS_REG))]
1798   "reload_completed"
1799   "xor{l}\t%k0, %k0"
1800   [(set_attr "type" "alu1")
1801    (set_attr "mode" "SI")
1802    (set_attr "length_immediate" "0")])
1803
1804 (define_insn "*mov<mode>_or"
1805   [(set (match_operand:SWI48 0 "register_operand" "=r")
1806         (match_operand:SWI48 1 "const_int_operand" ""))
1807    (clobber (reg:CC FLAGS_REG))]
1808   "reload_completed
1809    && operands[1] == constm1_rtx"
1810   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1811   [(set_attr "type" "alu1")
1812    (set_attr "mode" "<MODE>")
1813    (set_attr "length_immediate" "1")])
1814
1815 (define_insn "*movoi_internal_avx"
1816   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1817         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1818   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1819 {
1820   switch (which_alternative)
1821     {
1822     case 0:
1823       return "vxorps\t%0, %0, %0";
1824     case 1:
1825     case 2:
1826       if (misaligned_operand (operands[0], OImode)
1827           || misaligned_operand (operands[1], OImode))
1828         return "vmovdqu\t{%1, %0|%0, %1}";
1829       else
1830         return "vmovdqa\t{%1, %0|%0, %1}";
1831     default:
1832       gcc_unreachable ();
1833     }
1834 }
1835   [(set_attr "type" "sselog1,ssemov,ssemov")
1836    (set_attr "prefix" "vex")
1837    (set_attr "mode" "OI")])
1838
1839 (define_insn "*movti_internal_rex64"
1840   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1841         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1842   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1843 {
1844   switch (which_alternative)
1845     {
1846     case 0:
1847     case 1:
1848       return "#";
1849     case 2:
1850       if (get_attr_mode (insn) == MODE_V4SF)
1851         return "%vxorps\t%0, %d0";
1852       else
1853         return "%vpxor\t%0, %d0";
1854     case 3:
1855     case 4:
1856       /* TDmode values are passed as TImode on the stack.  Moving them
1857          to stack may result in unaligned memory access.  */
1858       if (misaligned_operand (operands[0], TImode)
1859           || misaligned_operand (operands[1], TImode))
1860         {
1861           if (get_attr_mode (insn) == MODE_V4SF)
1862             return "%vmovups\t{%1, %0|%0, %1}";
1863          else
1864            return "%vmovdqu\t{%1, %0|%0, %1}";
1865         }
1866       else
1867         {
1868           if (get_attr_mode (insn) == MODE_V4SF)
1869             return "%vmovaps\t{%1, %0|%0, %1}";
1870          else
1871            return "%vmovdqa\t{%1, %0|%0, %1}";
1872         }
1873     default:
1874       gcc_unreachable ();
1875     }
1876 }
1877   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1878    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1879    (set (attr "mode")
1880         (cond [(eq_attr "alternative" "2,3")
1881                  (if_then_else
1882                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1883                        (const_int 0))
1884                    (const_string "V4SF")
1885                    (const_string "TI"))
1886                (eq_attr "alternative" "4")
1887                  (if_then_else
1888                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1889                             (const_int 0))
1890                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1891                             (const_int 0)))
1892                    (const_string "V4SF")
1893                    (const_string "TI"))]
1894                (const_string "DI")))])
1895
1896 (define_split
1897   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1898         (match_operand:TI 1 "general_operand" ""))]
1899   "reload_completed
1900    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1901   [(const_int 0)]
1902   "ix86_split_long_move (operands); DONE;")
1903
1904 (define_insn "*movti_internal_sse"
1905   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1906         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1907   "TARGET_SSE && !TARGET_64BIT
1908    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1909 {
1910   switch (which_alternative)
1911     {
1912     case 0:
1913       if (get_attr_mode (insn) == MODE_V4SF)
1914         return "%vxorps\t%0, %d0";
1915       else
1916         return "%vpxor\t%0, %d0";
1917     case 1:
1918     case 2:
1919       /* TDmode values are passed as TImode on the stack.  Moving them
1920          to stack may result in unaligned memory access.  */
1921       if (misaligned_operand (operands[0], TImode)
1922           || misaligned_operand (operands[1], TImode))
1923         {
1924           if (get_attr_mode (insn) == MODE_V4SF)
1925             return "%vmovups\t{%1, %0|%0, %1}";
1926          else
1927            return "%vmovdqu\t{%1, %0|%0, %1}";
1928         }
1929       else
1930         {
1931           if (get_attr_mode (insn) == MODE_V4SF)
1932             return "%vmovaps\t{%1, %0|%0, %1}";
1933          else
1934            return "%vmovdqa\t{%1, %0|%0, %1}";
1935         }
1936     default:
1937       gcc_unreachable ();
1938     }
1939 }
1940   [(set_attr "type" "sselog1,ssemov,ssemov")
1941    (set_attr "prefix" "maybe_vex")
1942    (set (attr "mode")
1943         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1944                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1945                         (const_int 0)))
1946                  (const_string "V4SF")
1947                (and (eq_attr "alternative" "2")
1948                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1949                         (const_int 0)))
1950                  (const_string "V4SF")]
1951               (const_string "TI")))])
1952
1953 (define_insn "*movdi_internal_rex64"
1954   [(set (match_operand:DI 0 "nonimmediate_operand"
1955           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1956         (match_operand:DI 1 "general_operand"
1957           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1958   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1959 {
1960   switch (get_attr_type (insn))
1961     {
1962     case TYPE_SSECVT:
1963       if (SSE_REG_P (operands[0]))
1964         return "movq2dq\t{%1, %0|%0, %1}";
1965       else
1966         return "movdq2q\t{%1, %0|%0, %1}";
1967
1968     case TYPE_SSEMOV:
1969       if (TARGET_AVX)
1970         {
1971           if (get_attr_mode (insn) == MODE_TI)
1972             return "vmovdqa\t{%1, %0|%0, %1}";
1973           else
1974             return "vmovq\t{%1, %0|%0, %1}";
1975         }
1976
1977       if (get_attr_mode (insn) == MODE_TI)
1978         return "movdqa\t{%1, %0|%0, %1}";
1979       /* FALLTHRU */
1980
1981     case TYPE_MMXMOV:
1982       /* Moves from and into integer register is done using movd
1983          opcode with REX prefix.  */
1984       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1985         return "movd\t{%1, %0|%0, %1}";
1986       return "movq\t{%1, %0|%0, %1}";
1987
1988     case TYPE_SSELOG1:
1989       return "%vpxor\t%0, %d0";
1990
1991     case TYPE_MMX:
1992       return "pxor\t%0, %0";
1993
1994     case TYPE_MULTI:
1995       return "#";
1996
1997     case TYPE_LEA:
1998       return "lea{q}\t{%a1, %0|%0, %a1}";
1999
2000     default:
2001       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2002       if (get_attr_mode (insn) == MODE_SI)
2003         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2004       else if (which_alternative == 2)
2005         return "movabs{q}\t{%1, %0|%0, %1}";
2006       else
2007         return "mov{q}\t{%1, %0|%0, %1}";
2008     }
2009 }
2010   [(set (attr "type")
2011      (cond [(eq_attr "alternative" "5")
2012               (const_string "mmx")
2013             (eq_attr "alternative" "6,7,8,9,10")
2014               (const_string "mmxmov")
2015             (eq_attr "alternative" "11")
2016               (const_string "sselog1")
2017             (eq_attr "alternative" "12,13,14,15,16")
2018               (const_string "ssemov")
2019             (eq_attr "alternative" "17,18")
2020               (const_string "ssecvt")
2021             (eq_attr "alternative" "4")
2022               (const_string "multi")
2023             (match_operand:DI 1 "pic_32bit_operand" "")
2024               (const_string "lea")
2025            ]
2026            (const_string "imov")))
2027    (set (attr "modrm")
2028      (if_then_else
2029        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2030          (const_string "0")
2031          (const_string "*")))
2032    (set (attr "length_immediate")
2033      (if_then_else
2034        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2035          (const_string "8")
2036          (const_string "*")))
2037    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2038    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2039    (set (attr "prefix")
2040      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2041        (const_string "maybe_vex")
2042        (const_string "orig")))
2043    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2044
2045 ;; Convert impossible stores of immediate to existing instructions.
2046 ;; First try to get scratch register and go through it.  In case this
2047 ;; fails, move by 32bit parts.
2048 (define_peephole2
2049   [(match_scratch:DI 2 "r")
2050    (set (match_operand:DI 0 "memory_operand" "")
2051         (match_operand:DI 1 "immediate_operand" ""))]
2052   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2053    && !x86_64_immediate_operand (operands[1], DImode)"
2054   [(set (match_dup 2) (match_dup 1))
2055    (set (match_dup 0) (match_dup 2))])
2056
2057 ;; We need to define this as both peepholer and splitter for case
2058 ;; peephole2 pass is not run.
2059 ;; "&& 1" is needed to keep it from matching the previous pattern.
2060 (define_peephole2
2061   [(set (match_operand:DI 0 "memory_operand" "")
2062         (match_operand:DI 1 "immediate_operand" ""))]
2063   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2064    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2065   [(set (match_dup 2) (match_dup 3))
2066    (set (match_dup 4) (match_dup 5))]
2067   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2068
2069 (define_split
2070   [(set (match_operand:DI 0 "memory_operand" "")
2071         (match_operand:DI 1 "immediate_operand" ""))]
2072   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2073                     ? epilogue_completed : reload_completed)
2074    && !symbolic_operand (operands[1], DImode)
2075    && !x86_64_immediate_operand (operands[1], DImode)"
2076   [(set (match_dup 2) (match_dup 3))
2077    (set (match_dup 4) (match_dup 5))]
2078   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2079
2080 (define_insn "*movdi_internal"
2081   [(set (match_operand:DI 0 "nonimmediate_operand"
2082                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2083         (match_operand:DI 1 "general_operand"
2084                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2085   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2086   "@
2087    #
2088    #
2089    pxor\t%0, %0
2090    movq\t{%1, %0|%0, %1}
2091    movq\t{%1, %0|%0, %1}
2092    %vpxor\t%0, %d0
2093    %vmovq\t{%1, %0|%0, %1}
2094    %vmovdqa\t{%1, %0|%0, %1}
2095    %vmovq\t{%1, %0|%0, %1}
2096    xorps\t%0, %0
2097    movlps\t{%1, %0|%0, %1}
2098    movaps\t{%1, %0|%0, %1}
2099    movlps\t{%1, %0|%0, %1}"
2100   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2101    (set (attr "prefix")
2102      (if_then_else (eq_attr "alternative" "5,6,7,8")
2103        (const_string "vex")
2104        (const_string "orig")))
2105    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2106
2107 (define_split
2108   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2109         (match_operand:DI 1 "general_operand" ""))]
2110   "!TARGET_64BIT && reload_completed
2111    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2112    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2113   [(const_int 0)]
2114   "ix86_split_long_move (operands); DONE;")
2115
2116 (define_insn "*movsi_internal"
2117   [(set (match_operand:SI 0 "nonimmediate_operand"
2118                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2119         (match_operand:SI 1 "general_operand"
2120                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2121   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2122 {
2123   switch (get_attr_type (insn))
2124     {
2125     case TYPE_SSELOG1:
2126       if (get_attr_mode (insn) == MODE_TI)
2127         return "%vpxor\t%0, %d0";
2128       return "%vxorps\t%0, %d0";
2129
2130     case TYPE_SSEMOV:
2131       switch (get_attr_mode (insn))
2132         {
2133         case MODE_TI:
2134           return "%vmovdqa\t{%1, %0|%0, %1}";
2135         case MODE_V4SF:
2136           return "%vmovaps\t{%1, %0|%0, %1}";
2137         case MODE_SI:
2138           return "%vmovd\t{%1, %0|%0, %1}";
2139         case MODE_SF:
2140           return "%vmovss\t{%1, %0|%0, %1}";
2141         default:
2142           gcc_unreachable ();
2143         }
2144
2145     case TYPE_MMX:
2146       return "pxor\t%0, %0";
2147
2148     case TYPE_MMXMOV:
2149       if (get_attr_mode (insn) == MODE_DI)
2150         return "movq\t{%1, %0|%0, %1}";
2151       return "movd\t{%1, %0|%0, %1}";
2152
2153     case TYPE_LEA:
2154       return "lea{l}\t{%a1, %0|%0, %a1}";
2155
2156     default:
2157       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2158       return "mov{l}\t{%1, %0|%0, %1}";
2159     }
2160 }
2161   [(set (attr "type")
2162      (cond [(eq_attr "alternative" "2")
2163               (const_string "mmx")
2164             (eq_attr "alternative" "3,4,5")
2165               (const_string "mmxmov")
2166             (eq_attr "alternative" "6")
2167               (const_string "sselog1")
2168             (eq_attr "alternative" "7,8,9,10,11")
2169               (const_string "ssemov")
2170             (match_operand:DI 1 "pic_32bit_operand" "")
2171               (const_string "lea")
2172            ]
2173            (const_string "imov")))
2174    (set (attr "prefix")
2175      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2176        (const_string "orig")
2177        (const_string "maybe_vex")))
2178    (set (attr "prefix_data16")
2179      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2180        (const_string "1")
2181        (const_string "*")))
2182    (set (attr "mode")
2183      (cond [(eq_attr "alternative" "2,3")
2184               (const_string "DI")
2185             (eq_attr "alternative" "6,7")
2186               (if_then_else
2187                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2188                 (const_string "V4SF")
2189                 (const_string "TI"))
2190             (and (eq_attr "alternative" "8,9,10,11")
2191                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2192               (const_string "SF")
2193            ]
2194            (const_string "SI")))])
2195
2196 (define_insn "*movhi_internal"
2197   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2198         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2199   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2200 {
2201   switch (get_attr_type (insn))
2202     {
2203     case TYPE_IMOVX:
2204       /* movzwl is faster than movw on p2 due to partial word stalls,
2205          though not as fast as an aligned movl.  */
2206       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2207     default:
2208       if (get_attr_mode (insn) == MODE_SI)
2209         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2210       else
2211         return "mov{w}\t{%1, %0|%0, %1}";
2212     }
2213 }
2214   [(set (attr "type")
2215      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2216                 (const_int 0))
2217               (const_string "imov")
2218             (and (eq_attr "alternative" "0")
2219                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2220                           (const_int 0))
2221                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2222                           (const_int 0))))
2223               (const_string "imov")
2224             (and (eq_attr "alternative" "1,2")
2225                  (match_operand:HI 1 "aligned_operand" ""))
2226               (const_string "imov")
2227             (and (ne (symbol_ref "TARGET_MOVX")
2228                      (const_int 0))
2229                  (eq_attr "alternative" "0,2"))
2230               (const_string "imovx")
2231            ]
2232            (const_string "imov")))
2233     (set (attr "mode")
2234       (cond [(eq_attr "type" "imovx")
2235                (const_string "SI")
2236              (and (eq_attr "alternative" "1,2")
2237                   (match_operand:HI 1 "aligned_operand" ""))
2238                (const_string "SI")
2239              (and (eq_attr "alternative" "0")
2240                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2241                            (const_int 0))
2242                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2243                            (const_int 0))))
2244                (const_string "SI")
2245             ]
2246             (const_string "HI")))])
2247
2248 ;; Situation is quite tricky about when to choose full sized (SImode) move
2249 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2250 ;; partial register dependency machines (such as AMD Athlon), where QImode
2251 ;; moves issue extra dependency and for partial register stalls machines
2252 ;; that don't use QImode patterns (and QImode move cause stall on the next
2253 ;; instruction).
2254 ;;
2255 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2256 ;; register stall machines with, where we use QImode instructions, since
2257 ;; partial register stall can be caused there.  Then we use movzx.
2258 (define_insn "*movqi_internal"
2259   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2260         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2261   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2262 {
2263   switch (get_attr_type (insn))
2264     {
2265     case TYPE_IMOVX:
2266       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2267       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2268     default:
2269       if (get_attr_mode (insn) == MODE_SI)
2270         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2271       else
2272         return "mov{b}\t{%1, %0|%0, %1}";
2273     }
2274 }
2275   [(set (attr "type")
2276      (cond [(and (eq_attr "alternative" "5")
2277                  (not (match_operand:QI 1 "aligned_operand" "")))
2278               (const_string "imovx")
2279             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2280                 (const_int 0))
2281               (const_string "imov")
2282             (and (eq_attr "alternative" "3")
2283                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2284                           (const_int 0))
2285                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2286                           (const_int 0))))
2287               (const_string "imov")
2288             (eq_attr "alternative" "3,5")
2289               (const_string "imovx")
2290             (and (ne (symbol_ref "TARGET_MOVX")
2291                      (const_int 0))
2292                  (eq_attr "alternative" "2"))
2293               (const_string "imovx")
2294            ]
2295            (const_string "imov")))
2296    (set (attr "mode")
2297       (cond [(eq_attr "alternative" "3,4,5")
2298                (const_string "SI")
2299              (eq_attr "alternative" "6")
2300                (const_string "QI")
2301              (eq_attr "type" "imovx")
2302                (const_string "SI")
2303              (and (eq_attr "type" "imov")
2304                   (and (eq_attr "alternative" "0,1")
2305                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2306                                 (const_int 0))
2307                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2308                                      (const_int 0))
2309                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2310                                      (const_int 0))))))
2311                (const_string "SI")
2312              ;; Avoid partial register stalls when not using QImode arithmetic
2313              (and (eq_attr "type" "imov")
2314                   (and (eq_attr "alternative" "0,1")
2315                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2316                                 (const_int 0))
2317                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2318                                 (const_int 0)))))
2319                (const_string "SI")
2320            ]
2321            (const_string "QI")))])
2322
2323 ;; Stores and loads of ax to arbitrary constant address.
2324 ;; We fake an second form of instruction to force reload to load address
2325 ;; into register when rax is not available
2326 (define_insn "*movabs<mode>_1"
2327   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2328         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2329   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2330   "@
2331    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2332    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2333   [(set_attr "type" "imov")
2334    (set_attr "modrm" "0,*")
2335    (set_attr "length_address" "8,0")
2336    (set_attr "length_immediate" "0,*")
2337    (set_attr "memory" "store")
2338    (set_attr "mode" "<MODE>")])
2339
2340 (define_insn "*movabs<mode>_2"
2341   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2342         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2343   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2344   "@
2345    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2346    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2347   [(set_attr "type" "imov")
2348    (set_attr "modrm" "0,*")
2349    (set_attr "length_address" "8,0")
2350    (set_attr "length_immediate" "0")
2351    (set_attr "memory" "load")
2352    (set_attr "mode" "<MODE>")])
2353
2354 (define_insn "*swap<mode>"
2355   [(set (match_operand:SWI48 0 "register_operand" "+r")
2356         (match_operand:SWI48 1 "register_operand" "+r"))
2357    (set (match_dup 1)
2358         (match_dup 0))]
2359   ""
2360   "xchg{<imodesuffix>}\t%1, %0"
2361   [(set_attr "type" "imov")
2362    (set_attr "mode" "<MODE>")
2363    (set_attr "pent_pair" "np")
2364    (set_attr "athlon_decode" "vector")
2365    (set_attr "amdfam10_decode" "double")
2366    (set_attr "bdver1_decode" "double")])
2367
2368 (define_insn "*swap<mode>_1"
2369   [(set (match_operand:SWI12 0 "register_operand" "+r")
2370         (match_operand:SWI12 1 "register_operand" "+r"))
2371    (set (match_dup 1)
2372         (match_dup 0))]
2373   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2374   "xchg{l}\t%k1, %k0"
2375   [(set_attr "type" "imov")
2376    (set_attr "mode" "SI")
2377    (set_attr "pent_pair" "np")
2378    (set_attr "athlon_decode" "vector")
2379    (set_attr "amdfam10_decode" "double")
2380    (set_attr "bdver1_decode" "double")])
2381
2382 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2383 ;; is disabled for AMDFAM10
2384 (define_insn "*swap<mode>_2"
2385   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2386         (match_operand:SWI12 1 "register_operand" "+<r>"))
2387    (set (match_dup 1)
2388         (match_dup 0))]
2389   "TARGET_PARTIAL_REG_STALL"
2390   "xchg{<imodesuffix>}\t%1, %0"
2391   [(set_attr "type" "imov")
2392    (set_attr "mode" "<MODE>")
2393    (set_attr "pent_pair" "np")
2394    (set_attr "athlon_decode" "vector")])
2395
2396 (define_expand "movstrict<mode>"
2397   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2398         (match_operand:SWI12 1 "general_operand" ""))]
2399   ""
2400 {
2401   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2402     FAIL;
2403   /* Don't generate memory->memory moves, go through a register */
2404   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2405     operands[1] = force_reg (<MODE>mode, operands[1]);
2406 })
2407
2408 (define_insn "*movstrict<mode>_1"
2409   [(set (strict_low_part
2410           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2411         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2412   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2413    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2414   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2415   [(set_attr "type" "imov")
2416    (set_attr "mode" "<MODE>")])
2417
2418 (define_insn "*movstrict<mode>_xor"
2419   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2420         (match_operand:SWI12 1 "const0_operand" ""))
2421    (clobber (reg:CC FLAGS_REG))]
2422   "reload_completed"
2423   "xor{<imodesuffix>}\t%0, %0"
2424   [(set_attr "type" "alu1")
2425    (set_attr "mode" "<MODE>")
2426    (set_attr "length_immediate" "0")])
2427
2428 (define_insn "*mov<mode>_extv_1"
2429   [(set (match_operand:SWI24 0 "register_operand" "=R")
2430         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2431                             (const_int 8)
2432                             (const_int 8)))]
2433   ""
2434   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2435   [(set_attr "type" "imovx")
2436    (set_attr "mode" "SI")])
2437
2438 (define_insn "*movqi_extv_1_rex64"
2439   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2440         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2441                          (const_int 8)
2442                          (const_int 8)))]
2443   "TARGET_64BIT"
2444 {
2445   switch (get_attr_type (insn))
2446     {
2447     case TYPE_IMOVX:
2448       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2449     default:
2450       return "mov{b}\t{%h1, %0|%0, %h1}";
2451     }
2452 }
2453   [(set (attr "type")
2454      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2455                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2456                              (ne (symbol_ref "TARGET_MOVX")
2457                                  (const_int 0))))
2458         (const_string "imovx")
2459         (const_string "imov")))
2460    (set (attr "mode")
2461      (if_then_else (eq_attr "type" "imovx")
2462         (const_string "SI")
2463         (const_string "QI")))])
2464
2465 (define_insn "*movqi_extv_1"
2466   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2467         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2468                          (const_int 8)
2469                          (const_int 8)))]
2470   "!TARGET_64BIT"
2471 {
2472   switch (get_attr_type (insn))
2473     {
2474     case TYPE_IMOVX:
2475       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2476     default:
2477       return "mov{b}\t{%h1, %0|%0, %h1}";
2478     }
2479 }
2480   [(set (attr "type")
2481      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2482                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2483                              (ne (symbol_ref "TARGET_MOVX")
2484                                  (const_int 0))))
2485         (const_string "imovx")
2486         (const_string "imov")))
2487    (set (attr "mode")
2488      (if_then_else (eq_attr "type" "imovx")
2489         (const_string "SI")
2490         (const_string "QI")))])
2491
2492 (define_insn "*mov<mode>_extzv_1"
2493   [(set (match_operand:SWI48 0 "register_operand" "=R")
2494         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2495                             (const_int 8)
2496                             (const_int 8)))]
2497   ""
2498   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2499   [(set_attr "type" "imovx")
2500    (set_attr "mode" "SI")])
2501
2502 (define_insn "*movqi_extzv_2_rex64"
2503   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2504         (subreg:QI
2505           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2506                            (const_int 8)
2507                            (const_int 8)) 0))]
2508   "TARGET_64BIT"
2509 {
2510   switch (get_attr_type (insn))
2511     {
2512     case TYPE_IMOVX:
2513       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2514     default:
2515       return "mov{b}\t{%h1, %0|%0, %h1}";
2516     }
2517 }
2518   [(set (attr "type")
2519      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2520                         (ne (symbol_ref "TARGET_MOVX")
2521                             (const_int 0)))
2522         (const_string "imovx")
2523         (const_string "imov")))
2524    (set (attr "mode")
2525      (if_then_else (eq_attr "type" "imovx")
2526         (const_string "SI")
2527         (const_string "QI")))])
2528
2529 (define_insn "*movqi_extzv_2"
2530   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2531         (subreg:QI
2532           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2533                            (const_int 8)
2534                            (const_int 8)) 0))]
2535   "!TARGET_64BIT"
2536 {
2537   switch (get_attr_type (insn))
2538     {
2539     case TYPE_IMOVX:
2540       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2541     default:
2542       return "mov{b}\t{%h1, %0|%0, %h1}";
2543     }
2544 }
2545   [(set (attr "type")
2546      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2547                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2548                              (ne (symbol_ref "TARGET_MOVX")
2549                                  (const_int 0))))
2550         (const_string "imovx")
2551         (const_string "imov")))
2552    (set (attr "mode")
2553      (if_then_else (eq_attr "type" "imovx")
2554         (const_string "SI")
2555         (const_string "QI")))])
2556
2557 (define_expand "mov<mode>_insv_1"
2558   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2559                             (const_int 8)
2560                             (const_int 8))
2561         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2562
2563 (define_insn "*mov<mode>_insv_1_rex64"
2564   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2565                              (const_int 8)
2566                              (const_int 8))
2567         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2568   "TARGET_64BIT"
2569   "mov{b}\t{%b1, %h0|%h0, %b1}"
2570   [(set_attr "type" "imov")
2571    (set_attr "mode" "QI")])
2572
2573 (define_insn "*movsi_insv_1"
2574   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2575                          (const_int 8)
2576                          (const_int 8))
2577         (match_operand:SI 1 "general_operand" "Qmn"))]
2578   "!TARGET_64BIT"
2579   "mov{b}\t{%b1, %h0|%h0, %b1}"
2580   [(set_attr "type" "imov")
2581    (set_attr "mode" "QI")])
2582
2583 (define_insn "*movqi_insv_2"
2584   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2585                          (const_int 8)
2586                          (const_int 8))
2587         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2588                      (const_int 8)))]
2589   ""
2590   "mov{b}\t{%h1, %h0|%h0, %h1}"
2591   [(set_attr "type" "imov")
2592    (set_attr "mode" "QI")])
2593 \f
2594 ;; Floating point push instructions.
2595
2596 (define_insn "*pushtf"
2597   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2598         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2599   "TARGET_SSE2"
2600 {
2601   /* This insn should be already split before reg-stack.  */
2602   gcc_unreachable ();
2603 }
2604   [(set_attr "type" "multi")
2605    (set_attr "unit" "sse,*,*")
2606    (set_attr "mode" "TF,SI,SI")])
2607
2608 (define_split
2609   [(set (match_operand:TF 0 "push_operand" "")
2610         (match_operand:TF 1 "sse_reg_operand" ""))]
2611   "TARGET_SSE2 && reload_completed"
2612   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2613    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2614
2615 (define_split
2616   [(set (match_operand:TF 0 "push_operand" "")
2617         (match_operand:TF 1 "general_operand" ""))]
2618   "TARGET_SSE2 && reload_completed
2619    && !SSE_REG_P (operands[1])"
2620   [(const_int 0)]
2621   "ix86_split_long_move (operands); DONE;")
2622
2623 (define_insn "*pushxf"
2624   [(set (match_operand:XF 0 "push_operand" "=<,<")
2625         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2626   "optimize_function_for_speed_p (cfun)"
2627 {
2628   /* This insn should be already split before reg-stack.  */
2629   gcc_unreachable ();
2630 }
2631   [(set_attr "type" "multi")
2632    (set_attr "unit" "i387,*")
2633    (set_attr "mode" "XF,SI")])
2634
2635 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2636 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2637 ;; Pushing using integer instructions is longer except for constants
2638 ;; and direct memory references (assuming that any given constant is pushed
2639 ;; only once, but this ought to be handled elsewhere).
2640
2641 (define_insn "*pushxf_nointeger"
2642   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2643         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2644   "optimize_function_for_size_p (cfun)"
2645 {
2646   /* This insn should be already split before reg-stack.  */
2647   gcc_unreachable ();
2648 }
2649   [(set_attr "type" "multi")
2650    (set_attr "unit" "i387,*,*")
2651    (set_attr "mode" "XF,SI,SI")])
2652
2653 (define_split
2654   [(set (match_operand:XF 0 "push_operand" "")
2655         (match_operand:XF 1 "fp_register_operand" ""))]
2656   "reload_completed"
2657   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2658    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2659   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2660
2661 (define_split
2662   [(set (match_operand:XF 0 "push_operand" "")
2663         (match_operand:XF 1 "general_operand" ""))]
2664   "reload_completed
2665    && !FP_REG_P (operands[1])"
2666   [(const_int 0)]
2667   "ix86_split_long_move (operands); DONE;")
2668
2669 (define_insn "*pushdf"
2670   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2671         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2672   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2673 {
2674   /* This insn should be already split before reg-stack.  */
2675   gcc_unreachable ();
2676 }
2677   [(set_attr "type" "multi")
2678    (set_attr "unit" "i387,*,*")
2679    (set_attr "mode" "DF,SI,DF")])
2680
2681 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2682 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2683 ;; On the average, pushdf using integers can be still shorter.  Allow this
2684 ;; pattern for optimize_size too.
2685
2686 (define_insn "*pushdf_nointeger"
2687   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2688         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2689   "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2690 {
2691   /* This insn should be already split before reg-stack.  */
2692   gcc_unreachable ();
2693 }
2694   [(set_attr "type" "multi")
2695    (set_attr "unit" "i387,*,*,*")
2696    (set_attr "mode" "DF,SI,SI,DF")])
2697
2698 ;; %%% Kill this when call knows how to work this out.
2699 (define_split
2700   [(set (match_operand:DF 0 "push_operand" "")
2701         (match_operand:DF 1 "any_fp_register_operand" ""))]
2702   "reload_completed"
2703   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2704    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2705
2706 (define_split
2707   [(set (match_operand:DF 0 "push_operand" "")
2708         (match_operand:DF 1 "general_operand" ""))]
2709   "reload_completed
2710    && !ANY_FP_REG_P (operands[1])"
2711   [(const_int 0)]
2712   "ix86_split_long_move (operands); DONE;")
2713
2714 (define_insn "*pushsf_rex64"
2715   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2716         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2717   "TARGET_64BIT"
2718 {
2719   /* Anything else should be already split before reg-stack.  */
2720   gcc_assert (which_alternative == 1);
2721   return "push{q}\t%q1";
2722 }
2723   [(set_attr "type" "multi,push,multi")
2724    (set_attr "unit" "i387,*,*")
2725    (set_attr "mode" "SF,DI,SF")])
2726
2727 (define_insn "*pushsf"
2728   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2729         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2730   "!TARGET_64BIT"
2731 {
2732   /* Anything else should be already split before reg-stack.  */
2733   gcc_assert (which_alternative == 1);
2734   return "push{l}\t%1";
2735 }
2736   [(set_attr "type" "multi,push,multi")
2737    (set_attr "unit" "i387,*,*")
2738    (set_attr "mode" "SF,SI,SF")])
2739
2740 (define_split
2741   [(set (match_operand:SF 0 "push_operand" "")
2742         (match_operand:SF 1 "memory_operand" ""))]
2743   "reload_completed
2744    && MEM_P (operands[1])
2745    && (operands[2] = find_constant_src (insn))"
2746   [(set (match_dup 0)
2747         (match_dup 2))])
2748
2749 ;; %%% Kill this when call knows how to work this out.
2750 (define_split
2751   [(set (match_operand:SF 0 "push_operand" "")
2752         (match_operand:SF 1 "any_fp_register_operand" ""))]
2753   "reload_completed"
2754   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2755    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2756   "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2757 \f
2758 ;; Floating point move instructions.
2759
2760 (define_expand "movtf"
2761   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2762         (match_operand:TF 1 "nonimmediate_operand" ""))]
2763   "TARGET_SSE2"
2764 {
2765   ix86_expand_move (TFmode, operands);
2766   DONE;
2767 })
2768
2769 (define_expand "mov<mode>"
2770   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2771         (match_operand:X87MODEF 1 "general_operand" ""))]
2772   ""
2773   "ix86_expand_move (<MODE>mode, operands); DONE;")
2774
2775 (define_insn "*movtf_internal"
2776   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2777         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2778   "TARGET_SSE2
2779    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2780 {
2781   switch (which_alternative)
2782     {
2783     case 0:
2784     case 1:
2785       if (get_attr_mode (insn) == MODE_V4SF)
2786         return "%vmovaps\t{%1, %0|%0, %1}";
2787       else
2788         return "%vmovdqa\t{%1, %0|%0, %1}";
2789     case 2:
2790       if (get_attr_mode (insn) == MODE_V4SF)
2791         return "%vxorps\t%0, %d0";
2792       else
2793         return "%vpxor\t%0, %d0";
2794     case 3:
2795     case 4:
2796         return "#";
2797     default:
2798       gcc_unreachable ();
2799     }
2800 }
2801   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2802    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2803    (set (attr "mode")
2804         (cond [(eq_attr "alternative" "0,2")
2805                  (if_then_else
2806                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2807                        (const_int 0))
2808                    (const_string "V4SF")
2809                    (const_string "TI"))
2810                (eq_attr "alternative" "1")
2811                  (if_then_else
2812                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2813                             (const_int 0))
2814                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2815                             (const_int 0)))
2816                    (const_string "V4SF")
2817                    (const_string "TI"))]
2818                (const_string "DI")))])
2819
2820 (define_split
2821   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2822         (match_operand:TF 1 "general_operand" ""))]
2823   "reload_completed
2824    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2825   [(const_int 0)]
2826   "ix86_split_long_move (operands); DONE;")
2827
2828 (define_insn "*movxf_internal"
2829   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2830         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2831   "optimize_function_for_speed_p (cfun)
2832    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2833    && (reload_in_progress || reload_completed
2834        || GET_CODE (operands[1]) != CONST_DOUBLE
2835        || memory_operand (operands[0], XFmode))"
2836 {
2837   switch (which_alternative)
2838     {
2839     case 0:
2840     case 1:
2841       return output_387_reg_move (insn, operands);
2842
2843     case 2:
2844       return standard_80387_constant_opcode (operands[1]);
2845
2846     case 3: case 4:
2847       return "#";
2848
2849     default:
2850       gcc_unreachable ();
2851     }
2852 }
2853   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2854    (set_attr "mode" "XF,XF,XF,SI,SI")])
2855
2856 ;; Do not use integer registers when optimizing for size
2857 (define_insn "*movxf_internal_nointeger"
2858   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2859         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2860   "optimize_function_for_size_p (cfun)
2861    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2862    && (reload_in_progress || reload_completed
2863        || standard_80387_constant_p (operands[1])
2864        || GET_CODE (operands[1]) != CONST_DOUBLE
2865        || memory_operand (operands[0], XFmode))"
2866 {
2867   switch (which_alternative)
2868     {
2869     case 0:
2870     case 1:
2871       return output_387_reg_move (insn, operands);
2872
2873     case 2:
2874       return standard_80387_constant_opcode (operands[1]);
2875
2876     case 3: case 4:
2877       return "#";
2878     default:
2879       gcc_unreachable ();
2880     }
2881 }
2882   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2883    (set_attr "mode" "XF,XF,XF,SI,SI")])
2884
2885 (define_split
2886   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2887         (match_operand:XF 1 "general_operand" ""))]
2888   "reload_completed
2889    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2890    && ! (FP_REG_P (operands[0]) ||
2891          (GET_CODE (operands[0]) == SUBREG
2892           && FP_REG_P (SUBREG_REG (operands[0]))))
2893    && ! (FP_REG_P (operands[1]) ||
2894          (GET_CODE (operands[1]) == SUBREG
2895           && FP_REG_P (SUBREG_REG (operands[1]))))"
2896   [(const_int 0)]
2897   "ix86_split_long_move (operands); DONE;")
2898
2899 (define_insn "*movdf_internal_rex64"
2900   [(set (match_operand:DF 0 "nonimmediate_operand"
2901                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2902         (match_operand:DF 1 "general_operand"
2903                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2904   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2905    && (reload_in_progress || reload_completed
2906        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2907        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2908            && optimize_function_for_size_p (cfun)
2909            && standard_80387_constant_p (operands[1]))
2910        || GET_CODE (operands[1]) != CONST_DOUBLE
2911        || memory_operand (operands[0], DFmode))"
2912 {
2913   switch (which_alternative)
2914     {
2915     case 0:
2916     case 1:
2917       return output_387_reg_move (insn, operands);
2918
2919     case 2:
2920       return standard_80387_constant_opcode (operands[1]);
2921
2922     case 3:
2923     case 4:
2924       return "#";
2925
2926     case 5:
2927       switch (get_attr_mode (insn))
2928         {
2929         case MODE_V4SF:
2930           return "%vxorps\t%0, %d0";
2931         case MODE_V2DF:
2932           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2933             return "%vxorps\t%0, %d0";
2934           else
2935             return "%vxorpd\t%0, %d0";
2936         case MODE_TI:
2937           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2938             return "%vxorps\t%0, %d0";
2939           else
2940             return "%vpxor\t%0, %d0";
2941         default:
2942           gcc_unreachable ();
2943         }
2944     case 6:
2945     case 7:
2946     case 8:
2947       switch (get_attr_mode (insn))
2948         {
2949         case MODE_V4SF:
2950           return "%vmovaps\t{%1, %0|%0, %1}";
2951         case MODE_V2DF:
2952           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2953             return "%vmovaps\t{%1, %0|%0, %1}";
2954           else
2955             return "%vmovapd\t{%1, %0|%0, %1}";
2956         case MODE_TI:
2957           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2958             return "%vmovaps\t{%1, %0|%0, %1}";
2959           else
2960             return "%vmovdqa\t{%1, %0|%0, %1}";
2961         case MODE_DI:
2962           return "%vmovq\t{%1, %0|%0, %1}";
2963         case MODE_DF:
2964           if (TARGET_AVX)
2965             {
2966               if (REG_P (operands[0]) && REG_P (operands[1]))
2967                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2968               else
2969                 return "vmovsd\t{%1, %0|%0, %1}";
2970             }
2971           else
2972             return "movsd\t{%1, %0|%0, %1}";
2973         case MODE_V1DF:
2974           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2975         case MODE_V2SF:
2976           return "%vmovlps\t{%1, %d0|%d0, %1}";
2977         default:
2978           gcc_unreachable ();
2979         }
2980
2981     case 9:
2982     case 10:
2983     return "%vmovd\t{%1, %0|%0, %1}";
2984
2985     default:
2986       gcc_unreachable();
2987     }
2988 }
2989   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2990    (set (attr "prefix")
2991      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2992        (const_string "orig")
2993        (const_string "maybe_vex")))
2994    (set (attr "prefix_data16")
2995      (if_then_else (eq_attr "mode" "V1DF")
2996        (const_string "1")
2997        (const_string "*")))
2998    (set (attr "mode")
2999         (cond [(eq_attr "alternative" "0,1,2")
3000                  (const_string "DF")
3001                (eq_attr "alternative" "3,4,9,10")
3002                  (const_string "DI")
3003
3004                /* For SSE1, we have many fewer alternatives.  */
3005                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3006                  (cond [(eq_attr "alternative" "5,6")
3007                           (const_string "V4SF")
3008                        ]
3009                    (const_string "V2SF"))
3010
3011                /* xorps is one byte shorter.  */
3012                (eq_attr "alternative" "5")
3013                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3014                             (const_int 0))
3015                           (const_string "V4SF")
3016                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3017                             (const_int 0))
3018                           (const_string "TI")
3019                        ]
3020                        (const_string "V2DF"))
3021
3022                /* For architectures resolving dependencies on
3023                   whole SSE registers use APD move to break dependency
3024                   chains, otherwise use short move to avoid extra work.
3025
3026                   movaps encodes one byte shorter.  */
3027                (eq_attr "alternative" "6")
3028                  (cond
3029                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3030                         (const_int 0))
3031                       (const_string "V4SF")
3032                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3033                         (const_int 0))
3034                       (const_string "V2DF")
3035                    ]
3036                    (const_string "DF"))
3037                /* For architectures resolving dependencies on register
3038                   parts we may avoid extra work to zero out upper part
3039                   of register.  */
3040                (eq_attr "alternative" "7")
3041                  (if_then_else
3042                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3043                        (const_int 0))
3044                    (const_string "V1DF")
3045                    (const_string "DF"))
3046               ]
3047               (const_string "DF")))])
3048
3049 (define_insn "*movdf_internal"
3050   [(set (match_operand:DF 0 "nonimmediate_operand"
3051                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3052         (match_operand:DF 1 "general_operand"
3053                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3054   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3055    && optimize_function_for_speed_p (cfun)
3056    && TARGET_INTEGER_DFMODE_MOVES
3057    && (reload_in_progress || reload_completed
3058        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3059        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3060            && optimize_function_for_size_p (cfun)
3061            && standard_80387_constant_p (operands[1]))
3062        || GET_CODE (operands[1]) != CONST_DOUBLE
3063        || memory_operand (operands[0], DFmode))"
3064 {
3065   switch (which_alternative)
3066     {
3067     case 0:
3068     case 1:
3069       return output_387_reg_move (insn, operands);
3070
3071     case 2:
3072       return standard_80387_constant_opcode (operands[1]);
3073
3074     case 3:
3075     case 4:
3076       return "#";
3077
3078     case 5:
3079       switch (get_attr_mode (insn))
3080         {
3081         case MODE_V4SF:
3082           return "xorps\t%0, %0";
3083         case MODE_V2DF:
3084           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3085             return "xorps\t%0, %0";
3086           else
3087             return "xorpd\t%0, %0";
3088         case MODE_TI:
3089           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3090             return "xorps\t%0, %0";
3091           else
3092             return "pxor\t%0, %0";
3093         default:
3094           gcc_unreachable ();
3095         }
3096     case 6:
3097     case 7:
3098     case 8:
3099       switch (get_attr_mode (insn))
3100         {
3101         case MODE_V4SF:
3102           return "movaps\t{%1, %0|%0, %1}";
3103         case MODE_V2DF:
3104           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3105             return "movaps\t{%1, %0|%0, %1}";
3106           else
3107             return "movapd\t{%1, %0|%0, %1}";
3108         case MODE_TI:
3109           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3110             return "movaps\t{%1, %0|%0, %1}";
3111           else
3112             return "movdqa\t{%1, %0|%0, %1}";
3113         case MODE_DI:
3114           return "movq\t{%1, %0|%0, %1}";
3115         case MODE_DF:
3116           return "movsd\t{%1, %0|%0, %1}";
3117         case MODE_V1DF:
3118           return "movlpd\t{%1, %0|%0, %1}";
3119         case MODE_V2SF:
3120           return "movlps\t{%1, %0|%0, %1}";
3121         default:
3122           gcc_unreachable ();
3123         }
3124
3125     default:
3126       gcc_unreachable();
3127     }
3128 }
3129   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3130    (set (attr "prefix_data16")
3131      (if_then_else (eq_attr "mode" "V1DF")
3132        (const_string "1")
3133        (const_string "*")))
3134    (set (attr "mode")
3135         (cond [(eq_attr "alternative" "0,1,2")
3136                  (const_string "DF")
3137                (eq_attr "alternative" "3,4")
3138                  (const_string "SI")
3139
3140                /* For SSE1, we have many fewer alternatives.  */
3141                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3142                  (cond [(eq_attr "alternative" "5,6")
3143                           (const_string "V4SF")
3144                        ]
3145                    (const_string "V2SF"))
3146
3147                /* xorps is one byte shorter.  */
3148                (eq_attr "alternative" "5")
3149                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3150                             (const_int 0))
3151                           (const_string "V4SF")
3152                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3153                             (const_int 0))
3154                           (const_string "TI")
3155                        ]
3156                        (const_string "V2DF"))
3157
3158                /* For architectures resolving dependencies on
3159                   whole SSE registers use APD move to break dependency
3160                   chains, otherwise use short move to avoid extra work.
3161
3162                   movaps encodes one byte shorter.  */
3163                (eq_attr "alternative" "6")
3164                  (cond
3165                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3166                         (const_int 0))
3167                       (const_string "V4SF")
3168                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3169                         (const_int 0))
3170                       (const_string "V2DF")
3171                    ]
3172                    (const_string "DF"))
3173                /* For architectures resolving dependencies on register
3174                   parts we may avoid extra work to zero out upper part
3175                   of register.  */
3176                (eq_attr "alternative" "7")
3177                  (if_then_else
3178                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3179                        (const_int 0))
3180                    (const_string "V1DF")
3181                    (const_string "DF"))
3182               ]
3183               (const_string "DF")))])
3184
3185 ;; Moving is usually shorter when only FP registers are used. This separate
3186 ;; movdf pattern avoids the use of integer registers for FP operations
3187 ;; when optimizing for size.
3188
3189 (define_insn "*movdf_internal_nointeger"
3190   [(set (match_operand:DF 0 "nonimmediate_operand"
3191                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3192         (match_operand:DF 1 "general_operand"
3193                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3194   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3195    && ((optimize_function_for_size_p (cfun)
3196        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3197    && (reload_in_progress || reload_completed
3198        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3199        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3200            && optimize_function_for_size_p (cfun)
3201            && !memory_operand (operands[0], DFmode)
3202            && standard_80387_constant_p (operands[1]))
3203        || GET_CODE (operands[1]) != CONST_DOUBLE
3204        || ((optimize_function_for_size_p (cfun)
3205             || !TARGET_MEMORY_MISMATCH_STALL
3206             || reload_in_progress || reload_completed)
3207            && memory_operand (operands[0], DFmode)))"
3208 {
3209   switch (which_alternative)
3210     {
3211     case 0:
3212     case 1:
3213       return output_387_reg_move (insn, operands);
3214
3215     case 2:
3216       return standard_80387_constant_opcode (operands[1]);
3217
3218     case 3:
3219     case 4:
3220       return "#";
3221
3222     case 5:
3223       switch (get_attr_mode (insn))
3224         {
3225         case MODE_V4SF:
3226           return "%vxorps\t%0, %d0";
3227         case MODE_V2DF:
3228           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3229             return "%vxorps\t%0, %d0";
3230           else
3231             return "%vxorpd\t%0, %d0";
3232         case MODE_TI:
3233           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3234             return "%vxorps\t%0, %d0";
3235           else
3236             return "%vpxor\t%0, %d0";
3237         default:
3238           gcc_unreachable ();
3239         }
3240     case 6:
3241     case 7:
3242     case 8:
3243       switch (get_attr_mode (insn))
3244         {
3245         case MODE_V4SF:
3246           return "%vmovaps\t{%1, %0|%0, %1}";
3247         case MODE_V2DF:
3248           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3249             return "%vmovaps\t{%1, %0|%0, %1}";
3250           else
3251             return "%vmovapd\t{%1, %0|%0, %1}";
3252         case MODE_TI:
3253           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3254             return "%vmovaps\t{%1, %0|%0, %1}";
3255           else
3256             return "%vmovdqa\t{%1, %0|%0, %1}";
3257         case MODE_DI:
3258           return "%vmovq\t{%1, %0|%0, %1}";
3259         case MODE_DF:
3260           if (TARGET_AVX)
3261             {
3262               if (REG_P (operands[0]) && REG_P (operands[1]))
3263                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3264               else
3265                 return "vmovsd\t{%1, %0|%0, %1}";
3266             }
3267           else
3268             return "movsd\t{%1, %0|%0, %1}";
3269         case MODE_V1DF:
3270           if (TARGET_AVX)
3271             {
3272               if (REG_P (operands[0]))
3273                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3274               else
3275                 return "vmovlpd\t{%1, %0|%0, %1}";
3276             }
3277           else
3278             return "movlpd\t{%1, %0|%0, %1}";
3279         case MODE_V2SF:
3280           if (TARGET_AVX)
3281             {
3282               if (REG_P (operands[0]))
3283                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3284               else
3285                 return "vmovlps\t{%1, %0|%0, %1}";
3286             }
3287           else
3288             return "movlps\t{%1, %0|%0, %1}";
3289         default:
3290           gcc_unreachable ();
3291         }
3292
3293     default:
3294       gcc_unreachable ();
3295     }
3296 }
3297   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3298    (set (attr "prefix")
3299      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3300        (const_string "orig")
3301        (const_string "maybe_vex")))
3302    (set (attr "prefix_data16")
3303      (if_then_else (eq_attr "mode" "V1DF")
3304        (const_string "1")
3305        (const_string "*")))
3306    (set (attr "mode")
3307         (cond [(eq_attr "alternative" "0,1,2")
3308                  (const_string "DF")
3309                (eq_attr "alternative" "3,4")
3310                  (const_string "SI")
3311
3312                /* For SSE1, we have many fewer alternatives.  */
3313                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3314                  (cond [(eq_attr "alternative" "5,6")
3315                           (const_string "V4SF")
3316                        ]
3317                    (const_string "V2SF"))
3318
3319                /* xorps is one byte shorter.  */
3320                (eq_attr "alternative" "5")
3321                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3322                             (const_int 0))
3323                           (const_string "V4SF")
3324                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3325                             (const_int 0))
3326                           (const_string "TI")
3327                        ]
3328                        (const_string "V2DF"))
3329
3330                /* For architectures resolving dependencies on
3331                   whole SSE registers use APD move to break dependency
3332                   chains, otherwise use short move to avoid extra work.
3333
3334                   movaps encodes one byte shorter.  */
3335                (eq_attr "alternative" "6")
3336                  (cond
3337                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3338                         (const_int 0))
3339                       (const_string "V4SF")
3340                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3341                         (const_int 0))
3342                       (const_string "V2DF")
3343                    ]
3344                    (const_string "DF"))
3345                /* For architectures resolving dependencies on register
3346                   parts we may avoid extra work to zero out upper part
3347                   of register.  */
3348                (eq_attr "alternative" "7")
3349                  (if_then_else
3350                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3351                        (const_int 0))
3352                    (const_string "V1DF")
3353                    (const_string "DF"))
3354               ]
3355               (const_string "DF")))])
3356
3357 (define_split
3358   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3359         (match_operand:DF 1 "general_operand" ""))]
3360   "reload_completed
3361    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3362    && ! (ANY_FP_REG_P (operands[0]) ||
3363          (GET_CODE (operands[0]) == SUBREG
3364           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3365    && ! (ANY_FP_REG_P (operands[1]) ||
3366          (GET_CODE (operands[1]) == SUBREG
3367           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3368   [(const_int 0)]
3369   "ix86_split_long_move (operands); DONE;")
3370
3371 (define_insn "*movsf_internal"
3372   [(set (match_operand:SF 0 "nonimmediate_operand"
3373           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3374         (match_operand:SF 1 "general_operand"
3375           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3376   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3377    && (reload_in_progress || reload_completed
3378        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3379        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3380            && standard_80387_constant_p (operands[1]))
3381        || GET_CODE (operands[1]) != CONST_DOUBLE
3382        || memory_operand (operands[0], SFmode))"
3383 {
3384   switch (which_alternative)
3385     {
3386     case 0:
3387     case 1:
3388       return output_387_reg_move (insn, operands);
3389
3390     case 2:
3391       return standard_80387_constant_opcode (operands[1]);
3392
3393     case 3:
3394     case 4:
3395       return "mov{l}\t{%1, %0|%0, %1}";
3396     case 5:
3397       if (get_attr_mode (insn) == MODE_TI)
3398         return "%vpxor\t%0, %d0";
3399       else
3400         return "%vxorps\t%0, %d0";
3401     case 6:
3402       if (get_attr_mode (insn) == MODE_V4SF)
3403         return "%vmovaps\t{%1, %0|%0, %1}";
3404       else
3405         return "%vmovss\t{%1, %d0|%d0, %1}";
3406     case 7:
3407       if (TARGET_AVX)
3408         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3409                                    : "vmovss\t{%1, %0|%0, %1}";
3410       else
3411         return "movss\t{%1, %0|%0, %1}";
3412     case 8:
3413       return "%vmovss\t{%1, %0|%0, %1}";
3414
3415     case 9: case 10: case 14: case 15:
3416       return "movd\t{%1, %0|%0, %1}";
3417     case 12: case 13:
3418       return "%vmovd\t{%1, %0|%0, %1}";
3419
3420     case 11:
3421       return "movq\t{%1, %0|%0, %1}";
3422
3423     default:
3424       gcc_unreachable ();
3425     }
3426 }
3427   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3428    (set (attr "prefix")
3429      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3430        (const_string "maybe_vex")
3431        (const_string "orig")))
3432    (set (attr "mode")
3433         (cond [(eq_attr "alternative" "3,4,9,10")
3434                  (const_string "SI")
3435                (eq_attr "alternative" "5")
3436                  (if_then_else
3437                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3438                                  (const_int 0))
3439                              (ne (symbol_ref "TARGET_SSE2")
3440                                  (const_int 0)))
3441                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3442                             (const_int 0)))
3443                    (const_string "TI")
3444                    (const_string "V4SF"))
3445                /* For architectures resolving dependencies on
3446                   whole SSE registers use APS move to break dependency
3447                   chains, otherwise use short move to avoid extra work.
3448
3449                   Do the same for architectures resolving dependencies on
3450                   the parts.  While in DF mode it is better to always handle
3451                   just register parts, the SF mode is different due to lack
3452                   of instructions to load just part of the register.  It is
3453                   better to maintain the whole registers in single format
3454                   to avoid problems on using packed logical operations.  */
3455                (eq_attr "alternative" "6")
3456                  (if_then_else
3457                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3458                             (const_int 0))
3459                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3460                             (const_int 0)))
3461                    (const_string "V4SF")
3462                    (const_string "SF"))
3463                (eq_attr "alternative" "11")
3464                  (const_string "DI")]
3465                (const_string "SF")))])
3466
3467 (define_split
3468   [(set (match_operand 0 "register_operand" "")
3469         (match_operand 1 "memory_operand" ""))]
3470   "reload_completed
3471    && MEM_P (operands[1])
3472    && (GET_MODE (operands[0]) == TFmode
3473        || GET_MODE (operands[0]) == XFmode
3474        || GET_MODE (operands[0]) == DFmode
3475        || GET_MODE (operands[0]) == SFmode)
3476    && (operands[2] = find_constant_src (insn))"
3477   [(set (match_dup 0) (match_dup 2))]
3478 {
3479   rtx c = operands[2];
3480   rtx r = operands[0];
3481
3482   if (GET_CODE (r) == SUBREG)
3483     r = SUBREG_REG (r);
3484
3485   if (SSE_REG_P (r))
3486     {
3487       if (!standard_sse_constant_p (c))
3488         FAIL;
3489     }
3490   else if (FP_REG_P (r))
3491     {
3492       if (!standard_80387_constant_p (c))
3493         FAIL;
3494     }
3495   else if (MMX_REG_P (r))
3496     FAIL;
3497 })
3498
3499 (define_split
3500   [(set (match_operand 0 "register_operand" "")
3501         (float_extend (match_operand 1 "memory_operand" "")))]
3502   "reload_completed
3503    && MEM_P (operands[1])
3504    && (GET_MODE (operands[0]) == TFmode
3505        || GET_MODE (operands[0]) == XFmode
3506        || GET_MODE (operands[0]) == DFmode
3507        || GET_MODE (operands[0]) == SFmode)
3508    && (operands[2] = find_constant_src (insn))"
3509   [(set (match_dup 0) (match_dup 2))]
3510 {
3511   rtx c = operands[2];
3512   rtx r = operands[0];
3513
3514   if (GET_CODE (r) == SUBREG)
3515     r = SUBREG_REG (r);
3516
3517   if (SSE_REG_P (r))
3518     {
3519       if (!standard_sse_constant_p (c))
3520         FAIL;
3521     }
3522   else if (FP_REG_P (r))
3523     {
3524       if (!standard_80387_constant_p (c))
3525         FAIL;
3526     }
3527   else if (MMX_REG_P (r))
3528     FAIL;
3529 })
3530
3531 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3532 (define_split
3533   [(set (match_operand:X87MODEF 0 "register_operand" "")
3534         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3535   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3536    && (standard_80387_constant_p (operands[1]) == 8
3537        || standard_80387_constant_p (operands[1]) == 9)"
3538   [(set (match_dup 0)(match_dup 1))
3539    (set (match_dup 0)
3540         (neg:X87MODEF (match_dup 0)))]
3541 {
3542   REAL_VALUE_TYPE r;
3543
3544   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3545   if (real_isnegzero (&r))
3546     operands[1] = CONST0_RTX (<MODE>mode);
3547   else
3548     operands[1] = CONST1_RTX (<MODE>mode);
3549 })
3550
3551 (define_insn "swapxf"
3552   [(set (match_operand:XF 0 "register_operand" "+f")
3553         (match_operand:XF 1 "register_operand" "+f"))
3554    (set (match_dup 1)
3555         (match_dup 0))]
3556   "TARGET_80387"
3557 {
3558   if (STACK_TOP_P (operands[0]))
3559     return "fxch\t%1";
3560   else
3561     return "fxch\t%0";
3562 }
3563   [(set_attr "type" "fxch")
3564    (set_attr "mode" "XF")])
3565
3566 (define_insn "*swap<mode>"
3567   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3568         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3569    (set (match_dup 1)
3570         (match_dup 0))]
3571   "TARGET_80387 || reload_completed"
3572 {
3573   if (STACK_TOP_P (operands[0]))
3574     return "fxch\t%1";
3575   else
3576     return "fxch\t%0";
3577 }
3578   [(set_attr "type" "fxch")
3579    (set_attr "mode" "<MODE>")])
3580 \f
3581 ;; Zero extension instructions
3582
3583 (define_expand "zero_extendsidi2"
3584   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3585         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3586   ""
3587 {
3588   if (!TARGET_64BIT)
3589     {
3590       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3591       DONE;
3592     }
3593 })
3594
3595 (define_insn "*zero_extendsidi2_rex64"
3596   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3597         (zero_extend:DI
3598          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3599   "TARGET_64BIT"
3600   "@
3601    mov\t{%k1, %k0|%k0, %k1}
3602    #
3603    movd\t{%1, %0|%0, %1}
3604    movd\t{%1, %0|%0, %1}
3605    %vmovd\t{%1, %0|%0, %1}
3606    %vmovd\t{%1, %0|%0, %1}"
3607   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3608    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3609    (set_attr "prefix_0f" "0,*,*,*,*,*")
3610    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3611
3612 (define_split
3613   [(set (match_operand:DI 0 "memory_operand" "")
3614         (zero_extend:DI (match_dup 0)))]
3615   "TARGET_64BIT"
3616   [(set (match_dup 4) (const_int 0))]
3617   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3618
3619 ;; %%% Kill me once multi-word ops are sane.
3620 (define_insn "zero_extendsidi2_1"
3621   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3622         (zero_extend:DI
3623          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3624    (clobber (reg:CC FLAGS_REG))]
3625   "!TARGET_64BIT"
3626   "@
3627    #
3628    #
3629    #
3630    movd\t{%1, %0|%0, %1}
3631    movd\t{%1, %0|%0, %1}
3632    %vmovd\t{%1, %0|%0, %1}
3633    %vmovd\t{%1, %0|%0, %1}"
3634   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3635    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3636    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3637
3638 (define_split
3639   [(set (match_operand:DI 0 "register_operand" "")
3640         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3641    (clobber (reg:CC FLAGS_REG))]
3642   "!TARGET_64BIT && reload_completed
3643    && true_regnum (operands[0]) == true_regnum (operands[1])"
3644   [(set (match_dup 4) (const_int 0))]
3645   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3646
3647 (define_split
3648   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3649         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3650    (clobber (reg:CC FLAGS_REG))]
3651   "!TARGET_64BIT && reload_completed
3652    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3653   [(set (match_dup 3) (match_dup 1))
3654    (set (match_dup 4) (const_int 0))]
3655   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3656
3657 (define_insn "zero_extend<mode>di2"
3658   [(set (match_operand:DI 0 "register_operand" "=r")
3659         (zero_extend:DI
3660          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3661   "TARGET_64BIT"
3662   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3663   [(set_attr "type" "imovx")
3664    (set_attr "mode" "SI")])
3665
3666 (define_expand "zero_extendhisi2"
3667   [(set (match_operand:SI 0 "register_operand" "")
3668         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3669   ""
3670 {
3671   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3672     {
3673       operands[1] = force_reg (HImode, operands[1]);
3674       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3675       DONE;
3676     }
3677 })
3678
3679 (define_insn_and_split "zero_extendhisi2_and"
3680   [(set (match_operand:SI 0 "register_operand" "=r")
3681         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3682    (clobber (reg:CC FLAGS_REG))]
3683   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3684   "#"
3685   "&& reload_completed"
3686   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3687               (clobber (reg:CC FLAGS_REG))])]
3688   ""
3689   [(set_attr "type" "alu1")
3690    (set_attr "mode" "SI")])
3691
3692 (define_insn "*zero_extendhisi2_movzwl"
3693   [(set (match_operand:SI 0 "register_operand" "=r")
3694         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3695   "!TARGET_ZERO_EXTEND_WITH_AND
3696    || optimize_function_for_size_p (cfun)"
3697   "movz{wl|x}\t{%1, %0|%0, %1}"
3698   [(set_attr "type" "imovx")
3699    (set_attr "mode" "SI")])
3700
3701 (define_expand "zero_extendqi<mode>2"
3702   [(parallel
3703     [(set (match_operand:SWI24 0 "register_operand" "")
3704           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3705      (clobber (reg:CC FLAGS_REG))])])
3706
3707 (define_insn "*zero_extendqi<mode>2_and"
3708   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3709         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3710    (clobber (reg:CC FLAGS_REG))]
3711   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3712   "#"
3713   [(set_attr "type" "alu1")
3714    (set_attr "mode" "<MODE>")])
3715
3716 ;; When source and destination does not overlap, clear destination
3717 ;; first and then do the movb
3718 (define_split
3719   [(set (match_operand:SWI24 0 "register_operand" "")
3720         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3721    (clobber (reg:CC FLAGS_REG))]
3722   "reload_completed
3723    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3724    && ANY_QI_REG_P (operands[0])
3725    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3726    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3727   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3728 {
3729   operands[2] = gen_lowpart (QImode, operands[0]);
3730   ix86_expand_clear (operands[0]);
3731 })
3732
3733 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3734   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3735         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3736    (clobber (reg:CC FLAGS_REG))]
3737   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3738   "#"
3739   [(set_attr "type" "imovx,alu1")
3740    (set_attr "mode" "<MODE>")])
3741
3742 ;; For the movzbl case strip only the clobber
3743 (define_split
3744   [(set (match_operand:SWI24 0 "register_operand" "")
3745         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3746    (clobber (reg:CC FLAGS_REG))]
3747   "reload_completed
3748    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3749    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3750   [(set (match_dup 0)
3751         (zero_extend:SWI24 (match_dup 1)))])
3752
3753 ; zero extend to SImode to avoid partial register stalls
3754 (define_insn "*zero_extendqi<mode>2_movzbl"
3755   [(set (match_operand:SWI24 0 "register_operand" "=r")
3756         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3757   "reload_completed
3758    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3759   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3760   [(set_attr "type" "imovx")
3761    (set_attr "mode" "SI")])
3762
3763 ;; Rest is handled by single and.
3764 (define_split
3765   [(set (match_operand:SWI24 0 "register_operand" "")
3766         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3767    (clobber (reg:CC FLAGS_REG))]
3768   "reload_completed
3769    && true_regnum (operands[0]) == true_regnum (operands[1])"
3770   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3771               (clobber (reg:CC FLAGS_REG))])])
3772 \f
3773 ;; Sign extension instructions
3774
3775 (define_expand "extendsidi2"
3776   [(set (match_operand:DI 0 "register_operand" "")
3777         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3778   ""
3779 {
3780   if (!TARGET_64BIT)
3781     {
3782       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3783       DONE;
3784     }
3785 })
3786
3787 (define_insn "*extendsidi2_rex64"
3788   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3789         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3790   "TARGET_64BIT"
3791   "@
3792    {cltq|cdqe}
3793    movs{lq|x}\t{%1, %0|%0, %1}"
3794   [(set_attr "type" "imovx")
3795    (set_attr "mode" "DI")
3796    (set_attr "prefix_0f" "0")
3797    (set_attr "modrm" "0,1")])
3798
3799 (define_insn "extendsidi2_1"
3800   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3801         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3802    (clobber (reg:CC FLAGS_REG))
3803    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3804   "!TARGET_64BIT"
3805   "#")
3806
3807 ;; Extend to memory case when source register does die.
3808 (define_split
3809   [(set (match_operand:DI 0 "memory_operand" "")
3810         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3811    (clobber (reg:CC FLAGS_REG))
3812    (clobber (match_operand:SI 2 "register_operand" ""))]
3813   "(reload_completed
3814     && dead_or_set_p (insn, operands[1])
3815     && !reg_mentioned_p (operands[1], operands[0]))"
3816   [(set (match_dup 3) (match_dup 1))
3817    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3818               (clobber (reg:CC FLAGS_REG))])
3819    (set (match_dup 4) (match_dup 1))]
3820   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3821
3822 ;; Extend to memory case when source register does not die.
3823 (define_split
3824   [(set (match_operand:DI 0 "memory_operand" "")
3825         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3826    (clobber (reg:CC FLAGS_REG))
3827    (clobber (match_operand:SI 2 "register_operand" ""))]
3828   "reload_completed"
3829   [(const_int 0)]
3830 {
3831   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3832
3833   emit_move_insn (operands[3], operands[1]);
3834
3835   /* Generate a cltd if possible and doing so it profitable.  */
3836   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3837       && true_regnum (operands[1]) == AX_REG
3838       && true_regnum (operands[2]) == DX_REG)
3839     {
3840       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3841     }
3842   else
3843     {
3844       emit_move_insn (operands[2], operands[1]);
3845       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3846     }
3847   emit_move_insn (operands[4], operands[2]);
3848   DONE;
3849 })
3850
3851 ;; Extend to register case.  Optimize case where source and destination
3852 ;; registers match and cases where we can use cltd.
3853 (define_split
3854   [(set (match_operand:DI 0 "register_operand" "")
3855         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3856    (clobber (reg:CC FLAGS_REG))
3857    (clobber (match_scratch:SI 2 ""))]
3858   "reload_completed"
3859   [(const_int 0)]
3860 {
3861   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3862
3863   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3864     emit_move_insn (operands[3], operands[1]);
3865
3866   /* Generate a cltd if possible and doing so it profitable.  */
3867   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3868       && true_regnum (operands[3]) == AX_REG
3869       && true_regnum (operands[4]) == DX_REG)
3870     {
3871       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3872       DONE;
3873     }
3874
3875   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3876     emit_move_insn (operands[4], operands[1]);
3877
3878   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3879   DONE;
3880 })
3881
3882 (define_insn "extend<mode>di2"
3883   [(set (match_operand:DI 0 "register_operand" "=r")
3884         (sign_extend:DI
3885          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3886   "TARGET_64BIT"
3887   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3888   [(set_attr "type" "imovx")
3889    (set_attr "mode" "DI")])
3890
3891 (define_insn "extendhisi2"
3892   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3893         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3894   ""
3895 {
3896   switch (get_attr_prefix_0f (insn))
3897     {
3898     case 0:
3899       return "{cwtl|cwde}";
3900     default:
3901       return "movs{wl|x}\t{%1, %0|%0, %1}";
3902     }
3903 }
3904   [(set_attr "type" "imovx")
3905    (set_attr "mode" "SI")
3906    (set (attr "prefix_0f")
3907      ;; movsx is short decodable while cwtl is vector decoded.
3908      (if_then_else (and (eq_attr "cpu" "!k6")
3909                         (eq_attr "alternative" "0"))
3910         (const_string "0")
3911         (const_string "1")))
3912    (set (attr "modrm")
3913      (if_then_else (eq_attr "prefix_0f" "0")
3914         (const_string "0")
3915         (const_string "1")))])
3916
3917 (define_insn "*extendhisi2_zext"
3918   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3919         (zero_extend:DI
3920          (sign_extend:SI
3921           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3922   "TARGET_64BIT"
3923 {
3924   switch (get_attr_prefix_0f (insn))
3925     {
3926     case 0:
3927       return "{cwtl|cwde}";
3928     default:
3929       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3930     }
3931 }
3932   [(set_attr "type" "imovx")
3933    (set_attr "mode" "SI")
3934    (set (attr "prefix_0f")
3935      ;; movsx is short decodable while cwtl is vector decoded.
3936      (if_then_else (and (eq_attr "cpu" "!k6")
3937                         (eq_attr "alternative" "0"))
3938         (const_string "0")
3939         (const_string "1")))
3940    (set (attr "modrm")
3941      (if_then_else (eq_attr "prefix_0f" "0")
3942         (const_string "0")
3943         (const_string "1")))])
3944
3945 (define_insn "extendqisi2"
3946   [(set (match_operand:SI 0 "register_operand" "=r")
3947         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3948   ""
3949   "movs{bl|x}\t{%1, %0|%0, %1}"
3950    [(set_attr "type" "imovx")
3951     (set_attr "mode" "SI")])
3952
3953 (define_insn "*extendqisi2_zext"
3954   [(set (match_operand:DI 0 "register_operand" "=r")
3955         (zero_extend:DI
3956           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3957   "TARGET_64BIT"
3958   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3959    [(set_attr "type" "imovx")
3960     (set_attr "mode" "SI")])
3961
3962 (define_insn "extendqihi2"
3963   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3964         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3965   ""
3966 {
3967   switch (get_attr_prefix_0f (insn))
3968     {
3969     case 0:
3970       return "{cbtw|cbw}";
3971     default:
3972       return "movs{bw|x}\t{%1, %0|%0, %1}";
3973     }
3974 }
3975   [(set_attr "type" "imovx")
3976    (set_attr "mode" "HI")
3977    (set (attr "prefix_0f")
3978      ;; movsx is short decodable while cwtl is vector decoded.
3979      (if_then_else (and (eq_attr "cpu" "!k6")
3980                         (eq_attr "alternative" "0"))
3981         (const_string "0")
3982         (const_string "1")))
3983    (set (attr "modrm")
3984      (if_then_else (eq_attr "prefix_0f" "0")
3985         (const_string "0")
3986         (const_string "1")))])
3987 \f
3988 ;; Conversions between float and double.
3989
3990 ;; These are all no-ops in the model used for the 80387.
3991 ;; So just emit moves.
3992
3993 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3994 (define_split
3995   [(set (match_operand:DF 0 "push_operand" "")
3996         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3997   "reload_completed"
3998   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3999    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4000
4001 (define_split
4002   [(set (match_operand:XF 0 "push_operand" "")
4003         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4004   "reload_completed"
4005   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4006    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4007   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4008
4009 (define_expand "extendsfdf2"
4010   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4011         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4012   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4013 {
4014   /* ??? Needed for compress_float_constant since all fp constants
4015      are LEGITIMATE_CONSTANT_P.  */
4016   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4017     {
4018       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4019           && standard_80387_constant_p (operands[1]) > 0)
4020         {
4021           operands[1] = simplify_const_unary_operation
4022             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4023           emit_move_insn_1 (operands[0], operands[1]);
4024           DONE;
4025         }
4026       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4027     }
4028 })
4029
4030 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4031    cvtss2sd:
4032       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4033       cvtps2pd xmm2,xmm1
4034    We do the conversion post reload to avoid producing of 128bit spills
4035    that might lead to ICE on 32bit target.  The sequence unlikely combine
4036    anyway.  */
4037 (define_split
4038   [(set (match_operand:DF 0 "register_operand" "")
4039         (float_extend:DF
4040           (match_operand:SF 1 "nonimmediate_operand" "")))]
4041   "TARGET_USE_VECTOR_FP_CONVERTS
4042    && optimize_insn_for_speed_p ()
4043    && reload_completed && SSE_REG_P (operands[0])"
4044    [(set (match_dup 2)
4045          (float_extend:V2DF
4046            (vec_select:V2SF
4047              (match_dup 3)
4048              (parallel [(const_int 0) (const_int 1)]))))]
4049 {
4050   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4051   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4052   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4053      Try to avoid move when unpacking can be done in source.  */
4054   if (REG_P (operands[1]))
4055     {
4056       /* If it is unsafe to overwrite upper half of source, we need
4057          to move to destination and unpack there.  */
4058       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4059            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4060           && true_regnum (operands[0]) != true_regnum (operands[1]))
4061         {
4062           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4063           emit_move_insn (tmp, operands[1]);
4064         }
4065       else
4066         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4067       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4068                                              operands[3]));
4069     }
4070   else
4071     emit_insn (gen_vec_setv4sf_0 (operands[3],
4072                                   CONST0_RTX (V4SFmode), operands[1]));
4073 })
4074
4075 (define_insn "*extendsfdf2_mixed"
4076   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4077         (float_extend:DF
4078           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4079   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4080 {
4081   switch (which_alternative)
4082     {
4083     case 0:
4084     case 1:
4085       return output_387_reg_move (insn, operands);
4086
4087     case 2:
4088       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4089
4090     default:
4091       gcc_unreachable ();
4092     }
4093 }
4094   [(set_attr "type" "fmov,fmov,ssecvt")
4095    (set_attr "prefix" "orig,orig,maybe_vex")
4096    (set_attr "mode" "SF,XF,DF")])
4097
4098 (define_insn "*extendsfdf2_sse"
4099   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4100         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4101   "TARGET_SSE2 && TARGET_SSE_MATH"
4102   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4103   [(set_attr "type" "ssecvt")
4104    (set_attr "prefix" "maybe_vex")
4105    (set_attr "mode" "DF")])
4106
4107 (define_insn "*extendsfdf2_i387"
4108   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4109         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4110   "TARGET_80387"
4111   "* return output_387_reg_move (insn, operands);"
4112   [(set_attr "type" "fmov")
4113    (set_attr "mode" "SF,XF")])
4114
4115 (define_expand "extend<mode>xf2"
4116   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4117         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4118   "TARGET_80387"
4119 {
4120   /* ??? Needed for compress_float_constant since all fp constants
4121      are LEGITIMATE_CONSTANT_P.  */
4122   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4123     {
4124       if (standard_80387_constant_p (operands[1]) > 0)
4125         {
4126           operands[1] = simplify_const_unary_operation
4127             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4128           emit_move_insn_1 (operands[0], operands[1]);
4129           DONE;
4130         }
4131       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4132     }
4133 })
4134
4135 (define_insn "*extend<mode>xf2_i387"
4136   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4137         (float_extend:XF
4138           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4139   "TARGET_80387"
4140   "* return output_387_reg_move (insn, operands);"
4141   [(set_attr "type" "fmov")
4142    (set_attr "mode" "<MODE>,XF")])
4143
4144 ;; %%% This seems bad bad news.
4145 ;; This cannot output into an f-reg because there is no way to be sure
4146 ;; of truncating in that case.  Otherwise this is just like a simple move
4147 ;; insn.  So we pretend we can output to a reg in order to get better
4148 ;; register preferencing, but we really use a stack slot.
4149
4150 ;; Conversion from DFmode to SFmode.
4151
4152 (define_expand "truncdfsf2"
4153   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4154         (float_truncate:SF
4155           (match_operand:DF 1 "nonimmediate_operand" "")))]
4156   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4157 {
4158   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4159     ;
4160   else if (flag_unsafe_math_optimizations)
4161     ;
4162   else
4163     {
4164       enum ix86_stack_slot slot = (virtuals_instantiated
4165                                    ? SLOT_TEMP
4166                                    : SLOT_VIRTUAL);
4167       rtx temp = assign_386_stack_local (SFmode, slot);
4168       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4169       DONE;
4170     }
4171 })
4172
4173 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4174    cvtsd2ss:
4175       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4176       cvtpd2ps xmm2,xmm1
4177    We do the conversion post reload to avoid producing of 128bit spills
4178    that might lead to ICE on 32bit target.  The sequence unlikely combine
4179    anyway.  */
4180 (define_split
4181   [(set (match_operand:SF 0 "register_operand" "")
4182         (float_truncate:SF
4183           (match_operand:DF 1 "nonimmediate_operand" "")))]
4184   "TARGET_USE_VECTOR_FP_CONVERTS
4185    && optimize_insn_for_speed_p ()
4186    && reload_completed && SSE_REG_P (operands[0])"
4187    [(set (match_dup 2)
4188          (vec_concat:V4SF
4189            (float_truncate:V2SF
4190              (match_dup 4))
4191            (match_dup 3)))]
4192 {
4193   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4194   operands[3] = CONST0_RTX (V2SFmode);
4195   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4196   /* Use movsd for loading from memory, unpcklpd for registers.
4197      Try to avoid move when unpacking can be done in source, or SSE3
4198      movddup is available.  */
4199   if (REG_P (operands[1]))
4200     {
4201       if (!TARGET_SSE3
4202           && true_regnum (operands[0]) != true_regnum (operands[1])
4203           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4204               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4205         {
4206           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4207           emit_move_insn (tmp, operands[1]);
4208           operands[1] = tmp;
4209         }
4210       else if (!TARGET_SSE3)
4211         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4212       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4213     }
4214   else
4215     emit_insn (gen_sse2_loadlpd (operands[4],
4216                                  CONST0_RTX (V2DFmode), operands[1]));
4217 })
4218
4219 (define_expand "truncdfsf2_with_temp"
4220   [(parallel [(set (match_operand:SF 0 "" "")
4221                    (float_truncate:SF (match_operand:DF 1 "" "")))
4222               (clobber (match_operand:SF 2 "" ""))])])
4223
4224 (define_insn "*truncdfsf_fast_mixed"
4225   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4226         (float_truncate:SF
4227           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4228   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4229 {
4230   switch (which_alternative)
4231     {
4232     case 0:
4233       return output_387_reg_move (insn, operands);
4234     case 1:
4235       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4236     default:
4237       gcc_unreachable ();
4238     }
4239 }
4240   [(set_attr "type" "fmov,ssecvt")
4241    (set_attr "prefix" "orig,maybe_vex")
4242    (set_attr "mode" "SF")])
4243
4244 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4245 ;; because nothing we do here is unsafe.
4246 (define_insn "*truncdfsf_fast_sse"
4247   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4248         (float_truncate:SF
4249           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4250   "TARGET_SSE2 && TARGET_SSE_MATH"
4251   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4252   [(set_attr "type" "ssecvt")
4253    (set_attr "prefix" "maybe_vex")
4254    (set_attr "mode" "SF")])
4255
4256 (define_insn "*truncdfsf_fast_i387"
4257   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4258         (float_truncate:SF
4259           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4260   "TARGET_80387 && flag_unsafe_math_optimizations"
4261   "* return output_387_reg_move (insn, operands);"
4262   [(set_attr "type" "fmov")
4263    (set_attr "mode" "SF")])
4264
4265 (define_insn "*truncdfsf_mixed"
4266   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4267         (float_truncate:SF
4268           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4269    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4270   "TARGET_MIX_SSE_I387"
4271 {
4272   switch (which_alternative)
4273     {
4274     case 0:
4275       return output_387_reg_move (insn, operands);
4276     case 1:
4277       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4278
4279     default:
4280       return "#";
4281     }
4282 }
4283   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4284    (set_attr "unit" "*,*,i387,i387,i387")
4285    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4286    (set_attr "mode" "SF")])
4287
4288 (define_insn "*truncdfsf_i387"
4289   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4290         (float_truncate:SF
4291           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4292    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4293   "TARGET_80387"
4294 {
4295   switch (which_alternative)
4296     {
4297     case 0:
4298       return output_387_reg_move (insn, operands);
4299
4300     default:
4301       return "#";
4302     }
4303 }
4304   [(set_attr "type" "fmov,multi,multi,multi")
4305    (set_attr "unit" "*,i387,i387,i387")
4306    (set_attr "mode" "SF")])
4307
4308 (define_insn "*truncdfsf2_i387_1"
4309   [(set (match_operand:SF 0 "memory_operand" "=m")
4310         (float_truncate:SF
4311           (match_operand:DF 1 "register_operand" "f")))]
4312   "TARGET_80387
4313    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4314    && !TARGET_MIX_SSE_I387"
4315   "* return output_387_reg_move (insn, operands);"
4316   [(set_attr "type" "fmov")
4317    (set_attr "mode" "SF")])
4318
4319 (define_split
4320   [(set (match_operand:SF 0 "register_operand" "")
4321         (float_truncate:SF
4322          (match_operand:DF 1 "fp_register_operand" "")))
4323    (clobber (match_operand 2 "" ""))]
4324   "reload_completed"
4325   [(set (match_dup 2) (match_dup 1))
4326    (set (match_dup 0) (match_dup 2))]
4327   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4328
4329 ;; Conversion from XFmode to {SF,DF}mode
4330
4331 (define_expand "truncxf<mode>2"
4332   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4333                    (float_truncate:MODEF
4334                      (match_operand:XF 1 "register_operand" "")))
4335               (clobber (match_dup 2))])]
4336   "TARGET_80387"
4337 {
4338   if (flag_unsafe_math_optimizations)
4339     {
4340       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4341       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4342       if (reg != operands[0])
4343         emit_move_insn (operands[0], reg);
4344       DONE;
4345     }
4346   else
4347     {
4348       enum ix86_stack_slot slot = (virtuals_instantiated
4349                                    ? SLOT_TEMP
4350                                    : SLOT_VIRTUAL);
4351       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4352     }
4353 })
4354
4355 (define_insn "*truncxfsf2_mixed"
4356   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4357         (float_truncate:SF
4358           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4359    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4360   "TARGET_80387"
4361 {
4362   gcc_assert (!which_alternative);
4363   return output_387_reg_move (insn, operands);
4364 }
4365   [(set_attr "type" "fmov,multi,multi,multi")
4366    (set_attr "unit" "*,i387,i387,i387")
4367    (set_attr "mode" "SF")])
4368
4369 (define_insn "*truncxfdf2_mixed"
4370   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4371         (float_truncate:DF
4372           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4373    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4374   "TARGET_80387"
4375 {
4376   gcc_assert (!which_alternative);
4377   return output_387_reg_move (insn, operands);
4378 }
4379   [(set_attr "type" "fmov,multi,multi,multi")
4380    (set_attr "unit" "*,i387,i387,i387")
4381    (set_attr "mode" "DF")])
4382
4383 (define_insn "truncxf<mode>2_i387_noop"
4384   [(set (match_operand:MODEF 0 "register_operand" "=f")
4385         (float_truncate:MODEF
4386           (match_operand:XF 1 "register_operand" "f")))]
4387   "TARGET_80387 && flag_unsafe_math_optimizations"
4388   "* return output_387_reg_move (insn, operands);"
4389   [(set_attr "type" "fmov")
4390    (set_attr "mode" "<MODE>")])
4391
4392 (define_insn "*truncxf<mode>2_i387"
4393   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4394         (float_truncate:MODEF
4395           (match_operand:XF 1 "register_operand" "f")))]
4396   "TARGET_80387"
4397   "* return output_387_reg_move (insn, operands);"
4398   [(set_attr "type" "fmov")
4399    (set_attr "mode" "<MODE>")])
4400
4401 (define_split
4402   [(set (match_operand:MODEF 0 "register_operand" "")
4403         (float_truncate:MODEF
4404           (match_operand:XF 1 "register_operand" "")))
4405    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4406   "TARGET_80387 && reload_completed"
4407   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4408    (set (match_dup 0) (match_dup 2))])
4409
4410 (define_split
4411   [(set (match_operand:MODEF 0 "memory_operand" "")
4412         (float_truncate:MODEF
4413           (match_operand:XF 1 "register_operand" "")))
4414    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4415   "TARGET_80387"
4416   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4417 \f
4418 ;; Signed conversion to DImode.
4419
4420 (define_expand "fix_truncxfdi2"
4421   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4422                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4423               (clobber (reg:CC FLAGS_REG))])]
4424   "TARGET_80387"
4425 {
4426   if (TARGET_FISTTP)
4427    {
4428      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4429      DONE;
4430    }
4431 })
4432
4433 (define_expand "fix_trunc<mode>di2"
4434   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4435                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4436               (clobber (reg:CC FLAGS_REG))])]
4437   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4438 {
4439   if (TARGET_FISTTP
4440       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4441    {
4442      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4443      DONE;
4444    }
4445   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4446    {
4447      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4448      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4449      if (out != operands[0])
4450         emit_move_insn (operands[0], out);
4451      DONE;
4452    }
4453 })
4454
4455 ;; Signed conversion to SImode.
4456
4457 (define_expand "fix_truncxfsi2"
4458   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4459                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4460               (clobber (reg:CC FLAGS_REG))])]
4461   "TARGET_80387"
4462 {
4463   if (TARGET_FISTTP)
4464    {
4465      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4466      DONE;
4467    }
4468 })
4469
4470 (define_expand "fix_trunc<mode>si2"
4471   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4472                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4473               (clobber (reg:CC FLAGS_REG))])]
4474   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4475 {
4476   if (TARGET_FISTTP
4477       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4478    {
4479      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4480      DONE;
4481    }
4482   if (SSE_FLOAT_MODE_P (<MODE>mode))
4483    {
4484      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4485      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4486      if (out != operands[0])
4487         emit_move_insn (operands[0], out);
4488      DONE;
4489    }
4490 })
4491
4492 ;; Signed conversion to HImode.
4493
4494 (define_expand "fix_trunc<mode>hi2"
4495   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4496                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4497               (clobber (reg:CC FLAGS_REG))])]
4498   "TARGET_80387
4499    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4500 {
4501   if (TARGET_FISTTP)
4502    {
4503      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4504      DONE;
4505    }
4506 })
4507
4508 ;; Unsigned conversion to SImode.
4509
4510 (define_expand "fixuns_trunc<mode>si2"
4511   [(parallel
4512     [(set (match_operand:SI 0 "register_operand" "")
4513           (unsigned_fix:SI
4514             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4515      (use (match_dup 2))
4516      (clobber (match_scratch:<ssevecmode> 3 ""))
4517      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4518   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4519 {
4520   enum machine_mode mode = <MODE>mode;
4521   enum machine_mode vecmode = <ssevecmode>mode;
4522   REAL_VALUE_TYPE TWO31r;
4523   rtx two31;
4524
4525   if (optimize_insn_for_size_p ())
4526     FAIL;
4527
4528   real_ldexp (&TWO31r, &dconst1, 31);
4529   two31 = const_double_from_real_value (TWO31r, mode);
4530   two31 = ix86_build_const_vector (vecmode, true, two31);
4531   operands[2] = force_reg (vecmode, two31);
4532 })
4533
4534 (define_insn_and_split "*fixuns_trunc<mode>_1"
4535   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4536         (unsigned_fix:SI
4537           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4538    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4539    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4540    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4541   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4542    && optimize_function_for_speed_p (cfun)"
4543   "#"
4544   "&& reload_completed"
4545   [(const_int 0)]
4546 {
4547   ix86_split_convert_uns_si_sse (operands);
4548   DONE;
4549 })
4550
4551 ;; Unsigned conversion to HImode.
4552 ;; Without these patterns, we'll try the unsigned SI conversion which
4553 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4554
4555 (define_expand "fixuns_trunc<mode>hi2"
4556   [(set (match_dup 2)
4557         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4558    (set (match_operand:HI 0 "nonimmediate_operand" "")
4559         (subreg:HI (match_dup 2) 0))]
4560   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4561   "operands[2] = gen_reg_rtx (SImode);")
4562
4563 ;; When SSE is available, it is always faster to use it!
4564 (define_insn "fix_trunc<mode>di_sse"
4565   [(set (match_operand:DI 0 "register_operand" "=r,r")
4566         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4567   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4568    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4569   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4570   [(set_attr "type" "sseicvt")
4571    (set_attr "prefix" "maybe_vex")
4572    (set_attr "prefix_rex" "1")
4573    (set_attr "mode" "<MODE>")
4574    (set_attr "athlon_decode" "double,vector")
4575    (set_attr "amdfam10_decode" "double,double")
4576    (set_attr "bdver1_decode" "double,double")])
4577
4578 (define_insn "fix_trunc<mode>si_sse"
4579   [(set (match_operand:SI 0 "register_operand" "=r,r")
4580         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4581   "SSE_FLOAT_MODE_P (<MODE>mode)
4582    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4583   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4584   [(set_attr "type" "sseicvt")
4585    (set_attr "prefix" "maybe_vex")
4586    (set_attr "mode" "<MODE>")
4587    (set_attr "athlon_decode" "double,vector")
4588    (set_attr "amdfam10_decode" "double,double")
4589    (set_attr "bdver1_decode" "double,double")])
4590
4591 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4592 (define_peephole2
4593   [(set (match_operand:MODEF 0 "register_operand" "")
4594         (match_operand:MODEF 1 "memory_operand" ""))
4595    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4596         (fix:SSEMODEI24 (match_dup 0)))]
4597   "TARGET_SHORTEN_X87_SSE
4598    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4599    && peep2_reg_dead_p (2, operands[0])"
4600   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4601
4602 ;; Avoid vector decoded forms of the instruction.
4603 (define_peephole2
4604   [(match_scratch:DF 2 "Y2")
4605    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4606         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4607   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4608   [(set (match_dup 2) (match_dup 1))
4609    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4610
4611 (define_peephole2
4612   [(match_scratch:SF 2 "x")
4613    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4614         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4615   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4616   [(set (match_dup 2) (match_dup 1))
4617    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4618
4619 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4620   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4621         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4622   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4623    && TARGET_FISTTP
4624    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4625          && (TARGET_64BIT || <MODE>mode != DImode))
4626         && TARGET_SSE_MATH)
4627    && can_create_pseudo_p ()"
4628   "#"
4629   "&& 1"
4630   [(const_int 0)]
4631 {
4632   if (memory_operand (operands[0], VOIDmode))
4633     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4634   else
4635     {
4636       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4637       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4638                                                             operands[1],
4639                                                             operands[2]));
4640     }
4641   DONE;
4642 }
4643   [(set_attr "type" "fisttp")
4644    (set_attr "mode" "<MODE>")])
4645
4646 (define_insn "fix_trunc<mode>_i387_fisttp"
4647   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4648         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4649    (clobber (match_scratch:XF 2 "=&1f"))]
4650   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4651    && TARGET_FISTTP
4652    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4653          && (TARGET_64BIT || <MODE>mode != DImode))
4654         && TARGET_SSE_MATH)"
4655   "* return output_fix_trunc (insn, operands, 1);"
4656   [(set_attr "type" "fisttp")
4657    (set_attr "mode" "<MODE>")])
4658
4659 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4660   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4661         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4662    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4663    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4664   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4665    && TARGET_FISTTP
4666    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4667         && (TARGET_64BIT || <MODE>mode != DImode))
4668         && TARGET_SSE_MATH)"
4669   "#"
4670   [(set_attr "type" "fisttp")
4671    (set_attr "mode" "<MODE>")])
4672
4673 (define_split
4674   [(set (match_operand:X87MODEI 0 "register_operand" "")
4675         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4676    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4677    (clobber (match_scratch 3 ""))]
4678   "reload_completed"
4679   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4680               (clobber (match_dup 3))])
4681    (set (match_dup 0) (match_dup 2))])
4682
4683 (define_split
4684   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4685         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4686    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4687    (clobber (match_scratch 3 ""))]
4688   "reload_completed"
4689   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4690               (clobber (match_dup 3))])])
4691
4692 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4693 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4694 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4695 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4696 ;; function in i386.c.
4697 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4698   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4699         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4700    (clobber (reg:CC FLAGS_REG))]
4701   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4702    && !TARGET_FISTTP
4703    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4704          && (TARGET_64BIT || <MODE>mode != DImode))
4705    && can_create_pseudo_p ()"
4706   "#"
4707   "&& 1"
4708   [(const_int 0)]
4709 {
4710   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4711
4712   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4713   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4714   if (memory_operand (operands[0], VOIDmode))
4715     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4716                                          operands[2], operands[3]));
4717   else
4718     {
4719       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4720       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4721                                                      operands[2], operands[3],
4722                                                      operands[4]));
4723     }
4724   DONE;
4725 }
4726   [(set_attr "type" "fistp")
4727    (set_attr "i387_cw" "trunc")
4728    (set_attr "mode" "<MODE>")])
4729
4730 (define_insn "fix_truncdi_i387"
4731   [(set (match_operand:DI 0 "memory_operand" "=m")
4732         (fix:DI (match_operand 1 "register_operand" "f")))
4733    (use (match_operand:HI 2 "memory_operand" "m"))
4734    (use (match_operand:HI 3 "memory_operand" "m"))
4735    (clobber (match_scratch:XF 4 "=&1f"))]
4736   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4737    && !TARGET_FISTTP
4738    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4739   "* return output_fix_trunc (insn, operands, 0);"
4740   [(set_attr "type" "fistp")
4741    (set_attr "i387_cw" "trunc")
4742    (set_attr "mode" "DI")])
4743
4744 (define_insn "fix_truncdi_i387_with_temp"
4745   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4746         (fix:DI (match_operand 1 "register_operand" "f,f")))
4747    (use (match_operand:HI 2 "memory_operand" "m,m"))
4748    (use (match_operand:HI 3 "memory_operand" "m,m"))
4749    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4750    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4751   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4752    && !TARGET_FISTTP
4753    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4754   "#"
4755   [(set_attr "type" "fistp")
4756    (set_attr "i387_cw" "trunc")
4757    (set_attr "mode" "DI")])
4758
4759 (define_split
4760   [(set (match_operand:DI 0 "register_operand" "")
4761         (fix:DI (match_operand 1 "register_operand" "")))
4762    (use (match_operand:HI 2 "memory_operand" ""))
4763    (use (match_operand:HI 3 "memory_operand" ""))
4764    (clobber (match_operand:DI 4 "memory_operand" ""))
4765    (clobber (match_scratch 5 ""))]
4766   "reload_completed"
4767   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4768               (use (match_dup 2))
4769               (use (match_dup 3))
4770               (clobber (match_dup 5))])
4771    (set (match_dup 0) (match_dup 4))])
4772
4773 (define_split
4774   [(set (match_operand:DI 0 "memory_operand" "")
4775         (fix:DI (match_operand 1 "register_operand" "")))
4776    (use (match_operand:HI 2 "memory_operand" ""))
4777    (use (match_operand:HI 3 "memory_operand" ""))
4778    (clobber (match_operand:DI 4 "memory_operand" ""))
4779    (clobber (match_scratch 5 ""))]
4780   "reload_completed"
4781   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4782               (use (match_dup 2))
4783               (use (match_dup 3))
4784               (clobber (match_dup 5))])])
4785
4786 (define_insn "fix_trunc<mode>_i387"
4787   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4788         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4789    (use (match_operand:HI 2 "memory_operand" "m"))
4790    (use (match_operand:HI 3 "memory_operand" "m"))]
4791   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4792    && !TARGET_FISTTP
4793    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4794   "* return output_fix_trunc (insn, operands, 0);"
4795   [(set_attr "type" "fistp")
4796    (set_attr "i387_cw" "trunc")
4797    (set_attr "mode" "<MODE>")])
4798
4799 (define_insn "fix_trunc<mode>_i387_with_temp"
4800   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4801         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4802    (use (match_operand:HI 2 "memory_operand" "m,m"))
4803    (use (match_operand:HI 3 "memory_operand" "m,m"))
4804    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4805   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4806    && !TARGET_FISTTP
4807    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4808   "#"
4809   [(set_attr "type" "fistp")
4810    (set_attr "i387_cw" "trunc")
4811    (set_attr "mode" "<MODE>")])
4812
4813 (define_split
4814   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4815         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4816    (use (match_operand:HI 2 "memory_operand" ""))
4817    (use (match_operand:HI 3 "memory_operand" ""))
4818    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4819   "reload_completed"
4820   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4821               (use (match_dup 2))
4822               (use (match_dup 3))])
4823    (set (match_dup 0) (match_dup 4))])
4824
4825 (define_split
4826   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4827         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4828    (use (match_operand:HI 2 "memory_operand" ""))
4829    (use (match_operand:HI 3 "memory_operand" ""))
4830    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4831   "reload_completed"
4832   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4833               (use (match_dup 2))
4834               (use (match_dup 3))])])
4835
4836 (define_insn "x86_fnstcw_1"
4837   [(set (match_operand:HI 0 "memory_operand" "=m")
4838         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4839   "TARGET_80387"
4840   "fnstcw\t%0"
4841   [(set (attr "length")
4842         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4843    (set_attr "mode" "HI")
4844    (set_attr "unit" "i387")
4845    (set_attr "bdver1_decode" "vector")])
4846
4847 (define_insn "x86_fldcw_1"
4848   [(set (reg:HI FPCR_REG)
4849         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4850   "TARGET_80387"
4851   "fldcw\t%0"
4852   [(set (attr "length")
4853         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4854    (set_attr "mode" "HI")
4855    (set_attr "unit" "i387")
4856    (set_attr "athlon_decode" "vector")
4857    (set_attr "amdfam10_decode" "vector")
4858    (set_attr "bdver1_decode" "vector")])
4859 \f
4860 ;; Conversion between fixed point and floating point.
4861
4862 ;; Even though we only accept memory inputs, the backend _really_
4863 ;; wants to be able to do this between registers.
4864
4865 (define_expand "floathi<mode>2"
4866   [(set (match_operand:X87MODEF 0 "register_operand" "")
4867         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4868   "TARGET_80387
4869    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4870        || TARGET_MIX_SSE_I387)")
4871
4872 ;; Pre-reload splitter to add memory clobber to the pattern.
4873 (define_insn_and_split "*floathi<mode>2_1"
4874   [(set (match_operand:X87MODEF 0 "register_operand" "")
4875         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4876   "TARGET_80387
4877    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4878        || TARGET_MIX_SSE_I387)
4879    && can_create_pseudo_p ()"
4880   "#"
4881   "&& 1"
4882   [(parallel [(set (match_dup 0)
4883               (float:X87MODEF (match_dup 1)))
4884    (clobber (match_dup 2))])]
4885   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4886
4887 (define_insn "*floathi<mode>2_i387_with_temp"
4888   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4889         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4890   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4891   "TARGET_80387
4892    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4893        || TARGET_MIX_SSE_I387)"
4894   "#"
4895   [(set_attr "type" "fmov,multi")
4896    (set_attr "mode" "<MODE>")
4897    (set_attr "unit" "*,i387")
4898    (set_attr "fp_int_src" "true")])
4899
4900 (define_insn "*floathi<mode>2_i387"
4901   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4902         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4903   "TARGET_80387
4904    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4905        || TARGET_MIX_SSE_I387)"
4906   "fild%Z1\t%1"
4907   [(set_attr "type" "fmov")
4908    (set_attr "mode" "<MODE>")
4909    (set_attr "fp_int_src" "true")])
4910
4911 (define_split
4912   [(set (match_operand:X87MODEF 0 "register_operand" "")
4913         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4914    (clobber (match_operand:HI 2 "memory_operand" ""))]
4915   "TARGET_80387
4916    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4917        || TARGET_MIX_SSE_I387)
4918    && reload_completed"
4919   [(set (match_dup 2) (match_dup 1))
4920    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4921
4922 (define_split
4923   [(set (match_operand:X87MODEF 0 "register_operand" "")
4924         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4925    (clobber (match_operand:HI 2 "memory_operand" ""))]
4926    "TARGET_80387
4927     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4928         || TARGET_MIX_SSE_I387)
4929     && reload_completed"
4930   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4931
4932 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4933   [(set (match_operand:X87MODEF 0 "register_operand" "")
4934         (float:X87MODEF
4935           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4936   "TARGET_80387
4937    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4938        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4939 {
4940   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4941         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4942       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4943     {
4944       rtx reg = gen_reg_rtx (XFmode);
4945       rtx insn;
4946
4947       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4948
4949       if (<X87MODEF:MODE>mode == SFmode)
4950         insn = gen_truncxfsf2 (operands[0], reg);
4951       else if (<X87MODEF:MODE>mode == DFmode)
4952         insn = gen_truncxfdf2 (operands[0], reg);
4953       else
4954         gcc_unreachable ();
4955
4956       emit_insn (insn);
4957       DONE;
4958     }
4959 })
4960
4961 ;; Pre-reload splitter to add memory clobber to the pattern.
4962 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4963   [(set (match_operand:X87MODEF 0 "register_operand" "")
4964         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4965   "((TARGET_80387
4966      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4967      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4968            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4969          || TARGET_MIX_SSE_I387))
4970     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4971         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4972         && ((<SSEMODEI24:MODE>mode == SImode
4973              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4974              && optimize_function_for_speed_p (cfun)
4975              && flag_trapping_math)
4976             || !(TARGET_INTER_UNIT_CONVERSIONS
4977                  || optimize_function_for_size_p (cfun)))))
4978    && can_create_pseudo_p ()"
4979   "#"
4980   "&& 1"
4981   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4982               (clobber (match_dup 2))])]
4983 {
4984   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4985
4986   /* Avoid store forwarding (partial memory) stall penalty
4987      by passing DImode value through XMM registers.  */
4988   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4989       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4990       && optimize_function_for_speed_p (cfun))
4991     {
4992       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4993                                                             operands[1],
4994                                                             operands[2]));
4995       DONE;
4996     }
4997 })
4998
4999 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5000   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5001         (float:MODEF
5002           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5003    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5004   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5005    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5006   "#"
5007   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5008    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5009    (set_attr "unit" "*,i387,*,*,*")
5010    (set_attr "athlon_decode" "*,*,double,direct,double")
5011    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5012    (set_attr "bdver1_decode" "*,*,double,direct,double")
5013    (set_attr "fp_int_src" "true")])
5014
5015 (define_insn "*floatsi<mode>2_vector_mixed"
5016   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5017         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5018   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5019    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5020   "@
5021    fild%Z1\t%1
5022    #"
5023   [(set_attr "type" "fmov,sseicvt")
5024    (set_attr "mode" "<MODE>,<ssevecmode>")
5025    (set_attr "unit" "i387,*")
5026    (set_attr "athlon_decode" "*,direct")
5027    (set_attr "amdfam10_decode" "*,double")
5028    (set_attr "bdver1_decode" "*,direct")
5029    (set_attr "fp_int_src" "true")])
5030
5031 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5032   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5033         (float:MODEF
5034           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5035   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5036   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5037    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5038   "#"
5039   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5040    (set_attr "mode" "<MODEF:MODE>")
5041    (set_attr "unit" "*,i387,*,*")
5042    (set_attr "athlon_decode" "*,*,double,direct")
5043    (set_attr "amdfam10_decode" "*,*,vector,double")
5044    (set_attr "bdver1_decode" "*,*,double,direct")
5045    (set_attr "fp_int_src" "true")])
5046
5047 (define_split
5048   [(set (match_operand:MODEF 0 "register_operand" "")
5049         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5050    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5051   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5052    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5053    && TARGET_INTER_UNIT_CONVERSIONS
5054    && reload_completed
5055    && (SSE_REG_P (operands[0])
5056        || (GET_CODE (operands[0]) == SUBREG
5057            && SSE_REG_P (operands[0])))"
5058   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5059
5060 (define_split
5061   [(set (match_operand:MODEF 0 "register_operand" "")
5062         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5063    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5064   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5065    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5066    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5067    && reload_completed
5068    && (SSE_REG_P (operands[0])
5069        || (GET_CODE (operands[0]) == SUBREG
5070            && SSE_REG_P (operands[0])))"
5071   [(set (match_dup 2) (match_dup 1))
5072    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5073
5074 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5075   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5076         (float:MODEF
5077           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5078   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5079    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5080    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5081   "@
5082    fild%Z1\t%1
5083    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5084    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5085   [(set_attr "type" "fmov,sseicvt,sseicvt")
5086    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5087    (set_attr "mode" "<MODEF:MODE>")
5088    (set (attr "prefix_rex")
5089      (if_then_else
5090        (and (eq_attr "prefix" "maybe_vex")
5091             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5092        (const_string "1")
5093        (const_string "*")))
5094    (set_attr "unit" "i387,*,*")
5095    (set_attr "athlon_decode" "*,double,direct")
5096    (set_attr "amdfam10_decode" "*,vector,double")
5097    (set_attr "bdver1_decode" "*,double,direct")
5098    (set_attr "fp_int_src" "true")])
5099
5100 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5101   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5102         (float:MODEF
5103           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5104   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5105    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5106    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5107   "@
5108    fild%Z1\t%1
5109    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5110   [(set_attr "type" "fmov,sseicvt")
5111    (set_attr "prefix" "orig,maybe_vex")
5112    (set_attr "mode" "<MODEF:MODE>")
5113    (set (attr "prefix_rex")
5114      (if_then_else
5115        (and (eq_attr "prefix" "maybe_vex")
5116             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5117        (const_string "1")
5118        (const_string "*")))
5119    (set_attr "athlon_decode" "*,direct")
5120    (set_attr "amdfam10_decode" "*,double")
5121    (set_attr "bdver1_decode" "*,direct")
5122    (set_attr "fp_int_src" "true")])
5123
5124 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5125   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5126         (float:MODEF
5127           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5128    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5129   "TARGET_SSE2 && TARGET_SSE_MATH
5130    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5131   "#"
5132   [(set_attr "type" "sseicvt")
5133    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5134    (set_attr "athlon_decode" "double,direct,double")
5135    (set_attr "amdfam10_decode" "vector,double,double")
5136    (set_attr "bdver1_decode" "double,direct,double")
5137    (set_attr "fp_int_src" "true")])
5138
5139 (define_insn "*floatsi<mode>2_vector_sse"
5140   [(set (match_operand:MODEF 0 "register_operand" "=x")
5141         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5142   "TARGET_SSE2 && TARGET_SSE_MATH
5143    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5144   "#"
5145   [(set_attr "type" "sseicvt")
5146    (set_attr "mode" "<MODE>")
5147    (set_attr "athlon_decode" "direct")
5148    (set_attr "amdfam10_decode" "double")
5149    (set_attr "bdver1_decode" "direct")
5150    (set_attr "fp_int_src" "true")])
5151
5152 (define_split
5153   [(set (match_operand:MODEF 0 "register_operand" "")
5154         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5155    (clobber (match_operand:SI 2 "memory_operand" ""))]
5156   "TARGET_SSE2 && TARGET_SSE_MATH
5157    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5158    && reload_completed
5159    && (SSE_REG_P (operands[0])
5160        || (GET_CODE (operands[0]) == SUBREG
5161            && SSE_REG_P (operands[0])))"
5162   [(const_int 0)]
5163 {
5164   rtx op1 = operands[1];
5165
5166   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5167                                      <MODE>mode, 0);
5168   if (GET_CODE (op1) == SUBREG)
5169     op1 = SUBREG_REG (op1);
5170
5171   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5172     {
5173       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5174       emit_insn (gen_sse2_loadld (operands[4],
5175                                   CONST0_RTX (V4SImode), operands[1]));
5176     }
5177   /* We can ignore possible trapping value in the
5178      high part of SSE register for non-trapping math. */
5179   else if (SSE_REG_P (op1) && !flag_trapping_math)
5180     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5181   else
5182     {
5183       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5184       emit_move_insn (operands[2], operands[1]);
5185       emit_insn (gen_sse2_loadld (operands[4],
5186                                   CONST0_RTX (V4SImode), operands[2]));
5187     }
5188   emit_insn
5189     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5190   DONE;
5191 })
5192
5193 (define_split
5194   [(set (match_operand:MODEF 0 "register_operand" "")
5195         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5196    (clobber (match_operand:SI 2 "memory_operand" ""))]
5197   "TARGET_SSE2 && TARGET_SSE_MATH
5198    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5199    && reload_completed
5200    && (SSE_REG_P (operands[0])
5201        || (GET_CODE (operands[0]) == SUBREG
5202            && SSE_REG_P (operands[0])))"
5203   [(const_int 0)]
5204 {
5205   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5206                                      <MODE>mode, 0);
5207   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5208
5209   emit_insn (gen_sse2_loadld (operands[4],
5210                               CONST0_RTX (V4SImode), operands[1]));
5211   emit_insn
5212     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5213   DONE;
5214 })
5215
5216 (define_split
5217   [(set (match_operand:MODEF 0 "register_operand" "")
5218         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5219   "TARGET_SSE2 && TARGET_SSE_MATH
5220    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5221    && reload_completed
5222    && (SSE_REG_P (operands[0])
5223        || (GET_CODE (operands[0]) == SUBREG
5224            && SSE_REG_P (operands[0])))"
5225   [(const_int 0)]
5226 {
5227   rtx op1 = operands[1];
5228
5229   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5230                                      <MODE>mode, 0);
5231   if (GET_CODE (op1) == SUBREG)
5232     op1 = SUBREG_REG (op1);
5233
5234   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5235     {
5236       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5237       emit_insn (gen_sse2_loadld (operands[4],
5238                                   CONST0_RTX (V4SImode), operands[1]));
5239     }
5240   /* We can ignore possible trapping value in the
5241      high part of SSE register for non-trapping math. */
5242   else if (SSE_REG_P (op1) && !flag_trapping_math)
5243     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5244   else
5245     gcc_unreachable ();
5246   emit_insn
5247     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5248   DONE;
5249 })
5250
5251 (define_split
5252   [(set (match_operand:MODEF 0 "register_operand" "")
5253         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5254   "TARGET_SSE2 && TARGET_SSE_MATH
5255    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5256    && reload_completed
5257    && (SSE_REG_P (operands[0])
5258        || (GET_CODE (operands[0]) == SUBREG
5259            && SSE_REG_P (operands[0])))"
5260   [(const_int 0)]
5261 {
5262   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5263                                      <MODE>mode, 0);
5264   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5265
5266   emit_insn (gen_sse2_loadld (operands[4],
5267                               CONST0_RTX (V4SImode), operands[1]));
5268   emit_insn
5269     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5270   DONE;
5271 })
5272
5273 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5274   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5275         (float:MODEF
5276           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5277   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5278   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5279    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5280   "#"
5281   [(set_attr "type" "sseicvt")
5282    (set_attr "mode" "<MODEF:MODE>")
5283    (set_attr "athlon_decode" "double,direct")
5284    (set_attr "amdfam10_decode" "vector,double")
5285    (set_attr "bdver1_decode" "double,direct")
5286    (set_attr "fp_int_src" "true")])
5287
5288 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5289   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5290         (float:MODEF
5291           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5292   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5293    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5294    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5295   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5296   [(set_attr "type" "sseicvt")
5297    (set_attr "prefix" "maybe_vex")
5298    (set_attr "mode" "<MODEF:MODE>")
5299    (set (attr "prefix_rex")
5300      (if_then_else
5301        (and (eq_attr "prefix" "maybe_vex")
5302             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5303        (const_string "1")
5304        (const_string "*")))
5305    (set_attr "athlon_decode" "double,direct")
5306    (set_attr "amdfam10_decode" "vector,double")
5307    (set_attr "bdver1_decode" "double,direct")
5308    (set_attr "fp_int_src" "true")])
5309
5310 (define_split
5311   [(set (match_operand:MODEF 0 "register_operand" "")
5312         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5313    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5314   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5315    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5316    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5317    && reload_completed
5318    && (SSE_REG_P (operands[0])
5319        || (GET_CODE (operands[0]) == SUBREG
5320            && SSE_REG_P (operands[0])))"
5321   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5322
5323 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5324   [(set (match_operand:MODEF 0 "register_operand" "=x")
5325         (float:MODEF
5326           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5327   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5328    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5329    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5330   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5331   [(set_attr "type" "sseicvt")
5332    (set_attr "prefix" "maybe_vex")
5333    (set_attr "mode" "<MODEF:MODE>")
5334    (set (attr "prefix_rex")
5335      (if_then_else
5336        (and (eq_attr "prefix" "maybe_vex")
5337             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5338        (const_string "1")
5339        (const_string "*")))
5340    (set_attr "athlon_decode" "direct")
5341    (set_attr "amdfam10_decode" "double")
5342    (set_attr "bdver1_decode" "direct")
5343    (set_attr "fp_int_src" "true")])
5344
5345 (define_split
5346   [(set (match_operand:MODEF 0 "register_operand" "")
5347         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5348    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5349   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5350    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5351    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5352    && reload_completed
5353    && (SSE_REG_P (operands[0])
5354        || (GET_CODE (operands[0]) == SUBREG
5355            && SSE_REG_P (operands[0])))"
5356   [(set (match_dup 2) (match_dup 1))
5357    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5358
5359 (define_split
5360   [(set (match_operand:MODEF 0 "register_operand" "")
5361         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5362    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5363   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5364    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5365    && reload_completed
5366    && (SSE_REG_P (operands[0])
5367        || (GET_CODE (operands[0]) == SUBREG
5368            && SSE_REG_P (operands[0])))"
5369   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5370
5371 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5372   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5373         (float:X87MODEF
5374           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5375   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5376   "TARGET_80387
5377    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5378   "@
5379    fild%Z1\t%1
5380    #"
5381   [(set_attr "type" "fmov,multi")
5382    (set_attr "mode" "<X87MODEF:MODE>")
5383    (set_attr "unit" "*,i387")
5384    (set_attr "fp_int_src" "true")])
5385
5386 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5387   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5388         (float:X87MODEF
5389           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5390   "TARGET_80387
5391    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5392   "fild%Z1\t%1"
5393   [(set_attr "type" "fmov")
5394    (set_attr "mode" "<X87MODEF:MODE>")
5395    (set_attr "fp_int_src" "true")])
5396
5397 (define_split
5398   [(set (match_operand:X87MODEF 0 "register_operand" "")
5399         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5400    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5401   "TARGET_80387
5402    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5403    && reload_completed
5404    && FP_REG_P (operands[0])"
5405   [(set (match_dup 2) (match_dup 1))
5406    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5407
5408 (define_split
5409   [(set (match_operand:X87MODEF 0 "register_operand" "")
5410         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5411    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5412   "TARGET_80387
5413    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5414    && reload_completed
5415    && FP_REG_P (operands[0])"
5416   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5417
5418 ;; Avoid store forwarding (partial memory) stall penalty
5419 ;; by passing DImode value through XMM registers.  */
5420
5421 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5422   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5423         (float:X87MODEF
5424           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5425    (clobber (match_scratch:V4SI 3 "=X,x"))
5426    (clobber (match_scratch:V4SI 4 "=X,x"))
5427    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5428   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5429    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5430    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5431   "#"
5432   [(set_attr "type" "multi")
5433    (set_attr "mode" "<X87MODEF:MODE>")
5434    (set_attr "unit" "i387")
5435    (set_attr "fp_int_src" "true")])
5436
5437 (define_split
5438   [(set (match_operand:X87MODEF 0 "register_operand" "")
5439         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5440    (clobber (match_scratch:V4SI 3 ""))
5441    (clobber (match_scratch:V4SI 4 ""))
5442    (clobber (match_operand:DI 2 "memory_operand" ""))]
5443   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5444    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5445    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5446    && reload_completed
5447    && FP_REG_P (operands[0])"
5448   [(set (match_dup 2) (match_dup 3))
5449    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5450 {
5451   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5452      Assemble the 64-bit DImode value in an xmm register.  */
5453   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5454                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5455   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5456                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5457   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5458                                          operands[4]));
5459
5460   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5461 })
5462
5463 (define_split
5464   [(set (match_operand:X87MODEF 0 "register_operand" "")
5465         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5466    (clobber (match_scratch:V4SI 3 ""))
5467    (clobber (match_scratch:V4SI 4 ""))
5468    (clobber (match_operand:DI 2 "memory_operand" ""))]
5469   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5470    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5471    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5472    && reload_completed
5473    && FP_REG_P (operands[0])"
5474   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5475
5476 ;; Avoid store forwarding (partial memory) stall penalty by extending
5477 ;; SImode value to DImode through XMM register instead of pushing two
5478 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5479 ;; targets benefit from this optimization. Also note that fild
5480 ;; loads from memory only.
5481
5482 (define_insn "*floatunssi<mode>2_1"
5483   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5484         (unsigned_float:X87MODEF
5485           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5486    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5487    (clobber (match_scratch:SI 3 "=X,x"))]
5488   "!TARGET_64BIT
5489    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5490    && TARGET_SSE"
5491   "#"
5492   [(set_attr "type" "multi")
5493    (set_attr "mode" "<MODE>")])
5494
5495 (define_split
5496   [(set (match_operand:X87MODEF 0 "register_operand" "")
5497         (unsigned_float:X87MODEF
5498           (match_operand:SI 1 "register_operand" "")))
5499    (clobber (match_operand:DI 2 "memory_operand" ""))
5500    (clobber (match_scratch:SI 3 ""))]
5501   "!TARGET_64BIT
5502    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5503    && TARGET_SSE
5504    && reload_completed"
5505   [(set (match_dup 2) (match_dup 1))
5506    (set (match_dup 0)
5507         (float:X87MODEF (match_dup 2)))]
5508   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5509
5510 (define_split
5511   [(set (match_operand:X87MODEF 0 "register_operand" "")
5512         (unsigned_float:X87MODEF
5513           (match_operand:SI 1 "memory_operand" "")))
5514    (clobber (match_operand:DI 2 "memory_operand" ""))
5515    (clobber (match_scratch:SI 3 ""))]
5516   "!TARGET_64BIT
5517    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5518    && TARGET_SSE
5519    && reload_completed"
5520   [(set (match_dup 2) (match_dup 3))
5521    (set (match_dup 0)
5522         (float:X87MODEF (match_dup 2)))]
5523 {
5524   emit_move_insn (operands[3], operands[1]);
5525   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5526 })
5527
5528 (define_expand "floatunssi<mode>2"
5529   [(parallel
5530      [(set (match_operand:X87MODEF 0 "register_operand" "")
5531            (unsigned_float:X87MODEF
5532              (match_operand:SI 1 "nonimmediate_operand" "")))
5533       (clobber (match_dup 2))
5534       (clobber (match_scratch:SI 3 ""))])]
5535   "!TARGET_64BIT
5536    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5537         && TARGET_SSE)
5538        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5539 {
5540   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5541     {
5542       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5543       DONE;
5544     }
5545   else
5546     {
5547       enum ix86_stack_slot slot = (virtuals_instantiated
5548                                    ? SLOT_TEMP
5549                                    : SLOT_VIRTUAL);
5550       operands[2] = assign_386_stack_local (DImode, slot);
5551     }
5552 })
5553
5554 (define_expand "floatunsdisf2"
5555   [(use (match_operand:SF 0 "register_operand" ""))
5556    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5557   "TARGET_64BIT && TARGET_SSE_MATH"
5558   "x86_emit_floatuns (operands); DONE;")
5559
5560 (define_expand "floatunsdidf2"
5561   [(use (match_operand:DF 0 "register_operand" ""))
5562    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5563   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5564    && TARGET_SSE2 && TARGET_SSE_MATH"
5565 {
5566   if (TARGET_64BIT)
5567     x86_emit_floatuns (operands);
5568   else
5569     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5570   DONE;
5571 })
5572 \f
5573 ;; Add instructions
5574
5575 (define_expand "add<mode>3"
5576   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5577         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5578                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5579   ""
5580   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5581
5582 (define_insn_and_split "*add<dwi>3_doubleword"
5583   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5584         (plus:<DWI>
5585           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5586           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5587    (clobber (reg:CC FLAGS_REG))]
5588   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5589   "#"
5590   "reload_completed"
5591   [(parallel [(set (reg:CC FLAGS_REG)
5592                    (unspec:CC [(match_dup 1) (match_dup 2)]
5593                               UNSPEC_ADD_CARRY))
5594               (set (match_dup 0)
5595                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5596    (parallel [(set (match_dup 3)
5597                    (plus:DWIH
5598                      (match_dup 4)
5599                      (plus:DWIH
5600                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5601                        (match_dup 5))))
5602               (clobber (reg:CC FLAGS_REG))])]
5603   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5604
5605 (define_insn "*add<mode>3_cc"
5606   [(set (reg:CC FLAGS_REG)
5607         (unspec:CC
5608           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5609            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5610           UNSPEC_ADD_CARRY))
5611    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5612         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5613   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5614   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5615   [(set_attr "type" "alu")
5616    (set_attr "mode" "<MODE>")])
5617
5618 (define_insn "addqi3_cc"
5619   [(set (reg:CC FLAGS_REG)
5620         (unspec:CC
5621           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5622            (match_operand:QI 2 "general_operand" "qn,qm")]
5623           UNSPEC_ADD_CARRY))
5624    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5625         (plus:QI (match_dup 1) (match_dup 2)))]
5626   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5627   "add{b}\t{%2, %0|%0, %2}"
5628   [(set_attr "type" "alu")
5629    (set_attr "mode" "QI")])
5630
5631 (define_insn "*lea_1"
5632   [(set (match_operand:P 0 "register_operand" "=r")
5633         (match_operand:P 1 "no_seg_address_operand" "p"))]
5634   ""
5635   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5636   [(set_attr "type" "lea")
5637    (set_attr "mode" "<MODE>")])
5638
5639 (define_insn "*lea_2"
5640   [(set (match_operand:SI 0 "register_operand" "=r")
5641         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5642   "TARGET_64BIT"
5643   "lea{l}\t{%a1, %0|%0, %a1}"
5644   [(set_attr "type" "lea")
5645    (set_attr "mode" "SI")])
5646
5647 (define_insn "*lea_2_zext"
5648   [(set (match_operand:DI 0 "register_operand" "=r")
5649         (zero_extend:DI
5650           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5651   "TARGET_64BIT"
5652   "lea{l}\t{%a1, %k0|%k0, %a1}"
5653   [(set_attr "type" "lea")
5654    (set_attr "mode" "SI")])
5655
5656 (define_insn "*add<mode>_1"
5657   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5658         (plus:SWI48
5659           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5660           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5661    (clobber (reg:CC FLAGS_REG))]
5662   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5663 {
5664   switch (get_attr_type (insn))
5665     {
5666     case TYPE_LEA:
5667       return "#";
5668
5669     case TYPE_INCDEC:
5670       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5671       if (operands[2] == const1_rtx)
5672         return "inc{<imodesuffix>}\t%0";
5673       else
5674         {
5675           gcc_assert (operands[2] == constm1_rtx);
5676           return "dec{<imodesuffix>}\t%0";
5677         }
5678
5679     default:
5680       /* For most processors, ADD is faster than LEA.  This alternative
5681          was added to use ADD as much as possible.  */
5682       if (which_alternative == 2)
5683         {
5684           rtx tmp;
5685           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5686         }
5687         
5688       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5690         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5691
5692       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5693     }
5694 }
5695   [(set (attr "type")
5696      (cond [(eq_attr "alternative" "3")
5697               (const_string "lea")
5698             (match_operand:SWI48 2 "incdec_operand" "")
5699               (const_string "incdec")
5700            ]
5701            (const_string "alu")))
5702    (set (attr "length_immediate")
5703       (if_then_else
5704         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5705         (const_string "1")
5706         (const_string "*")))
5707    (set_attr "mode" "<MODE>")])
5708
5709 ;; It may seem that nonimmediate operand is proper one for operand 1.
5710 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5711 ;; we take care in ix86_binary_operator_ok to not allow two memory
5712 ;; operands so proper swapping will be done in reload.  This allow
5713 ;; patterns constructed from addsi_1 to match.
5714
5715 (define_insn "*addsi_1_zext"
5716   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5717         (zero_extend:DI
5718           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5719                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5720    (clobber (reg:CC FLAGS_REG))]
5721   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5722 {
5723   switch (get_attr_type (insn))
5724     {
5725     case TYPE_LEA:
5726       return "#";
5727
5728     case TYPE_INCDEC:
5729       if (operands[2] == const1_rtx)
5730         return "inc{l}\t%k0";
5731       else
5732         {
5733           gcc_assert (operands[2] == constm1_rtx);
5734           return "dec{l}\t%k0";
5735         }
5736
5737     default:
5738       /* For most processors, ADD is faster than LEA.  This alternative
5739          was added to use ADD as much as possible.  */
5740       if (which_alternative == 1)
5741         {
5742           rtx tmp;
5743           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5744         }
5745
5746       if (x86_maybe_negate_const_int (&operands[2], SImode))
5747         return "sub{l}\t{%2, %k0|%k0, %2}";
5748
5749       return "add{l}\t{%2, %k0|%k0, %2}";
5750     }
5751 }
5752   [(set (attr "type")
5753      (cond [(eq_attr "alternative" "2")
5754               (const_string "lea")
5755             (match_operand:SI 2 "incdec_operand" "")
5756               (const_string "incdec")
5757            ]
5758            (const_string "alu")))
5759    (set (attr "length_immediate")
5760       (if_then_else
5761         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5762         (const_string "1")
5763         (const_string "*")))
5764    (set_attr "mode" "SI")])
5765
5766 (define_insn "*addhi_1"
5767   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5768         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5769                  (match_operand:HI 2 "general_operand" "rn,rm")))
5770    (clobber (reg:CC FLAGS_REG))]
5771   "TARGET_PARTIAL_REG_STALL
5772    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5773 {
5774   switch (get_attr_type (insn))
5775     {
5776     case TYPE_INCDEC:
5777       if (operands[2] == const1_rtx)
5778         return "inc{w}\t%0";
5779       else
5780         {
5781           gcc_assert (operands[2] == constm1_rtx);
5782           return "dec{w}\t%0";
5783         }
5784
5785     default:
5786       if (x86_maybe_negate_const_int (&operands[2], HImode))
5787         return "sub{w}\t{%2, %0|%0, %2}";
5788
5789       return "add{w}\t{%2, %0|%0, %2}";
5790     }
5791 }
5792   [(set (attr "type")
5793      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5794         (const_string "incdec")
5795         (const_string "alu")))
5796    (set (attr "length_immediate")
5797       (if_then_else
5798         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5799         (const_string "1")
5800         (const_string "*")))
5801    (set_attr "mode" "HI")])
5802
5803 (define_insn "*addhi_1_lea"
5804   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5805         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5806                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5807    (clobber (reg:CC FLAGS_REG))]
5808   "!TARGET_PARTIAL_REG_STALL
5809    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5810 {
5811   switch (get_attr_type (insn))
5812     {
5813     case TYPE_LEA:
5814       return "#";
5815
5816     case TYPE_INCDEC:
5817       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5818       if (operands[2] == const1_rtx)
5819         return "inc{w}\t%0";
5820       else
5821         {
5822           gcc_assert (operands[2] == constm1_rtx);
5823           return "dec{w}\t%0";
5824         }
5825
5826     default:
5827       /* For most processors, ADD is faster than LEA.  This alternative
5828          was added to use ADD as much as possible.  */
5829       if (which_alternative == 2)
5830         {
5831           rtx tmp;
5832           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5833         }
5834
5835       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5836       if (x86_maybe_negate_const_int (&operands[2], HImode))
5837         return "sub{w}\t{%2, %0|%0, %2}";
5838
5839       return "add{w}\t{%2, %0|%0, %2}";
5840     }
5841 }
5842   [(set (attr "type")
5843      (cond [(eq_attr "alternative" "3")
5844               (const_string "lea")
5845             (match_operand:HI 2 "incdec_operand" "")
5846               (const_string "incdec")
5847            ]
5848            (const_string "alu")))
5849    (set (attr "length_immediate")
5850       (if_then_else
5851         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5852         (const_string "1")
5853         (const_string "*")))
5854    (set_attr "mode" "HI,HI,HI,SI")])
5855
5856 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5857 (define_insn "*addqi_1"
5858   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5859         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5860                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5861    (clobber (reg:CC FLAGS_REG))]
5862   "TARGET_PARTIAL_REG_STALL
5863    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5864 {
5865   int widen = (which_alternative == 2);
5866   switch (get_attr_type (insn))
5867     {
5868     case TYPE_INCDEC:
5869       if (operands[2] == const1_rtx)
5870         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5871       else
5872         {
5873           gcc_assert (operands[2] == constm1_rtx);
5874           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5875         }
5876
5877     default:
5878       if (x86_maybe_negate_const_int (&operands[2], QImode))
5879         {
5880           if (widen)
5881             return "sub{l}\t{%2, %k0|%k0, %2}";
5882           else
5883             return "sub{b}\t{%2, %0|%0, %2}";
5884         }
5885       if (widen)
5886         return "add{l}\t{%k2, %k0|%k0, %k2}";
5887       else
5888         return "add{b}\t{%2, %0|%0, %2}";
5889     }
5890 }
5891   [(set (attr "type")
5892      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5893         (const_string "incdec")
5894         (const_string "alu")))
5895    (set (attr "length_immediate")
5896       (if_then_else
5897         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5898         (const_string "1")
5899         (const_string "*")))
5900    (set_attr "mode" "QI,QI,SI")])
5901
5902 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5903 (define_insn "*addqi_1_lea"
5904   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5905         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5906                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5907    (clobber (reg:CC FLAGS_REG))]
5908   "!TARGET_PARTIAL_REG_STALL
5909    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5910 {
5911   int widen = (which_alternative == 3 || which_alternative == 4);
5912
5913   switch (get_attr_type (insn))
5914     {
5915     case TYPE_LEA:
5916       return "#";
5917
5918     case TYPE_INCDEC:
5919       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5920       if (operands[2] == const1_rtx)
5921         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5922       else
5923         {
5924           gcc_assert (operands[2] == constm1_rtx);
5925           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5926         }
5927
5928     default:
5929       /* For most processors, ADD is faster than LEA.  These alternatives
5930          were added to use ADD as much as possible.  */
5931       if (which_alternative == 2 || which_alternative == 4)
5932         {
5933           rtx tmp;
5934           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5935         }
5936
5937       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5938       if (x86_maybe_negate_const_int (&operands[2], QImode))
5939         {
5940           if (widen)
5941             return "sub{l}\t{%2, %k0|%k0, %2}";
5942           else
5943             return "sub{b}\t{%2, %0|%0, %2}";
5944         }
5945       if (widen)
5946         return "add{l}\t{%k2, %k0|%k0, %k2}";
5947       else
5948         return "add{b}\t{%2, %0|%0, %2}";
5949     }
5950 }
5951   [(set (attr "type")
5952      (cond [(eq_attr "alternative" "5")
5953               (const_string "lea")
5954             (match_operand:QI 2 "incdec_operand" "")
5955               (const_string "incdec")
5956            ]
5957            (const_string "alu")))
5958    (set (attr "length_immediate")
5959       (if_then_else
5960         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5961         (const_string "1")
5962         (const_string "*")))
5963    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5964
5965 (define_insn "*addqi_1_slp"
5966   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5967         (plus:QI (match_dup 0)
5968                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5969    (clobber (reg:CC FLAGS_REG))]
5970   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5971    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5972 {
5973   switch (get_attr_type (insn))
5974     {
5975     case TYPE_INCDEC:
5976       if (operands[1] == const1_rtx)
5977         return "inc{b}\t%0";
5978       else
5979         {
5980           gcc_assert (operands[1] == constm1_rtx);
5981           return "dec{b}\t%0";
5982         }
5983
5984     default:
5985       if (x86_maybe_negate_const_int (&operands[1], QImode))
5986         return "sub{b}\t{%1, %0|%0, %1}";
5987
5988       return "add{b}\t{%1, %0|%0, %1}";
5989     }
5990 }
5991   [(set (attr "type")
5992      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5993         (const_string "incdec")
5994         (const_string "alu1")))
5995    (set (attr "memory")
5996      (if_then_else (match_operand 1 "memory_operand" "")
5997         (const_string "load")
5998         (const_string "none")))
5999    (set_attr "mode" "QI")])
6000
6001 ;; Convert lea to the lea pattern to avoid flags dependency.
6002 (define_split
6003   [(set (match_operand 0 "register_operand" "")
6004         (plus (match_operand 1 "register_operand" "")
6005               (match_operand 2 "nonmemory_operand" "")))
6006    (clobber (reg:CC FLAGS_REG))]
6007   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
6008   [(const_int 0)]
6009 {
6010   rtx pat;
6011   enum machine_mode mode = GET_MODE (operands[0]);
6012
6013   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6014      may confuse gen_lowpart.  */
6015   if (mode != Pmode)
6016     {
6017       operands[1] = gen_lowpart (Pmode, operands[1]);
6018       operands[2] = gen_lowpart (Pmode, operands[2]);
6019     }
6020
6021   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6022
6023   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6024     operands[0] = gen_lowpart (SImode, operands[0]);
6025
6026   if (TARGET_64BIT && mode != Pmode)
6027     pat = gen_rtx_SUBREG (SImode, pat, 0);
6028
6029   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6030   DONE;
6031 })
6032
6033 ;; Convert lea to the lea pattern to avoid flags dependency.
6034 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6035 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6036 (define_split
6037   [(set (match_operand:DI 0 "register_operand" "")
6038         (plus:DI (match_operand:DI 1 "register_operand" "")
6039                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
6040    (clobber (reg:CC FLAGS_REG))]
6041   "TARGET_64BIT && reload_completed 
6042    && true_regnum (operands[0]) != true_regnum (operands[1])"
6043   [(set (match_dup 0)
6044         (plus:DI (match_dup 1) (match_dup 2)))])
6045
6046 ;; Convert lea to the lea pattern to avoid flags dependency.
6047 (define_split
6048   [(set (match_operand:DI 0 "register_operand" "")
6049         (zero_extend:DI
6050           (plus:SI (match_operand:SI 1 "register_operand" "")
6051                    (match_operand:SI 2 "nonmemory_operand" ""))))
6052    (clobber (reg:CC FLAGS_REG))]
6053   "TARGET_64BIT && reload_completed
6054    && ix86_lea_for_add_ok (insn, operands)"
6055   [(set (match_dup 0)
6056         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6057 {
6058   operands[1] = gen_lowpart (DImode, operands[1]);
6059   operands[2] = gen_lowpart (DImode, operands[2]);
6060 })
6061
6062 (define_insn "*add<mode>_2"
6063   [(set (reg FLAGS_REG)
6064         (compare
6065           (plus:SWI
6066             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6067             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6068           (const_int 0)))
6069    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6070         (plus:SWI (match_dup 1) (match_dup 2)))]
6071   "ix86_match_ccmode (insn, CCGOCmode)
6072    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6073 {
6074   switch (get_attr_type (insn))
6075     {
6076     case TYPE_INCDEC:
6077       if (operands[2] == const1_rtx)
6078         return "inc{<imodesuffix>}\t%0";
6079       else
6080         {
6081           gcc_assert (operands[2] == constm1_rtx);
6082           return "dec{<imodesuffix>}\t%0";
6083         }
6084
6085     default:
6086       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6087         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6088
6089       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6090     }
6091 }
6092   [(set (attr "type")
6093      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6094         (const_string "incdec")
6095         (const_string "alu")))
6096    (set (attr "length_immediate")
6097       (if_then_else
6098         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6099         (const_string "1")
6100         (const_string "*")))
6101    (set_attr "mode" "<MODE>")])
6102
6103 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6104 (define_insn "*addsi_2_zext"
6105   [(set (reg FLAGS_REG)
6106         (compare
6107           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6108                    (match_operand:SI 2 "general_operand" "g"))
6109           (const_int 0)))
6110    (set (match_operand:DI 0 "register_operand" "=r")
6111         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6112   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6113    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6114 {
6115   switch (get_attr_type (insn))
6116     {
6117     case TYPE_INCDEC:
6118       if (operands[2] == const1_rtx)
6119         return "inc{l}\t%k0";
6120       else
6121         {
6122           gcc_assert (operands[2] == constm1_rtx);
6123           return "dec{l}\t%k0";
6124         }
6125
6126     default:
6127       if (x86_maybe_negate_const_int (&operands[2], SImode))
6128         return "sub{l}\t{%2, %k0|%k0, %2}";
6129
6130       return "add{l}\t{%2, %k0|%k0, %2}";
6131     }
6132 }
6133   [(set (attr "type")
6134      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6135         (const_string "incdec")
6136         (const_string "alu")))
6137    (set (attr "length_immediate")
6138       (if_then_else
6139         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6140         (const_string "1")
6141         (const_string "*")))
6142    (set_attr "mode" "SI")])
6143
6144 (define_insn "*add<mode>_3"
6145   [(set (reg FLAGS_REG)
6146         (compare
6147           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6148           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6149    (clobber (match_scratch:SWI 0 "=<r>"))]
6150   "ix86_match_ccmode (insn, CCZmode)
6151    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6152 {
6153   switch (get_attr_type (insn))
6154     {
6155     case TYPE_INCDEC:
6156       if (operands[2] == const1_rtx)
6157         return "inc{<imodesuffix>}\t%0";
6158       else
6159         {
6160           gcc_assert (operands[2] == constm1_rtx);
6161           return "dec{<imodesuffix>}\t%0";
6162         }
6163
6164     default:
6165       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6166         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6167
6168       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6169     }
6170 }
6171   [(set (attr "type")
6172      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6173         (const_string "incdec")
6174         (const_string "alu")))
6175    (set (attr "length_immediate")
6176       (if_then_else
6177         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6178         (const_string "1")
6179         (const_string "*")))
6180    (set_attr "mode" "<MODE>")])
6181
6182 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6183 (define_insn "*addsi_3_zext"
6184   [(set (reg FLAGS_REG)
6185         (compare
6186           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6187           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6188    (set (match_operand:DI 0 "register_operand" "=r")
6189         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6190   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6191    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6192 {
6193   switch (get_attr_type (insn))
6194     {
6195     case TYPE_INCDEC:
6196       if (operands[2] == const1_rtx)
6197         return "inc{l}\t%k0";
6198       else
6199         {
6200           gcc_assert (operands[2] == constm1_rtx);
6201           return "dec{l}\t%k0";
6202         }
6203
6204     default:
6205       if (x86_maybe_negate_const_int (&operands[2], SImode))
6206         return "sub{l}\t{%2, %k0|%k0, %2}";
6207
6208       return "add{l}\t{%2, %k0|%k0, %2}";
6209     }
6210 }
6211   [(set (attr "type")
6212      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6213         (const_string "incdec")
6214         (const_string "alu")))
6215    (set (attr "length_immediate")
6216       (if_then_else
6217         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6218         (const_string "1")
6219         (const_string "*")))
6220    (set_attr "mode" "SI")])
6221
6222 ; For comparisons against 1, -1 and 128, we may generate better code
6223 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6224 ; is matched then.  We can't accept general immediate, because for
6225 ; case of overflows,  the result is messed up.
6226 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6227 ; only for comparisons not depending on it.
6228
6229 (define_insn "*adddi_4"
6230   [(set (reg FLAGS_REG)
6231         (compare
6232           (match_operand:DI 1 "nonimmediate_operand" "0")
6233           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6234    (clobber (match_scratch:DI 0 "=rm"))]
6235   "TARGET_64BIT
6236    && ix86_match_ccmode (insn, CCGCmode)"
6237 {
6238   switch (get_attr_type (insn))
6239     {
6240     case TYPE_INCDEC:
6241       if (operands[2] == constm1_rtx)
6242         return "inc{q}\t%0";
6243       else
6244         {
6245           gcc_assert (operands[2] == const1_rtx);
6246           return "dec{q}\t%0";
6247         }
6248
6249     default:
6250       if (x86_maybe_negate_const_int (&operands[2], DImode))
6251         return "add{q}\t{%2, %0|%0, %2}";
6252
6253       return "sub{q}\t{%2, %0|%0, %2}";
6254     }
6255 }
6256   [(set (attr "type")
6257      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6258         (const_string "incdec")
6259         (const_string "alu")))
6260    (set (attr "length_immediate")
6261       (if_then_else
6262         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6263         (const_string "1")
6264         (const_string "*")))
6265    (set_attr "mode" "DI")])
6266
6267 ; For comparisons against 1, -1 and 128, we may generate better code
6268 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6269 ; is matched then.  We can't accept general immediate, because for
6270 ; case of overflows,  the result is messed up.
6271 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6272 ; only for comparisons not depending on it.
6273
6274 (define_insn "*add<mode>_4"
6275   [(set (reg FLAGS_REG)
6276         (compare
6277           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6278           (match_operand:SWI124 2 "const_int_operand" "n")))
6279    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6280   "ix86_match_ccmode (insn, CCGCmode)"
6281 {
6282   switch (get_attr_type (insn))
6283     {
6284     case TYPE_INCDEC:
6285       if (operands[2] == constm1_rtx)
6286         return "inc{<imodesuffix>}\t%0";
6287       else
6288         {
6289           gcc_assert (operands[2] == const1_rtx);
6290           return "dec{<imodesuffix>}\t%0";
6291         }
6292
6293     default:
6294       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6295         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6296
6297       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6298     }
6299 }
6300   [(set (attr "type")
6301      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6302         (const_string "incdec")
6303         (const_string "alu")))
6304    (set (attr "length_immediate")
6305       (if_then_else
6306         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6307         (const_string "1")
6308         (const_string "*")))
6309    (set_attr "mode" "<MODE>")])
6310
6311 (define_insn "*add<mode>_5"
6312   [(set (reg FLAGS_REG)
6313         (compare
6314           (plus:SWI
6315             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6316             (match_operand:SWI 2 "<general_operand>" "<g>"))
6317           (const_int 0)))
6318    (clobber (match_scratch:SWI 0 "=<r>"))]
6319   "ix86_match_ccmode (insn, CCGOCmode)
6320    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6321 {
6322   switch (get_attr_type (insn))
6323     {
6324     case TYPE_INCDEC:
6325       if (operands[2] == const1_rtx)
6326         return "inc{<imodesuffix>}\t%0";
6327       else
6328         {
6329           gcc_assert (operands[2] == constm1_rtx);
6330           return "dec{<imodesuffix>}\t%0";
6331         }
6332
6333     default:
6334       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6335         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6336
6337       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6338     }
6339 }
6340   [(set (attr "type")
6341      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6342         (const_string "incdec")
6343         (const_string "alu")))
6344    (set (attr "length_immediate")
6345       (if_then_else
6346         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6347         (const_string "1")
6348         (const_string "*")))
6349    (set_attr "mode" "<MODE>")])
6350
6351 (define_insn "*addqi_ext_1_rex64"
6352   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6353                          (const_int 8)
6354                          (const_int 8))
6355         (plus:SI
6356           (zero_extract:SI
6357             (match_operand 1 "ext_register_operand" "0")
6358             (const_int 8)
6359             (const_int 8))
6360           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6361    (clobber (reg:CC FLAGS_REG))]
6362   "TARGET_64BIT"
6363 {
6364   switch (get_attr_type (insn))
6365     {
6366     case TYPE_INCDEC:
6367       if (operands[2] == const1_rtx)
6368         return "inc{b}\t%h0";
6369       else
6370         {
6371           gcc_assert (operands[2] == constm1_rtx);
6372           return "dec{b}\t%h0";
6373         }
6374
6375     default:
6376       return "add{b}\t{%2, %h0|%h0, %2}";
6377     }
6378 }
6379   [(set (attr "type")
6380      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6381         (const_string "incdec")
6382         (const_string "alu")))
6383    (set_attr "modrm" "1")
6384    (set_attr "mode" "QI")])
6385
6386 (define_insn "addqi_ext_1"
6387   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6388                          (const_int 8)
6389                          (const_int 8))
6390         (plus:SI
6391           (zero_extract:SI
6392             (match_operand 1 "ext_register_operand" "0")
6393             (const_int 8)
6394             (const_int 8))
6395           (match_operand:QI 2 "general_operand" "Qmn")))
6396    (clobber (reg:CC FLAGS_REG))]
6397   "!TARGET_64BIT"
6398 {
6399   switch (get_attr_type (insn))
6400     {
6401     case TYPE_INCDEC:
6402       if (operands[2] == const1_rtx)
6403         return "inc{b}\t%h0";
6404       else
6405         {
6406           gcc_assert (operands[2] == constm1_rtx);
6407           return "dec{b}\t%h0";
6408         }
6409
6410     default:
6411       return "add{b}\t{%2, %h0|%h0, %2}";
6412     }
6413 }
6414   [(set (attr "type")
6415      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6416         (const_string "incdec")
6417         (const_string "alu")))
6418    (set_attr "modrm" "1")
6419    (set_attr "mode" "QI")])
6420
6421 (define_insn "*addqi_ext_2"
6422   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6423                          (const_int 8)
6424                          (const_int 8))
6425         (plus:SI
6426           (zero_extract:SI
6427             (match_operand 1 "ext_register_operand" "%0")
6428             (const_int 8)
6429             (const_int 8))
6430           (zero_extract:SI
6431             (match_operand 2 "ext_register_operand" "Q")
6432             (const_int 8)
6433             (const_int 8))))
6434    (clobber (reg:CC FLAGS_REG))]
6435   ""
6436   "add{b}\t{%h2, %h0|%h0, %h2}"
6437   [(set_attr "type" "alu")
6438    (set_attr "mode" "QI")])
6439
6440 ;; The lea patterns for non-Pmodes needs to be matched by
6441 ;; several insns converted to real lea by splitters.
6442
6443 (define_insn_and_split "*lea_general_1"
6444   [(set (match_operand 0 "register_operand" "=r")
6445         (plus (plus (match_operand 1 "index_register_operand" "l")
6446                     (match_operand 2 "register_operand" "r"))
6447               (match_operand 3 "immediate_operand" "i")))]
6448   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6449     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6450    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6451    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6452    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6453    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6454        || GET_MODE (operands[3]) == VOIDmode)"
6455   "#"
6456   "&& reload_completed"
6457   [(const_int 0)]
6458 {
6459   rtx pat;
6460   operands[0] = gen_lowpart (SImode, operands[0]);
6461   operands[1] = gen_lowpart (Pmode, operands[1]);
6462   operands[2] = gen_lowpart (Pmode, operands[2]);
6463   operands[3] = gen_lowpart (Pmode, operands[3]);
6464   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6465                       operands[3]);
6466   if (Pmode != SImode)
6467     pat = gen_rtx_SUBREG (SImode, pat, 0);
6468   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6469   DONE;
6470 }
6471   [(set_attr "type" "lea")
6472    (set_attr "mode" "SI")])
6473
6474 (define_insn_and_split "*lea_general_1_zext"
6475   [(set (match_operand:DI 0 "register_operand" "=r")
6476         (zero_extend:DI
6477           (plus:SI (plus:SI
6478                      (match_operand:SI 1 "index_register_operand" "l")
6479                      (match_operand:SI 2 "register_operand" "r"))
6480                    (match_operand:SI 3 "immediate_operand" "i"))))]
6481   "TARGET_64BIT"
6482   "#"
6483   "&& reload_completed"
6484   [(set (match_dup 0)
6485         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6486                                                      (match_dup 2))
6487                                             (match_dup 3)) 0)))]
6488 {
6489   operands[1] = gen_lowpart (Pmode, operands[1]);
6490   operands[2] = gen_lowpart (Pmode, operands[2]);
6491   operands[3] = gen_lowpart (Pmode, operands[3]);
6492 }
6493   [(set_attr "type" "lea")
6494    (set_attr "mode" "SI")])
6495
6496 (define_insn_and_split "*lea_general_2"
6497   [(set (match_operand 0 "register_operand" "=r")
6498         (plus (mult (match_operand 1 "index_register_operand" "l")
6499                     (match_operand 2 "const248_operand" "i"))
6500               (match_operand 3 "nonmemory_operand" "ri")))]
6501   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6502     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6503    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6504    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6505    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6506        || GET_MODE (operands[3]) == VOIDmode)"
6507   "#"
6508   "&& reload_completed"
6509   [(const_int 0)]
6510 {
6511   rtx pat;
6512   operands[0] = gen_lowpart (SImode, operands[0]);
6513   operands[1] = gen_lowpart (Pmode, operands[1]);
6514   operands[3] = gen_lowpart (Pmode, operands[3]);
6515   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6516                       operands[3]);
6517   if (Pmode != SImode)
6518     pat = gen_rtx_SUBREG (SImode, pat, 0);
6519   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6520   DONE;
6521 }
6522   [(set_attr "type" "lea")
6523    (set_attr "mode" "SI")])
6524
6525 (define_insn_and_split "*lea_general_2_zext"
6526   [(set (match_operand:DI 0 "register_operand" "=r")
6527         (zero_extend:DI
6528           (plus:SI (mult:SI
6529                      (match_operand:SI 1 "index_register_operand" "l")
6530                      (match_operand:SI 2 "const248_operand" "n"))
6531                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6532   "TARGET_64BIT"
6533   "#"
6534   "&& reload_completed"
6535   [(set (match_dup 0)
6536         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6537                                                      (match_dup 2))
6538                                             (match_dup 3)) 0)))]
6539 {
6540   operands[1] = gen_lowpart (Pmode, operands[1]);
6541   operands[3] = gen_lowpart (Pmode, operands[3]);
6542 }
6543   [(set_attr "type" "lea")
6544    (set_attr "mode" "SI")])
6545
6546 (define_insn_and_split "*lea_general_3"
6547   [(set (match_operand 0 "register_operand" "=r")
6548         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6549                           (match_operand 2 "const248_operand" "i"))
6550                     (match_operand 3 "register_operand" "r"))
6551               (match_operand 4 "immediate_operand" "i")))]
6552   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6553     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6554    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6555    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6556    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6557   "#"
6558   "&& reload_completed"
6559   [(const_int 0)]
6560 {
6561   rtx pat;
6562   operands[0] = gen_lowpart (SImode, operands[0]);
6563   operands[1] = gen_lowpart (Pmode, operands[1]);
6564   operands[3] = gen_lowpart (Pmode, operands[3]);
6565   operands[4] = gen_lowpart (Pmode, operands[4]);
6566   pat = gen_rtx_PLUS (Pmode,
6567                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6568                                                          operands[2]),
6569                                     operands[3]),
6570                       operands[4]);
6571   if (Pmode != SImode)
6572     pat = gen_rtx_SUBREG (SImode, pat, 0);
6573   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6574   DONE;
6575 }
6576   [(set_attr "type" "lea")
6577    (set_attr "mode" "SI")])
6578
6579 (define_insn_and_split "*lea_general_3_zext"
6580   [(set (match_operand:DI 0 "register_operand" "=r")
6581         (zero_extend:DI
6582           (plus:SI (plus:SI
6583                      (mult:SI
6584                        (match_operand:SI 1 "index_register_operand" "l")
6585                        (match_operand:SI 2 "const248_operand" "n"))
6586                      (match_operand:SI 3 "register_operand" "r"))
6587                    (match_operand:SI 4 "immediate_operand" "i"))))]
6588   "TARGET_64BIT"
6589   "#"
6590   "&& reload_completed"
6591   [(set (match_dup 0)
6592         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6593                                                               (match_dup 2))
6594                                                      (match_dup 3))
6595                                             (match_dup 4)) 0)))]
6596 {
6597   operands[1] = gen_lowpart (Pmode, operands[1]);
6598   operands[3] = gen_lowpart (Pmode, operands[3]);
6599   operands[4] = gen_lowpart (Pmode, operands[4]);
6600 }
6601   [(set_attr "type" "lea")
6602    (set_attr "mode" "SI")])
6603 \f
6604 ;; Subtract instructions
6605
6606 (define_expand "sub<mode>3"
6607   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6608         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6609                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6610   ""
6611   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6612
6613 (define_insn_and_split "*sub<dwi>3_doubleword"
6614   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6615         (minus:<DWI>
6616           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6617           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6618    (clobber (reg:CC FLAGS_REG))]
6619   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6620   "#"
6621   "reload_completed"
6622   [(parallel [(set (reg:CC FLAGS_REG)
6623                    (compare:CC (match_dup 1) (match_dup 2)))
6624               (set (match_dup 0)
6625                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6626    (parallel [(set (match_dup 3)
6627                    (minus:DWIH
6628                      (match_dup 4)
6629                      (plus:DWIH
6630                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6631                        (match_dup 5))))
6632               (clobber (reg:CC FLAGS_REG))])]
6633   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6634
6635 (define_insn "*sub<mode>_1"
6636   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6637         (minus:SWI
6638           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6639           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6640    (clobber (reg:CC FLAGS_REG))]
6641   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6642   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6643   [(set_attr "type" "alu")
6644    (set_attr "mode" "<MODE>")])
6645
6646 (define_insn "*subsi_1_zext"
6647   [(set (match_operand:DI 0 "register_operand" "=r")
6648         (zero_extend:DI
6649           (minus:SI (match_operand:SI 1 "register_operand" "0")
6650                     (match_operand:SI 2 "general_operand" "g"))))
6651    (clobber (reg:CC FLAGS_REG))]
6652   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6653   "sub{l}\t{%2, %k0|%k0, %2}"
6654   [(set_attr "type" "alu")
6655    (set_attr "mode" "SI")])
6656
6657 (define_insn "*subqi_1_slp"
6658   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6659         (minus:QI (match_dup 0)
6660                   (match_operand:QI 1 "general_operand" "qn,qm")))
6661    (clobber (reg:CC FLAGS_REG))]
6662   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6663    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6664   "sub{b}\t{%1, %0|%0, %1}"
6665   [(set_attr "type" "alu1")
6666    (set_attr "mode" "QI")])
6667
6668 (define_insn "*sub<mode>_2"
6669   [(set (reg FLAGS_REG)
6670         (compare
6671           (minus:SWI
6672             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6673             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6674           (const_int 0)))
6675    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6676         (minus:SWI (match_dup 1) (match_dup 2)))]
6677   "ix86_match_ccmode (insn, CCGOCmode)
6678    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6679   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6680   [(set_attr "type" "alu")
6681    (set_attr "mode" "<MODE>")])
6682
6683 (define_insn "*subsi_2_zext"
6684   [(set (reg FLAGS_REG)
6685         (compare
6686           (minus:SI (match_operand:SI 1 "register_operand" "0")
6687                     (match_operand:SI 2 "general_operand" "g"))
6688           (const_int 0)))
6689    (set (match_operand:DI 0 "register_operand" "=r")
6690         (zero_extend:DI
6691           (minus:SI (match_dup 1)
6692                     (match_dup 2))))]
6693   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6694    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6695   "sub{l}\t{%2, %k0|%k0, %2}"
6696   [(set_attr "type" "alu")
6697    (set_attr "mode" "SI")])
6698
6699 (define_insn "*sub<mode>_3"
6700   [(set (reg FLAGS_REG)
6701         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6702                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6703    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6704         (minus:SWI (match_dup 1) (match_dup 2)))]
6705   "ix86_match_ccmode (insn, CCmode)
6706    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6707   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6708   [(set_attr "type" "alu")
6709    (set_attr "mode" "<MODE>")])
6710
6711 (define_insn "*subsi_3_zext"
6712   [(set (reg FLAGS_REG)
6713         (compare (match_operand:SI 1 "register_operand" "0")
6714                  (match_operand:SI 2 "general_operand" "g")))
6715    (set (match_operand:DI 0 "register_operand" "=r")
6716         (zero_extend:DI
6717           (minus:SI (match_dup 1)
6718                     (match_dup 2))))]
6719   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6720    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721   "sub{l}\t{%2, %1|%1, %2}"
6722   [(set_attr "type" "alu")
6723    (set_attr "mode" "SI")])
6724 \f
6725 ;; Add with carry and subtract with borrow
6726
6727 (define_expand "<plusminus_insn><mode>3_carry"
6728   [(parallel
6729     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6730           (plusminus:SWI
6731             (match_operand:SWI 1 "nonimmediate_operand" "")
6732             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6733                        [(match_operand 3 "flags_reg_operand" "")
6734                         (const_int 0)])
6735                       (match_operand:SWI 2 "<general_operand>" ""))))
6736      (clobber (reg:CC FLAGS_REG))])]
6737   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6738
6739 (define_insn "*<plusminus_insn><mode>3_carry"
6740   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6741         (plusminus:SWI
6742           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6743           (plus:SWI
6744             (match_operator 3 "ix86_carry_flag_operator"
6745              [(reg FLAGS_REG) (const_int 0)])
6746             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6747    (clobber (reg:CC FLAGS_REG))]
6748   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6749   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6750   [(set_attr "type" "alu")
6751    (set_attr "use_carry" "1")
6752    (set_attr "pent_pair" "pu")
6753    (set_attr "mode" "<MODE>")])
6754
6755 (define_insn "*addsi3_carry_zext"
6756   [(set (match_operand:DI 0 "register_operand" "=r")
6757         (zero_extend:DI
6758           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6759                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6760                              [(reg FLAGS_REG) (const_int 0)])
6761                             (match_operand:SI 2 "general_operand" "g")))))
6762    (clobber (reg:CC FLAGS_REG))]
6763   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6764   "adc{l}\t{%2, %k0|%k0, %2}"
6765   [(set_attr "type" "alu")
6766    (set_attr "use_carry" "1")
6767    (set_attr "pent_pair" "pu")
6768    (set_attr "mode" "SI")])
6769
6770 (define_insn "*subsi3_carry_zext"
6771   [(set (match_operand:DI 0 "register_operand" "=r")
6772         (zero_extend:DI
6773           (minus:SI (match_operand:SI 1 "register_operand" "0")
6774                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6775                               [(reg FLAGS_REG) (const_int 0)])
6776                              (match_operand:SI 2 "general_operand" "g")))))
6777    (clobber (reg:CC FLAGS_REG))]
6778   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6779   "sbb{l}\t{%2, %k0|%k0, %2}"
6780   [(set_attr "type" "alu")
6781    (set_attr "pent_pair" "pu")
6782    (set_attr "mode" "SI")])
6783 \f
6784 ;; Overflow setting add and subtract instructions
6785
6786 (define_insn "*add<mode>3_cconly_overflow"
6787   [(set (reg:CCC FLAGS_REG)
6788         (compare:CCC
6789           (plus:SWI
6790             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6791             (match_operand:SWI 2 "<general_operand>" "<g>"))
6792           (match_dup 1)))
6793    (clobber (match_scratch:SWI 0 "=<r>"))]
6794   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6795   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6796   [(set_attr "type" "alu")
6797    (set_attr "mode" "<MODE>")])
6798
6799 (define_insn "*sub<mode>3_cconly_overflow"
6800   [(set (reg:CCC FLAGS_REG)
6801         (compare:CCC
6802           (minus:SWI
6803             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6804             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6805           (match_dup 0)))]
6806   ""
6807   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6808   [(set_attr "type" "icmp")
6809    (set_attr "mode" "<MODE>")])
6810
6811 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6812   [(set (reg:CCC FLAGS_REG)
6813         (compare:CCC
6814             (plusminus:SWI
6815                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6816                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6817             (match_dup 1)))
6818    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6819         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6820   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6821   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6822   [(set_attr "type" "alu")
6823    (set_attr "mode" "<MODE>")])
6824
6825 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6826   [(set (reg:CCC FLAGS_REG)
6827         (compare:CCC
6828           (plusminus:SI
6829             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6830             (match_operand:SI 2 "general_operand" "g"))
6831           (match_dup 1)))
6832    (set (match_operand:DI 0 "register_operand" "=r")
6833         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6834   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6835   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6836   [(set_attr "type" "alu")
6837    (set_attr "mode" "SI")])
6838
6839 ;; The patterns that match these are at the end of this file.
6840
6841 (define_expand "<plusminus_insn>xf3"
6842   [(set (match_operand:XF 0 "register_operand" "")
6843         (plusminus:XF
6844           (match_operand:XF 1 "register_operand" "")
6845           (match_operand:XF 2 "register_operand" "")))]
6846   "TARGET_80387")
6847
6848 (define_expand "<plusminus_insn><mode>3"
6849   [(set (match_operand:MODEF 0 "register_operand" "")
6850         (plusminus:MODEF
6851           (match_operand:MODEF 1 "register_operand" "")
6852           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6853   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6854     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6855 \f
6856 ;; Multiply instructions
6857
6858 (define_expand "mul<mode>3"
6859   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6860                    (mult:SWIM248
6861                      (match_operand:SWIM248 1 "register_operand" "")
6862                      (match_operand:SWIM248 2 "<general_operand>" "")))
6863               (clobber (reg:CC FLAGS_REG))])])
6864
6865 (define_expand "mulqi3"
6866   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6867                    (mult:QI
6868                      (match_operand:QI 1 "register_operand" "")
6869                      (match_operand:QI 2 "nonimmediate_operand" "")))
6870               (clobber (reg:CC FLAGS_REG))])]
6871   "TARGET_QIMODE_MATH")
6872
6873 ;; On AMDFAM10
6874 ;; IMUL reg32/64, reg32/64, imm8        Direct
6875 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6876 ;; IMUL reg32/64, reg32/64, imm32       Direct
6877 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6878 ;; IMUL reg32/64, reg32/64              Direct
6879 ;; IMUL reg32/64, mem32/64              Direct
6880 ;;
6881 ;; On BDVER1, all above IMULs use DirectPath
6882
6883 (define_insn "*mul<mode>3_1"
6884   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6885         (mult:SWI48
6886           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6887           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6888    (clobber (reg:CC FLAGS_REG))]
6889   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6890   "@
6891    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6892    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6893    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6894   [(set_attr "type" "imul")
6895    (set_attr "prefix_0f" "0,0,1")
6896    (set (attr "athlon_decode")
6897         (cond [(eq_attr "cpu" "athlon")
6898                   (const_string "vector")
6899                (eq_attr "alternative" "1")
6900                   (const_string "vector")
6901                (and (eq_attr "alternative" "2")
6902                     (match_operand 1 "memory_operand" ""))
6903                   (const_string "vector")]
6904               (const_string "direct")))
6905    (set (attr "amdfam10_decode")
6906         (cond [(and (eq_attr "alternative" "0,1")
6907                     (match_operand 1 "memory_operand" ""))
6908                   (const_string "vector")]
6909               (const_string "direct")))
6910    (set_attr "bdver1_decode" "direct")
6911    (set_attr "mode" "<MODE>")])
6912
6913 (define_insn "*mulsi3_1_zext"
6914   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6915         (zero_extend:DI
6916           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6917                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6918    (clobber (reg:CC FLAGS_REG))]
6919   "TARGET_64BIT
6920    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6921   "@
6922    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6923    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6924    imul{l}\t{%2, %k0|%k0, %2}"
6925   [(set_attr "type" "imul")
6926    (set_attr "prefix_0f" "0,0,1")
6927    (set (attr "athlon_decode")
6928         (cond [(eq_attr "cpu" "athlon")
6929                   (const_string "vector")
6930                (eq_attr "alternative" "1")
6931                   (const_string "vector")
6932                (and (eq_attr "alternative" "2")
6933                     (match_operand 1 "memory_operand" ""))
6934                   (const_string "vector")]
6935               (const_string "direct")))
6936    (set (attr "amdfam10_decode")
6937         (cond [(and (eq_attr "alternative" "0,1")
6938                     (match_operand 1 "memory_operand" ""))
6939                   (const_string "vector")]
6940               (const_string "direct")))
6941    (set_attr "bdver1_decode" "direct")
6942    (set_attr "mode" "SI")])
6943
6944 ;; On AMDFAM10
6945 ;; IMUL reg16, reg16, imm8      VectorPath
6946 ;; IMUL reg16, mem16, imm8      VectorPath
6947 ;; IMUL reg16, reg16, imm16     VectorPath
6948 ;; IMUL reg16, mem16, imm16     VectorPath
6949 ;; IMUL reg16, reg16            Direct
6950 ;; IMUL reg16, mem16            Direct
6951 ;;
6952 ;; On BDVER1, all HI MULs use DoublePath
6953
6954 (define_insn "*mulhi3_1"
6955   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6956         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6957                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6958    (clobber (reg:CC FLAGS_REG))]
6959   "TARGET_HIMODE_MATH
6960    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6961   "@
6962    imul{w}\t{%2, %1, %0|%0, %1, %2}
6963    imul{w}\t{%2, %1, %0|%0, %1, %2}
6964    imul{w}\t{%2, %0|%0, %2}"
6965   [(set_attr "type" "imul")
6966    (set_attr "prefix_0f" "0,0,1")
6967    (set (attr "athlon_decode")
6968         (cond [(eq_attr "cpu" "athlon")
6969                   (const_string "vector")
6970                (eq_attr "alternative" "1,2")
6971                   (const_string "vector")]
6972               (const_string "direct")))
6973    (set (attr "amdfam10_decode")
6974         (cond [(eq_attr "alternative" "0,1")
6975                   (const_string "vector")]
6976               (const_string "direct")))
6977    (set_attr "bdver1_decode" "double")
6978    (set_attr "mode" "HI")])
6979
6980 ;;On AMDFAM10 and BDVER1
6981 ;; MUL reg8     Direct
6982 ;; MUL mem8     Direct
6983
6984 (define_insn "*mulqi3_1"
6985   [(set (match_operand:QI 0 "register_operand" "=a")
6986         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6987                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6988    (clobber (reg:CC FLAGS_REG))]
6989   "TARGET_QIMODE_MATH
6990    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6991   "mul{b}\t%2"
6992   [(set_attr "type" "imul")
6993    (set_attr "length_immediate" "0")
6994    (set (attr "athlon_decode")
6995      (if_then_else (eq_attr "cpu" "athlon")
6996         (const_string "vector")
6997         (const_string "direct")))
6998    (set_attr "amdfam10_decode" "direct")
6999    (set_attr "bdver1_decode" "direct")
7000    (set_attr "mode" "QI")])
7001
7002 (define_expand "<u>mul<mode><dwi>3"
7003   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7004                    (mult:<DWI>
7005                      (any_extend:<DWI>
7006                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7007                      (any_extend:<DWI>
7008                        (match_operand:DWIH 2 "register_operand" ""))))
7009               (clobber (reg:CC FLAGS_REG))])])
7010
7011 (define_expand "<u>mulqihi3"
7012   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7013                    (mult:HI
7014                      (any_extend:HI
7015                        (match_operand:QI 1 "nonimmediate_operand" ""))
7016                      (any_extend:HI
7017                        (match_operand:QI 2 "register_operand" ""))))
7018               (clobber (reg:CC FLAGS_REG))])]
7019   "TARGET_QIMODE_MATH")
7020
7021 (define_insn "*<u>mul<mode><dwi>3_1"
7022   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7023         (mult:<DWI>
7024           (any_extend:<DWI>
7025             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7026           (any_extend:<DWI>
7027             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7028    (clobber (reg:CC FLAGS_REG))]
7029   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7030   "<sgnprefix>mul{<imodesuffix>}\t%2"
7031   [(set_attr "type" "imul")
7032    (set_attr "length_immediate" "0")
7033    (set (attr "athlon_decode")
7034      (if_then_else (eq_attr "cpu" "athlon")
7035         (const_string "vector")
7036         (const_string "double")))
7037    (set_attr "amdfam10_decode" "double")
7038    (set_attr "bdver1_decode" "direct")
7039    (set_attr "mode" "<MODE>")])
7040
7041 (define_insn "*<u>mulqihi3_1"
7042   [(set (match_operand:HI 0 "register_operand" "=a")
7043         (mult:HI
7044           (any_extend:HI
7045             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7046           (any_extend:HI
7047             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7048    (clobber (reg:CC FLAGS_REG))]
7049   "TARGET_QIMODE_MATH
7050    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7051   "<sgnprefix>mul{b}\t%2"
7052   [(set_attr "type" "imul")
7053    (set_attr "length_immediate" "0")
7054    (set (attr "athlon_decode")
7055      (if_then_else (eq_attr "cpu" "athlon")
7056         (const_string "vector")
7057         (const_string "direct")))
7058    (set_attr "amdfam10_decode" "direct")
7059    (set_attr "bdver1_decode" "direct")
7060    (set_attr "mode" "QI")])
7061
7062 (define_expand "<s>mul<mode>3_highpart"
7063   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7064                    (truncate:SWI48
7065                      (lshiftrt:<DWI>
7066                        (mult:<DWI>
7067                          (any_extend:<DWI>
7068                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7069                          (any_extend:<DWI>
7070                            (match_operand:SWI48 2 "register_operand" "")))
7071                        (match_dup 4))))
7072               (clobber (match_scratch:SWI48 3 ""))
7073               (clobber (reg:CC FLAGS_REG))])]
7074   ""
7075   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7076
7077 (define_insn "*<s>muldi3_highpart_1"
7078   [(set (match_operand:DI 0 "register_operand" "=d")
7079         (truncate:DI
7080           (lshiftrt:TI
7081             (mult:TI
7082               (any_extend:TI
7083                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7084               (any_extend:TI
7085                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7086             (const_int 64))))
7087    (clobber (match_scratch:DI 3 "=1"))
7088    (clobber (reg:CC FLAGS_REG))]
7089   "TARGET_64BIT
7090    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7091   "<sgnprefix>mul{q}\t%2"
7092   [(set_attr "type" "imul")
7093    (set_attr "length_immediate" "0")
7094    (set (attr "athlon_decode")
7095      (if_then_else (eq_attr "cpu" "athlon")
7096         (const_string "vector")
7097         (const_string "double")))
7098    (set_attr "amdfam10_decode" "double")
7099    (set_attr "bdver1_decode" "direct")
7100    (set_attr "mode" "DI")])
7101
7102 (define_insn "*<s>mulsi3_highpart_1"
7103   [(set (match_operand:SI 0 "register_operand" "=d")
7104         (truncate:SI
7105           (lshiftrt:DI
7106             (mult:DI
7107               (any_extend:DI
7108                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7109               (any_extend:DI
7110                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7111             (const_int 32))))
7112    (clobber (match_scratch:SI 3 "=1"))
7113    (clobber (reg:CC FLAGS_REG))]
7114   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7115   "<sgnprefix>mul{l}\t%2"
7116   [(set_attr "type" "imul")
7117    (set_attr "length_immediate" "0")
7118    (set (attr "athlon_decode")
7119      (if_then_else (eq_attr "cpu" "athlon")
7120         (const_string "vector")
7121         (const_string "double")))
7122    (set_attr "amdfam10_decode" "double")
7123    (set_attr "bdver1_decode" "direct")
7124    (set_attr "mode" "SI")])
7125
7126 (define_insn "*<s>mulsi3_highpart_zext"
7127   [(set (match_operand:DI 0 "register_operand" "=d")
7128         (zero_extend:DI (truncate:SI
7129           (lshiftrt:DI
7130             (mult:DI (any_extend:DI
7131                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7132                      (any_extend:DI
7133                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7134             (const_int 32)))))
7135    (clobber (match_scratch:SI 3 "=1"))
7136    (clobber (reg:CC FLAGS_REG))]
7137   "TARGET_64BIT
7138    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7139   "<sgnprefix>mul{l}\t%2"
7140   [(set_attr "type" "imul")
7141    (set_attr "length_immediate" "0")
7142    (set (attr "athlon_decode")
7143      (if_then_else (eq_attr "cpu" "athlon")
7144         (const_string "vector")
7145         (const_string "double")))
7146    (set_attr "amdfam10_decode" "double")
7147    (set_attr "bdver1_decode" "direct")
7148    (set_attr "mode" "SI")])
7149
7150 ;; The patterns that match these are at the end of this file.
7151
7152 (define_expand "mulxf3"
7153   [(set (match_operand:XF 0 "register_operand" "")
7154         (mult:XF (match_operand:XF 1 "register_operand" "")
7155                  (match_operand:XF 2 "register_operand" "")))]
7156   "TARGET_80387")
7157
7158 (define_expand "mul<mode>3"
7159   [(set (match_operand:MODEF 0 "register_operand" "")
7160         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7161                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7162   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7163     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7164 \f
7165 ;; Divide instructions
7166
7167 ;; The patterns that match these are at the end of this file.
7168
7169 (define_expand "divxf3"
7170   [(set (match_operand:XF 0 "register_operand" "")
7171         (div:XF (match_operand:XF 1 "register_operand" "")
7172                 (match_operand:XF 2 "register_operand" "")))]
7173   "TARGET_80387")
7174
7175 (define_expand "divdf3"
7176   [(set (match_operand:DF 0 "register_operand" "")
7177         (div:DF (match_operand:DF 1 "register_operand" "")
7178                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7179    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7180     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7181
7182 (define_expand "divsf3"
7183   [(set (match_operand:SF 0 "register_operand" "")
7184         (div:SF (match_operand:SF 1 "register_operand" "")
7185                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7186   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7187     || TARGET_SSE_MATH"
7188 {
7189   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7190       && flag_finite_math_only && !flag_trapping_math
7191       && flag_unsafe_math_optimizations)
7192     {
7193       ix86_emit_swdivsf (operands[0], operands[1],
7194                          operands[2], SFmode);
7195       DONE;
7196     }
7197 })
7198 \f
7199 ;; Divmod instructions.
7200
7201 (define_expand "divmod<mode>4"
7202   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7203                    (div:SWIM248
7204                      (match_operand:SWIM248 1 "register_operand" "")
7205                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7206               (set (match_operand:SWIM248 3 "register_operand" "")
7207                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7208               (clobber (reg:CC FLAGS_REG))])])
7209
7210 ;; Split with 8bit unsigned divide:
7211 ;;      if (dividend an divisor are in [0-255])
7212 ;;         use 8bit unsigned integer divide
7213 ;;       else
7214 ;;         use original integer divide
7215 (define_split
7216   [(set (match_operand:SWI48 0 "register_operand" "")
7217         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7218                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7219    (set (match_operand:SWI48 1 "register_operand" "")
7220         (mod:SWI48 (match_dup 2) (match_dup 3)))
7221    (clobber (reg:CC FLAGS_REG))]
7222   "TARGET_USE_8BIT_IDIV
7223    && TARGET_QIMODE_MATH
7224    && can_create_pseudo_p ()
7225    && !optimize_insn_for_size_p ()"
7226   [(const_int 0)]
7227   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7228
7229 (define_insn_and_split "divmod<mode>4_1"
7230   [(set (match_operand:SWI48 0 "register_operand" "=a")
7231         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7232                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7233    (set (match_operand:SWI48 1 "register_operand" "=&d")
7234         (mod:SWI48 (match_dup 2) (match_dup 3)))
7235    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7236    (clobber (reg:CC FLAGS_REG))]
7237   ""
7238   "#"
7239   "reload_completed"
7240   [(parallel [(set (match_dup 1)
7241                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7242               (clobber (reg:CC FLAGS_REG))])
7243    (parallel [(set (match_dup 0)
7244                    (div:SWI48 (match_dup 2) (match_dup 3)))
7245               (set (match_dup 1)
7246                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7247               (use (match_dup 1))
7248               (clobber (reg:CC FLAGS_REG))])]
7249 {
7250   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7251
7252   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7253     operands[4] = operands[2];
7254   else
7255     {
7256       /* Avoid use of cltd in favor of a mov+shift.  */
7257       emit_move_insn (operands[1], operands[2]);
7258       operands[4] = operands[1];
7259     }
7260 }
7261   [(set_attr "type" "multi")
7262    (set_attr "mode" "<MODE>")])
7263
7264 (define_insn_and_split "*divmod<mode>4"
7265   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7266         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7267                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7268    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7269         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7270    (clobber (reg:CC FLAGS_REG))]
7271   ""
7272   "#"
7273   "reload_completed"
7274   [(parallel [(set (match_dup 1)
7275                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7276               (clobber (reg:CC FLAGS_REG))])
7277    (parallel [(set (match_dup 0)
7278                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7279               (set (match_dup 1)
7280                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7281               (use (match_dup 1))
7282               (clobber (reg:CC FLAGS_REG))])]
7283 {
7284   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7285
7286   if (<MODE>mode != HImode
7287       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7288     operands[4] = operands[2];
7289   else
7290     {
7291       /* Avoid use of cltd in favor of a mov+shift.  */
7292       emit_move_insn (operands[1], operands[2]);
7293       operands[4] = operands[1];
7294     }
7295 }
7296   [(set_attr "type" "multi")
7297    (set_attr "mode" "<MODE>")])
7298
7299 (define_insn "*divmod<mode>4_noext"
7300   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7301         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7302                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7303    (set (match_operand:SWIM248 1 "register_operand" "=d")
7304         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7305    (use (match_operand:SWIM248 4 "register_operand" "1"))
7306    (clobber (reg:CC FLAGS_REG))]
7307   ""
7308   "idiv{<imodesuffix>}\t%3"
7309   [(set_attr "type" "idiv")
7310    (set_attr "mode" "<MODE>")])
7311
7312 (define_expand "divmodqi4"
7313   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7314                    (div:QI
7315                      (match_operand:QI 1 "register_operand" "")
7316                      (match_operand:QI 2 "nonimmediate_operand" "")))
7317               (set (match_operand:QI 3 "register_operand" "")
7318                    (mod:QI (match_dup 1) (match_dup 2)))
7319               (clobber (reg:CC FLAGS_REG))])]
7320   "TARGET_QIMODE_MATH"
7321 {
7322   rtx div, mod, insn;
7323   rtx tmp0, tmp1;
7324   
7325   tmp0 = gen_reg_rtx (HImode);
7326   tmp1 = gen_reg_rtx (HImode);
7327
7328   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7329      in AX.  */
7330   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7331   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7332
7333   /* Extract remainder from AH.  */
7334   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7335   insn = emit_move_insn (operands[3], tmp1);
7336
7337   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7338   set_unique_reg_note (insn, REG_EQUAL, mod);
7339
7340   /* Extract quotient from AL.  */
7341   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7342
7343   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7344   set_unique_reg_note (insn, REG_EQUAL, div);
7345
7346   DONE;
7347 })
7348
7349 ;; Divide AX by r/m8, with result stored in
7350 ;; AL <- Quotient
7351 ;; AH <- Remainder
7352 ;; Change div/mod to HImode and extend the second argument to HImode
7353 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7354 ;; combine may fail.
7355 (define_insn "divmodhiqi3"
7356   [(set (match_operand:HI 0 "register_operand" "=a")
7357         (ior:HI
7358           (ashift:HI
7359             (zero_extend:HI
7360               (truncate:QI
7361                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7362                         (sign_extend:HI
7363                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7364             (const_int 8))
7365           (zero_extend:HI
7366             (truncate:QI
7367               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7368    (clobber (reg:CC FLAGS_REG))]
7369   "TARGET_QIMODE_MATH"
7370   "idiv{b}\t%2"
7371   [(set_attr "type" "idiv")
7372    (set_attr "mode" "QI")])
7373
7374 (define_expand "udivmod<mode>4"
7375   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7376                    (udiv:SWIM248
7377                      (match_operand:SWIM248 1 "register_operand" "")
7378                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7379               (set (match_operand:SWIM248 3 "register_operand" "")
7380                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7381               (clobber (reg:CC FLAGS_REG))])])
7382
7383 ;; Split with 8bit unsigned divide:
7384 ;;      if (dividend an divisor are in [0-255])
7385 ;;         use 8bit unsigned integer divide
7386 ;;       else
7387 ;;         use original integer divide
7388 (define_split
7389   [(set (match_operand:SWI48 0 "register_operand" "")
7390         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7391                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7392    (set (match_operand:SWI48 1 "register_operand" "")
7393         (umod:SWI48 (match_dup 2) (match_dup 3)))
7394    (clobber (reg:CC FLAGS_REG))]
7395   "TARGET_USE_8BIT_IDIV
7396    && TARGET_QIMODE_MATH
7397    && can_create_pseudo_p ()
7398    && !optimize_insn_for_size_p ()"
7399   [(const_int 0)]
7400   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7401
7402 (define_insn_and_split "udivmod<mode>4_1"
7403   [(set (match_operand:SWI48 0 "register_operand" "=a")
7404         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7405                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7406    (set (match_operand:SWI48 1 "register_operand" "=&d")
7407         (umod:SWI48 (match_dup 2) (match_dup 3)))
7408    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7409    (clobber (reg:CC FLAGS_REG))]
7410   ""
7411   "#"
7412   "reload_completed"
7413   [(set (match_dup 1) (const_int 0))
7414    (parallel [(set (match_dup 0)
7415                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7416               (set (match_dup 1)
7417                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7418               (use (match_dup 1))
7419               (clobber (reg:CC FLAGS_REG))])]
7420   ""
7421   [(set_attr "type" "multi")
7422    (set_attr "mode" "<MODE>")])
7423
7424 (define_insn_and_split "*udivmod<mode>4"
7425   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7426         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7427                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7428    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7429         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7430    (clobber (reg:CC FLAGS_REG))]
7431   ""
7432   "#"
7433   "reload_completed"
7434   [(set (match_dup 1) (const_int 0))
7435    (parallel [(set (match_dup 0)
7436                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7437               (set (match_dup 1)
7438                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7439               (use (match_dup 1))
7440               (clobber (reg:CC FLAGS_REG))])]
7441   ""
7442   [(set_attr "type" "multi")
7443    (set_attr "mode" "<MODE>")])
7444
7445 (define_insn "*udivmod<mode>4_noext"
7446   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7447         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7448                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7449    (set (match_operand:SWIM248 1 "register_operand" "=d")
7450         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7451    (use (match_operand:SWIM248 4 "register_operand" "1"))
7452    (clobber (reg:CC FLAGS_REG))]
7453   ""
7454   "div{<imodesuffix>}\t%3"
7455   [(set_attr "type" "idiv")
7456    (set_attr "mode" "<MODE>")])
7457
7458 (define_expand "udivmodqi4"
7459   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7460                    (udiv:QI
7461                      (match_operand:QI 1 "register_operand" "")
7462                      (match_operand:QI 2 "nonimmediate_operand" "")))
7463               (set (match_operand:QI 3 "register_operand" "")
7464                    (umod:QI (match_dup 1) (match_dup 2)))
7465               (clobber (reg:CC FLAGS_REG))])]
7466   "TARGET_QIMODE_MATH"
7467 {
7468   rtx div, mod, insn;
7469   rtx tmp0, tmp1;
7470   
7471   tmp0 = gen_reg_rtx (HImode);
7472   tmp1 = gen_reg_rtx (HImode);
7473
7474   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7475      in AX.  */
7476   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7477   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7478
7479   /* Extract remainder from AH.  */
7480   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7481   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7482   insn = emit_move_insn (operands[3], tmp1);
7483
7484   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7485   set_unique_reg_note (insn, REG_EQUAL, mod);
7486
7487   /* Extract quotient from AL.  */
7488   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7489
7490   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7491   set_unique_reg_note (insn, REG_EQUAL, div);
7492
7493   DONE;
7494 })
7495
7496 (define_insn "udivmodhiqi3"
7497   [(set (match_operand:HI 0 "register_operand" "=a")
7498         (ior:HI
7499           (ashift:HI
7500             (zero_extend:HI
7501               (truncate:QI
7502                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7503                         (zero_extend:HI
7504                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7505             (const_int 8))
7506           (zero_extend:HI
7507             (truncate:QI
7508               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7509    (clobber (reg:CC FLAGS_REG))]
7510   "TARGET_QIMODE_MATH"
7511   "div{b}\t%2"
7512   [(set_attr "type" "idiv")
7513    (set_attr "mode" "QI")])
7514
7515 ;; We cannot use div/idiv for double division, because it causes
7516 ;; "division by zero" on the overflow and that's not what we expect
7517 ;; from truncate.  Because true (non truncating) double division is
7518 ;; never generated, we can't create this insn anyway.
7519 ;
7520 ;(define_insn ""
7521 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7522 ;       (truncate:SI
7523 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7524 ;                  (zero_extend:DI
7525 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7526 ;   (set (match_operand:SI 3 "register_operand" "=d")
7527 ;       (truncate:SI
7528 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7529 ;   (clobber (reg:CC FLAGS_REG))]
7530 ;  ""
7531 ;  "div{l}\t{%2, %0|%0, %2}"
7532 ;  [(set_attr "type" "idiv")])
7533 \f
7534 ;;- Logical AND instructions
7535
7536 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7537 ;; Note that this excludes ah.
7538
7539 (define_expand "testsi_ccno_1"
7540   [(set (reg:CCNO FLAGS_REG)
7541         (compare:CCNO
7542           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7543                   (match_operand:SI 1 "nonmemory_operand" ""))
7544           (const_int 0)))])
7545
7546 (define_expand "testqi_ccz_1"
7547   [(set (reg:CCZ FLAGS_REG)
7548         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7549                              (match_operand:QI 1 "nonmemory_operand" ""))
7550                  (const_int 0)))])
7551
7552 (define_expand "testdi_ccno_1"
7553   [(set (reg:CCNO FLAGS_REG)
7554         (compare:CCNO
7555           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7556                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7557           (const_int 0)))]
7558   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7559
7560 (define_insn "*testdi_1"
7561   [(set (reg FLAGS_REG)
7562         (compare
7563          (and:DI
7564           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7565           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7566          (const_int 0)))]
7567   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7568    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7569   "@
7570    test{l}\t{%k1, %k0|%k0, %k1}
7571    test{l}\t{%k1, %k0|%k0, %k1}
7572    test{q}\t{%1, %0|%0, %1}
7573    test{q}\t{%1, %0|%0, %1}
7574    test{q}\t{%1, %0|%0, %1}"
7575   [(set_attr "type" "test")
7576    (set_attr "modrm" "0,1,0,1,1")
7577    (set_attr "mode" "SI,SI,DI,DI,DI")])
7578
7579 (define_insn "*testqi_1_maybe_si"
7580   [(set (reg FLAGS_REG)
7581         (compare
7582           (and:QI
7583             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7584             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7585           (const_int 0)))]
7586    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7587     && ix86_match_ccmode (insn,
7588                          CONST_INT_P (operands[1])
7589                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7590 {
7591   if (which_alternative == 3)
7592     {
7593       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7594         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7595       return "test{l}\t{%1, %k0|%k0, %1}";
7596     }
7597   return "test{b}\t{%1, %0|%0, %1}";
7598 }
7599   [(set_attr "type" "test")
7600    (set_attr "modrm" "0,1,1,1")
7601    (set_attr "mode" "QI,QI,QI,SI")
7602    (set_attr "pent_pair" "uv,np,uv,np")])
7603
7604 (define_insn "*test<mode>_1"
7605   [(set (reg FLAGS_REG)
7606         (compare
7607          (and:SWI124
7608           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7609           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7610          (const_int 0)))]
7611   "ix86_match_ccmode (insn, CCNOmode)
7612    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7613   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7614   [(set_attr "type" "test")
7615    (set_attr "modrm" "0,1,1")
7616    (set_attr "mode" "<MODE>")
7617    (set_attr "pent_pair" "uv,np,uv")])
7618
7619 (define_expand "testqi_ext_ccno_0"
7620   [(set (reg:CCNO FLAGS_REG)
7621         (compare:CCNO
7622           (and:SI
7623             (zero_extract:SI
7624               (match_operand 0 "ext_register_operand" "")
7625               (const_int 8)
7626               (const_int 8))
7627             (match_operand 1 "const_int_operand" ""))
7628           (const_int 0)))])
7629
7630 (define_insn "*testqi_ext_0"
7631   [(set (reg FLAGS_REG)
7632         (compare
7633           (and:SI
7634             (zero_extract:SI
7635               (match_operand 0 "ext_register_operand" "Q")
7636               (const_int 8)
7637               (const_int 8))
7638             (match_operand 1 "const_int_operand" "n"))
7639           (const_int 0)))]
7640   "ix86_match_ccmode (insn, CCNOmode)"
7641   "test{b}\t{%1, %h0|%h0, %1}"
7642   [(set_attr "type" "test")
7643    (set_attr "mode" "QI")
7644    (set_attr "length_immediate" "1")
7645    (set_attr "modrm" "1")
7646    (set_attr "pent_pair" "np")])
7647
7648 (define_insn "*testqi_ext_1_rex64"
7649   [(set (reg FLAGS_REG)
7650         (compare
7651           (and:SI
7652             (zero_extract:SI
7653               (match_operand 0 "ext_register_operand" "Q")
7654               (const_int 8)
7655               (const_int 8))
7656             (zero_extend:SI
7657               (match_operand:QI 1 "register_operand" "Q")))
7658           (const_int 0)))]
7659   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7660   "test{b}\t{%1, %h0|%h0, %1}"
7661   [(set_attr "type" "test")
7662    (set_attr "mode" "QI")])
7663
7664 (define_insn "*testqi_ext_1"
7665   [(set (reg FLAGS_REG)
7666         (compare
7667           (and:SI
7668             (zero_extract:SI
7669               (match_operand 0 "ext_register_operand" "Q")
7670               (const_int 8)
7671               (const_int 8))
7672             (zero_extend:SI
7673               (match_operand:QI 1 "general_operand" "Qm")))
7674           (const_int 0)))]
7675   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7676   "test{b}\t{%1, %h0|%h0, %1}"
7677   [(set_attr "type" "test")
7678    (set_attr "mode" "QI")])
7679
7680 (define_insn "*testqi_ext_2"
7681   [(set (reg FLAGS_REG)
7682         (compare
7683           (and:SI
7684             (zero_extract:SI
7685               (match_operand 0 "ext_register_operand" "Q")
7686               (const_int 8)
7687               (const_int 8))
7688             (zero_extract:SI
7689               (match_operand 1 "ext_register_operand" "Q")
7690               (const_int 8)
7691               (const_int 8)))
7692           (const_int 0)))]
7693   "ix86_match_ccmode (insn, CCNOmode)"
7694   "test{b}\t{%h1, %h0|%h0, %h1}"
7695   [(set_attr "type" "test")
7696    (set_attr "mode" "QI")])
7697
7698 (define_insn "*testqi_ext_3_rex64"
7699   [(set (reg FLAGS_REG)
7700         (compare (zero_extract:DI
7701                    (match_operand 0 "nonimmediate_operand" "rm")
7702                    (match_operand:DI 1 "const_int_operand" "")
7703                    (match_operand:DI 2 "const_int_operand" ""))
7704                  (const_int 0)))]
7705   "TARGET_64BIT
7706    && ix86_match_ccmode (insn, CCNOmode)
7707    && INTVAL (operands[1]) > 0
7708    && INTVAL (operands[2]) >= 0
7709    /* Ensure that resulting mask is zero or sign extended operand.  */
7710    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7711        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7712            && INTVAL (operands[1]) > 32))
7713    && (GET_MODE (operands[0]) == SImode
7714        || GET_MODE (operands[0]) == DImode
7715        || GET_MODE (operands[0]) == HImode
7716        || GET_MODE (operands[0]) == QImode)"
7717   "#")
7718
7719 ;; Combine likes to form bit extractions for some tests.  Humor it.
7720 (define_insn "*testqi_ext_3"
7721   [(set (reg FLAGS_REG)
7722         (compare (zero_extract:SI
7723                    (match_operand 0 "nonimmediate_operand" "rm")
7724                    (match_operand:SI 1 "const_int_operand" "")
7725                    (match_operand:SI 2 "const_int_operand" ""))
7726                  (const_int 0)))]
7727   "ix86_match_ccmode (insn, CCNOmode)
7728    && INTVAL (operands[1]) > 0
7729    && INTVAL (operands[2]) >= 0
7730    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7731    && (GET_MODE (operands[0]) == SImode
7732        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7733        || GET_MODE (operands[0]) == HImode
7734        || GET_MODE (operands[0]) == QImode)"
7735   "#")
7736
7737 (define_split
7738   [(set (match_operand 0 "flags_reg_operand" "")
7739         (match_operator 1 "compare_operator"
7740           [(zero_extract
7741              (match_operand 2 "nonimmediate_operand" "")
7742              (match_operand 3 "const_int_operand" "")
7743              (match_operand 4 "const_int_operand" ""))
7744            (const_int 0)]))]
7745   "ix86_match_ccmode (insn, CCNOmode)"
7746   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7747 {
7748   rtx val = operands[2];
7749   HOST_WIDE_INT len = INTVAL (operands[3]);
7750   HOST_WIDE_INT pos = INTVAL (operands[4]);
7751   HOST_WIDE_INT mask;
7752   enum machine_mode mode, submode;
7753
7754   mode = GET_MODE (val);
7755   if (MEM_P (val))
7756     {
7757       /* ??? Combine likes to put non-volatile mem extractions in QImode
7758          no matter the size of the test.  So find a mode that works.  */
7759       if (! MEM_VOLATILE_P (val))
7760         {
7761           mode = smallest_mode_for_size (pos + len, MODE_INT);
7762           val = adjust_address (val, mode, 0);
7763         }
7764     }
7765   else if (GET_CODE (val) == SUBREG
7766            && (submode = GET_MODE (SUBREG_REG (val)),
7767                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7768            && pos + len <= GET_MODE_BITSIZE (submode)
7769            && GET_MODE_CLASS (submode) == MODE_INT)
7770     {
7771       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7772       mode = submode;
7773       val = SUBREG_REG (val);
7774     }
7775   else if (mode == HImode && pos + len <= 8)
7776     {
7777       /* Small HImode tests can be converted to QImode.  */
7778       mode = QImode;
7779       val = gen_lowpart (QImode, val);
7780     }
7781
7782   if (len == HOST_BITS_PER_WIDE_INT)
7783     mask = -1;
7784   else
7785     mask = ((HOST_WIDE_INT)1 << len) - 1;
7786   mask <<= pos;
7787
7788   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7789 })
7790
7791 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7792 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7793 ;; this is relatively important trick.
7794 ;; Do the conversion only post-reload to avoid limiting of the register class
7795 ;; to QI regs.
7796 (define_split
7797   [(set (match_operand 0 "flags_reg_operand" "")
7798         (match_operator 1 "compare_operator"
7799           [(and (match_operand 2 "register_operand" "")
7800                 (match_operand 3 "const_int_operand" ""))
7801            (const_int 0)]))]
7802    "reload_completed
7803     && QI_REG_P (operands[2])
7804     && GET_MODE (operands[2]) != QImode
7805     && ((ix86_match_ccmode (insn, CCZmode)
7806          && !(INTVAL (operands[3]) & ~(255 << 8)))
7807         || (ix86_match_ccmode (insn, CCNOmode)
7808             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7809   [(set (match_dup 0)
7810         (match_op_dup 1
7811           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7812                    (match_dup 3))
7813            (const_int 0)]))]
7814   "operands[2] = gen_lowpart (SImode, operands[2]);
7815    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7816
7817 (define_split
7818   [(set (match_operand 0 "flags_reg_operand" "")
7819         (match_operator 1 "compare_operator"
7820           [(and (match_operand 2 "nonimmediate_operand" "")
7821                 (match_operand 3 "const_int_operand" ""))
7822            (const_int 0)]))]
7823    "reload_completed
7824     && GET_MODE (operands[2]) != QImode
7825     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7826     && ((ix86_match_ccmode (insn, CCZmode)
7827          && !(INTVAL (operands[3]) & ~255))
7828         || (ix86_match_ccmode (insn, CCNOmode)
7829             && !(INTVAL (operands[3]) & ~127)))"
7830   [(set (match_dup 0)
7831         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7832                          (const_int 0)]))]
7833   "operands[2] = gen_lowpart (QImode, operands[2]);
7834    operands[3] = gen_lowpart (QImode, operands[3]);")
7835
7836 ;; %%% This used to optimize known byte-wide and operations to memory,
7837 ;; and sometimes to QImode registers.  If this is considered useful,
7838 ;; it should be done with splitters.
7839
7840 (define_expand "and<mode>3"
7841   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7842         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7843                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7844   ""
7845   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7846
7847 (define_insn "*anddi_1"
7848   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7849         (and:DI
7850          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7851          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7852    (clobber (reg:CC FLAGS_REG))]
7853   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7854 {
7855   switch (get_attr_type (insn))
7856     {
7857     case TYPE_IMOVX:
7858       {
7859         enum machine_mode mode;
7860
7861         gcc_assert (CONST_INT_P (operands[2]));
7862         if (INTVAL (operands[2]) == 0xff)
7863           mode = QImode;
7864         else
7865           {
7866             gcc_assert (INTVAL (operands[2]) == 0xffff);
7867             mode = HImode;
7868           }
7869
7870         operands[1] = gen_lowpart (mode, operands[1]);
7871         if (mode == QImode)
7872           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7873         else
7874           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7875       }
7876
7877     default:
7878       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7879       if (get_attr_mode (insn) == MODE_SI)
7880         return "and{l}\t{%k2, %k0|%k0, %k2}";
7881       else
7882         return "and{q}\t{%2, %0|%0, %2}";
7883     }
7884 }
7885   [(set_attr "type" "alu,alu,alu,imovx")
7886    (set_attr "length_immediate" "*,*,*,0")
7887    (set (attr "prefix_rex")
7888      (if_then_else
7889        (and (eq_attr "type" "imovx")
7890             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7891                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7892        (const_string "1")
7893        (const_string "*")))
7894    (set_attr "mode" "SI,DI,DI,SI")])
7895
7896 (define_insn "*andsi_1"
7897   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7898         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7899                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7900    (clobber (reg:CC FLAGS_REG))]
7901   "ix86_binary_operator_ok (AND, SImode, operands)"
7902 {
7903   switch (get_attr_type (insn))
7904     {
7905     case TYPE_IMOVX:
7906       {
7907         enum machine_mode mode;
7908
7909         gcc_assert (CONST_INT_P (operands[2]));
7910         if (INTVAL (operands[2]) == 0xff)
7911           mode = QImode;
7912         else
7913           {
7914             gcc_assert (INTVAL (operands[2]) == 0xffff);
7915             mode = HImode;
7916           }
7917
7918         operands[1] = gen_lowpart (mode, operands[1]);
7919         if (mode == QImode)
7920           return "movz{bl|x}\t{%1, %0|%0, %1}";
7921         else
7922           return "movz{wl|x}\t{%1, %0|%0, %1}";
7923       }
7924
7925     default:
7926       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7927       return "and{l}\t{%2, %0|%0, %2}";
7928     }
7929 }
7930   [(set_attr "type" "alu,alu,imovx")
7931    (set (attr "prefix_rex")
7932      (if_then_else
7933        (and (eq_attr "type" "imovx")
7934             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7935                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7936        (const_string "1")
7937        (const_string "*")))
7938    (set_attr "length_immediate" "*,*,0")
7939    (set_attr "mode" "SI")])
7940
7941 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7942 (define_insn "*andsi_1_zext"
7943   [(set (match_operand:DI 0 "register_operand" "=r")
7944         (zero_extend:DI
7945           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7946                   (match_operand:SI 2 "general_operand" "g"))))
7947    (clobber (reg:CC FLAGS_REG))]
7948   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7949   "and{l}\t{%2, %k0|%k0, %2}"
7950   [(set_attr "type" "alu")
7951    (set_attr "mode" "SI")])
7952
7953 (define_insn "*andhi_1"
7954   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7955         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7956                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7957    (clobber (reg:CC FLAGS_REG))]
7958   "ix86_binary_operator_ok (AND, HImode, operands)"
7959 {
7960   switch (get_attr_type (insn))
7961     {
7962     case TYPE_IMOVX:
7963       gcc_assert (CONST_INT_P (operands[2]));
7964       gcc_assert (INTVAL (operands[2]) == 0xff);
7965       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7966
7967     default:
7968       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7969
7970       return "and{w}\t{%2, %0|%0, %2}";
7971     }
7972 }
7973   [(set_attr "type" "alu,alu,imovx")
7974    (set_attr "length_immediate" "*,*,0")
7975    (set (attr "prefix_rex")
7976      (if_then_else
7977        (and (eq_attr "type" "imovx")
7978             (match_operand 1 "ext_QIreg_nomode_operand" ""))
7979        (const_string "1")
7980        (const_string "*")))
7981    (set_attr "mode" "HI,HI,SI")])
7982
7983 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7984 (define_insn "*andqi_1"
7985   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7986         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7987                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7988    (clobber (reg:CC FLAGS_REG))]
7989   "ix86_binary_operator_ok (AND, QImode, operands)"
7990   "@
7991    and{b}\t{%2, %0|%0, %2}
7992    and{b}\t{%2, %0|%0, %2}
7993    and{l}\t{%k2, %k0|%k0, %k2}"
7994   [(set_attr "type" "alu")
7995    (set_attr "mode" "QI,QI,SI")])
7996
7997 (define_insn "*andqi_1_slp"
7998   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7999         (and:QI (match_dup 0)
8000                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8001    (clobber (reg:CC FLAGS_REG))]
8002   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8003    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8004   "and{b}\t{%1, %0|%0, %1}"
8005   [(set_attr "type" "alu1")
8006    (set_attr "mode" "QI")])
8007
8008 (define_split
8009   [(set (match_operand 0 "register_operand" "")
8010         (and (match_dup 0)
8011              (const_int -65536)))
8012    (clobber (reg:CC FLAGS_REG))]
8013   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8014     || optimize_function_for_size_p (cfun)"
8015   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8016   "operands[1] = gen_lowpart (HImode, operands[0]);")
8017
8018 (define_split
8019   [(set (match_operand 0 "ext_register_operand" "")
8020         (and (match_dup 0)
8021              (const_int -256)))
8022    (clobber (reg:CC FLAGS_REG))]
8023   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8024    && reload_completed"
8025   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8026   "operands[1] = gen_lowpart (QImode, operands[0]);")
8027
8028 (define_split
8029   [(set (match_operand 0 "ext_register_operand" "")
8030         (and (match_dup 0)
8031              (const_int -65281)))
8032    (clobber (reg:CC FLAGS_REG))]
8033   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8034    && reload_completed"
8035   [(parallel [(set (zero_extract:SI (match_dup 0)
8036                                     (const_int 8)
8037                                     (const_int 8))
8038                    (xor:SI
8039                      (zero_extract:SI (match_dup 0)
8040                                       (const_int 8)
8041                                       (const_int 8))
8042                      (zero_extract:SI (match_dup 0)
8043                                       (const_int 8)
8044                                       (const_int 8))))
8045               (clobber (reg:CC FLAGS_REG))])]
8046   "operands[0] = gen_lowpart (SImode, operands[0]);")
8047
8048 (define_insn "*anddi_2"
8049   [(set (reg FLAGS_REG)
8050         (compare
8051          (and:DI
8052           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8053           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8054          (const_int 0)))
8055    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8056         (and:DI (match_dup 1) (match_dup 2)))]
8057   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8058    && ix86_binary_operator_ok (AND, DImode, operands)"
8059   "@
8060    and{l}\t{%k2, %k0|%k0, %k2}
8061    and{q}\t{%2, %0|%0, %2}
8062    and{q}\t{%2, %0|%0, %2}"
8063   [(set_attr "type" "alu")
8064    (set_attr "mode" "SI,DI,DI")])
8065
8066 (define_insn "*andqi_2_maybe_si"
8067   [(set (reg FLAGS_REG)
8068         (compare (and:QI
8069                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8070                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8071                  (const_int 0)))
8072    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8073         (and:QI (match_dup 1) (match_dup 2)))]
8074   "ix86_binary_operator_ok (AND, QImode, operands)
8075    && ix86_match_ccmode (insn,
8076                          CONST_INT_P (operands[2])
8077                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8078 {
8079   if (which_alternative == 2)
8080     {
8081       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8082         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8083       return "and{l}\t{%2, %k0|%k0, %2}";
8084     }
8085   return "and{b}\t{%2, %0|%0, %2}";
8086 }
8087   [(set_attr "type" "alu")
8088    (set_attr "mode" "QI,QI,SI")])
8089
8090 (define_insn "*and<mode>_2"
8091   [(set (reg FLAGS_REG)
8092         (compare (and:SWI124
8093                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8094                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8095                  (const_int 0)))
8096    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8097         (and:SWI124 (match_dup 1) (match_dup 2)))]
8098   "ix86_match_ccmode (insn, CCNOmode)
8099    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8100   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8101   [(set_attr "type" "alu")
8102    (set_attr "mode" "<MODE>")])
8103
8104 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8105 (define_insn "*andsi_2_zext"
8106   [(set (reg FLAGS_REG)
8107         (compare (and:SI
8108                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8109                   (match_operand:SI 2 "general_operand" "g"))
8110                  (const_int 0)))
8111    (set (match_operand:DI 0 "register_operand" "=r")
8112         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8113   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8114    && ix86_binary_operator_ok (AND, SImode, operands)"
8115   "and{l}\t{%2, %k0|%k0, %2}"
8116   [(set_attr "type" "alu")
8117    (set_attr "mode" "SI")])
8118
8119 (define_insn "*andqi_2_slp"
8120   [(set (reg FLAGS_REG)
8121         (compare (and:QI
8122                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8123                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8124                  (const_int 0)))
8125    (set (strict_low_part (match_dup 0))
8126         (and:QI (match_dup 0) (match_dup 1)))]
8127   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8128    && ix86_match_ccmode (insn, CCNOmode)
8129    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8130   "and{b}\t{%1, %0|%0, %1}"
8131   [(set_attr "type" "alu1")
8132    (set_attr "mode" "QI")])
8133
8134 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8135 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8136 ;; for a QImode operand, which of course failed.
8137 (define_insn "andqi_ext_0"
8138   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8139                          (const_int 8)
8140                          (const_int 8))
8141         (and:SI
8142           (zero_extract:SI
8143             (match_operand 1 "ext_register_operand" "0")
8144             (const_int 8)
8145             (const_int 8))
8146           (match_operand 2 "const_int_operand" "n")))
8147    (clobber (reg:CC FLAGS_REG))]
8148   ""
8149   "and{b}\t{%2, %h0|%h0, %2}"
8150   [(set_attr "type" "alu")
8151    (set_attr "length_immediate" "1")
8152    (set_attr "modrm" "1")
8153    (set_attr "mode" "QI")])
8154
8155 ;; Generated by peephole translating test to and.  This shows up
8156 ;; often in fp comparisons.
8157 (define_insn "*andqi_ext_0_cc"
8158   [(set (reg FLAGS_REG)
8159         (compare
8160           (and:SI
8161             (zero_extract:SI
8162               (match_operand 1 "ext_register_operand" "0")
8163               (const_int 8)
8164               (const_int 8))
8165             (match_operand 2 "const_int_operand" "n"))
8166           (const_int 0)))
8167    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8168                          (const_int 8)
8169                          (const_int 8))
8170         (and:SI
8171           (zero_extract:SI
8172             (match_dup 1)
8173             (const_int 8)
8174             (const_int 8))
8175           (match_dup 2)))]
8176   "ix86_match_ccmode (insn, CCNOmode)"
8177   "and{b}\t{%2, %h0|%h0, %2}"
8178   [(set_attr "type" "alu")
8179    (set_attr "length_immediate" "1")
8180    (set_attr "modrm" "1")
8181    (set_attr "mode" "QI")])
8182
8183 (define_insn "*andqi_ext_1_rex64"
8184   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8185                          (const_int 8)
8186                          (const_int 8))
8187         (and:SI
8188           (zero_extract:SI
8189             (match_operand 1 "ext_register_operand" "0")
8190             (const_int 8)
8191             (const_int 8))
8192           (zero_extend:SI
8193             (match_operand 2 "ext_register_operand" "Q"))))
8194    (clobber (reg:CC FLAGS_REG))]
8195   "TARGET_64BIT"
8196   "and{b}\t{%2, %h0|%h0, %2}"
8197   [(set_attr "type" "alu")
8198    (set_attr "length_immediate" "0")
8199    (set_attr "mode" "QI")])
8200
8201 (define_insn "*andqi_ext_1"
8202   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8203                          (const_int 8)
8204                          (const_int 8))
8205         (and:SI
8206           (zero_extract:SI
8207             (match_operand 1 "ext_register_operand" "0")
8208             (const_int 8)
8209             (const_int 8))
8210           (zero_extend:SI
8211             (match_operand:QI 2 "general_operand" "Qm"))))
8212    (clobber (reg:CC FLAGS_REG))]
8213   "!TARGET_64BIT"
8214   "and{b}\t{%2, %h0|%h0, %2}"
8215   [(set_attr "type" "alu")
8216    (set_attr "length_immediate" "0")
8217    (set_attr "mode" "QI")])
8218
8219 (define_insn "*andqi_ext_2"
8220   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8221                          (const_int 8)
8222                          (const_int 8))
8223         (and:SI
8224           (zero_extract:SI
8225             (match_operand 1 "ext_register_operand" "%0")
8226             (const_int 8)
8227             (const_int 8))
8228           (zero_extract:SI
8229             (match_operand 2 "ext_register_operand" "Q")
8230             (const_int 8)
8231             (const_int 8))))
8232    (clobber (reg:CC FLAGS_REG))]
8233   ""
8234   "and{b}\t{%h2, %h0|%h0, %h2}"
8235   [(set_attr "type" "alu")
8236    (set_attr "length_immediate" "0")
8237    (set_attr "mode" "QI")])
8238
8239 ;; Convert wide AND instructions with immediate operand to shorter QImode
8240 ;; equivalents when possible.
8241 ;; Don't do the splitting with memory operands, since it introduces risk
8242 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8243 ;; for size, but that can (should?) be handled by generic code instead.
8244 (define_split
8245   [(set (match_operand 0 "register_operand" "")
8246         (and (match_operand 1 "register_operand" "")
8247              (match_operand 2 "const_int_operand" "")))
8248    (clobber (reg:CC FLAGS_REG))]
8249    "reload_completed
8250     && QI_REG_P (operands[0])
8251     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8252     && !(~INTVAL (operands[2]) & ~(255 << 8))
8253     && GET_MODE (operands[0]) != QImode"
8254   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8255                    (and:SI (zero_extract:SI (match_dup 1)
8256                                             (const_int 8) (const_int 8))
8257                            (match_dup 2)))
8258               (clobber (reg:CC FLAGS_REG))])]
8259   "operands[0] = gen_lowpart (SImode, operands[0]);
8260    operands[1] = gen_lowpart (SImode, operands[1]);
8261    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8262
8263 ;; Since AND can be encoded with sign extended immediate, this is only
8264 ;; profitable when 7th bit is not set.
8265 (define_split
8266   [(set (match_operand 0 "register_operand" "")
8267         (and (match_operand 1 "general_operand" "")
8268              (match_operand 2 "const_int_operand" "")))
8269    (clobber (reg:CC FLAGS_REG))]
8270    "reload_completed
8271     && ANY_QI_REG_P (operands[0])
8272     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8273     && !(~INTVAL (operands[2]) & ~255)
8274     && !(INTVAL (operands[2]) & 128)
8275     && GET_MODE (operands[0]) != QImode"
8276   [(parallel [(set (strict_low_part (match_dup 0))
8277                    (and:QI (match_dup 1)
8278                            (match_dup 2)))
8279               (clobber (reg:CC FLAGS_REG))])]
8280   "operands[0] = gen_lowpart (QImode, operands[0]);
8281    operands[1] = gen_lowpart (QImode, operands[1]);
8282    operands[2] = gen_lowpart (QImode, operands[2]);")
8283 \f
8284 ;; Logical inclusive and exclusive OR instructions
8285
8286 ;; %%% This used to optimize known byte-wide and operations to memory.
8287 ;; If this is considered useful, it should be done with splitters.
8288
8289 (define_expand "<code><mode>3"
8290   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8291         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8292                      (match_operand:SWIM 2 "<general_operand>" "")))]
8293   ""
8294   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8295
8296 (define_insn "*<code><mode>_1"
8297   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8298         (any_or:SWI248
8299          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8300          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8301    (clobber (reg:CC FLAGS_REG))]
8302   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8303   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8304   [(set_attr "type" "alu")
8305    (set_attr "mode" "<MODE>")])
8306
8307 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8308 (define_insn "*<code>qi_1"
8309   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8310         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8311                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8312    (clobber (reg:CC FLAGS_REG))]
8313   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8314   "@
8315    <logic>{b}\t{%2, %0|%0, %2}
8316    <logic>{b}\t{%2, %0|%0, %2}
8317    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8318   [(set_attr "type" "alu")
8319    (set_attr "mode" "QI,QI,SI")])
8320
8321 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8322 (define_insn "*<code>si_1_zext"
8323   [(set (match_operand:DI 0 "register_operand" "=r")
8324         (zero_extend:DI
8325          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8326                     (match_operand:SI 2 "general_operand" "g"))))
8327    (clobber (reg:CC FLAGS_REG))]
8328   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8329   "<logic>{l}\t{%2, %k0|%k0, %2}"
8330   [(set_attr "type" "alu")
8331    (set_attr "mode" "SI")])
8332
8333 (define_insn "*<code>si_1_zext_imm"
8334   [(set (match_operand:DI 0 "register_operand" "=r")
8335         (any_or:DI
8336          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8337          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8338    (clobber (reg:CC FLAGS_REG))]
8339   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8340   "<logic>{l}\t{%2, %k0|%k0, %2}"
8341   [(set_attr "type" "alu")
8342    (set_attr "mode" "SI")])
8343
8344 (define_insn "*<code>qi_1_slp"
8345   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8346         (any_or:QI (match_dup 0)
8347                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8348    (clobber (reg:CC FLAGS_REG))]
8349   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8350    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8351   "<logic>{b}\t{%1, %0|%0, %1}"
8352   [(set_attr "type" "alu1")
8353    (set_attr "mode" "QI")])
8354
8355 (define_insn "*<code><mode>_2"
8356   [(set (reg FLAGS_REG)
8357         (compare (any_or:SWI
8358                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8359                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8360                  (const_int 0)))
8361    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8362         (any_or:SWI (match_dup 1) (match_dup 2)))]
8363   "ix86_match_ccmode (insn, CCNOmode)
8364    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8365   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8366   [(set_attr "type" "alu")
8367    (set_attr "mode" "<MODE>")])
8368
8369 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8370 ;; ??? Special case for immediate operand is missing - it is tricky.
8371 (define_insn "*<code>si_2_zext"
8372   [(set (reg FLAGS_REG)
8373         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8374                             (match_operand:SI 2 "general_operand" "g"))
8375                  (const_int 0)))
8376    (set (match_operand:DI 0 "register_operand" "=r")
8377         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8378   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8379    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8380   "<logic>{l}\t{%2, %k0|%k0, %2}"
8381   [(set_attr "type" "alu")
8382    (set_attr "mode" "SI")])
8383
8384 (define_insn "*<code>si_2_zext_imm"
8385   [(set (reg FLAGS_REG)
8386         (compare (any_or:SI
8387                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8388                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8389                  (const_int 0)))
8390    (set (match_operand:DI 0 "register_operand" "=r")
8391         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8392   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8393    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8394   "<logic>{l}\t{%2, %k0|%k0, %2}"
8395   [(set_attr "type" "alu")
8396    (set_attr "mode" "SI")])
8397
8398 (define_insn "*<code>qi_2_slp"
8399   [(set (reg FLAGS_REG)
8400         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8401                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8402                  (const_int 0)))
8403    (set (strict_low_part (match_dup 0))
8404         (any_or:QI (match_dup 0) (match_dup 1)))]
8405   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8406    && ix86_match_ccmode (insn, CCNOmode)
8407    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8408   "<logic>{b}\t{%1, %0|%0, %1}"
8409   [(set_attr "type" "alu1")
8410    (set_attr "mode" "QI")])
8411
8412 (define_insn "*<code><mode>_3"
8413   [(set (reg FLAGS_REG)
8414         (compare (any_or:SWI
8415                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8416                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8417                  (const_int 0)))
8418    (clobber (match_scratch:SWI 0 "=<r>"))]
8419   "ix86_match_ccmode (insn, CCNOmode)
8420    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8421   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8422   [(set_attr "type" "alu")
8423    (set_attr "mode" "<MODE>")])
8424
8425 (define_insn "*<code>qi_ext_0"
8426   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8427                          (const_int 8)
8428                          (const_int 8))
8429         (any_or:SI
8430           (zero_extract:SI
8431             (match_operand 1 "ext_register_operand" "0")
8432             (const_int 8)
8433             (const_int 8))
8434           (match_operand 2 "const_int_operand" "n")))
8435    (clobber (reg:CC FLAGS_REG))]
8436   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8437   "<logic>{b}\t{%2, %h0|%h0, %2}"
8438   [(set_attr "type" "alu")
8439    (set_attr "length_immediate" "1")
8440    (set_attr "modrm" "1")
8441    (set_attr "mode" "QI")])
8442
8443 (define_insn "*<code>qi_ext_1_rex64"
8444   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8445                          (const_int 8)
8446                          (const_int 8))
8447         (any_or:SI
8448           (zero_extract:SI
8449             (match_operand 1 "ext_register_operand" "0")
8450             (const_int 8)
8451             (const_int 8))
8452           (zero_extend:SI
8453             (match_operand 2 "ext_register_operand" "Q"))))
8454    (clobber (reg:CC FLAGS_REG))]
8455   "TARGET_64BIT
8456    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8457   "<logic>{b}\t{%2, %h0|%h0, %2}"
8458   [(set_attr "type" "alu")
8459    (set_attr "length_immediate" "0")
8460    (set_attr "mode" "QI")])
8461
8462 (define_insn "*<code>qi_ext_1"
8463   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8464                          (const_int 8)
8465                          (const_int 8))
8466         (any_or:SI
8467           (zero_extract:SI
8468             (match_operand 1 "ext_register_operand" "0")
8469             (const_int 8)
8470             (const_int 8))
8471           (zero_extend:SI
8472             (match_operand:QI 2 "general_operand" "Qm"))))
8473    (clobber (reg:CC FLAGS_REG))]
8474   "!TARGET_64BIT
8475    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8476   "<logic>{b}\t{%2, %h0|%h0, %2}"
8477   [(set_attr "type" "alu")
8478    (set_attr "length_immediate" "0")
8479    (set_attr "mode" "QI")])
8480
8481 (define_insn "*<code>qi_ext_2"
8482   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8483                          (const_int 8)
8484                          (const_int 8))
8485         (any_or:SI
8486           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8487                            (const_int 8)
8488                            (const_int 8))
8489           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8490                            (const_int 8)
8491                            (const_int 8))))
8492    (clobber (reg:CC FLAGS_REG))]
8493   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8494   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8495   [(set_attr "type" "alu")
8496    (set_attr "length_immediate" "0")
8497    (set_attr "mode" "QI")])
8498
8499 (define_split
8500   [(set (match_operand 0 "register_operand" "")
8501         (any_or (match_operand 1 "register_operand" "")
8502                 (match_operand 2 "const_int_operand" "")))
8503    (clobber (reg:CC FLAGS_REG))]
8504    "reload_completed
8505     && QI_REG_P (operands[0])
8506     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8507     && !(INTVAL (operands[2]) & ~(255 << 8))
8508     && GET_MODE (operands[0]) != QImode"
8509   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8510                    (any_or:SI (zero_extract:SI (match_dup 1)
8511                                                (const_int 8) (const_int 8))
8512                               (match_dup 2)))
8513               (clobber (reg:CC FLAGS_REG))])]
8514   "operands[0] = gen_lowpart (SImode, operands[0]);
8515    operands[1] = gen_lowpart (SImode, operands[1]);
8516    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8517
8518 ;; Since OR can be encoded with sign extended immediate, this is only
8519 ;; profitable when 7th bit is set.
8520 (define_split
8521   [(set (match_operand 0 "register_operand" "")
8522         (any_or (match_operand 1 "general_operand" "")
8523                 (match_operand 2 "const_int_operand" "")))
8524    (clobber (reg:CC FLAGS_REG))]
8525    "reload_completed
8526     && ANY_QI_REG_P (operands[0])
8527     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8528     && !(INTVAL (operands[2]) & ~255)
8529     && (INTVAL (operands[2]) & 128)
8530     && GET_MODE (operands[0]) != QImode"
8531   [(parallel [(set (strict_low_part (match_dup 0))
8532                    (any_or:QI (match_dup 1)
8533                               (match_dup 2)))
8534               (clobber (reg:CC FLAGS_REG))])]
8535   "operands[0] = gen_lowpart (QImode, operands[0]);
8536    operands[1] = gen_lowpart (QImode, operands[1]);
8537    operands[2] = gen_lowpart (QImode, operands[2]);")
8538
8539 (define_expand "xorqi_cc_ext_1"
8540   [(parallel [
8541      (set (reg:CCNO FLAGS_REG)
8542           (compare:CCNO
8543             (xor:SI
8544               (zero_extract:SI
8545                 (match_operand 1 "ext_register_operand" "")
8546                 (const_int 8)
8547                 (const_int 8))
8548               (match_operand:QI 2 "general_operand" ""))
8549             (const_int 0)))
8550      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8551                            (const_int 8)
8552                            (const_int 8))
8553           (xor:SI
8554             (zero_extract:SI
8555              (match_dup 1)
8556              (const_int 8)
8557              (const_int 8))
8558             (match_dup 2)))])])
8559
8560 (define_insn "*xorqi_cc_ext_1_rex64"
8561   [(set (reg FLAGS_REG)
8562         (compare
8563           (xor:SI
8564             (zero_extract:SI
8565               (match_operand 1 "ext_register_operand" "0")
8566               (const_int 8)
8567               (const_int 8))
8568             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8569           (const_int 0)))
8570    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8571                          (const_int 8)
8572                          (const_int 8))
8573         (xor:SI
8574           (zero_extract:SI
8575            (match_dup 1)
8576            (const_int 8)
8577            (const_int 8))
8578           (match_dup 2)))]
8579   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8580   "xor{b}\t{%2, %h0|%h0, %2}"
8581   [(set_attr "type" "alu")
8582    (set_attr "modrm" "1")
8583    (set_attr "mode" "QI")])
8584
8585 (define_insn "*xorqi_cc_ext_1"
8586   [(set (reg FLAGS_REG)
8587         (compare
8588           (xor:SI
8589             (zero_extract:SI
8590               (match_operand 1 "ext_register_operand" "0")
8591               (const_int 8)
8592               (const_int 8))
8593             (match_operand:QI 2 "general_operand" "qmn"))
8594           (const_int 0)))
8595    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8596                          (const_int 8)
8597                          (const_int 8))
8598         (xor:SI
8599           (zero_extract:SI
8600            (match_dup 1)
8601            (const_int 8)
8602            (const_int 8))
8603           (match_dup 2)))]
8604   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8605   "xor{b}\t{%2, %h0|%h0, %2}"
8606   [(set_attr "type" "alu")
8607    (set_attr "modrm" "1")
8608    (set_attr "mode" "QI")])
8609 \f
8610 ;; Negation instructions
8611
8612 (define_expand "neg<mode>2"
8613   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8614         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8615   ""
8616   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8617
8618 (define_insn_and_split "*neg<dwi>2_doubleword"
8619   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8620         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8621    (clobber (reg:CC FLAGS_REG))]
8622   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8623   "#"
8624   "reload_completed"
8625   [(parallel
8626     [(set (reg:CCZ FLAGS_REG)
8627           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8628      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8629    (parallel
8630     [(set (match_dup 2)
8631           (plus:DWIH (match_dup 3)
8632                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8633                                 (const_int 0))))
8634      (clobber (reg:CC FLAGS_REG))])
8635    (parallel
8636     [(set (match_dup 2)
8637           (neg:DWIH (match_dup 2)))
8638      (clobber (reg:CC FLAGS_REG))])]
8639   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8640
8641 (define_insn "*neg<mode>2_1"
8642   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8643         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8644    (clobber (reg:CC FLAGS_REG))]
8645   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8646   "neg{<imodesuffix>}\t%0"
8647   [(set_attr "type" "negnot")
8648    (set_attr "mode" "<MODE>")])
8649
8650 ;; Combine is quite creative about this pattern.
8651 (define_insn "*negsi2_1_zext"
8652   [(set (match_operand:DI 0 "register_operand" "=r")
8653         (lshiftrt:DI
8654           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8655                              (const_int 32)))
8656         (const_int 32)))
8657    (clobber (reg:CC FLAGS_REG))]
8658   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8659   "neg{l}\t%k0"
8660   [(set_attr "type" "negnot")
8661    (set_attr "mode" "SI")])
8662
8663 ;; The problem with neg is that it does not perform (compare x 0),
8664 ;; it really performs (compare 0 x), which leaves us with the zero
8665 ;; flag being the only useful item.
8666
8667 (define_insn "*neg<mode>2_cmpz"
8668   [(set (reg:CCZ FLAGS_REG)
8669         (compare:CCZ
8670           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8671                    (const_int 0)))
8672    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8673         (neg:SWI (match_dup 1)))]
8674   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8675   "neg{<imodesuffix>}\t%0"
8676   [(set_attr "type" "negnot")
8677    (set_attr "mode" "<MODE>")])
8678
8679 (define_insn "*negsi2_cmpz_zext"
8680   [(set (reg:CCZ FLAGS_REG)
8681         (compare:CCZ
8682           (lshiftrt:DI
8683             (neg:DI (ashift:DI
8684                       (match_operand:DI 1 "register_operand" "0")
8685                       (const_int 32)))
8686             (const_int 32))
8687           (const_int 0)))
8688    (set (match_operand:DI 0 "register_operand" "=r")
8689         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8690                                         (const_int 32)))
8691                      (const_int 32)))]
8692   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8693   "neg{l}\t%k0"
8694   [(set_attr "type" "negnot")
8695    (set_attr "mode" "SI")])
8696
8697 ;; Changing of sign for FP values is doable using integer unit too.
8698
8699 (define_expand "<code><mode>2"
8700   [(set (match_operand:X87MODEF 0 "register_operand" "")
8701         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8702   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8703   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8704
8705 (define_insn "*absneg<mode>2_mixed"
8706   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8707         (match_operator:MODEF 3 "absneg_operator"
8708           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8709    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8710    (clobber (reg:CC FLAGS_REG))]
8711   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8712   "#")
8713
8714 (define_insn "*absneg<mode>2_sse"
8715   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8716         (match_operator:MODEF 3 "absneg_operator"
8717           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8718    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8719    (clobber (reg:CC FLAGS_REG))]
8720   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8721   "#")
8722
8723 (define_insn "*absneg<mode>2_i387"
8724   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8725         (match_operator:X87MODEF 3 "absneg_operator"
8726           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8727    (use (match_operand 2 "" ""))
8728    (clobber (reg:CC FLAGS_REG))]
8729   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8730   "#")
8731
8732 (define_expand "<code>tf2"
8733   [(set (match_operand:TF 0 "register_operand" "")
8734         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8735   "TARGET_SSE2"
8736   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8737
8738 (define_insn "*absnegtf2_sse"
8739   [(set (match_operand:TF 0 "register_operand" "=x,x")
8740         (match_operator:TF 3 "absneg_operator"
8741           [(match_operand:TF 1 "register_operand" "0,x")]))
8742    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8743    (clobber (reg:CC FLAGS_REG))]
8744   "TARGET_SSE2"
8745   "#")
8746
8747 ;; Splitters for fp abs and neg.
8748
8749 (define_split
8750   [(set (match_operand 0 "fp_register_operand" "")
8751         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8752    (use (match_operand 2 "" ""))
8753    (clobber (reg:CC FLAGS_REG))]
8754   "reload_completed"
8755   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8756
8757 (define_split
8758   [(set (match_operand 0 "register_operand" "")
8759         (match_operator 3 "absneg_operator"
8760           [(match_operand 1 "register_operand" "")]))
8761    (use (match_operand 2 "nonimmediate_operand" ""))
8762    (clobber (reg:CC FLAGS_REG))]
8763   "reload_completed && SSE_REG_P (operands[0])"
8764   [(set (match_dup 0) (match_dup 3))]
8765 {
8766   enum machine_mode mode = GET_MODE (operands[0]);
8767   enum machine_mode vmode = GET_MODE (operands[2]);
8768   rtx tmp;
8769
8770   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8771   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8772   if (operands_match_p (operands[0], operands[2]))
8773     {
8774       tmp = operands[1];
8775       operands[1] = operands[2];
8776       operands[2] = tmp;
8777     }
8778   if (GET_CODE (operands[3]) == ABS)
8779     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8780   else
8781     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8782   operands[3] = tmp;
8783 })
8784
8785 (define_split
8786   [(set (match_operand:SF 0 "register_operand" "")
8787         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8788    (use (match_operand:V4SF 2 "" ""))
8789    (clobber (reg:CC FLAGS_REG))]
8790   "reload_completed"
8791   [(parallel [(set (match_dup 0) (match_dup 1))
8792               (clobber (reg:CC FLAGS_REG))])]
8793 {
8794   rtx tmp;
8795   operands[0] = gen_lowpart (SImode, operands[0]);
8796   if (GET_CODE (operands[1]) == ABS)
8797     {
8798       tmp = gen_int_mode (0x7fffffff, SImode);
8799       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8800     }
8801   else
8802     {
8803       tmp = gen_int_mode (0x80000000, SImode);
8804       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8805     }
8806   operands[1] = tmp;
8807 })
8808
8809 (define_split
8810   [(set (match_operand:DF 0 "register_operand" "")
8811         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8812    (use (match_operand 2 "" ""))
8813    (clobber (reg:CC FLAGS_REG))]
8814   "reload_completed"
8815   [(parallel [(set (match_dup 0) (match_dup 1))
8816               (clobber (reg:CC FLAGS_REG))])]
8817 {
8818   rtx tmp;
8819   if (TARGET_64BIT)
8820     {
8821       tmp = gen_lowpart (DImode, operands[0]);
8822       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8823       operands[0] = tmp;
8824
8825       if (GET_CODE (operands[1]) == ABS)
8826         tmp = const0_rtx;
8827       else
8828         tmp = gen_rtx_NOT (DImode, tmp);
8829     }
8830   else
8831     {
8832       operands[0] = gen_highpart (SImode, operands[0]);
8833       if (GET_CODE (operands[1]) == ABS)
8834         {
8835           tmp = gen_int_mode (0x7fffffff, SImode);
8836           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8837         }
8838       else
8839         {
8840           tmp = gen_int_mode (0x80000000, SImode);
8841           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8842         }
8843     }
8844   operands[1] = tmp;
8845 })
8846
8847 (define_split
8848   [(set (match_operand:XF 0 "register_operand" "")
8849         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8850    (use (match_operand 2 "" ""))
8851    (clobber (reg:CC FLAGS_REG))]
8852   "reload_completed"
8853   [(parallel [(set (match_dup 0) (match_dup 1))
8854               (clobber (reg:CC FLAGS_REG))])]
8855 {
8856   rtx tmp;
8857   operands[0] = gen_rtx_REG (SImode,
8858                              true_regnum (operands[0])
8859                              + (TARGET_64BIT ? 1 : 2));
8860   if (GET_CODE (operands[1]) == ABS)
8861     {
8862       tmp = GEN_INT (0x7fff);
8863       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8864     }
8865   else
8866     {
8867       tmp = GEN_INT (0x8000);
8868       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8869     }
8870   operands[1] = tmp;
8871 })
8872
8873 ;; Conditionalize these after reload. If they match before reload, we
8874 ;; lose the clobber and ability to use integer instructions.
8875
8876 (define_insn "*<code><mode>2_1"
8877   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8878         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8879   "TARGET_80387
8880    && (reload_completed
8881        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8882   "f<absneg_mnemonic>"
8883   [(set_attr "type" "fsgn")
8884    (set_attr "mode" "<MODE>")])
8885
8886 (define_insn "*<code>extendsfdf2"
8887   [(set (match_operand:DF 0 "register_operand" "=f")
8888         (absneg:DF (float_extend:DF
8889                      (match_operand:SF 1 "register_operand" "0"))))]
8890   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8891   "f<absneg_mnemonic>"
8892   [(set_attr "type" "fsgn")
8893    (set_attr "mode" "DF")])
8894
8895 (define_insn "*<code>extendsfxf2"
8896   [(set (match_operand:XF 0 "register_operand" "=f")
8897         (absneg:XF (float_extend:XF
8898                      (match_operand:SF 1 "register_operand" "0"))))]
8899   "TARGET_80387"
8900   "f<absneg_mnemonic>"
8901   [(set_attr "type" "fsgn")
8902    (set_attr "mode" "XF")])
8903
8904 (define_insn "*<code>extenddfxf2"
8905   [(set (match_operand:XF 0 "register_operand" "=f")
8906         (absneg:XF (float_extend:XF
8907                      (match_operand:DF 1 "register_operand" "0"))))]
8908   "TARGET_80387"
8909   "f<absneg_mnemonic>"
8910   [(set_attr "type" "fsgn")
8911    (set_attr "mode" "XF")])
8912
8913 ;; Copysign instructions
8914
8915 (define_mode_iterator CSGNMODE [SF DF TF])
8916 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8917
8918 (define_expand "copysign<mode>3"
8919   [(match_operand:CSGNMODE 0 "register_operand" "")
8920    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8921    (match_operand:CSGNMODE 2 "register_operand" "")]
8922   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8923    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8924   "ix86_expand_copysign (operands); DONE;")
8925
8926 (define_insn_and_split "copysign<mode>3_const"
8927   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8928         (unspec:CSGNMODE
8929           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8930            (match_operand:CSGNMODE 2 "register_operand" "0")
8931            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8932           UNSPEC_COPYSIGN))]
8933   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8934    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8935   "#"
8936   "&& reload_completed"
8937   [(const_int 0)]
8938   "ix86_split_copysign_const (operands); DONE;")
8939
8940 (define_insn "copysign<mode>3_var"
8941   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8942         (unspec:CSGNMODE
8943           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8944            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8945            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8946            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8947           UNSPEC_COPYSIGN))
8948    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8949   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8950    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8951   "#")
8952
8953 (define_split
8954   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8955         (unspec:CSGNMODE
8956           [(match_operand:CSGNMODE 2 "register_operand" "")
8957            (match_operand:CSGNMODE 3 "register_operand" "")
8958            (match_operand:<CSGNVMODE> 4 "" "")
8959            (match_operand:<CSGNVMODE> 5 "" "")]
8960           UNSPEC_COPYSIGN))
8961    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8962   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8963     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8964    && reload_completed"
8965   [(const_int 0)]
8966   "ix86_split_copysign_var (operands); DONE;")
8967 \f
8968 ;; One complement instructions
8969
8970 (define_expand "one_cmpl<mode>2"
8971   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8972         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8973   ""
8974   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8975
8976 (define_insn "*one_cmpl<mode>2_1"
8977   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8978         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8979   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8980   "not{<imodesuffix>}\t%0"
8981   [(set_attr "type" "negnot")
8982    (set_attr "mode" "<MODE>")])
8983
8984 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8985 (define_insn "*one_cmplqi2_1"
8986   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8987         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8988   "ix86_unary_operator_ok (NOT, QImode, operands)"
8989   "@
8990    not{b}\t%0
8991    not{l}\t%k0"
8992   [(set_attr "type" "negnot")
8993    (set_attr "mode" "QI,SI")])
8994
8995 ;; ??? Currently never generated - xor is used instead.
8996 (define_insn "*one_cmplsi2_1_zext"
8997   [(set (match_operand:DI 0 "register_operand" "=r")
8998         (zero_extend:DI
8999           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9000   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9001   "not{l}\t%k0"
9002   [(set_attr "type" "negnot")
9003    (set_attr "mode" "SI")])
9004
9005 (define_insn "*one_cmpl<mode>2_2"
9006   [(set (reg FLAGS_REG)
9007         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9008                  (const_int 0)))
9009    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9010         (not:SWI (match_dup 1)))]
9011   "ix86_match_ccmode (insn, CCNOmode)
9012    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9013   "#"
9014   [(set_attr "type" "alu1")
9015    (set_attr "mode" "<MODE>")])
9016
9017 (define_split
9018   [(set (match_operand 0 "flags_reg_operand" "")
9019         (match_operator 2 "compare_operator"
9020           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9021            (const_int 0)]))
9022    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9023         (not:SWI (match_dup 3)))]
9024   "ix86_match_ccmode (insn, CCNOmode)"
9025   [(parallel [(set (match_dup 0)
9026                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9027                                     (const_int 0)]))
9028               (set (match_dup 1)
9029                    (xor:SWI (match_dup 3) (const_int -1)))])])
9030
9031 ;; ??? Currently never generated - xor is used instead.
9032 (define_insn "*one_cmplsi2_2_zext"
9033   [(set (reg FLAGS_REG)
9034         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9035                  (const_int 0)))
9036    (set (match_operand:DI 0 "register_operand" "=r")
9037         (zero_extend:DI (not:SI (match_dup 1))))]
9038   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9039    && ix86_unary_operator_ok (NOT, SImode, operands)"
9040   "#"
9041   [(set_attr "type" "alu1")
9042    (set_attr "mode" "SI")])
9043
9044 (define_split
9045   [(set (match_operand 0 "flags_reg_operand" "")
9046         (match_operator 2 "compare_operator"
9047           [(not:SI (match_operand:SI 3 "register_operand" ""))
9048            (const_int 0)]))
9049    (set (match_operand:DI 1 "register_operand" "")
9050         (zero_extend:DI (not:SI (match_dup 3))))]
9051   "ix86_match_ccmode (insn, CCNOmode)"
9052   [(parallel [(set (match_dup 0)
9053                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9054                                     (const_int 0)]))
9055               (set (match_dup 1)
9056                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9057 \f
9058 ;; Shift instructions
9059
9060 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9061 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9062 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9063 ;; from the assembler input.
9064 ;;
9065 ;; This instruction shifts the target reg/mem as usual, but instead of
9066 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9067 ;; is a left shift double, bits are taken from the high order bits of
9068 ;; reg, else if the insn is a shift right double, bits are taken from the
9069 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9070 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9071 ;;
9072 ;; Since sh[lr]d does not change the `reg' operand, that is done
9073 ;; separately, making all shifts emit pairs of shift double and normal
9074 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9075 ;; support a 63 bit shift, each shift where the count is in a reg expands
9076 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9077 ;;
9078 ;; If the shift count is a constant, we need never emit more than one
9079 ;; shift pair, instead using moves and sign extension for counts greater
9080 ;; than 31.
9081
9082 (define_expand "ashl<mode>3"
9083   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9084         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9085                       (match_operand:QI 2 "nonmemory_operand" "")))]
9086   ""
9087   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9088
9089 (define_insn "*ashl<mode>3_doubleword"
9090   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9091         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9092                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   ""
9095   "#"
9096   [(set_attr "type" "multi")])
9097
9098 (define_split
9099   [(set (match_operand:DWI 0 "register_operand" "")
9100         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9101                     (match_operand:QI 2 "nonmemory_operand" "")))
9102    (clobber (reg:CC FLAGS_REG))]
9103   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9104   [(const_int 0)]
9105   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9106
9107 ;; By default we don't ask for a scratch register, because when DWImode
9108 ;; values are manipulated, registers are already at a premium.  But if
9109 ;; we have one handy, we won't turn it away.
9110
9111 (define_peephole2
9112   [(match_scratch:DWIH 3 "r")
9113    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9114                    (ashift:<DWI>
9115                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9116                      (match_operand:QI 2 "nonmemory_operand" "")))
9117               (clobber (reg:CC FLAGS_REG))])
9118    (match_dup 3)]
9119   "TARGET_CMOVE"
9120   [(const_int 0)]
9121   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9122
9123 (define_insn "x86_64_shld"
9124   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9125         (ior:DI (ashift:DI (match_dup 0)
9126                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9127                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9128                   (minus:QI (const_int 64) (match_dup 2)))))
9129    (clobber (reg:CC FLAGS_REG))]
9130   "TARGET_64BIT"
9131   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9132   [(set_attr "type" "ishift")
9133    (set_attr "prefix_0f" "1")
9134    (set_attr "mode" "DI")
9135    (set_attr "athlon_decode" "vector")
9136    (set_attr "amdfam10_decode" "vector")
9137    (set_attr "bdver1_decode" "vector")])
9138
9139 (define_insn "x86_shld"
9140   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9141         (ior:SI (ashift:SI (match_dup 0)
9142                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9143                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9144                   (minus:QI (const_int 32) (match_dup 2)))))
9145    (clobber (reg:CC FLAGS_REG))]
9146   ""
9147   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9148   [(set_attr "type" "ishift")
9149    (set_attr "prefix_0f" "1")
9150    (set_attr "mode" "SI")
9151    (set_attr "pent_pair" "np")
9152    (set_attr "athlon_decode" "vector")
9153    (set_attr "amdfam10_decode" "vector")
9154    (set_attr "bdver1_decode" "vector")])
9155
9156 (define_expand "x86_shift<mode>_adj_1"
9157   [(set (reg:CCZ FLAGS_REG)
9158         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9159                              (match_dup 4))
9160                      (const_int 0)))
9161    (set (match_operand:SWI48 0 "register_operand" "")
9162         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9163                             (match_operand:SWI48 1 "register_operand" "")
9164                             (match_dup 0)))
9165    (set (match_dup 1)
9166         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9167                             (match_operand:SWI48 3 "register_operand" "r")
9168                             (match_dup 1)))]
9169   "TARGET_CMOVE"
9170   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9171
9172 (define_expand "x86_shift<mode>_adj_2"
9173   [(use (match_operand:SWI48 0 "register_operand" ""))
9174    (use (match_operand:SWI48 1 "register_operand" ""))
9175    (use (match_operand:QI 2 "register_operand" ""))]
9176   ""
9177 {
9178   rtx label = gen_label_rtx ();
9179   rtx tmp;
9180
9181   emit_insn (gen_testqi_ccz_1 (operands[2],
9182                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9183
9184   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9185   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9186   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9187                               gen_rtx_LABEL_REF (VOIDmode, label),
9188                               pc_rtx);
9189   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9190   JUMP_LABEL (tmp) = label;
9191
9192   emit_move_insn (operands[0], operands[1]);
9193   ix86_expand_clear (operands[1]);
9194
9195   emit_label (label);
9196   LABEL_NUSES (label) = 1;
9197
9198   DONE;
9199 })
9200
9201 ;; Avoid useless masking of count operand.
9202 (define_insn_and_split "*ashl<mode>3_mask"
9203   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9204         (ashift:SWI48
9205           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9206           (subreg:QI
9207             (and:SI
9208               (match_operand:SI 2 "nonimmediate_operand" "c")
9209               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9210    (clobber (reg:CC FLAGS_REG))]
9211   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9212    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9213       == GET_MODE_BITSIZE (<MODE>mode)-1"
9214   "#"
9215   "&& 1"
9216   [(parallel [(set (match_dup 0)
9217                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9218               (clobber (reg:CC FLAGS_REG))])]
9219 {
9220   if (can_create_pseudo_p ())
9221     operands [2] = force_reg (SImode, operands[2]);
9222
9223   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9224 }
9225   [(set_attr "type" "ishift")
9226    (set_attr "mode" "<MODE>")])
9227
9228 (define_insn "*ashl<mode>3_1"
9229   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9230         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9231                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9232    (clobber (reg:CC FLAGS_REG))]
9233   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9234 {
9235   switch (get_attr_type (insn))
9236     {
9237     case TYPE_LEA:
9238       return "#";
9239
9240     case TYPE_ALU:
9241       gcc_assert (operands[2] == const1_rtx);
9242       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9243       return "add{<imodesuffix>}\t%0, %0";
9244
9245     default:
9246       if (operands[2] == const1_rtx
9247           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9248         return "sal{<imodesuffix>}\t%0";
9249       else
9250         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9251     }
9252 }
9253   [(set (attr "type")
9254      (cond [(eq_attr "alternative" "1")
9255               (const_string "lea")
9256             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9257                           (const_int 0))
9258                       (match_operand 0 "register_operand" ""))
9259                  (match_operand 2 "const1_operand" ""))
9260               (const_string "alu")
9261            ]
9262            (const_string "ishift")))
9263    (set (attr "length_immediate")
9264      (if_then_else
9265        (ior (eq_attr "type" "alu")
9266             (and (eq_attr "type" "ishift")
9267                  (and (match_operand 2 "const1_operand" "")
9268                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9269                           (const_int 0)))))
9270        (const_string "0")
9271        (const_string "*")))
9272    (set_attr "mode" "<MODE>")])
9273
9274 (define_insn "*ashlsi3_1_zext"
9275   [(set (match_operand:DI 0 "register_operand" "=r,r")
9276         (zero_extend:DI
9277           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9278                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9279    (clobber (reg:CC FLAGS_REG))]
9280   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9281 {
9282   switch (get_attr_type (insn))
9283     {
9284     case TYPE_LEA:
9285       return "#";
9286
9287     case TYPE_ALU:
9288       gcc_assert (operands[2] == const1_rtx);
9289       return "add{l}\t%k0, %k0";
9290
9291     default:
9292       if (operands[2] == const1_rtx
9293           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9294         return "sal{l}\t%k0";
9295       else
9296         return "sal{l}\t{%2, %k0|%k0, %2}";
9297     }
9298 }
9299   [(set (attr "type")
9300      (cond [(eq_attr "alternative" "1")
9301               (const_string "lea")
9302             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9303                      (const_int 0))
9304                  (match_operand 2 "const1_operand" ""))
9305               (const_string "alu")
9306            ]
9307            (const_string "ishift")))
9308    (set (attr "length_immediate")
9309      (if_then_else
9310        (ior (eq_attr "type" "alu")
9311             (and (eq_attr "type" "ishift")
9312                  (and (match_operand 2 "const1_operand" "")
9313                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9314                           (const_int 0)))))
9315        (const_string "0")
9316        (const_string "*")))
9317    (set_attr "mode" "SI")])
9318
9319 (define_insn "*ashlhi3_1"
9320   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9321         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9322                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9323    (clobber (reg:CC FLAGS_REG))]
9324   "TARGET_PARTIAL_REG_STALL
9325    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9326 {
9327   switch (get_attr_type (insn))
9328     {
9329     case TYPE_ALU:
9330       gcc_assert (operands[2] == const1_rtx);
9331       return "add{w}\t%0, %0";
9332
9333     default:
9334       if (operands[2] == const1_rtx
9335           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9336         return "sal{w}\t%0";
9337       else
9338         return "sal{w}\t{%2, %0|%0, %2}";
9339     }
9340 }
9341   [(set (attr "type")
9342      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9343                           (const_int 0))
9344                       (match_operand 0 "register_operand" ""))
9345                  (match_operand 2 "const1_operand" ""))
9346               (const_string "alu")
9347            ]
9348            (const_string "ishift")))
9349    (set (attr "length_immediate")
9350      (if_then_else
9351        (ior (eq_attr "type" "alu")
9352             (and (eq_attr "type" "ishift")
9353                  (and (match_operand 2 "const1_operand" "")
9354                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9355                           (const_int 0)))))
9356        (const_string "0")
9357        (const_string "*")))
9358    (set_attr "mode" "HI")])
9359
9360 (define_insn "*ashlhi3_1_lea"
9361   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9362         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9363                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9364    (clobber (reg:CC FLAGS_REG))]
9365   "!TARGET_PARTIAL_REG_STALL
9366    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9367 {
9368   switch (get_attr_type (insn))
9369     {
9370     case TYPE_LEA:
9371       return "#";
9372
9373     case TYPE_ALU:
9374       gcc_assert (operands[2] == const1_rtx);
9375       return "add{w}\t%0, %0";
9376
9377     default:
9378       if (operands[2] == const1_rtx
9379           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9380         return "sal{w}\t%0";
9381       else
9382         return "sal{w}\t{%2, %0|%0, %2}";
9383     }
9384 }
9385   [(set (attr "type")
9386      (cond [(eq_attr "alternative" "1")
9387               (const_string "lea")
9388             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9389                           (const_int 0))
9390                       (match_operand 0 "register_operand" ""))
9391                  (match_operand 2 "const1_operand" ""))
9392               (const_string "alu")
9393            ]
9394            (const_string "ishift")))
9395    (set (attr "length_immediate")
9396      (if_then_else
9397        (ior (eq_attr "type" "alu")
9398             (and (eq_attr "type" "ishift")
9399                  (and (match_operand 2 "const1_operand" "")
9400                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9401                           (const_int 0)))))
9402        (const_string "0")
9403        (const_string "*")))
9404    (set_attr "mode" "HI,SI")])
9405
9406 (define_insn "*ashlqi3_1"
9407   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9408         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9409                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9410    (clobber (reg:CC FLAGS_REG))]
9411   "TARGET_PARTIAL_REG_STALL
9412    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9413 {
9414   switch (get_attr_type (insn))
9415     {
9416     case TYPE_ALU:
9417       gcc_assert (operands[2] == const1_rtx);
9418       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9419         return "add{l}\t%k0, %k0";
9420       else
9421         return "add{b}\t%0, %0";
9422
9423     default:
9424       if (operands[2] == const1_rtx
9425           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9426         {
9427           if (get_attr_mode (insn) == MODE_SI)
9428             return "sal{l}\t%k0";
9429           else
9430             return "sal{b}\t%0";
9431         }
9432       else
9433         {
9434           if (get_attr_mode (insn) == MODE_SI)
9435             return "sal{l}\t{%2, %k0|%k0, %2}";
9436           else
9437             return "sal{b}\t{%2, %0|%0, %2}";
9438         }
9439     }
9440 }
9441   [(set (attr "type")
9442      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9443                           (const_int 0))
9444                       (match_operand 0 "register_operand" ""))
9445                  (match_operand 2 "const1_operand" ""))
9446               (const_string "alu")
9447            ]
9448            (const_string "ishift")))
9449    (set (attr "length_immediate")
9450      (if_then_else
9451        (ior (eq_attr "type" "alu")
9452             (and (eq_attr "type" "ishift")
9453                  (and (match_operand 2 "const1_operand" "")
9454                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9455                           (const_int 0)))))
9456        (const_string "0")
9457        (const_string "*")))
9458    (set_attr "mode" "QI,SI")])
9459
9460 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9461 (define_insn "*ashlqi3_1_lea"
9462   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9463         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9464                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9465    (clobber (reg:CC FLAGS_REG))]
9466   "!TARGET_PARTIAL_REG_STALL
9467    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9468 {
9469   switch (get_attr_type (insn))
9470     {
9471     case TYPE_LEA:
9472       return "#";
9473
9474     case TYPE_ALU:
9475       gcc_assert (operands[2] == const1_rtx);
9476       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9477         return "add{l}\t%k0, %k0";
9478       else
9479         return "add{b}\t%0, %0";
9480
9481     default:
9482       if (operands[2] == const1_rtx
9483           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9484         {
9485           if (get_attr_mode (insn) == MODE_SI)
9486             return "sal{l}\t%k0";
9487           else
9488             return "sal{b}\t%0";
9489         }
9490       else
9491         {
9492           if (get_attr_mode (insn) == MODE_SI)
9493             return "sal{l}\t{%2, %k0|%k0, %2}";
9494           else
9495             return "sal{b}\t{%2, %0|%0, %2}";
9496         }
9497     }
9498 }
9499   [(set (attr "type")
9500      (cond [(eq_attr "alternative" "2")
9501               (const_string "lea")
9502             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9503                           (const_int 0))
9504                       (match_operand 0 "register_operand" ""))
9505                  (match_operand 2 "const1_operand" ""))
9506               (const_string "alu")
9507            ]
9508            (const_string "ishift")))
9509    (set (attr "length_immediate")
9510      (if_then_else
9511        (ior (eq_attr "type" "alu")
9512             (and (eq_attr "type" "ishift")
9513                  (and (match_operand 2 "const1_operand" "")
9514                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9515                           (const_int 0)))))
9516        (const_string "0")
9517        (const_string "*")))
9518    (set_attr "mode" "QI,SI,SI")])
9519
9520 (define_insn "*ashlqi3_1_slp"
9521   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9522         (ashift:QI (match_dup 0)
9523                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9524    (clobber (reg:CC FLAGS_REG))]
9525   "(optimize_function_for_size_p (cfun)
9526     || !TARGET_PARTIAL_FLAG_REG_STALL
9527     || (operands[1] == const1_rtx
9528         && (TARGET_SHIFT1
9529             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9530 {
9531   switch (get_attr_type (insn))
9532     {
9533     case TYPE_ALU:
9534       gcc_assert (operands[1] == const1_rtx);
9535       return "add{b}\t%0, %0";
9536
9537     default:
9538       if (operands[1] == const1_rtx
9539           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9540         return "sal{b}\t%0";
9541       else
9542         return "sal{b}\t{%1, %0|%0, %1}";
9543     }
9544 }
9545   [(set (attr "type")
9546      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9547                           (const_int 0))
9548                       (match_operand 0 "register_operand" ""))
9549                  (match_operand 1 "const1_operand" ""))
9550               (const_string "alu")
9551            ]
9552            (const_string "ishift1")))
9553    (set (attr "length_immediate")
9554      (if_then_else
9555        (ior (eq_attr "type" "alu")
9556             (and (eq_attr "type" "ishift1")
9557                  (and (match_operand 1 "const1_operand" "")
9558                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9559                           (const_int 0)))))
9560        (const_string "0")
9561        (const_string "*")))
9562    (set_attr "mode" "QI")])
9563
9564 ;; Convert lea to the lea pattern to avoid flags dependency.
9565 (define_split
9566   [(set (match_operand 0 "register_operand" "")
9567         (ashift (match_operand 1 "index_register_operand" "")
9568                 (match_operand:QI 2 "const_int_operand" "")))
9569    (clobber (reg:CC FLAGS_REG))]
9570   "reload_completed
9571    && true_regnum (operands[0]) != true_regnum (operands[1])"
9572   [(const_int 0)]
9573 {
9574   rtx pat;
9575   enum machine_mode mode = GET_MODE (operands[0]);
9576
9577   if (mode != Pmode)
9578     operands[1] = gen_lowpart (Pmode, operands[1]);
9579   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9580
9581   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9582
9583   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9584     operands[0] = gen_lowpart (SImode, operands[0]);
9585
9586   if (TARGET_64BIT && mode != Pmode)
9587     pat = gen_rtx_SUBREG (SImode, pat, 0);
9588
9589   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9590   DONE;
9591 })
9592
9593 ;; Convert lea to the lea pattern to avoid flags dependency.
9594 (define_split
9595   [(set (match_operand:DI 0 "register_operand" "")
9596         (zero_extend:DI
9597           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9598                      (match_operand:QI 2 "const_int_operand" ""))))
9599    (clobber (reg:CC FLAGS_REG))]
9600   "TARGET_64BIT && reload_completed
9601    && true_regnum (operands[0]) != true_regnum (operands[1])"
9602   [(set (match_dup 0)
9603         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9604 {
9605   operands[1] = gen_lowpart (DImode, operands[1]);
9606   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9607 })
9608
9609 ;; This pattern can't accept a variable shift count, since shifts by
9610 ;; zero don't affect the flags.  We assume that shifts by constant
9611 ;; zero are optimized away.
9612 (define_insn "*ashl<mode>3_cmp"
9613   [(set (reg FLAGS_REG)
9614         (compare
9615           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9616                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9617           (const_int 0)))
9618    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9619         (ashift:SWI (match_dup 1) (match_dup 2)))]
9620   "(optimize_function_for_size_p (cfun)
9621     || !TARGET_PARTIAL_FLAG_REG_STALL
9622     || (operands[2] == const1_rtx
9623         && (TARGET_SHIFT1
9624             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9625    && ix86_match_ccmode (insn, CCGOCmode)
9626    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9627 {
9628   switch (get_attr_type (insn))
9629     {
9630     case TYPE_ALU:
9631       gcc_assert (operands[2] == const1_rtx);
9632       return "add{<imodesuffix>}\t%0, %0";
9633
9634     default:
9635       if (operands[2] == const1_rtx
9636           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9637         return "sal{<imodesuffix>}\t%0";
9638       else
9639         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9640     }
9641 }
9642   [(set (attr "type")
9643      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9644                           (const_int 0))
9645                       (match_operand 0 "register_operand" ""))
9646                  (match_operand 2 "const1_operand" ""))
9647               (const_string "alu")
9648            ]
9649            (const_string "ishift")))
9650    (set (attr "length_immediate")
9651      (if_then_else
9652        (ior (eq_attr "type" "alu")
9653             (and (eq_attr "type" "ishift")
9654                  (and (match_operand 2 "const1_operand" "")
9655                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9656                           (const_int 0)))))
9657        (const_string "0")
9658        (const_string "*")))
9659    (set_attr "mode" "<MODE>")])
9660
9661 (define_insn "*ashlsi3_cmp_zext"
9662   [(set (reg FLAGS_REG)
9663         (compare
9664           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9665                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9666           (const_int 0)))
9667    (set (match_operand:DI 0 "register_operand" "=r")
9668         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9669   "TARGET_64BIT
9670    && (optimize_function_for_size_p (cfun)
9671        || !TARGET_PARTIAL_FLAG_REG_STALL
9672        || (operands[2] == const1_rtx
9673            && (TARGET_SHIFT1
9674                || TARGET_DOUBLE_WITH_ADD)))
9675    && ix86_match_ccmode (insn, CCGOCmode)
9676    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9677 {
9678   switch (get_attr_type (insn))
9679     {
9680     case TYPE_ALU:
9681       gcc_assert (operands[2] == const1_rtx);
9682       return "add{l}\t%k0, %k0";
9683
9684     default:
9685       if (operands[2] == const1_rtx
9686           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9687         return "sal{l}\t%k0";
9688       else
9689         return "sal{l}\t{%2, %k0|%k0, %2}";
9690     }
9691 }
9692   [(set (attr "type")
9693      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9694                      (const_int 0))
9695                  (match_operand 2 "const1_operand" ""))
9696               (const_string "alu")
9697            ]
9698            (const_string "ishift")))
9699    (set (attr "length_immediate")
9700      (if_then_else
9701        (ior (eq_attr "type" "alu")
9702             (and (eq_attr "type" "ishift")
9703                  (and (match_operand 2 "const1_operand" "")
9704                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9705                           (const_int 0)))))
9706        (const_string "0")
9707        (const_string "*")))
9708    (set_attr "mode" "SI")])
9709
9710 (define_insn "*ashl<mode>3_cconly"
9711   [(set (reg FLAGS_REG)
9712         (compare
9713           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9714                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9715           (const_int 0)))
9716    (clobber (match_scratch:SWI 0 "=<r>"))]
9717   "(optimize_function_for_size_p (cfun)
9718     || !TARGET_PARTIAL_FLAG_REG_STALL
9719     || (operands[2] == const1_rtx
9720         && (TARGET_SHIFT1
9721             || TARGET_DOUBLE_WITH_ADD)))
9722    && ix86_match_ccmode (insn, CCGOCmode)
9723    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9724 {
9725   switch (get_attr_type (insn))
9726     {
9727     case TYPE_ALU:
9728       gcc_assert (operands[2] == const1_rtx);
9729       return "add{<imodesuffix>}\t%0, %0";
9730
9731     default:
9732       if (operands[2] == const1_rtx
9733           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9734         return "sal{<imodesuffix>}\t%0";
9735       else
9736         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9737     }
9738 }
9739   [(set (attr "type")
9740      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9741                           (const_int 0))
9742                       (match_operand 0 "register_operand" ""))
9743                  (match_operand 2 "const1_operand" ""))
9744               (const_string "alu")
9745            ]
9746            (const_string "ishift")))
9747    (set (attr "length_immediate")
9748      (if_then_else
9749        (ior (eq_attr "type" "alu")
9750             (and (eq_attr "type" "ishift")
9751                  (and (match_operand 2 "const1_operand" "")
9752                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9753                           (const_int 0)))))
9754        (const_string "0")
9755        (const_string "*")))
9756    (set_attr "mode" "<MODE>")])
9757
9758 ;; See comment above `ashl<mode>3' about how this works.
9759
9760 (define_expand "<shiftrt_insn><mode>3"
9761   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9762         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9763                            (match_operand:QI 2 "nonmemory_operand" "")))]
9764   ""
9765   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9766
9767 ;; Avoid useless masking of count operand.
9768 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9769   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9770         (any_shiftrt:SWI48
9771           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9772           (subreg:QI
9773             (and:SI
9774               (match_operand:SI 2 "nonimmediate_operand" "c")
9775               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9776    (clobber (reg:CC FLAGS_REG))]
9777   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9778    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9779       == GET_MODE_BITSIZE (<MODE>mode)-1"
9780   "#"
9781   "&& 1"
9782   [(parallel [(set (match_dup 0)
9783                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9784               (clobber (reg:CC FLAGS_REG))])]
9785 {
9786   if (can_create_pseudo_p ())
9787     operands [2] = force_reg (SImode, operands[2]);
9788
9789   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9790 }
9791   [(set_attr "type" "ishift")
9792    (set_attr "mode" "<MODE>")])
9793
9794 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9795   [(set (match_operand:DWI 0 "register_operand" "=r")
9796         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9797                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9798    (clobber (reg:CC FLAGS_REG))]
9799   ""
9800   "#"
9801   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9802   [(const_int 0)]
9803   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9804   [(set_attr "type" "multi")])
9805
9806 ;; By default we don't ask for a scratch register, because when DWImode
9807 ;; values are manipulated, registers are already at a premium.  But if
9808 ;; we have one handy, we won't turn it away.
9809
9810 (define_peephole2
9811   [(match_scratch:DWIH 3 "r")
9812    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9813                    (any_shiftrt:<DWI>
9814                      (match_operand:<DWI> 1 "register_operand" "")
9815                      (match_operand:QI 2 "nonmemory_operand" "")))
9816               (clobber (reg:CC FLAGS_REG))])
9817    (match_dup 3)]
9818   "TARGET_CMOVE"
9819   [(const_int 0)]
9820   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9821
9822 (define_insn "x86_64_shrd"
9823   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9824         (ior:DI (ashiftrt:DI (match_dup 0)
9825                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9826                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9827                   (minus:QI (const_int 64) (match_dup 2)))))
9828    (clobber (reg:CC FLAGS_REG))]
9829   "TARGET_64BIT"
9830   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9831   [(set_attr "type" "ishift")
9832    (set_attr "prefix_0f" "1")
9833    (set_attr "mode" "DI")
9834    (set_attr "athlon_decode" "vector")
9835    (set_attr "amdfam10_decode" "vector")
9836    (set_attr "bdver1_decode" "vector")])
9837
9838 (define_insn "x86_shrd"
9839   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9840         (ior:SI (ashiftrt:SI (match_dup 0)
9841                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9842                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9843                   (minus:QI (const_int 32) (match_dup 2)))))
9844    (clobber (reg:CC FLAGS_REG))]
9845   ""
9846   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9847   [(set_attr "type" "ishift")
9848    (set_attr "prefix_0f" "1")
9849    (set_attr "mode" "SI")
9850    (set_attr "pent_pair" "np")
9851    (set_attr "athlon_decode" "vector")
9852    (set_attr "amdfam10_decode" "vector")
9853    (set_attr "bdver1_decode" "vector")])
9854
9855 (define_insn "ashrdi3_cvt"
9856   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9857         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9858                      (match_operand:QI 2 "const_int_operand" "")))
9859    (clobber (reg:CC FLAGS_REG))]
9860   "TARGET_64BIT && INTVAL (operands[2]) == 63
9861    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9862    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9863   "@
9864    {cqto|cqo}
9865    sar{q}\t{%2, %0|%0, %2}"
9866   [(set_attr "type" "imovx,ishift")
9867    (set_attr "prefix_0f" "0,*")
9868    (set_attr "length_immediate" "0,*")
9869    (set_attr "modrm" "0,1")
9870    (set_attr "mode" "DI")])
9871
9872 (define_insn "ashrsi3_cvt"
9873   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9874         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9875                      (match_operand:QI 2 "const_int_operand" "")))
9876    (clobber (reg:CC FLAGS_REG))]
9877   "INTVAL (operands[2]) == 31
9878    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9879    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9880   "@
9881    {cltd|cdq}
9882    sar{l}\t{%2, %0|%0, %2}"
9883   [(set_attr "type" "imovx,ishift")
9884    (set_attr "prefix_0f" "0,*")
9885    (set_attr "length_immediate" "0,*")
9886    (set_attr "modrm" "0,1")
9887    (set_attr "mode" "SI")])
9888
9889 (define_insn "*ashrsi3_cvt_zext"
9890   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9891         (zero_extend:DI
9892           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9893                        (match_operand:QI 2 "const_int_operand" ""))))
9894    (clobber (reg:CC FLAGS_REG))]
9895   "TARGET_64BIT && INTVAL (operands[2]) == 31
9896    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9897    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9898   "@
9899    {cltd|cdq}
9900    sar{l}\t{%2, %k0|%k0, %2}"
9901   [(set_attr "type" "imovx,ishift")
9902    (set_attr "prefix_0f" "0,*")
9903    (set_attr "length_immediate" "0,*")
9904    (set_attr "modrm" "0,1")
9905    (set_attr "mode" "SI")])
9906
9907 (define_expand "x86_shift<mode>_adj_3"
9908   [(use (match_operand:SWI48 0 "register_operand" ""))
9909    (use (match_operand:SWI48 1 "register_operand" ""))
9910    (use (match_operand:QI 2 "register_operand" ""))]
9911   ""
9912 {
9913   rtx label = gen_label_rtx ();
9914   rtx tmp;
9915
9916   emit_insn (gen_testqi_ccz_1 (operands[2],
9917                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9918
9919   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9920   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9921   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9922                               gen_rtx_LABEL_REF (VOIDmode, label),
9923                               pc_rtx);
9924   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9925   JUMP_LABEL (tmp) = label;
9926
9927   emit_move_insn (operands[0], operands[1]);
9928   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9929                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9930   emit_label (label);
9931   LABEL_NUSES (label) = 1;
9932
9933   DONE;
9934 })
9935
9936 (define_insn "*<shiftrt_insn><mode>3_1"
9937   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9938         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9939                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9940    (clobber (reg:CC FLAGS_REG))]
9941   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9942 {
9943   if (operands[2] == const1_rtx
9944       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9945     return "<shiftrt>{<imodesuffix>}\t%0";
9946   else
9947     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9948 }
9949   [(set_attr "type" "ishift")
9950    (set (attr "length_immediate")
9951      (if_then_else
9952        (and (match_operand 2 "const1_operand" "")
9953             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9954                 (const_int 0)))
9955        (const_string "0")
9956        (const_string "*")))
9957    (set_attr "mode" "<MODE>")])
9958
9959 (define_insn "*<shiftrt_insn>si3_1_zext"
9960   [(set (match_operand:DI 0 "register_operand" "=r")
9961         (zero_extend:DI
9962           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9963                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9964    (clobber (reg:CC FLAGS_REG))]
9965   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9966 {
9967   if (operands[2] == const1_rtx
9968       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9969     return "<shiftrt>{l}\t%k0";
9970   else
9971     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9972 }
9973   [(set_attr "type" "ishift")
9974    (set (attr "length_immediate")
9975      (if_then_else
9976        (and (match_operand 2 "const1_operand" "")
9977             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9978                 (const_int 0)))
9979        (const_string "0")
9980        (const_string "*")))
9981    (set_attr "mode" "SI")])
9982
9983 (define_insn "*<shiftrt_insn>qi3_1_slp"
9984   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9985         (any_shiftrt:QI (match_dup 0)
9986                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9987    (clobber (reg:CC FLAGS_REG))]
9988   "(optimize_function_for_size_p (cfun)
9989     || !TARGET_PARTIAL_REG_STALL
9990     || (operands[1] == const1_rtx
9991         && TARGET_SHIFT1))"
9992 {
9993   if (operands[1] == const1_rtx
9994       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9995     return "<shiftrt>{b}\t%0";
9996   else
9997     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9998 }
9999   [(set_attr "type" "ishift1")
10000    (set (attr "length_immediate")
10001      (if_then_else
10002        (and (match_operand 1 "const1_operand" "")
10003             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10004                 (const_int 0)))
10005        (const_string "0")
10006        (const_string "*")))
10007    (set_attr "mode" "QI")])
10008
10009 ;; This pattern can't accept a variable shift count, since shifts by
10010 ;; zero don't affect the flags.  We assume that shifts by constant
10011 ;; zero are optimized away.
10012 (define_insn "*<shiftrt_insn><mode>3_cmp"
10013   [(set (reg FLAGS_REG)
10014         (compare
10015           (any_shiftrt:SWI
10016             (match_operand:SWI 1 "nonimmediate_operand" "0")
10017             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10018           (const_int 0)))
10019    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10020         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10021   "(optimize_function_for_size_p (cfun)
10022     || !TARGET_PARTIAL_FLAG_REG_STALL
10023     || (operands[2] == const1_rtx
10024         && TARGET_SHIFT1))
10025    && ix86_match_ccmode (insn, CCGOCmode)
10026    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10027 {
10028   if (operands[2] == const1_rtx
10029       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10030     return "<shiftrt>{<imodesuffix>}\t%0";
10031   else
10032     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10033 }
10034   [(set_attr "type" "ishift")
10035    (set (attr "length_immediate")
10036      (if_then_else
10037        (and (match_operand 2 "const1_operand" "")
10038             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10039                 (const_int 0)))
10040        (const_string "0")
10041        (const_string "*")))
10042    (set_attr "mode" "<MODE>")])
10043
10044 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10045   [(set (reg FLAGS_REG)
10046         (compare
10047           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10048                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10049           (const_int 0)))
10050    (set (match_operand:DI 0 "register_operand" "=r")
10051         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10052   "TARGET_64BIT
10053    && (optimize_function_for_size_p (cfun)
10054        || !TARGET_PARTIAL_FLAG_REG_STALL
10055        || (operands[2] == const1_rtx
10056            && TARGET_SHIFT1))
10057    && ix86_match_ccmode (insn, CCGOCmode)
10058    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10059 {
10060   if (operands[2] == const1_rtx
10061       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10062     return "<shiftrt>{l}\t%k0";
10063   else
10064     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10065 }
10066   [(set_attr "type" "ishift")
10067    (set (attr "length_immediate")
10068      (if_then_else
10069        (and (match_operand 2 "const1_operand" "")
10070             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10071                 (const_int 0)))
10072        (const_string "0")
10073        (const_string "*")))
10074    (set_attr "mode" "SI")])
10075
10076 (define_insn "*<shiftrt_insn><mode>3_cconly"
10077   [(set (reg FLAGS_REG)
10078         (compare
10079           (any_shiftrt:SWI
10080             (match_operand:SWI 1 "nonimmediate_operand" "0")
10081             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10082           (const_int 0)))
10083    (clobber (match_scratch:SWI 0 "=<r>"))]
10084   "(optimize_function_for_size_p (cfun)
10085     || !TARGET_PARTIAL_FLAG_REG_STALL
10086     || (operands[2] == const1_rtx
10087         && TARGET_SHIFT1))
10088    && ix86_match_ccmode (insn, CCGOCmode)
10089    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10090 {
10091   if (operands[2] == const1_rtx
10092       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10093     return "<shiftrt>{<imodesuffix>}\t%0";
10094   else
10095     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10096 }
10097   [(set_attr "type" "ishift")
10098    (set (attr "length_immediate")
10099      (if_then_else
10100        (and (match_operand 2 "const1_operand" "")
10101             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10102                 (const_int 0)))
10103        (const_string "0")
10104        (const_string "*")))
10105    (set_attr "mode" "<MODE>")])
10106 \f
10107 ;; Rotate instructions
10108
10109 (define_expand "<rotate_insn>ti3"
10110   [(set (match_operand:TI 0 "register_operand" "")
10111         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10112                        (match_operand:QI 2 "nonmemory_operand" "")))]
10113   "TARGET_64BIT"
10114 {
10115   if (const_1_to_63_operand (operands[2], VOIDmode))
10116     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10117                 (operands[0], operands[1], operands[2]));
10118   else
10119     FAIL;
10120
10121   DONE;
10122 })
10123
10124 (define_expand "<rotate_insn>di3"
10125   [(set (match_operand:DI 0 "shiftdi_operand" "")
10126         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10127                        (match_operand:QI 2 "nonmemory_operand" "")))]
10128  ""
10129 {
10130   if (TARGET_64BIT)
10131     ix86_expand_binary_operator (<CODE>, DImode, operands);
10132   else if (const_1_to_31_operand (operands[2], VOIDmode))
10133     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10134                 (operands[0], operands[1], operands[2]));
10135   else
10136     FAIL;
10137
10138   DONE;
10139 })
10140
10141 (define_expand "<rotate_insn><mode>3"
10142   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10143         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10144                             (match_operand:QI 2 "nonmemory_operand" "")))]
10145   ""
10146   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10147
10148 ;; Avoid useless masking of count operand.
10149 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10150   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10151         (any_rotate:SWI48
10152           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10153           (subreg:QI
10154             (and:SI
10155               (match_operand:SI 2 "nonimmediate_operand" "c")
10156               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10157    (clobber (reg:CC FLAGS_REG))]
10158   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10159    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10160       == GET_MODE_BITSIZE (<MODE>mode)-1"
10161   "#"
10162   "&& 1"
10163   [(parallel [(set (match_dup 0)
10164                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10165               (clobber (reg:CC FLAGS_REG))])]
10166 {
10167   if (can_create_pseudo_p ())
10168     operands [2] = force_reg (SImode, operands[2]);
10169
10170   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10171 }
10172   [(set_attr "type" "rotate")
10173    (set_attr "mode" "<MODE>")])
10174
10175 ;; Implement rotation using two double-precision
10176 ;; shift instructions and a scratch register.
10177
10178 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10179  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10180        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10181                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10182   (clobber (reg:CC FLAGS_REG))
10183   (clobber (match_scratch:DWIH 3 "=&r"))]
10184  ""
10185  "#"
10186  "reload_completed"
10187  [(set (match_dup 3) (match_dup 4))
10188   (parallel
10189    [(set (match_dup 4)
10190          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10191                    (lshiftrt:DWIH (match_dup 5)
10192                                   (minus:QI (match_dup 6) (match_dup 2)))))
10193     (clobber (reg:CC FLAGS_REG))])
10194   (parallel
10195    [(set (match_dup 5)
10196          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10197                    (lshiftrt:DWIH (match_dup 3)
10198                                   (minus:QI (match_dup 6) (match_dup 2)))))
10199     (clobber (reg:CC FLAGS_REG))])]
10200 {
10201   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10202
10203   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10204 })
10205
10206 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10207  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10208        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10209                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10210   (clobber (reg:CC FLAGS_REG))
10211   (clobber (match_scratch:DWIH 3 "=&r"))]
10212  ""
10213  "#"
10214  "reload_completed"
10215  [(set (match_dup 3) (match_dup 4))
10216   (parallel
10217    [(set (match_dup 4)
10218          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10219                    (ashift:DWIH (match_dup 5)
10220                                 (minus:QI (match_dup 6) (match_dup 2)))))
10221     (clobber (reg:CC FLAGS_REG))])
10222   (parallel
10223    [(set (match_dup 5)
10224          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10225                    (ashift:DWIH (match_dup 3)
10226                                 (minus:QI (match_dup 6) (match_dup 2)))))
10227     (clobber (reg:CC FLAGS_REG))])]
10228 {
10229   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10230
10231   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10232 })
10233
10234 (define_insn "*<rotate_insn><mode>3_1"
10235   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10236         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10237                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10238    (clobber (reg:CC FLAGS_REG))]
10239   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10240 {
10241   if (operands[2] == const1_rtx
10242       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10243     return "<rotate>{<imodesuffix>}\t%0";
10244   else
10245     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10246 }
10247   [(set_attr "type" "rotate")
10248    (set (attr "length_immediate")
10249      (if_then_else
10250        (and (match_operand 2 "const1_operand" "")
10251             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10252                 (const_int 0)))
10253        (const_string "0")
10254        (const_string "*")))
10255    (set_attr "mode" "<MODE>")])
10256
10257 (define_insn "*<rotate_insn>si3_1_zext"
10258   [(set (match_operand:DI 0 "register_operand" "=r")
10259         (zero_extend:DI
10260           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10261                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10262    (clobber (reg:CC FLAGS_REG))]
10263   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10264 {
10265     if (operands[2] == const1_rtx
10266         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10267     return "<rotate>{l}\t%k0";
10268   else
10269     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10270 }
10271   [(set_attr "type" "rotate")
10272    (set (attr "length_immediate")
10273      (if_then_else
10274        (and (match_operand 2 "const1_operand" "")
10275             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10276                 (const_int 0)))
10277        (const_string "0")
10278        (const_string "*")))
10279    (set_attr "mode" "SI")])
10280
10281 (define_insn "*<rotate_insn>qi3_1_slp"
10282   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10283         (any_rotate:QI (match_dup 0)
10284                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10285    (clobber (reg:CC FLAGS_REG))]
10286   "(optimize_function_for_size_p (cfun)
10287     || !TARGET_PARTIAL_REG_STALL
10288     || (operands[1] == const1_rtx
10289         && TARGET_SHIFT1))"
10290 {
10291   if (operands[1] == const1_rtx
10292       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10293     return "<rotate>{b}\t%0";
10294   else
10295     return "<rotate>{b}\t{%1, %0|%0, %1}";
10296 }
10297   [(set_attr "type" "rotate1")
10298    (set (attr "length_immediate")
10299      (if_then_else
10300        (and (match_operand 1 "const1_operand" "")
10301             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10302                 (const_int 0)))
10303        (const_string "0")
10304        (const_string "*")))
10305    (set_attr "mode" "QI")])
10306
10307 (define_split
10308  [(set (match_operand:HI 0 "register_operand" "")
10309        (any_rotate:HI (match_dup 0) (const_int 8)))
10310   (clobber (reg:CC FLAGS_REG))]
10311  "reload_completed
10312   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10313  [(parallel [(set (strict_low_part (match_dup 0))
10314                   (bswap:HI (match_dup 0)))
10315              (clobber (reg:CC FLAGS_REG))])])
10316 \f
10317 ;; Bit set / bit test instructions
10318
10319 (define_expand "extv"
10320   [(set (match_operand:SI 0 "register_operand" "")
10321         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10322                          (match_operand:SI 2 "const8_operand" "")
10323                          (match_operand:SI 3 "const8_operand" "")))]
10324   ""
10325 {
10326   /* Handle extractions from %ah et al.  */
10327   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10328     FAIL;
10329
10330   /* From mips.md: extract_bit_field doesn't verify that our source
10331      matches the predicate, so check it again here.  */
10332   if (! ext_register_operand (operands[1], VOIDmode))
10333     FAIL;
10334 })
10335
10336 (define_expand "extzv"
10337   [(set (match_operand:SI 0 "register_operand" "")
10338         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10339                          (match_operand:SI 2 "const8_operand" "")
10340                          (match_operand:SI 3 "const8_operand" "")))]
10341   ""
10342 {
10343   /* Handle extractions from %ah et al.  */
10344   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10345     FAIL;
10346
10347   /* From mips.md: extract_bit_field doesn't verify that our source
10348      matches the predicate, so check it again here.  */
10349   if (! ext_register_operand (operands[1], VOIDmode))
10350     FAIL;
10351 })
10352
10353 (define_expand "insv"
10354   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10355                       (match_operand 1 "const8_operand" "")
10356                       (match_operand 2 "const8_operand" ""))
10357         (match_operand 3 "register_operand" ""))]
10358   ""
10359 {
10360   rtx (*gen_mov_insv_1) (rtx, rtx);
10361
10362   /* Handle insertions to %ah et al.  */
10363   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10364     FAIL;
10365
10366   /* From mips.md: insert_bit_field doesn't verify that our source
10367      matches the predicate, so check it again here.  */
10368   if (! ext_register_operand (operands[0], VOIDmode))
10369     FAIL;
10370
10371   gen_mov_insv_1 = (TARGET_64BIT
10372                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10373
10374   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10375   DONE;
10376 })
10377
10378 ;; %%% bts, btr, btc, bt.
10379 ;; In general these instructions are *slow* when applied to memory,
10380 ;; since they enforce atomic operation.  When applied to registers,
10381 ;; it depends on the cpu implementation.  They're never faster than
10382 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10383 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10384 ;; within the instruction itself, so operating on bits in the high
10385 ;; 32-bits of a register becomes easier.
10386 ;;
10387 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10388 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10389 ;; negdf respectively, so they can never be disabled entirely.
10390
10391 (define_insn "*btsq"
10392   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10393                          (const_int 1)
10394                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10395         (const_int 1))
10396    (clobber (reg:CC FLAGS_REG))]
10397   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10398   "bts{q}\t{%1, %0|%0, %1}"
10399   [(set_attr "type" "alu1")
10400    (set_attr "prefix_0f" "1")
10401    (set_attr "mode" "DI")])
10402
10403 (define_insn "*btrq"
10404   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10405                          (const_int 1)
10406                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10407         (const_int 0))
10408    (clobber (reg:CC FLAGS_REG))]
10409   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10410   "btr{q}\t{%1, %0|%0, %1}"
10411   [(set_attr "type" "alu1")
10412    (set_attr "prefix_0f" "1")
10413    (set_attr "mode" "DI")])
10414
10415 (define_insn "*btcq"
10416   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10417                          (const_int 1)
10418                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10419         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10420    (clobber (reg:CC FLAGS_REG))]
10421   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10422   "btc{q}\t{%1, %0|%0, %1}"
10423   [(set_attr "type" "alu1")
10424    (set_attr "prefix_0f" "1")
10425    (set_attr "mode" "DI")])
10426
10427 ;; Allow Nocona to avoid these instructions if a register is available.
10428
10429 (define_peephole2
10430   [(match_scratch:DI 2 "r")
10431    (parallel [(set (zero_extract:DI
10432                      (match_operand:DI 0 "register_operand" "")
10433                      (const_int 1)
10434                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10435                    (const_int 1))
10436               (clobber (reg:CC FLAGS_REG))])]
10437   "TARGET_64BIT && !TARGET_USE_BT"
10438   [(const_int 0)]
10439 {
10440   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10441   rtx op1;
10442
10443   if (HOST_BITS_PER_WIDE_INT >= 64)
10444     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10445   else if (i < HOST_BITS_PER_WIDE_INT)
10446     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10447   else
10448     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10449
10450   op1 = immed_double_const (lo, hi, DImode);
10451   if (i >= 31)
10452     {
10453       emit_move_insn (operands[2], op1);
10454       op1 = operands[2];
10455     }
10456
10457   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10458   DONE;
10459 })
10460
10461 (define_peephole2
10462   [(match_scratch:DI 2 "r")
10463    (parallel [(set (zero_extract:DI
10464                      (match_operand:DI 0 "register_operand" "")
10465                      (const_int 1)
10466                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10467                    (const_int 0))
10468               (clobber (reg:CC FLAGS_REG))])]
10469   "TARGET_64BIT && !TARGET_USE_BT"
10470   [(const_int 0)]
10471 {
10472   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10473   rtx op1;
10474
10475   if (HOST_BITS_PER_WIDE_INT >= 64)
10476     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10477   else if (i < HOST_BITS_PER_WIDE_INT)
10478     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10479   else
10480     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10481
10482   op1 = immed_double_const (~lo, ~hi, DImode);
10483   if (i >= 32)
10484     {
10485       emit_move_insn (operands[2], op1);
10486       op1 = operands[2];
10487     }
10488
10489   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10490   DONE;
10491 })
10492
10493 (define_peephole2
10494   [(match_scratch:DI 2 "r")
10495    (parallel [(set (zero_extract:DI
10496                      (match_operand:DI 0 "register_operand" "")
10497                      (const_int 1)
10498                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10499               (not:DI (zero_extract:DI
10500                         (match_dup 0) (const_int 1) (match_dup 1))))
10501               (clobber (reg:CC FLAGS_REG))])]
10502   "TARGET_64BIT && !TARGET_USE_BT"
10503   [(const_int 0)]
10504 {
10505   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10506   rtx op1;
10507
10508   if (HOST_BITS_PER_WIDE_INT >= 64)
10509     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10510   else if (i < HOST_BITS_PER_WIDE_INT)
10511     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10512   else
10513     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10514
10515   op1 = immed_double_const (lo, hi, DImode);
10516   if (i >= 31)
10517     {
10518       emit_move_insn (operands[2], op1);
10519       op1 = operands[2];
10520     }
10521
10522   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10523   DONE;
10524 })
10525
10526 (define_insn "*bt<mode>"
10527   [(set (reg:CCC FLAGS_REG)
10528         (compare:CCC
10529           (zero_extract:SWI48
10530             (match_operand:SWI48 0 "register_operand" "r")
10531             (const_int 1)
10532             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10533           (const_int 0)))]
10534   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10535   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10536   [(set_attr "type" "alu1")
10537    (set_attr "prefix_0f" "1")
10538    (set_attr "mode" "<MODE>")])
10539 \f
10540 ;; Store-flag instructions.
10541
10542 ;; For all sCOND expanders, also expand the compare or test insn that
10543 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10544
10545 (define_insn_and_split "*setcc_di_1"
10546   [(set (match_operand:DI 0 "register_operand" "=q")
10547         (match_operator:DI 1 "ix86_comparison_operator"
10548           [(reg FLAGS_REG) (const_int 0)]))]
10549   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10550   "#"
10551   "&& reload_completed"
10552   [(set (match_dup 2) (match_dup 1))
10553    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10554 {
10555   PUT_MODE (operands[1], QImode);
10556   operands[2] = gen_lowpart (QImode, operands[0]);
10557 })
10558
10559 (define_insn_and_split "*setcc_si_1_and"
10560   [(set (match_operand:SI 0 "register_operand" "=q")
10561         (match_operator:SI 1 "ix86_comparison_operator"
10562           [(reg FLAGS_REG) (const_int 0)]))
10563    (clobber (reg:CC FLAGS_REG))]
10564   "!TARGET_PARTIAL_REG_STALL
10565    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10566   "#"
10567   "&& reload_completed"
10568   [(set (match_dup 2) (match_dup 1))
10569    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10570               (clobber (reg:CC FLAGS_REG))])]
10571 {
10572   PUT_MODE (operands[1], QImode);
10573   operands[2] = gen_lowpart (QImode, operands[0]);
10574 })
10575
10576 (define_insn_and_split "*setcc_si_1_movzbl"
10577   [(set (match_operand:SI 0 "register_operand" "=q")
10578         (match_operator:SI 1 "ix86_comparison_operator"
10579           [(reg FLAGS_REG) (const_int 0)]))]
10580   "!TARGET_PARTIAL_REG_STALL
10581    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10582   "#"
10583   "&& reload_completed"
10584   [(set (match_dup 2) (match_dup 1))
10585    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10586 {
10587   PUT_MODE (operands[1], QImode);
10588   operands[2] = gen_lowpart (QImode, operands[0]);
10589 })
10590
10591 (define_insn "*setcc_qi"
10592   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10593         (match_operator:QI 1 "ix86_comparison_operator"
10594           [(reg FLAGS_REG) (const_int 0)]))]
10595   ""
10596   "set%C1\t%0"
10597   [(set_attr "type" "setcc")
10598    (set_attr "mode" "QI")])
10599
10600 (define_insn "*setcc_qi_slp"
10601   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10602         (match_operator:QI 1 "ix86_comparison_operator"
10603           [(reg FLAGS_REG) (const_int 0)]))]
10604   ""
10605   "set%C1\t%0"
10606   [(set_attr "type" "setcc")
10607    (set_attr "mode" "QI")])
10608
10609 ;; In general it is not safe to assume too much about CCmode registers,
10610 ;; so simplify-rtx stops when it sees a second one.  Under certain
10611 ;; conditions this is safe on x86, so help combine not create
10612 ;;
10613 ;;      seta    %al
10614 ;;      testb   %al, %al
10615 ;;      sete    %al
10616
10617 (define_split
10618   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10619         (ne:QI (match_operator 1 "ix86_comparison_operator"
10620                  [(reg FLAGS_REG) (const_int 0)])
10621             (const_int 0)))]
10622   ""
10623   [(set (match_dup 0) (match_dup 1))]
10624   "PUT_MODE (operands[1], QImode);")
10625
10626 (define_split
10627   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10628         (ne:QI (match_operator 1 "ix86_comparison_operator"
10629                  [(reg FLAGS_REG) (const_int 0)])
10630             (const_int 0)))]
10631   ""
10632   [(set (match_dup 0) (match_dup 1))]
10633   "PUT_MODE (operands[1], QImode);")
10634
10635 (define_split
10636   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10637         (eq:QI (match_operator 1 "ix86_comparison_operator"
10638                  [(reg FLAGS_REG) (const_int 0)])
10639             (const_int 0)))]
10640   ""
10641   [(set (match_dup 0) (match_dup 1))]
10642 {
10643   rtx new_op1 = copy_rtx (operands[1]);
10644   operands[1] = new_op1;
10645   PUT_MODE (new_op1, QImode);
10646   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10647                                              GET_MODE (XEXP (new_op1, 0))));
10648
10649   /* Make sure that (a) the CCmode we have for the flags is strong
10650      enough for the reversed compare or (b) we have a valid FP compare.  */
10651   if (! ix86_comparison_operator (new_op1, VOIDmode))
10652     FAIL;
10653 })
10654
10655 (define_split
10656   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10657         (eq:QI (match_operator 1 "ix86_comparison_operator"
10658                  [(reg FLAGS_REG) (const_int 0)])
10659             (const_int 0)))]
10660   ""
10661   [(set (match_dup 0) (match_dup 1))]
10662 {
10663   rtx new_op1 = copy_rtx (operands[1]);
10664   operands[1] = new_op1;
10665   PUT_MODE (new_op1, QImode);
10666   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10667                                              GET_MODE (XEXP (new_op1, 0))));
10668
10669   /* Make sure that (a) the CCmode we have for the flags is strong
10670      enough for the reversed compare or (b) we have a valid FP compare.  */
10671   if (! ix86_comparison_operator (new_op1, VOIDmode))
10672     FAIL;
10673 })
10674
10675 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10676 ;; subsequent logical operations are used to imitate conditional moves.
10677 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10678 ;; it directly.
10679
10680 (define_insn "*avx_setcc<mode>"
10681   [(set (match_operand:MODEF 0 "register_operand" "=x")
10682         (match_operator:MODEF 1 "avx_comparison_float_operator"
10683           [(match_operand:MODEF 2 "register_operand" "x")
10684            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10685   "TARGET_AVX"
10686   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10687   [(set_attr "type" "ssecmp")
10688    (set_attr "prefix" "vex")
10689    (set_attr "length_immediate" "1")
10690    (set_attr "mode" "<MODE>")])
10691
10692 (define_insn "*sse_setcc<mode>"
10693   [(set (match_operand:MODEF 0 "register_operand" "=x")
10694         (match_operator:MODEF 1 "sse_comparison_operator"
10695           [(match_operand:MODEF 2 "register_operand" "0")
10696            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10697   "SSE_FLOAT_MODE_P (<MODE>mode)"
10698   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10699   [(set_attr "type" "ssecmp")
10700    (set_attr "length_immediate" "1")
10701    (set_attr "mode" "<MODE>")])
10702 \f
10703 ;; Basic conditional jump instructions.
10704 ;; We ignore the overflow flag for signed branch instructions.
10705
10706 (define_insn "*jcc_1"
10707   [(set (pc)
10708         (if_then_else (match_operator 1 "ix86_comparison_operator"
10709                                       [(reg FLAGS_REG) (const_int 0)])
10710                       (label_ref (match_operand 0 "" ""))
10711                       (pc)))]
10712   ""
10713   "%+j%C1\t%l0"
10714   [(set_attr "type" "ibr")
10715    (set_attr "modrm" "0")
10716    (set (attr "length")
10717            (if_then_else (and (ge (minus (match_dup 0) (pc))
10718                                   (const_int -126))
10719                               (lt (minus (match_dup 0) (pc))
10720                                   (const_int 128)))
10721              (const_int 2)
10722              (const_int 6)))])
10723
10724 (define_insn "*jcc_2"
10725   [(set (pc)
10726         (if_then_else (match_operator 1 "ix86_comparison_operator"
10727                                       [(reg FLAGS_REG) (const_int 0)])
10728                       (pc)
10729                       (label_ref (match_operand 0 "" ""))))]
10730   ""
10731   "%+j%c1\t%l0"
10732   [(set_attr "type" "ibr")
10733    (set_attr "modrm" "0")
10734    (set (attr "length")
10735            (if_then_else (and (ge (minus (match_dup 0) (pc))
10736                                   (const_int -126))
10737                               (lt (minus (match_dup 0) (pc))
10738                                   (const_int 128)))
10739              (const_int 2)
10740              (const_int 6)))])
10741
10742 ;; In general it is not safe to assume too much about CCmode registers,
10743 ;; so simplify-rtx stops when it sees a second one.  Under certain
10744 ;; conditions this is safe on x86, so help combine not create
10745 ;;
10746 ;;      seta    %al
10747 ;;      testb   %al, %al
10748 ;;      je      Lfoo
10749
10750 (define_split
10751   [(set (pc)
10752         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10753                                       [(reg FLAGS_REG) (const_int 0)])
10754                           (const_int 0))
10755                       (label_ref (match_operand 1 "" ""))
10756                       (pc)))]
10757   ""
10758   [(set (pc)
10759         (if_then_else (match_dup 0)
10760                       (label_ref (match_dup 1))
10761                       (pc)))]
10762   "PUT_MODE (operands[0], VOIDmode);")
10763
10764 (define_split
10765   [(set (pc)
10766         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10767                                       [(reg FLAGS_REG) (const_int 0)])
10768                           (const_int 0))
10769                       (label_ref (match_operand 1 "" ""))
10770                       (pc)))]
10771   ""
10772   [(set (pc)
10773         (if_then_else (match_dup 0)
10774                       (label_ref (match_dup 1))
10775                       (pc)))]
10776 {
10777   rtx new_op0 = copy_rtx (operands[0]);
10778   operands[0] = new_op0;
10779   PUT_MODE (new_op0, VOIDmode);
10780   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10781                                              GET_MODE (XEXP (new_op0, 0))));
10782
10783   /* Make sure that (a) the CCmode we have for the flags is strong
10784      enough for the reversed compare or (b) we have a valid FP compare.  */
10785   if (! ix86_comparison_operator (new_op0, VOIDmode))
10786     FAIL;
10787 })
10788
10789 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10790 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10791 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10792 ;; appropriate modulo of the bit offset value.
10793
10794 (define_insn_and_split "*jcc_bt<mode>"
10795   [(set (pc)
10796         (if_then_else (match_operator 0 "bt_comparison_operator"
10797                         [(zero_extract:SWI48
10798                            (match_operand:SWI48 1 "register_operand" "r")
10799                            (const_int 1)
10800                            (zero_extend:SI
10801                              (match_operand:QI 2 "register_operand" "r")))
10802                          (const_int 0)])
10803                       (label_ref (match_operand 3 "" ""))
10804                       (pc)))
10805    (clobber (reg:CC FLAGS_REG))]
10806   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10807   "#"
10808   "&& 1"
10809   [(set (reg:CCC FLAGS_REG)
10810         (compare:CCC
10811           (zero_extract:SWI48
10812             (match_dup 1)
10813             (const_int 1)
10814             (match_dup 2))
10815           (const_int 0)))
10816    (set (pc)
10817         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10818                       (label_ref (match_dup 3))
10819                       (pc)))]
10820 {
10821   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10822
10823   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10824 })
10825
10826 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10827 ;; also for DImode, this is what combine produces.
10828 (define_insn_and_split "*jcc_bt<mode>_mask"
10829   [(set (pc)
10830         (if_then_else (match_operator 0 "bt_comparison_operator"
10831                         [(zero_extract:SWI48
10832                            (match_operand:SWI48 1 "register_operand" "r")
10833                            (const_int 1)
10834                            (and:SI
10835                              (match_operand:SI 2 "register_operand" "r")
10836                              (match_operand:SI 3 "const_int_operand" "n")))])
10837                       (label_ref (match_operand 4 "" ""))
10838                       (pc)))
10839    (clobber (reg:CC FLAGS_REG))]
10840   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10841    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10842       == GET_MODE_BITSIZE (<MODE>mode)-1"
10843   "#"
10844   "&& 1"
10845   [(set (reg:CCC FLAGS_REG)
10846         (compare:CCC
10847           (zero_extract:SWI48
10848             (match_dup 1)
10849             (const_int 1)
10850             (match_dup 2))
10851           (const_int 0)))
10852    (set (pc)
10853         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10854                       (label_ref (match_dup 4))
10855                       (pc)))]
10856 {
10857   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10858
10859   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10860 })
10861
10862 (define_insn_and_split "*jcc_btsi_1"
10863   [(set (pc)
10864         (if_then_else (match_operator 0 "bt_comparison_operator"
10865                         [(and:SI
10866                            (lshiftrt:SI
10867                              (match_operand:SI 1 "register_operand" "r")
10868                              (match_operand:QI 2 "register_operand" "r"))
10869                            (const_int 1))
10870                          (const_int 0)])
10871                       (label_ref (match_operand 3 "" ""))
10872                       (pc)))
10873    (clobber (reg:CC FLAGS_REG))]
10874   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10875   "#"
10876   "&& 1"
10877   [(set (reg:CCC FLAGS_REG)
10878         (compare:CCC
10879           (zero_extract:SI
10880             (match_dup 1)
10881             (const_int 1)
10882             (match_dup 2))
10883           (const_int 0)))
10884    (set (pc)
10885         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10886                       (label_ref (match_dup 3))
10887                       (pc)))]
10888 {
10889   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10890
10891   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10892 })
10893
10894 ;; avoid useless masking of bit offset operand
10895 (define_insn_and_split "*jcc_btsi_mask_1"
10896   [(set (pc)
10897         (if_then_else
10898           (match_operator 0 "bt_comparison_operator"
10899             [(and:SI
10900                (lshiftrt:SI
10901                  (match_operand:SI 1 "register_operand" "r")
10902                  (subreg:QI
10903                    (and:SI
10904                      (match_operand:SI 2 "register_operand" "r")
10905                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10906                (const_int 1))
10907              (const_int 0)])
10908           (label_ref (match_operand 4 "" ""))
10909           (pc)))
10910    (clobber (reg:CC FLAGS_REG))]
10911   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10912    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10913   "#"
10914   "&& 1"
10915   [(set (reg:CCC FLAGS_REG)
10916         (compare:CCC
10917           (zero_extract:SI
10918             (match_dup 1)
10919             (const_int 1)
10920             (match_dup 2))
10921           (const_int 0)))
10922    (set (pc)
10923         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10924                       (label_ref (match_dup 4))
10925                       (pc)))]
10926   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10927
10928 ;; Define combination compare-and-branch fp compare instructions to help
10929 ;; combine.
10930
10931 (define_insn "*fp_jcc_1_387"
10932   [(set (pc)
10933         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10934                         [(match_operand 1 "register_operand" "f")
10935                          (match_operand 2 "nonimmediate_operand" "fm")])
10936           (label_ref (match_operand 3 "" ""))
10937           (pc)))
10938    (clobber (reg:CCFP FPSR_REG))
10939    (clobber (reg:CCFP FLAGS_REG))
10940    (clobber (match_scratch:HI 4 "=a"))]
10941   "TARGET_80387
10942    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10943    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10944    && SELECT_CC_MODE (GET_CODE (operands[0]),
10945                       operands[1], operands[2]) == CCFPmode
10946    && !TARGET_CMOVE"
10947   "#")
10948
10949 (define_insn "*fp_jcc_1r_387"
10950   [(set (pc)
10951         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10952                         [(match_operand 1 "register_operand" "f")
10953                          (match_operand 2 "nonimmediate_operand" "fm")])
10954           (pc)
10955           (label_ref (match_operand 3 "" ""))))
10956    (clobber (reg:CCFP FPSR_REG))
10957    (clobber (reg:CCFP FLAGS_REG))
10958    (clobber (match_scratch:HI 4 "=a"))]
10959   "TARGET_80387
10960    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10961    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10962    && SELECT_CC_MODE (GET_CODE (operands[0]),
10963                       operands[1], operands[2]) == CCFPmode
10964    && !TARGET_CMOVE"
10965   "#")
10966
10967 (define_insn "*fp_jcc_2_387"
10968   [(set (pc)
10969         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10970                         [(match_operand 1 "register_operand" "f")
10971                          (match_operand 2 "register_operand" "f")])
10972           (label_ref (match_operand 3 "" ""))
10973           (pc)))
10974    (clobber (reg:CCFP FPSR_REG))
10975    (clobber (reg:CCFP FLAGS_REG))
10976    (clobber (match_scratch:HI 4 "=a"))]
10977   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10978    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10979    && !TARGET_CMOVE"
10980   "#")
10981
10982 (define_insn "*fp_jcc_2r_387"
10983   [(set (pc)
10984         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10985                         [(match_operand 1 "register_operand" "f")
10986                          (match_operand 2 "register_operand" "f")])
10987           (pc)
10988           (label_ref (match_operand 3 "" ""))))
10989    (clobber (reg:CCFP FPSR_REG))
10990    (clobber (reg:CCFP FLAGS_REG))
10991    (clobber (match_scratch:HI 4 "=a"))]
10992   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10993    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10994    && !TARGET_CMOVE"
10995   "#")
10996
10997 (define_insn "*fp_jcc_3_387"
10998   [(set (pc)
10999         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11000                         [(match_operand 1 "register_operand" "f")
11001                          (match_operand 2 "const0_operand" "")])
11002           (label_ref (match_operand 3 "" ""))
11003           (pc)))
11004    (clobber (reg:CCFP FPSR_REG))
11005    (clobber (reg:CCFP FLAGS_REG))
11006    (clobber (match_scratch:HI 4 "=a"))]
11007   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11008    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11009    && SELECT_CC_MODE (GET_CODE (operands[0]),
11010                       operands[1], operands[2]) == CCFPmode
11011    && !TARGET_CMOVE"
11012   "#")
11013
11014 (define_split
11015   [(set (pc)
11016         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11017                         [(match_operand 1 "register_operand" "")
11018                          (match_operand 2 "nonimmediate_operand" "")])
11019           (match_operand 3 "" "")
11020           (match_operand 4 "" "")))
11021    (clobber (reg:CCFP FPSR_REG))
11022    (clobber (reg:CCFP FLAGS_REG))]
11023   "reload_completed"
11024   [(const_int 0)]
11025 {
11026   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11027                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11028   DONE;
11029 })
11030
11031 (define_split
11032   [(set (pc)
11033         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11034                         [(match_operand 1 "register_operand" "")
11035                          (match_operand 2 "general_operand" "")])
11036           (match_operand 3 "" "")
11037           (match_operand 4 "" "")))
11038    (clobber (reg:CCFP FPSR_REG))
11039    (clobber (reg:CCFP FLAGS_REG))
11040    (clobber (match_scratch:HI 5 "=a"))]
11041   "reload_completed"
11042   [(const_int 0)]
11043 {
11044   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11045                         operands[3], operands[4], operands[5], NULL_RTX);
11046   DONE;
11047 })
11048
11049 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11050 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11051 ;; with a precedence over other operators and is always put in the first
11052 ;; place. Swap condition and operands to match ficom instruction.
11053
11054 (define_insn "*fp_jcc_4_<mode>_387"
11055   [(set (pc)
11056         (if_then_else
11057           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11058             [(match_operator 1 "float_operator"
11059               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11060              (match_operand 3 "register_operand" "f,f")])
11061           (label_ref (match_operand 4 "" ""))
11062           (pc)))
11063    (clobber (reg:CCFP FPSR_REG))
11064    (clobber (reg:CCFP FLAGS_REG))
11065    (clobber (match_scratch:HI 5 "=a,a"))]
11066   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11067    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11068    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11069    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11070    && !TARGET_CMOVE"
11071   "#")
11072
11073 (define_split
11074   [(set (pc)
11075         (if_then_else
11076           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11077             [(match_operator 1 "float_operator"
11078               [(match_operand:X87MODEI12 2 "memory_operand" "")])
11079              (match_operand 3 "register_operand" "")])
11080           (match_operand 4 "" "")
11081           (match_operand 5 "" "")))
11082    (clobber (reg:CCFP FPSR_REG))
11083    (clobber (reg:CCFP FLAGS_REG))
11084    (clobber (match_scratch:HI 6 "=a"))]
11085   "reload_completed"
11086   [(const_int 0)]
11087 {
11088   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11089
11090   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11091                         operands[3], operands[7],
11092                         operands[4], operands[5], operands[6], NULL_RTX);
11093   DONE;
11094 })
11095
11096 ;; %%% Kill this when reload knows how to do it.
11097 (define_split
11098   [(set (pc)
11099         (if_then_else
11100           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11101             [(match_operator 1 "float_operator"
11102               [(match_operand:X87MODEI12 2 "register_operand" "")])
11103              (match_operand 3 "register_operand" "")])
11104           (match_operand 4 "" "")
11105           (match_operand 5 "" "")))
11106    (clobber (reg:CCFP FPSR_REG))
11107    (clobber (reg:CCFP FLAGS_REG))
11108    (clobber (match_scratch:HI 6 "=a"))]
11109   "reload_completed"
11110   [(const_int 0)]
11111 {
11112   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11113   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11114
11115   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11116                         operands[3], operands[7],
11117                         operands[4], operands[5], operands[6], operands[2]);
11118   DONE;
11119 })
11120 \f
11121 ;; Unconditional and other jump instructions
11122
11123 (define_insn "jump"
11124   [(set (pc)
11125         (label_ref (match_operand 0 "" "")))]
11126   ""
11127   "jmp\t%l0"
11128   [(set_attr "type" "ibr")
11129    (set (attr "length")
11130            (if_then_else (and (ge (minus (match_dup 0) (pc))
11131                                   (const_int -126))
11132                               (lt (minus (match_dup 0) (pc))
11133                                   (const_int 128)))
11134              (const_int 2)
11135              (const_int 5)))
11136    (set_attr "modrm" "0")])
11137
11138 (define_expand "indirect_jump"
11139   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11140   ""
11141   "")
11142
11143 (define_insn "*indirect_jump"
11144   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11145   ""
11146   "jmp\t%A0"
11147   [(set_attr "type" "ibr")
11148    (set_attr "length_immediate" "0")])
11149
11150 (define_expand "tablejump"
11151   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11152               (use (label_ref (match_operand 1 "" "")))])]
11153   ""
11154 {
11155   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11156      relative.  Convert the relative address to an absolute address.  */
11157   if (flag_pic)
11158     {
11159       rtx op0, op1;
11160       enum rtx_code code;
11161
11162       /* We can't use @GOTOFF for text labels on VxWorks;
11163          see gotoff_operand.  */
11164       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11165         {
11166           code = PLUS;
11167           op0 = operands[0];
11168           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11169         }
11170       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11171         {
11172           code = PLUS;
11173           op0 = operands[0];
11174           op1 = pic_offset_table_rtx;
11175         }
11176       else
11177         {
11178           code = MINUS;
11179           op0 = pic_offset_table_rtx;
11180           op1 = operands[0];
11181         }
11182
11183       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11184                                          OPTAB_DIRECT);
11185     }
11186 })
11187
11188 (define_insn "*tablejump_1"
11189   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11190    (use (label_ref (match_operand 1 "" "")))]
11191   ""
11192   "jmp\t%A0"
11193   [(set_attr "type" "ibr")
11194    (set_attr "length_immediate" "0")])
11195 \f
11196 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11197
11198 (define_peephole2
11199   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11200    (set (match_operand:QI 1 "register_operand" "")
11201         (match_operator:QI 2 "ix86_comparison_operator"
11202           [(reg FLAGS_REG) (const_int 0)]))
11203    (set (match_operand 3 "q_regs_operand" "")
11204         (zero_extend (match_dup 1)))]
11205   "(peep2_reg_dead_p (3, operands[1])
11206     || operands_match_p (operands[1], operands[3]))
11207    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11208   [(set (match_dup 4) (match_dup 0))
11209    (set (strict_low_part (match_dup 5))
11210         (match_dup 2))]
11211 {
11212   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11213   operands[5] = gen_lowpart (QImode, operands[3]);
11214   ix86_expand_clear (operands[3]);
11215 })
11216
11217 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11218
11219 (define_peephole2
11220   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11221    (set (match_operand:QI 1 "register_operand" "")
11222         (match_operator:QI 2 "ix86_comparison_operator"
11223           [(reg FLAGS_REG) (const_int 0)]))
11224    (parallel [(set (match_operand 3 "q_regs_operand" "")
11225                    (zero_extend (match_dup 1)))
11226               (clobber (reg:CC FLAGS_REG))])]
11227   "(peep2_reg_dead_p (3, operands[1])
11228     || operands_match_p (operands[1], operands[3]))
11229    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11230   [(set (match_dup 4) (match_dup 0))
11231    (set (strict_low_part (match_dup 5))
11232         (match_dup 2))]
11233 {
11234   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11235   operands[5] = gen_lowpart (QImode, operands[3]);
11236   ix86_expand_clear (operands[3]);
11237 })
11238 \f
11239 ;; Call instructions.
11240
11241 ;; The predicates normally associated with named expanders are not properly
11242 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11243 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11244
11245 ;; P6 processors will jump to the address after the decrement when %esp
11246 ;; is used as a call operand, so they will execute return address as a code.
11247 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11248  
11249 ;; Call subroutine returning no value.
11250
11251 (define_expand "call_pop"
11252   [(parallel [(call (match_operand:QI 0 "" "")
11253                     (match_operand:SI 1 "" ""))
11254               (set (reg:SI SP_REG)
11255                    (plus:SI (reg:SI SP_REG)
11256                             (match_operand:SI 3 "" "")))])]
11257   "!TARGET_64BIT"
11258 {
11259   ix86_expand_call (NULL, operands[0], operands[1],
11260                     operands[2], operands[3], 0);
11261   DONE;
11262 })
11263
11264 (define_insn_and_split "*call_pop_0_vzeroupper"
11265   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11266          (match_operand:SI 1 "" ""))
11267    (set (reg:SI SP_REG)
11268         (plus:SI (reg:SI SP_REG)
11269                  (match_operand:SI 2 "immediate_operand" "")))
11270    (unspec [(match_operand 3 "const_int_operand" "")]
11271            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11272   "TARGET_VZEROUPPER && !TARGET_64BIT"
11273   "#"
11274   "&& reload_completed"
11275   [(const_int 0)]
11276   "ix86_split_call_pop_vzeroupper (curr_insn, operands[3]); DONE;"
11277   [(set_attr "type" "call")])
11278
11279 (define_insn "*call_pop_0"
11280   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11281          (match_operand:SI 1 "" ""))
11282    (set (reg:SI SP_REG)
11283         (plus:SI (reg:SI SP_REG)
11284                  (match_operand:SI 2 "immediate_operand" "")))]
11285   "!TARGET_64BIT"
11286 {
11287   if (SIBLING_CALL_P (insn))
11288     return "jmp\t%P0";
11289   else
11290     return "call\t%P0";
11291 }
11292   [(set_attr "type" "call")])
11293
11294 (define_insn_and_split "*call_pop_1_vzeroupper"
11295   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11296          (match_operand:SI 1 "" ""))
11297    (set (reg:SI SP_REG)
11298         (plus:SI (reg:SI SP_REG)
11299                  (match_operand:SI 2 "immediate_operand" "i")))
11300    (unspec [(match_operand 3 "const_int_operand" "")]
11301            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11302   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11303   "#"
11304   "&& reload_completed"
11305   [(const_int 0)]
11306   "ix86_split_call_pop_vzeroupper (curr_insn, operands[3]); DONE;"
11307   [(set_attr "type" "call")])
11308
11309 (define_insn "*call_pop_1"
11310   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11311          (match_operand:SI 1 "" ""))
11312    (set (reg:SI SP_REG)
11313         (plus:SI (reg:SI SP_REG)
11314                  (match_operand:SI 2 "immediate_operand" "i")))]
11315   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11316 {
11317   if (constant_call_address_operand (operands[0], Pmode))
11318     return "call\t%P0";
11319   return "call\t%A0";
11320 }
11321   [(set_attr "type" "call")])
11322
11323 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
11324   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11325          (match_operand:SI 1 "" ""))
11326    (set (reg:SI SP_REG)
11327         (plus:SI (reg:SI SP_REG)
11328                  (match_operand:SI 2 "immediate_operand" "i,i")))
11329    (unspec [(match_operand 3 "const_int_operand" "")]
11330            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11331   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11332   "#"
11333   "&& reload_completed"
11334   [(const_int 0)]
11335   "ix86_split_call_pop_vzeroupper (curr_insn, operands[3]); DONE;"
11336   [(set_attr "type" "call")])
11337
11338 (define_insn "*sibcall_pop_1"
11339   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11340          (match_operand:SI 1 "" ""))
11341    (set (reg:SI SP_REG)
11342         (plus:SI (reg:SI SP_REG)
11343                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11344   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11345   "@
11346    jmp\t%P0
11347    jmp\t%A0"
11348   [(set_attr "type" "call")])
11349
11350 (define_expand "call"
11351   [(call (match_operand:QI 0 "" "")
11352          (match_operand 1 "" ""))
11353    (use (match_operand 2 "" ""))]
11354   ""
11355 {
11356   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11357   DONE;
11358 })
11359
11360 (define_expand "sibcall"
11361   [(call (match_operand:QI 0 "" "")
11362          (match_operand 1 "" ""))
11363    (use (match_operand 2 "" ""))]
11364   ""
11365 {
11366   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11367   DONE;
11368 })
11369
11370 (define_insn_and_split "*call_0_vzeroupper"
11371   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11372          (match_operand 1 "" ""))
11373    (unspec [(match_operand 2 "const_int_operand" "")]
11374            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11375   "TARGET_VZEROUPPER"
11376   "#"
11377   "&& reload_completed"
11378   [(const_int 0)]
11379   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11380   [(set_attr "type" "call")])
11381
11382 (define_insn "*call_0"
11383   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11384          (match_operand 1 "" ""))]
11385   ""
11386   { return ix86_output_call_insn (insn, operands[0], 0); }
11387   [(set_attr "type" "call")])
11388
11389 (define_insn_and_split "*call_1_vzeroupper"
11390   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11391          (match_operand 1 "" ""))
11392    (unspec [(match_operand 2 "const_int_operand" "")]
11393            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11394   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11395   "#"
11396   "&& reload_completed"
11397   [(const_int 0)]
11398   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11399   [(set_attr "type" "call")])
11400
11401 (define_insn "*call_1"
11402   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11403          (match_operand 1 "" ""))]
11404   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11405   { return ix86_output_call_insn (insn, operands[0], 0); }
11406   [(set_attr "type" "call")])
11407
11408 (define_insn_and_split "*sibcall_1_vzeroupper"
11409   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11410          (match_operand 1 "" ""))
11411    (unspec [(match_operand 2 "const_int_operand" "")]
11412            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11413   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11414   "#"
11415   "&& reload_completed"
11416   [(const_int 0)]
11417   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11418   [(set_attr "type" "call")])
11419
11420 (define_insn "*sibcall_1"
11421   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11422          (match_operand 1 "" ""))]
11423   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11424   { return ix86_output_call_insn (insn, operands[0], 0); }
11425   [(set_attr "type" "call")])
11426
11427 (define_insn_and_split "*call_1_rex64_vzeroupper"
11428   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11429          (match_operand 1 "" ""))
11430    (unspec [(match_operand 2 "const_int_operand" "")]
11431            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11432   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
11433    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11434   "#"
11435   "&& reload_completed"
11436   [(const_int 0)]
11437   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11438   [(set_attr "type" "call")])
11439
11440 (define_insn "*call_1_rex64"
11441   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11442          (match_operand 1 "" ""))]
11443   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11444    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11445   { return ix86_output_call_insn (insn, operands[0], 0); }
11446   [(set_attr "type" "call")])
11447
11448 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
11449   [(parallel
11450     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11451            (match_operand 1 "" ""))
11452      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11453      (clobber (reg:TI XMM6_REG))
11454      (clobber (reg:TI XMM7_REG))
11455      (clobber (reg:TI XMM8_REG))
11456      (clobber (reg:TI XMM9_REG))
11457      (clobber (reg:TI XMM10_REG))
11458      (clobber (reg:TI XMM11_REG))
11459      (clobber (reg:TI XMM12_REG))
11460      (clobber (reg:TI XMM13_REG))
11461      (clobber (reg:TI XMM14_REG))
11462      (clobber (reg:TI XMM15_REG))
11463      (clobber (reg:DI SI_REG))
11464      (clobber (reg:DI DI_REG))])
11465    (unspec [(match_operand 2 "const_int_operand" "")]
11466            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11467   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11468   "#"
11469   "&& reload_completed"
11470   [(const_int 0)]
11471   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11472   [(set_attr "type" "call")])
11473
11474 (define_insn "*call_1_rex64_ms_sysv"
11475   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11476          (match_operand 1 "" ""))
11477    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11478    (clobber (reg:TI XMM6_REG))
11479    (clobber (reg:TI XMM7_REG))
11480    (clobber (reg:TI XMM8_REG))
11481    (clobber (reg:TI XMM9_REG))
11482    (clobber (reg:TI XMM10_REG))
11483    (clobber (reg:TI XMM11_REG))
11484    (clobber (reg:TI XMM12_REG))
11485    (clobber (reg:TI XMM13_REG))
11486    (clobber (reg:TI XMM14_REG))
11487    (clobber (reg:TI XMM15_REG))
11488    (clobber (reg:DI SI_REG))
11489    (clobber (reg:DI DI_REG))]
11490   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11491   { return ix86_output_call_insn (insn, operands[0], 0); }
11492   [(set_attr "type" "call")])
11493
11494 (define_insn_and_split "*call_1_rex64_large_vzeroupper"
11495   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11496          (match_operand 1 "" ""))
11497    (unspec [(match_operand 2 "const_int_operand" "")]
11498            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11499   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11500   "#"
11501   "&& reload_completed"
11502   [(const_int 0)]
11503   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11504   [(set_attr "type" "call")])
11505
11506 (define_insn "*call_1_rex64_large"
11507   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11508          (match_operand 1 "" ""))]
11509   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11510   { return ix86_output_call_insn (insn, operands[0], 0); }
11511   [(set_attr "type" "call")])
11512
11513 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
11514   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11515          (match_operand 1 "" ""))
11516    (unspec [(match_operand 2 "const_int_operand" "")]
11517            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11518   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11519   "#"
11520   "&& reload_completed"
11521   [(const_int 0)]
11522   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11523   [(set_attr "type" "call")])
11524
11525 (define_insn "*sibcall_1_rex64"
11526   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11527          (match_operand 1 "" ""))]
11528   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11529   { return ix86_output_call_insn (insn, operands[0], 0); }
11530   [(set_attr "type" "call")])
11531
11532 ;; Call subroutine, returning value in operand 0
11533 (define_expand "call_value_pop"
11534   [(parallel [(set (match_operand 0 "" "")
11535                    (call (match_operand:QI 1 "" "")
11536                          (match_operand:SI 2 "" "")))
11537               (set (reg:SI SP_REG)
11538                    (plus:SI (reg:SI SP_REG)
11539                             (match_operand:SI 4 "" "")))])]
11540   "!TARGET_64BIT"
11541 {
11542   ix86_expand_call (operands[0], operands[1], operands[2],
11543                     operands[3], operands[4], 0);
11544   DONE;
11545 })
11546
11547 (define_expand "call_value"
11548   [(set (match_operand 0 "" "")
11549         (call (match_operand:QI 1 "" "")
11550               (match_operand:SI 2 "" "")))
11551    (use (match_operand:SI 3 "" ""))]
11552   ;; Operand 3 is not used on the i386.
11553   ""
11554 {
11555   ix86_expand_call (operands[0], operands[1], operands[2],
11556                     operands[3], NULL, 0);
11557   DONE;
11558 })
11559
11560 (define_expand "sibcall_value"
11561   [(set (match_operand 0 "" "")
11562         (call (match_operand:QI 1 "" "")
11563               (match_operand:SI 2 "" "")))
11564    (use (match_operand:SI 3 "" ""))]
11565   ;; Operand 3 is not used on the i386.
11566   ""
11567 {
11568   ix86_expand_call (operands[0], operands[1], operands[2],
11569                     operands[3], NULL, 1);
11570   DONE;
11571 })
11572
11573 ;; Call subroutine returning any type.
11574
11575 (define_expand "untyped_call"
11576   [(parallel [(call (match_operand 0 "" "")
11577                     (const_int 0))
11578               (match_operand 1 "" "")
11579               (match_operand 2 "" "")])]
11580   ""
11581 {
11582   int i;
11583
11584   /* In order to give reg-stack an easier job in validating two
11585      coprocessor registers as containing a possible return value,
11586      simply pretend the untyped call returns a complex long double
11587      value. 
11588
11589      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11590      and should have the default ABI.  */
11591
11592   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11593                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11594                     operands[0], const0_rtx,
11595                     GEN_INT ((TARGET_64BIT
11596                               ? (ix86_abi == SYSV_ABI
11597                                  ? X86_64_SSE_REGPARM_MAX
11598                                  : X86_64_MS_SSE_REGPARM_MAX)
11599                               : X86_32_SSE_REGPARM_MAX)
11600                              - 1),
11601                     NULL, 0);
11602
11603   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11604     {
11605       rtx set = XVECEXP (operands[2], 0, i);
11606       emit_move_insn (SET_DEST (set), SET_SRC (set));
11607     }
11608
11609   /* The optimizer does not know that the call sets the function value
11610      registers we stored in the result block.  We avoid problems by
11611      claiming that all hard registers are used and clobbered at this
11612      point.  */
11613   emit_insn (gen_blockage ());
11614
11615   DONE;
11616 })
11617 \f
11618 ;; Prologue and epilogue instructions
11619
11620 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11621 ;; all of memory.  This blocks insns from being moved across this point.
11622
11623 (define_insn "blockage"
11624   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11625   ""
11626   ""
11627   [(set_attr "length" "0")])
11628
11629 ;; Do not schedule instructions accessing memory across this point.
11630
11631 (define_expand "memory_blockage"
11632   [(set (match_dup 0)
11633         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11634   ""
11635 {
11636   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11637   MEM_VOLATILE_P (operands[0]) = 1;
11638 })
11639
11640 (define_insn "*memory_blockage"
11641   [(set (match_operand:BLK 0 "" "")
11642         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11643   ""
11644   ""
11645   [(set_attr "length" "0")])
11646
11647 ;; As USE insns aren't meaningful after reload, this is used instead
11648 ;; to prevent deleting instructions setting registers for PIC code
11649 (define_insn "prologue_use"
11650   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11651   ""
11652   ""
11653   [(set_attr "length" "0")])
11654
11655 ;; Insn emitted into the body of a function to return from a function.
11656 ;; This is only done if the function's epilogue is known to be simple.
11657 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11658
11659 (define_expand "return"
11660   [(return)]
11661   "ix86_can_use_return_insn_p ()"
11662 {
11663   if (crtl->args.pops_args)
11664     {
11665       rtx popc = GEN_INT (crtl->args.pops_args);
11666       emit_jump_insn (gen_return_pop_internal (popc));
11667       DONE;
11668     }
11669 })
11670
11671 (define_insn "return_internal"
11672   [(return)]
11673   "reload_completed"
11674   "ret"
11675   [(set_attr "length" "1")
11676    (set_attr "atom_unit" "jeu")
11677    (set_attr "length_immediate" "0")
11678    (set_attr "modrm" "0")])
11679
11680 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11681 ;; instruction Athlon and K8 have.
11682
11683 (define_insn "return_internal_long"
11684   [(return)
11685    (unspec [(const_int 0)] UNSPEC_REP)]
11686   "reload_completed"
11687   "rep\;ret"
11688   [(set_attr "length" "2")
11689    (set_attr "atom_unit" "jeu")
11690    (set_attr "length_immediate" "0")
11691    (set_attr "prefix_rep" "1")
11692    (set_attr "modrm" "0")])
11693
11694 (define_insn "return_pop_internal"
11695   [(return)
11696    (use (match_operand:SI 0 "const_int_operand" ""))]
11697   "reload_completed"
11698   "ret\t%0"
11699   [(set_attr "length" "3")
11700    (set_attr "atom_unit" "jeu")
11701    (set_attr "length_immediate" "2")
11702    (set_attr "modrm" "0")])
11703
11704 (define_insn "return_indirect_internal"
11705   [(return)
11706    (use (match_operand:SI 0 "register_operand" "r"))]
11707   "reload_completed"
11708   "jmp\t%A0"
11709   [(set_attr "type" "ibr")
11710    (set_attr "length_immediate" "0")])
11711
11712 (define_insn "nop"
11713   [(const_int 0)]
11714   ""
11715   "nop"
11716   [(set_attr "length" "1")
11717    (set_attr "length_immediate" "0")
11718    (set_attr "modrm" "0")])
11719
11720 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11721 (define_insn "nops"
11722   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11723                     UNSPECV_NOPS)]
11724   "reload_completed"
11725 {
11726   int num = INTVAL (operands[0]);
11727
11728   gcc_assert (num >= 1 && num <= 8);
11729
11730   while (num--)
11731     fputs ("\tnop\n", asm_out_file);
11732
11733   return "";
11734 }
11735   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11736    (set_attr "length_immediate" "0")
11737    (set_attr "modrm" "0")])
11738
11739 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11740 ;; branch prediction penalty for the third jump in a 16-byte
11741 ;; block on K8.
11742
11743 (define_insn "pad"
11744   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11745   ""
11746 {
11747 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11748   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11749 #else
11750   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11751      The align insn is used to avoid 3 jump instructions in the row to improve
11752      branch prediction and the benefits hardly outweigh the cost of extra 8
11753      nops on the average inserted by full alignment pseudo operation.  */
11754 #endif
11755   return "";
11756 }
11757   [(set_attr "length" "16")])
11758
11759 (define_expand "prologue"
11760   [(const_int 0)]
11761   ""
11762   "ix86_expand_prologue (); DONE;")
11763
11764 (define_insn "set_got"
11765   [(set (match_operand:SI 0 "register_operand" "=r")
11766         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11767    (clobber (reg:CC FLAGS_REG))]
11768   "!TARGET_64BIT"
11769   "* return output_set_got (operands[0], NULL_RTX);"
11770   [(set_attr "type" "multi")
11771    (set_attr "length" "12")])
11772
11773 (define_insn "set_got_labelled"
11774   [(set (match_operand:SI 0 "register_operand" "=r")
11775         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11776          UNSPEC_SET_GOT))
11777    (clobber (reg:CC FLAGS_REG))]
11778   "!TARGET_64BIT"
11779   "* return output_set_got (operands[0], operands[1]);"
11780   [(set_attr "type" "multi")
11781    (set_attr "length" "12")])
11782
11783 (define_insn "set_got_rex64"
11784   [(set (match_operand:DI 0 "register_operand" "=r")
11785         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11786   "TARGET_64BIT"
11787   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11788   [(set_attr "type" "lea")
11789    (set_attr "length_address" "4")
11790    (set_attr "mode" "DI")])
11791
11792 (define_insn "set_rip_rex64"
11793   [(set (match_operand:DI 0 "register_operand" "=r")
11794         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11795   "TARGET_64BIT"
11796   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11797   [(set_attr "type" "lea")
11798    (set_attr "length_address" "4")
11799    (set_attr "mode" "DI")])
11800
11801 (define_insn "set_got_offset_rex64"
11802   [(set (match_operand:DI 0 "register_operand" "=r")
11803         (unspec:DI
11804           [(label_ref (match_operand 1 "" ""))]
11805           UNSPEC_SET_GOT_OFFSET))]
11806   "TARGET_64BIT"
11807   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11808   [(set_attr "type" "imov")
11809    (set_attr "length_immediate" "0")
11810    (set_attr "length_address" "8")
11811    (set_attr "mode" "DI")])
11812
11813 (define_expand "epilogue"
11814   [(const_int 0)]
11815   ""
11816   "ix86_expand_epilogue (1); DONE;")
11817
11818 (define_expand "sibcall_epilogue"
11819   [(const_int 0)]
11820   ""
11821   "ix86_expand_epilogue (0); DONE;")
11822
11823 (define_expand "eh_return"
11824   [(use (match_operand 0 "register_operand" ""))]
11825   ""
11826 {
11827   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11828
11829   /* Tricky bit: we write the address of the handler to which we will
11830      be returning into someone else's stack frame, one word below the
11831      stack address we wish to restore.  */
11832   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11833   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11834   tmp = gen_rtx_MEM (Pmode, tmp);
11835   emit_move_insn (tmp, ra);
11836
11837   emit_jump_insn (gen_eh_return_internal ());
11838   emit_barrier ();
11839   DONE;
11840 })
11841
11842 (define_insn_and_split "eh_return_internal"
11843   [(eh_return)]
11844   ""
11845   "#"
11846   "epilogue_completed"
11847   [(const_int 0)]
11848   "ix86_expand_epilogue (2); DONE;")
11849
11850 (define_insn "leave"
11851   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11852    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11853    (clobber (mem:BLK (scratch)))]
11854   "!TARGET_64BIT"
11855   "leave"
11856   [(set_attr "type" "leave")])
11857
11858 (define_insn "leave_rex64"
11859   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11860    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11861    (clobber (mem:BLK (scratch)))]
11862   "TARGET_64BIT"
11863   "leave"
11864   [(set_attr "type" "leave")])
11865 \f
11866 ;; Handle -fsplit-stack.
11867
11868 (define_expand "split_stack_prologue"
11869   [(const_int 0)]
11870   ""
11871 {
11872   ix86_expand_split_stack_prologue ();
11873   DONE;
11874 })
11875
11876 ;; In order to support the call/return predictor, we use a return
11877 ;; instruction which the middle-end doesn't see.
11878 (define_insn "split_stack_return"
11879   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11880                      UNSPECV_SPLIT_STACK_RETURN)]
11881   ""
11882 {
11883   if (operands[0] == const0_rtx)
11884     return "ret";
11885   else
11886     return "ret\t%0";
11887 }
11888   [(set_attr "atom_unit" "jeu")
11889    (set_attr "modrm" "0")
11890    (set (attr "length")
11891         (if_then_else (match_operand:SI 0 "const0_operand" "")
11892                       (const_int 1)
11893                       (const_int 3)))
11894    (set (attr "length_immediate")
11895         (if_then_else (match_operand:SI 0 "const0_operand" "")
11896                       (const_int 0)
11897                       (const_int 2)))])
11898
11899 ;; If there are operand 0 bytes available on the stack, jump to
11900 ;; operand 1.
11901
11902 (define_expand "split_stack_space_check"
11903   [(set (pc) (if_then_else
11904               (ltu (minus (reg SP_REG)
11905                           (match_operand 0 "register_operand" ""))
11906                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11907               (label_ref (match_operand 1 "" ""))
11908               (pc)))]
11909   ""
11910 {
11911   rtx reg, size, limit;
11912
11913   reg = gen_reg_rtx (Pmode);
11914   size = force_reg (Pmode, operands[0]);
11915   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11916   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11917                           UNSPEC_STACK_CHECK);
11918   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11919   ix86_expand_branch (GEU, reg, limit, operands[1]);
11920
11921   DONE;
11922 })
11923 \f
11924 ;; Bit manipulation instructions.
11925
11926 (define_expand "ffs<mode>2"
11927   [(set (match_dup 2) (const_int -1))
11928    (parallel [(set (reg:CCZ FLAGS_REG)
11929                    (compare:CCZ
11930                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11931                      (const_int 0)))
11932               (set (match_operand:SWI48 0 "register_operand" "")
11933                    (ctz:SWI48 (match_dup 1)))])
11934    (set (match_dup 0) (if_then_else:SWI48
11935                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11936                         (match_dup 2)
11937                         (match_dup 0)))
11938    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11939               (clobber (reg:CC FLAGS_REG))])]
11940   ""
11941 {
11942   if (<MODE>mode == SImode && !TARGET_CMOVE)
11943     {
11944       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11945       DONE;
11946     }
11947   operands[2] = gen_reg_rtx (<MODE>mode);
11948 })
11949
11950 (define_insn_and_split "ffssi2_no_cmove"
11951   [(set (match_operand:SI 0 "register_operand" "=r")
11952         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11953    (clobber (match_scratch:SI 2 "=&q"))
11954    (clobber (reg:CC FLAGS_REG))]
11955   "!TARGET_CMOVE"
11956   "#"
11957   "&& reload_completed"
11958   [(parallel [(set (reg:CCZ FLAGS_REG)
11959                    (compare:CCZ (match_dup 1) (const_int 0)))
11960               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11961    (set (strict_low_part (match_dup 3))
11962         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11963    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11964               (clobber (reg:CC FLAGS_REG))])
11965    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11966               (clobber (reg:CC FLAGS_REG))])
11967    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11968               (clobber (reg:CC FLAGS_REG))])]
11969 {
11970   operands[3] = gen_lowpart (QImode, operands[2]);
11971   ix86_expand_clear (operands[2]);
11972 })
11973
11974 (define_insn "*ffs<mode>_1"
11975   [(set (reg:CCZ FLAGS_REG)
11976         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11977                      (const_int 0)))
11978    (set (match_operand:SWI48 0 "register_operand" "=r")
11979         (ctz:SWI48 (match_dup 1)))]
11980   ""
11981   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11982   [(set_attr "type" "alu1")
11983    (set_attr "prefix_0f" "1")
11984    (set_attr "mode" "<MODE>")])
11985
11986 (define_insn "ctz<mode>2"
11987   [(set (match_operand:SWI48 0 "register_operand" "=r")
11988         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11989    (clobber (reg:CC FLAGS_REG))]
11990   ""
11991   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11992   [(set_attr "type" "alu1")
11993    (set_attr "prefix_0f" "1")
11994    (set_attr "mode" "<MODE>")])
11995
11996 (define_expand "clz<mode>2"
11997   [(parallel
11998      [(set (match_operand:SWI248 0 "register_operand" "")
11999            (minus:SWI248
12000              (match_dup 2)
12001              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12002       (clobber (reg:CC FLAGS_REG))])
12003    (parallel
12004      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12005       (clobber (reg:CC FLAGS_REG))])]
12006   ""
12007 {
12008   if (TARGET_ABM)
12009     {
12010       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
12011       DONE;
12012     }
12013   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12014 })
12015
12016 (define_insn "clz<mode>2_abm"
12017   [(set (match_operand:SWI248 0 "register_operand" "=r")
12018         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12019    (clobber (reg:CC FLAGS_REG))]
12020   "TARGET_ABM"
12021   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12022   [(set_attr "prefix_rep" "1")
12023    (set_attr "type" "bitmanip")
12024    (set_attr "mode" "<MODE>")])
12025
12026 (define_insn "bsr_rex64"
12027   [(set (match_operand:DI 0 "register_operand" "=r")
12028         (minus:DI (const_int 63)
12029                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12030    (clobber (reg:CC FLAGS_REG))]
12031   "TARGET_64BIT"
12032   "bsr{q}\t{%1, %0|%0, %1}"
12033   [(set_attr "type" "alu1")
12034    (set_attr "prefix_0f" "1")
12035    (set_attr "mode" "DI")])
12036
12037 (define_insn "bsr"
12038   [(set (match_operand:SI 0 "register_operand" "=r")
12039         (minus:SI (const_int 31)
12040                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12041    (clobber (reg:CC FLAGS_REG))]
12042   ""
12043   "bsr{l}\t{%1, %0|%0, %1}"
12044   [(set_attr "type" "alu1")
12045    (set_attr "prefix_0f" "1")
12046    (set_attr "mode" "SI")])
12047
12048 (define_insn "*bsrhi"
12049   [(set (match_operand:HI 0 "register_operand" "=r")
12050         (minus:HI (const_int 15)
12051                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12052    (clobber (reg:CC FLAGS_REG))]
12053   ""
12054   "bsr{w}\t{%1, %0|%0, %1}"
12055   [(set_attr "type" "alu1")
12056    (set_attr "prefix_0f" "1")
12057    (set_attr "mode" "HI")])
12058
12059 (define_insn "popcount<mode>2"
12060   [(set (match_operand:SWI248 0 "register_operand" "=r")
12061         (popcount:SWI248
12062           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12063    (clobber (reg:CC FLAGS_REG))]
12064   "TARGET_POPCNT"
12065 {
12066 #if TARGET_MACHO
12067   return "popcnt\t{%1, %0|%0, %1}";
12068 #else
12069   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12070 #endif
12071 }
12072   [(set_attr "prefix_rep" "1")
12073    (set_attr "type" "bitmanip")
12074    (set_attr "mode" "<MODE>")])
12075
12076 (define_insn "*popcount<mode>2_cmp"
12077   [(set (reg FLAGS_REG)
12078         (compare
12079           (popcount:SWI248
12080             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12081           (const_int 0)))
12082    (set (match_operand:SWI248 0 "register_operand" "=r")
12083         (popcount:SWI248 (match_dup 1)))]
12084   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12085 {
12086 #if TARGET_MACHO
12087   return "popcnt\t{%1, %0|%0, %1}";
12088 #else
12089   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12090 #endif
12091 }
12092   [(set_attr "prefix_rep" "1")
12093    (set_attr "type" "bitmanip")
12094    (set_attr "mode" "<MODE>")])
12095
12096 (define_insn "*popcountsi2_cmp_zext"
12097   [(set (reg FLAGS_REG)
12098         (compare
12099           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12100           (const_int 0)))
12101    (set (match_operand:DI 0 "register_operand" "=r")
12102         (zero_extend:DI(popcount:SI (match_dup 1))))]
12103   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12104 {
12105 #if TARGET_MACHO
12106   return "popcnt\t{%1, %0|%0, %1}";
12107 #else
12108   return "popcnt{l}\t{%1, %0|%0, %1}";
12109 #endif
12110 }
12111   [(set_attr "prefix_rep" "1")
12112    (set_attr "type" "bitmanip")
12113    (set_attr "mode" "SI")])
12114
12115 (define_expand "bswap<mode>2"
12116   [(set (match_operand:SWI48 0 "register_operand" "")
12117         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12118   ""
12119 {
12120   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12121     {
12122       rtx x = operands[0];
12123
12124       emit_move_insn (x, operands[1]);
12125       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12126       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12127       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12128       DONE;
12129     }
12130 })
12131
12132 (define_insn "*bswap<mode>2_movbe"
12133   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12134         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12135   "TARGET_MOVBE
12136    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12137   "@
12138     bswap\t%0
12139     movbe\t{%1, %0|%0, %1}
12140     movbe\t{%1, %0|%0, %1}"
12141   [(set_attr "type" "bitmanip,imov,imov")
12142    (set_attr "modrm" "0,1,1")
12143    (set_attr "prefix_0f" "*,1,1")
12144    (set_attr "prefix_extra" "*,1,1")
12145    (set_attr "mode" "<MODE>")])
12146
12147 (define_insn "*bswap<mode>2_1"
12148   [(set (match_operand:SWI48 0 "register_operand" "=r")
12149         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12150   "TARGET_BSWAP"
12151   "bswap\t%0"
12152   [(set_attr "type" "bitmanip")
12153    (set_attr "modrm" "0")
12154    (set_attr "mode" "<MODE>")])
12155
12156 (define_insn "*bswaphi_lowpart_1"
12157   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12158         (bswap:HI (match_dup 0)))
12159    (clobber (reg:CC FLAGS_REG))]
12160   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12161   "@
12162     xchg{b}\t{%h0, %b0|%b0, %h0}
12163     rol{w}\t{$8, %0|%0, 8}"
12164   [(set_attr "length" "2,4")
12165    (set_attr "mode" "QI,HI")])
12166
12167 (define_insn "bswaphi_lowpart"
12168   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12169         (bswap:HI (match_dup 0)))
12170    (clobber (reg:CC FLAGS_REG))]
12171   ""
12172   "rol{w}\t{$8, %0|%0, 8}"
12173   [(set_attr "length" "4")
12174    (set_attr "mode" "HI")])
12175
12176 (define_expand "paritydi2"
12177   [(set (match_operand:DI 0 "register_operand" "")
12178         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12179   "! TARGET_POPCNT"
12180 {
12181   rtx scratch = gen_reg_rtx (QImode);
12182   rtx cond;
12183
12184   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12185                                 NULL_RTX, operands[1]));
12186
12187   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12188                          gen_rtx_REG (CCmode, FLAGS_REG),
12189                          const0_rtx);
12190   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12191
12192   if (TARGET_64BIT)
12193     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12194   else
12195     {
12196       rtx tmp = gen_reg_rtx (SImode);
12197
12198       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12199       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12200     }
12201   DONE;
12202 })
12203
12204 (define_expand "paritysi2"
12205   [(set (match_operand:SI 0 "register_operand" "")
12206         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12207   "! TARGET_POPCNT"
12208 {
12209   rtx scratch = gen_reg_rtx (QImode);
12210   rtx cond;
12211
12212   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12213
12214   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12215                          gen_rtx_REG (CCmode, FLAGS_REG),
12216                          const0_rtx);
12217   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12218
12219   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12220   DONE;
12221 })
12222
12223 (define_insn_and_split "paritydi2_cmp"
12224   [(set (reg:CC FLAGS_REG)
12225         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12226                    UNSPEC_PARITY))
12227    (clobber (match_scratch:DI 0 "=r"))
12228    (clobber (match_scratch:SI 1 "=&r"))
12229    (clobber (match_scratch:HI 2 "=Q"))]
12230   "! TARGET_POPCNT"
12231   "#"
12232   "&& reload_completed"
12233   [(parallel
12234      [(set (match_dup 1)
12235            (xor:SI (match_dup 1) (match_dup 4)))
12236       (clobber (reg:CC FLAGS_REG))])
12237    (parallel
12238      [(set (reg:CC FLAGS_REG)
12239            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12240       (clobber (match_dup 1))
12241       (clobber (match_dup 2))])]
12242 {
12243   operands[4] = gen_lowpart (SImode, operands[3]);
12244
12245   if (TARGET_64BIT)
12246     {
12247       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12248       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12249     }
12250   else
12251     operands[1] = gen_highpart (SImode, operands[3]);
12252 })
12253
12254 (define_insn_and_split "paritysi2_cmp"
12255   [(set (reg:CC FLAGS_REG)
12256         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12257                    UNSPEC_PARITY))
12258    (clobber (match_scratch:SI 0 "=r"))
12259    (clobber (match_scratch:HI 1 "=&Q"))]
12260   "! TARGET_POPCNT"
12261   "#"
12262   "&& reload_completed"
12263   [(parallel
12264      [(set (match_dup 1)
12265            (xor:HI (match_dup 1) (match_dup 3)))
12266       (clobber (reg:CC FLAGS_REG))])
12267    (parallel
12268      [(set (reg:CC FLAGS_REG)
12269            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12270       (clobber (match_dup 1))])]
12271 {
12272   operands[3] = gen_lowpart (HImode, operands[2]);
12273
12274   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12275   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12276 })
12277
12278 (define_insn "*parityhi2_cmp"
12279   [(set (reg:CC FLAGS_REG)
12280         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12281                    UNSPEC_PARITY))
12282    (clobber (match_scratch:HI 0 "=Q"))]
12283   "! TARGET_POPCNT"
12284   "xor{b}\t{%h0, %b0|%b0, %h0}"
12285   [(set_attr "length" "2")
12286    (set_attr "mode" "HI")])
12287 \f
12288 ;; Thread-local storage patterns for ELF.
12289 ;;
12290 ;; Note that these code sequences must appear exactly as shown
12291 ;; in order to allow linker relaxation.
12292
12293 (define_insn "*tls_global_dynamic_32_gnu"
12294   [(set (match_operand:SI 0 "register_operand" "=a")
12295         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12296                     (match_operand:SI 2 "tls_symbolic_operand" "")
12297                     (match_operand:SI 3 "call_insn_operand" "")]
12298                     UNSPEC_TLS_GD))
12299    (clobber (match_scratch:SI 4 "=d"))
12300    (clobber (match_scratch:SI 5 "=c"))
12301    (clobber (reg:CC FLAGS_REG))]
12302   "!TARGET_64BIT && TARGET_GNU_TLS"
12303   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12304   [(set_attr "type" "multi")
12305    (set_attr "length" "12")])
12306
12307 (define_expand "tls_global_dynamic_32"
12308   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12309                    (unspec:SI
12310                     [(match_dup 2)
12311                      (match_operand:SI 1 "tls_symbolic_operand" "")
12312                      (match_dup 3)]
12313                     UNSPEC_TLS_GD))
12314               (clobber (match_scratch:SI 4 ""))
12315               (clobber (match_scratch:SI 5 ""))
12316               (clobber (reg:CC FLAGS_REG))])]
12317   ""
12318 {
12319   if (flag_pic)
12320     operands[2] = pic_offset_table_rtx;
12321   else
12322     {
12323       operands[2] = gen_reg_rtx (Pmode);
12324       emit_insn (gen_set_got (operands[2]));
12325     }
12326   if (TARGET_GNU2_TLS)
12327     {
12328        emit_insn (gen_tls_dynamic_gnu2_32
12329                   (operands[0], operands[1], operands[2]));
12330        DONE;
12331     }
12332   operands[3] = ix86_tls_get_addr ();
12333 })
12334
12335 (define_insn "*tls_global_dynamic_64"
12336   [(set (match_operand:DI 0 "register_operand" "=a")
12337         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12338                  (match_operand:DI 3 "" "")))
12339    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12340               UNSPEC_TLS_GD)]
12341   "TARGET_64BIT"
12342   { 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"; }
12343   [(set_attr "type" "multi")
12344    (set_attr "length" "16")])
12345
12346 (define_expand "tls_global_dynamic_64"
12347   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12348                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12349               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12350                          UNSPEC_TLS_GD)])]
12351   ""
12352 {
12353   if (TARGET_GNU2_TLS)
12354     {
12355        emit_insn (gen_tls_dynamic_gnu2_64
12356                   (operands[0], operands[1]));
12357        DONE;
12358     }
12359   operands[2] = ix86_tls_get_addr ();
12360 })
12361
12362 (define_insn "*tls_local_dynamic_base_32_gnu"
12363   [(set (match_operand:SI 0 "register_operand" "=a")
12364         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12365                     (match_operand:SI 2 "call_insn_operand" "")]
12366                    UNSPEC_TLS_LD_BASE))
12367    (clobber (match_scratch:SI 3 "=d"))
12368    (clobber (match_scratch:SI 4 "=c"))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "!TARGET_64BIT && TARGET_GNU_TLS"
12371   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12372   [(set_attr "type" "multi")
12373    (set_attr "length" "11")])
12374
12375 (define_expand "tls_local_dynamic_base_32"
12376   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12377                    (unspec:SI [(match_dup 1) (match_dup 2)]
12378                               UNSPEC_TLS_LD_BASE))
12379               (clobber (match_scratch:SI 3 ""))
12380               (clobber (match_scratch:SI 4 ""))
12381               (clobber (reg:CC FLAGS_REG))])]
12382   ""
12383 {
12384   if (flag_pic)
12385     operands[1] = pic_offset_table_rtx;
12386   else
12387     {
12388       operands[1] = gen_reg_rtx (Pmode);
12389       emit_insn (gen_set_got (operands[1]));
12390     }
12391   if (TARGET_GNU2_TLS)
12392     {
12393        emit_insn (gen_tls_dynamic_gnu2_32
12394                   (operands[0], ix86_tls_module_base (), operands[1]));
12395        DONE;
12396     }
12397   operands[2] = ix86_tls_get_addr ();
12398 })
12399
12400 (define_insn "*tls_local_dynamic_base_64"
12401   [(set (match_operand:DI 0 "register_operand" "=a")
12402         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12403                  (match_operand:DI 2 "" "")))
12404    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12405   "TARGET_64BIT"
12406   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12407   [(set_attr "type" "multi")
12408    (set_attr "length" "12")])
12409
12410 (define_expand "tls_local_dynamic_base_64"
12411   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12412                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12413               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12414   ""
12415 {
12416   if (TARGET_GNU2_TLS)
12417     {
12418        emit_insn (gen_tls_dynamic_gnu2_64
12419                   (operands[0], ix86_tls_module_base ()));
12420        DONE;
12421     }
12422   operands[1] = ix86_tls_get_addr ();
12423 })
12424
12425 ;; Local dynamic of a single variable is a lose.  Show combine how
12426 ;; to convert that back to global dynamic.
12427
12428 (define_insn_and_split "*tls_local_dynamic_32_once"
12429   [(set (match_operand:SI 0 "register_operand" "=a")
12430         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12431                              (match_operand:SI 2 "call_insn_operand" "")]
12432                             UNSPEC_TLS_LD_BASE)
12433                  (const:SI (unspec:SI
12434                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12435                             UNSPEC_DTPOFF))))
12436    (clobber (match_scratch:SI 4 "=d"))
12437    (clobber (match_scratch:SI 5 "=c"))
12438    (clobber (reg:CC FLAGS_REG))]
12439   ""
12440   "#"
12441   ""
12442   [(parallel [(set (match_dup 0)
12443                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12444                               UNSPEC_TLS_GD))
12445               (clobber (match_dup 4))
12446               (clobber (match_dup 5))
12447               (clobber (reg:CC FLAGS_REG))])])
12448
12449 ;; Segment register for the thread base ptr load
12450 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12451
12452 ;; Load and add the thread base pointer from %gs:0.
12453 (define_insn "*load_tp_<mode>"
12454   [(set (match_operand:P 0 "register_operand" "=r")
12455         (unspec:P [(const_int 0)] UNSPEC_TP))]
12456   ""
12457   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12458   [(set_attr "type" "imov")
12459    (set_attr "modrm" "0")
12460    (set_attr "length" "7")
12461    (set_attr "memory" "load")
12462    (set_attr "imm_disp" "false")])
12463
12464 (define_insn "*add_tp_<mode>"
12465   [(set (match_operand:P 0 "register_operand" "=r")
12466         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12467                 (match_operand:P 1 "register_operand" "0")))
12468    (clobber (reg:CC FLAGS_REG))]
12469   ""
12470   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12471   [(set_attr "type" "alu")
12472    (set_attr "modrm" "0")
12473    (set_attr "length" "7")
12474    (set_attr "memory" "load")
12475    (set_attr "imm_disp" "false")])
12476
12477 ;; GNU2 TLS patterns can be split.
12478
12479 (define_expand "tls_dynamic_gnu2_32"
12480   [(set (match_dup 3)
12481         (plus:SI (match_operand:SI 2 "register_operand" "")
12482                  (const:SI
12483                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12484                              UNSPEC_TLSDESC))))
12485    (parallel
12486     [(set (match_operand:SI 0 "register_operand" "")
12487           (unspec:SI [(match_dup 1) (match_dup 3)
12488                       (match_dup 2) (reg:SI SP_REG)]
12489                       UNSPEC_TLSDESC))
12490      (clobber (reg:CC FLAGS_REG))])]
12491   "!TARGET_64BIT && TARGET_GNU2_TLS"
12492 {
12493   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12494   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12495 })
12496
12497 (define_insn "*tls_dynamic_lea_32"
12498   [(set (match_operand:SI 0 "register_operand" "=r")
12499         (plus:SI (match_operand:SI 1 "register_operand" "b")
12500                  (const:SI
12501                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12502                               UNSPEC_TLSDESC))))]
12503   "!TARGET_64BIT && TARGET_GNU2_TLS"
12504   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12505   [(set_attr "type" "lea")
12506    (set_attr "mode" "SI")
12507    (set_attr "length" "6")
12508    (set_attr "length_address" "4")])
12509
12510 (define_insn "*tls_dynamic_call_32"
12511   [(set (match_operand:SI 0 "register_operand" "=a")
12512         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12513                     (match_operand:SI 2 "register_operand" "0")
12514                     ;; we have to make sure %ebx still points to the GOT
12515                     (match_operand:SI 3 "register_operand" "b")
12516                     (reg:SI SP_REG)]
12517                    UNSPEC_TLSDESC))
12518    (clobber (reg:CC FLAGS_REG))]
12519   "!TARGET_64BIT && TARGET_GNU2_TLS"
12520   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12521   [(set_attr "type" "call")
12522    (set_attr "length" "2")
12523    (set_attr "length_address" "0")])
12524
12525 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12526   [(set (match_operand:SI 0 "register_operand" "=&a")
12527         (plus:SI
12528          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12529                      (match_operand:SI 4 "" "")
12530                      (match_operand:SI 2 "register_operand" "b")
12531                      (reg:SI SP_REG)]
12532                     UNSPEC_TLSDESC)
12533          (const:SI (unspec:SI
12534                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12535                     UNSPEC_DTPOFF))))
12536    (clobber (reg:CC FLAGS_REG))]
12537   "!TARGET_64BIT && TARGET_GNU2_TLS"
12538   "#"
12539   ""
12540   [(set (match_dup 0) (match_dup 5))]
12541 {
12542   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12543   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12544 })
12545
12546 (define_expand "tls_dynamic_gnu2_64"
12547   [(set (match_dup 2)
12548         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12549                    UNSPEC_TLSDESC))
12550    (parallel
12551     [(set (match_operand:DI 0 "register_operand" "")
12552           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12553                      UNSPEC_TLSDESC))
12554      (clobber (reg:CC FLAGS_REG))])]
12555   "TARGET_64BIT && TARGET_GNU2_TLS"
12556 {
12557   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12558   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12559 })
12560
12561 (define_insn "*tls_dynamic_lea_64"
12562   [(set (match_operand:DI 0 "register_operand" "=r")
12563         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12564                    UNSPEC_TLSDESC))]
12565   "TARGET_64BIT && TARGET_GNU2_TLS"
12566   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12567   [(set_attr "type" "lea")
12568    (set_attr "mode" "DI")
12569    (set_attr "length" "7")
12570    (set_attr "length_address" "4")])
12571
12572 (define_insn "*tls_dynamic_call_64"
12573   [(set (match_operand:DI 0 "register_operand" "=a")
12574         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12575                     (match_operand:DI 2 "register_operand" "0")
12576                     (reg:DI SP_REG)]
12577                    UNSPEC_TLSDESC))
12578    (clobber (reg:CC FLAGS_REG))]
12579   "TARGET_64BIT && TARGET_GNU2_TLS"
12580   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12581   [(set_attr "type" "call")
12582    (set_attr "length" "2")
12583    (set_attr "length_address" "0")])
12584
12585 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12586   [(set (match_operand:DI 0 "register_operand" "=&a")
12587         (plus:DI
12588          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12589                      (match_operand:DI 3 "" "")
12590                      (reg:DI SP_REG)]
12591                     UNSPEC_TLSDESC)
12592          (const:DI (unspec:DI
12593                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12594                     UNSPEC_DTPOFF))))
12595    (clobber (reg:CC FLAGS_REG))]
12596   "TARGET_64BIT && TARGET_GNU2_TLS"
12597   "#"
12598   ""
12599   [(set (match_dup 0) (match_dup 4))]
12600 {
12601   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12602   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12603 })
12604 \f
12605 ;; These patterns match the binary 387 instructions for addM3, subM3,
12606 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12607 ;; SFmode.  The first is the normal insn, the second the same insn but
12608 ;; with one operand a conversion, and the third the same insn but with
12609 ;; the other operand a conversion.  The conversion may be SFmode or
12610 ;; SImode if the target mode DFmode, but only SImode if the target mode
12611 ;; is SFmode.
12612
12613 ;; Gcc is slightly more smart about handling normal two address instructions
12614 ;; so use special patterns for add and mull.
12615
12616 (define_insn "*fop_<mode>_comm_mixed_avx"
12617   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12618         (match_operator:MODEF 3 "binary_fp_operator"
12619           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12620            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12621   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12622    && COMMUTATIVE_ARITH_P (operands[3])
12623    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12624   "* return output_387_binary_op (insn, operands);"
12625   [(set (attr "type")
12626         (if_then_else (eq_attr "alternative" "1")
12627            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12628               (const_string "ssemul")
12629               (const_string "sseadd"))
12630            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12631               (const_string "fmul")
12632               (const_string "fop"))))
12633    (set_attr "prefix" "orig,maybe_vex")
12634    (set_attr "mode" "<MODE>")])
12635
12636 (define_insn "*fop_<mode>_comm_mixed"
12637   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12638         (match_operator:MODEF 3 "binary_fp_operator"
12639           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12640            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12641   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12642    && COMMUTATIVE_ARITH_P (operands[3])
12643    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12644   "* return output_387_binary_op (insn, operands);"
12645   [(set (attr "type")
12646         (if_then_else (eq_attr "alternative" "1")
12647            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12648               (const_string "ssemul")
12649               (const_string "sseadd"))
12650            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12651               (const_string "fmul")
12652               (const_string "fop"))))
12653    (set_attr "mode" "<MODE>")])
12654
12655 (define_insn "*fop_<mode>_comm_avx"
12656   [(set (match_operand:MODEF 0 "register_operand" "=x")
12657         (match_operator:MODEF 3 "binary_fp_operator"
12658           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12659            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12660   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12661    && COMMUTATIVE_ARITH_P (operands[3])
12662    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12663   "* return output_387_binary_op (insn, operands);"
12664   [(set (attr "type")
12665         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12666            (const_string "ssemul")
12667            (const_string "sseadd")))
12668    (set_attr "prefix" "vex")
12669    (set_attr "mode" "<MODE>")])
12670
12671 (define_insn "*fop_<mode>_comm_sse"
12672   [(set (match_operand:MODEF 0 "register_operand" "=x")
12673         (match_operator:MODEF 3 "binary_fp_operator"
12674           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12675            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12676   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12677    && COMMUTATIVE_ARITH_P (operands[3])
12678    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12679   "* return output_387_binary_op (insn, operands);"
12680   [(set (attr "type")
12681         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12682            (const_string "ssemul")
12683            (const_string "sseadd")))
12684    (set_attr "mode" "<MODE>")])
12685
12686 (define_insn "*fop_<mode>_comm_i387"
12687   [(set (match_operand:MODEF 0 "register_operand" "=f")
12688         (match_operator:MODEF 3 "binary_fp_operator"
12689           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12690            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12691   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12692    && COMMUTATIVE_ARITH_P (operands[3])
12693    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12694   "* return output_387_binary_op (insn, operands);"
12695   [(set (attr "type")
12696         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12697            (const_string "fmul")
12698            (const_string "fop")))
12699    (set_attr "mode" "<MODE>")])
12700
12701 (define_insn "*fop_<mode>_1_mixed_avx"
12702   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12703         (match_operator:MODEF 3 "binary_fp_operator"
12704           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12705            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12706   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12707    && !COMMUTATIVE_ARITH_P (operands[3])
12708    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12709   "* return output_387_binary_op (insn, operands);"
12710   [(set (attr "type")
12711         (cond [(and (eq_attr "alternative" "2")
12712                     (match_operand:MODEF 3 "mult_operator" ""))
12713                  (const_string "ssemul")
12714                (and (eq_attr "alternative" "2")
12715                     (match_operand:MODEF 3 "div_operator" ""))
12716                  (const_string "ssediv")
12717                (eq_attr "alternative" "2")
12718                  (const_string "sseadd")
12719                (match_operand:MODEF 3 "mult_operator" "")
12720                  (const_string "fmul")
12721                (match_operand:MODEF 3 "div_operator" "")
12722                  (const_string "fdiv")
12723               ]
12724               (const_string "fop")))
12725    (set_attr "prefix" "orig,orig,maybe_vex")
12726    (set_attr "mode" "<MODE>")])
12727
12728 (define_insn "*fop_<mode>_1_mixed"
12729   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12730         (match_operator:MODEF 3 "binary_fp_operator"
12731           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12732            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12733   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12734    && !COMMUTATIVE_ARITH_P (operands[3])
12735    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12736   "* return output_387_binary_op (insn, operands);"
12737   [(set (attr "type")
12738         (cond [(and (eq_attr "alternative" "2")
12739                     (match_operand:MODEF 3 "mult_operator" ""))
12740                  (const_string "ssemul")
12741                (and (eq_attr "alternative" "2")
12742                     (match_operand:MODEF 3 "div_operator" ""))
12743                  (const_string "ssediv")
12744                (eq_attr "alternative" "2")
12745                  (const_string "sseadd")
12746                (match_operand:MODEF 3 "mult_operator" "")
12747                  (const_string "fmul")
12748                (match_operand:MODEF 3 "div_operator" "")
12749                  (const_string "fdiv")
12750               ]
12751               (const_string "fop")))
12752    (set_attr "mode" "<MODE>")])
12753
12754 (define_insn "*rcpsf2_sse"
12755   [(set (match_operand:SF 0 "register_operand" "=x")
12756         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12757                    UNSPEC_RCP))]
12758   "TARGET_SSE_MATH"
12759   "%vrcpss\t{%1, %d0|%d0, %1}"
12760   [(set_attr "type" "sse")
12761    (set_attr "atom_sse_attr" "rcp")
12762    (set_attr "prefix" "maybe_vex")
12763    (set_attr "mode" "SF")])
12764
12765 (define_insn "*fop_<mode>_1_avx"
12766   [(set (match_operand:MODEF 0 "register_operand" "=x")
12767         (match_operator:MODEF 3 "binary_fp_operator"
12768           [(match_operand:MODEF 1 "register_operand" "x")
12769            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12770   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12771    && !COMMUTATIVE_ARITH_P (operands[3])"
12772   "* return output_387_binary_op (insn, operands);"
12773   [(set (attr "type")
12774         (cond [(match_operand:MODEF 3 "mult_operator" "")
12775                  (const_string "ssemul")
12776                (match_operand:MODEF 3 "div_operator" "")
12777                  (const_string "ssediv")
12778               ]
12779               (const_string "sseadd")))
12780    (set_attr "prefix" "vex")
12781    (set_attr "mode" "<MODE>")])
12782
12783 (define_insn "*fop_<mode>_1_sse"
12784   [(set (match_operand:MODEF 0 "register_operand" "=x")
12785         (match_operator:MODEF 3 "binary_fp_operator"
12786           [(match_operand:MODEF 1 "register_operand" "0")
12787            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12788   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12789    && !COMMUTATIVE_ARITH_P (operands[3])"
12790   "* return output_387_binary_op (insn, operands);"
12791   [(set (attr "type")
12792         (cond [(match_operand:MODEF 3 "mult_operator" "")
12793                  (const_string "ssemul")
12794                (match_operand:MODEF 3 "div_operator" "")
12795                  (const_string "ssediv")
12796               ]
12797               (const_string "sseadd")))
12798    (set_attr "mode" "<MODE>")])
12799
12800 ;; This pattern is not fully shadowed by the pattern above.
12801 (define_insn "*fop_<mode>_1_i387"
12802   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12803         (match_operator:MODEF 3 "binary_fp_operator"
12804           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12805            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12806   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12807    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12808    && !COMMUTATIVE_ARITH_P (operands[3])
12809    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12810   "* return output_387_binary_op (insn, operands);"
12811   [(set (attr "type")
12812         (cond [(match_operand:MODEF 3 "mult_operator" "")
12813                  (const_string "fmul")
12814                (match_operand:MODEF 3 "div_operator" "")
12815                  (const_string "fdiv")
12816               ]
12817               (const_string "fop")))
12818    (set_attr "mode" "<MODE>")])
12819
12820 ;; ??? Add SSE splitters for these!
12821 (define_insn "*fop_<MODEF:mode>_2_i387"
12822   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12823         (match_operator:MODEF 3 "binary_fp_operator"
12824           [(float:MODEF
12825              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12826            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12827   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12828    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12829    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12830   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12831   [(set (attr "type")
12832         (cond [(match_operand:MODEF 3 "mult_operator" "")
12833                  (const_string "fmul")
12834                (match_operand:MODEF 3 "div_operator" "")
12835                  (const_string "fdiv")
12836               ]
12837               (const_string "fop")))
12838    (set_attr "fp_int_src" "true")
12839    (set_attr "mode" "<X87MODEI12:MODE>")])
12840
12841 (define_insn "*fop_<MODEF:mode>_3_i387"
12842   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12843         (match_operator:MODEF 3 "binary_fp_operator"
12844           [(match_operand:MODEF 1 "register_operand" "0,0")
12845            (float:MODEF
12846              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12847   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12848    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12849    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12850   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12851   [(set (attr "type")
12852         (cond [(match_operand:MODEF 3 "mult_operator" "")
12853                  (const_string "fmul")
12854                (match_operand:MODEF 3 "div_operator" "")
12855                  (const_string "fdiv")
12856               ]
12857               (const_string "fop")))
12858    (set_attr "fp_int_src" "true")
12859    (set_attr "mode" "<MODE>")])
12860
12861 (define_insn "*fop_df_4_i387"
12862   [(set (match_operand:DF 0 "register_operand" "=f,f")
12863         (match_operator:DF 3 "binary_fp_operator"
12864            [(float_extend:DF
12865              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12866             (match_operand:DF 2 "register_operand" "0,f")]))]
12867   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12868    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12869    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12870   "* return output_387_binary_op (insn, operands);"
12871   [(set (attr "type")
12872         (cond [(match_operand:DF 3 "mult_operator" "")
12873                  (const_string "fmul")
12874                (match_operand:DF 3 "div_operator" "")
12875                  (const_string "fdiv")
12876               ]
12877               (const_string "fop")))
12878    (set_attr "mode" "SF")])
12879
12880 (define_insn "*fop_df_5_i387"
12881   [(set (match_operand:DF 0 "register_operand" "=f,f")
12882         (match_operator:DF 3 "binary_fp_operator"
12883           [(match_operand:DF 1 "register_operand" "0,f")
12884            (float_extend:DF
12885             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12886   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12887    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12888   "* return output_387_binary_op (insn, operands);"
12889   [(set (attr "type")
12890         (cond [(match_operand:DF 3 "mult_operator" "")
12891                  (const_string "fmul")
12892                (match_operand:DF 3 "div_operator" "")
12893                  (const_string "fdiv")
12894               ]
12895               (const_string "fop")))
12896    (set_attr "mode" "SF")])
12897
12898 (define_insn "*fop_df_6_i387"
12899   [(set (match_operand:DF 0 "register_operand" "=f,f")
12900         (match_operator:DF 3 "binary_fp_operator"
12901           [(float_extend:DF
12902             (match_operand:SF 1 "register_operand" "0,f"))
12903            (float_extend:DF
12904             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12905   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12906    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12907   "* return output_387_binary_op (insn, operands);"
12908   [(set (attr "type")
12909         (cond [(match_operand:DF 3 "mult_operator" "")
12910                  (const_string "fmul")
12911                (match_operand:DF 3 "div_operator" "")
12912                  (const_string "fdiv")
12913               ]
12914               (const_string "fop")))
12915    (set_attr "mode" "SF")])
12916
12917 (define_insn "*fop_xf_comm_i387"
12918   [(set (match_operand:XF 0 "register_operand" "=f")
12919         (match_operator:XF 3 "binary_fp_operator"
12920                         [(match_operand:XF 1 "register_operand" "%0")
12921                          (match_operand:XF 2 "register_operand" "f")]))]
12922   "TARGET_80387
12923    && COMMUTATIVE_ARITH_P (operands[3])"
12924   "* return output_387_binary_op (insn, operands);"
12925   [(set (attr "type")
12926         (if_then_else (match_operand:XF 3 "mult_operator" "")
12927            (const_string "fmul")
12928            (const_string "fop")))
12929    (set_attr "mode" "XF")])
12930
12931 (define_insn "*fop_xf_1_i387"
12932   [(set (match_operand:XF 0 "register_operand" "=f,f")
12933         (match_operator:XF 3 "binary_fp_operator"
12934                         [(match_operand:XF 1 "register_operand" "0,f")
12935                          (match_operand:XF 2 "register_operand" "f,0")]))]
12936   "TARGET_80387
12937    && !COMMUTATIVE_ARITH_P (operands[3])"
12938   "* return output_387_binary_op (insn, operands);"
12939   [(set (attr "type")
12940         (cond [(match_operand:XF 3 "mult_operator" "")
12941                  (const_string "fmul")
12942                (match_operand:XF 3 "div_operator" "")
12943                  (const_string "fdiv")
12944               ]
12945               (const_string "fop")))
12946    (set_attr "mode" "XF")])
12947
12948 (define_insn "*fop_xf_2_i387"
12949   [(set (match_operand:XF 0 "register_operand" "=f,f")
12950         (match_operator:XF 3 "binary_fp_operator"
12951           [(float:XF
12952              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12953            (match_operand:XF 2 "register_operand" "0,0")]))]
12954   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12955   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12956   [(set (attr "type")
12957         (cond [(match_operand:XF 3 "mult_operator" "")
12958                  (const_string "fmul")
12959                (match_operand:XF 3 "div_operator" "")
12960                  (const_string "fdiv")
12961               ]
12962               (const_string "fop")))
12963    (set_attr "fp_int_src" "true")
12964    (set_attr "mode" "<MODE>")])
12965
12966 (define_insn "*fop_xf_3_i387"
12967   [(set (match_operand:XF 0 "register_operand" "=f,f")
12968         (match_operator:XF 3 "binary_fp_operator"
12969           [(match_operand:XF 1 "register_operand" "0,0")
12970            (float:XF
12971              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12972   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12973   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12974   [(set (attr "type")
12975         (cond [(match_operand:XF 3 "mult_operator" "")
12976                  (const_string "fmul")
12977                (match_operand:XF 3 "div_operator" "")
12978                  (const_string "fdiv")
12979               ]
12980               (const_string "fop")))
12981    (set_attr "fp_int_src" "true")
12982    (set_attr "mode" "<MODE>")])
12983
12984 (define_insn "*fop_xf_4_i387"
12985   [(set (match_operand:XF 0 "register_operand" "=f,f")
12986         (match_operator:XF 3 "binary_fp_operator"
12987            [(float_extend:XF
12988               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12989             (match_operand:XF 2 "register_operand" "0,f")]))]
12990   "TARGET_80387"
12991   "* return output_387_binary_op (insn, operands);"
12992   [(set (attr "type")
12993         (cond [(match_operand:XF 3 "mult_operator" "")
12994                  (const_string "fmul")
12995                (match_operand:XF 3 "div_operator" "")
12996                  (const_string "fdiv")
12997               ]
12998               (const_string "fop")))
12999    (set_attr "mode" "<MODE>")])
13000
13001 (define_insn "*fop_xf_5_i387"
13002   [(set (match_operand:XF 0 "register_operand" "=f,f")
13003         (match_operator:XF 3 "binary_fp_operator"
13004           [(match_operand:XF 1 "register_operand" "0,f")
13005            (float_extend:XF
13006              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13007   "TARGET_80387"
13008   "* return output_387_binary_op (insn, operands);"
13009   [(set (attr "type")
13010         (cond [(match_operand:XF 3 "mult_operator" "")
13011                  (const_string "fmul")
13012                (match_operand:XF 3 "div_operator" "")
13013                  (const_string "fdiv")
13014               ]
13015               (const_string "fop")))
13016    (set_attr "mode" "<MODE>")])
13017
13018 (define_insn "*fop_xf_6_i387"
13019   [(set (match_operand:XF 0 "register_operand" "=f,f")
13020         (match_operator:XF 3 "binary_fp_operator"
13021           [(float_extend:XF
13022              (match_operand:MODEF 1 "register_operand" "0,f"))
13023            (float_extend:XF
13024              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13025   "TARGET_80387"
13026   "* return output_387_binary_op (insn, operands);"
13027   [(set (attr "type")
13028         (cond [(match_operand:XF 3 "mult_operator" "")
13029                  (const_string "fmul")
13030                (match_operand:XF 3 "div_operator" "")
13031                  (const_string "fdiv")
13032               ]
13033               (const_string "fop")))
13034    (set_attr "mode" "<MODE>")])
13035
13036 (define_split
13037   [(set (match_operand 0 "register_operand" "")
13038         (match_operator 3 "binary_fp_operator"
13039            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13040             (match_operand 2 "register_operand" "")]))]
13041   "reload_completed
13042    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13043    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13044   [(const_int 0)]
13045 {
13046   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13047   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13048   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13049                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13050                                           GET_MODE (operands[3]),
13051                                           operands[4],
13052                                           operands[2])));
13053   ix86_free_from_memory (GET_MODE (operands[1]));
13054   DONE;
13055 })
13056
13057 (define_split
13058   [(set (match_operand 0 "register_operand" "")
13059         (match_operator 3 "binary_fp_operator"
13060            [(match_operand 1 "register_operand" "")
13061             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13062   "reload_completed
13063    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13064    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13065   [(const_int 0)]
13066 {
13067   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13068   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13069   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13070                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13071                                           GET_MODE (operands[3]),
13072                                           operands[1],
13073                                           operands[4])));
13074   ix86_free_from_memory (GET_MODE (operands[2]));
13075   DONE;
13076 })
13077 \f
13078 ;; FPU special functions.
13079
13080 ;; This pattern implements a no-op XFmode truncation for
13081 ;; all fancy i386 XFmode math functions.
13082
13083 (define_insn "truncxf<mode>2_i387_noop_unspec"
13084   [(set (match_operand:MODEF 0 "register_operand" "=f")
13085         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13086         UNSPEC_TRUNC_NOOP))]
13087   "TARGET_USE_FANCY_MATH_387"
13088   "* return output_387_reg_move (insn, operands);"
13089   [(set_attr "type" "fmov")
13090    (set_attr "mode" "<MODE>")])
13091
13092 (define_insn "sqrtxf2"
13093   [(set (match_operand:XF 0 "register_operand" "=f")
13094         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13095   "TARGET_USE_FANCY_MATH_387"
13096   "fsqrt"
13097   [(set_attr "type" "fpspc")
13098    (set_attr "mode" "XF")
13099    (set_attr "athlon_decode" "direct")
13100    (set_attr "amdfam10_decode" "direct")
13101    (set_attr "bdver1_decode" "direct")])
13102
13103 (define_insn "sqrt_extend<mode>xf2_i387"
13104   [(set (match_operand:XF 0 "register_operand" "=f")
13105         (sqrt:XF
13106           (float_extend:XF
13107             (match_operand:MODEF 1 "register_operand" "0"))))]
13108   "TARGET_USE_FANCY_MATH_387"
13109   "fsqrt"
13110   [(set_attr "type" "fpspc")
13111    (set_attr "mode" "XF")
13112    (set_attr "athlon_decode" "direct")
13113    (set_attr "amdfam10_decode" "direct")
13114    (set_attr "bdver1_decode" "direct")])
13115
13116 (define_insn "*rsqrtsf2_sse"
13117   [(set (match_operand:SF 0 "register_operand" "=x")
13118         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13119                    UNSPEC_RSQRT))]
13120   "TARGET_SSE_MATH"
13121   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13122   [(set_attr "type" "sse")
13123    (set_attr "atom_sse_attr" "rcp")
13124    (set_attr "prefix" "maybe_vex")
13125    (set_attr "mode" "SF")])
13126
13127 (define_expand "rsqrtsf2"
13128   [(set (match_operand:SF 0 "register_operand" "")
13129         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13130                    UNSPEC_RSQRT))]
13131   "TARGET_SSE_MATH"
13132 {
13133   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13134   DONE;
13135 })
13136
13137 (define_insn "*sqrt<mode>2_sse"
13138   [(set (match_operand:MODEF 0 "register_operand" "=x")
13139         (sqrt:MODEF
13140           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13141   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13142   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13143   [(set_attr "type" "sse")
13144    (set_attr "atom_sse_attr" "sqrt")
13145    (set_attr "prefix" "maybe_vex")
13146    (set_attr "mode" "<MODE>")
13147    (set_attr "athlon_decode" "*")
13148    (set_attr "amdfam10_decode" "*")
13149    (set_attr "bdver1_decode" "*")])
13150
13151 (define_expand "sqrt<mode>2"
13152   [(set (match_operand:MODEF 0 "register_operand" "")
13153         (sqrt:MODEF
13154           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13155   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13156    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13157 {
13158   if (<MODE>mode == SFmode
13159       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13160       && flag_finite_math_only && !flag_trapping_math
13161       && flag_unsafe_math_optimizations)
13162     {
13163       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13164       DONE;
13165     }
13166
13167   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13168     {
13169       rtx op0 = gen_reg_rtx (XFmode);
13170       rtx op1 = force_reg (<MODE>mode, operands[1]);
13171
13172       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13173       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13174       DONE;
13175    }
13176 })
13177
13178 (define_insn "fpremxf4_i387"
13179   [(set (match_operand:XF 0 "register_operand" "=f")
13180         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13181                     (match_operand:XF 3 "register_operand" "1")]
13182                    UNSPEC_FPREM_F))
13183    (set (match_operand:XF 1 "register_operand" "=u")
13184         (unspec:XF [(match_dup 2) (match_dup 3)]
13185                    UNSPEC_FPREM_U))
13186    (set (reg:CCFP FPSR_REG)
13187         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13188                      UNSPEC_C2_FLAG))]
13189   "TARGET_USE_FANCY_MATH_387"
13190   "fprem"
13191   [(set_attr "type" "fpspc")
13192    (set_attr "mode" "XF")])
13193
13194 (define_expand "fmodxf3"
13195   [(use (match_operand:XF 0 "register_operand" ""))
13196    (use (match_operand:XF 1 "general_operand" ""))
13197    (use (match_operand:XF 2 "general_operand" ""))]
13198   "TARGET_USE_FANCY_MATH_387"
13199 {
13200   rtx label = gen_label_rtx ();
13201
13202   rtx op1 = gen_reg_rtx (XFmode);
13203   rtx op2 = gen_reg_rtx (XFmode);
13204
13205   emit_move_insn (op2, operands[2]);
13206   emit_move_insn (op1, operands[1]);
13207
13208   emit_label (label);
13209   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13210   ix86_emit_fp_unordered_jump (label);
13211   LABEL_NUSES (label) = 1;
13212
13213   emit_move_insn (operands[0], op1);
13214   DONE;
13215 })
13216
13217 (define_expand "fmod<mode>3"
13218   [(use (match_operand:MODEF 0 "register_operand" ""))
13219    (use (match_operand:MODEF 1 "general_operand" ""))
13220    (use (match_operand:MODEF 2 "general_operand" ""))]
13221   "TARGET_USE_FANCY_MATH_387"
13222 {
13223   rtx (*gen_truncxf) (rtx, rtx);
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_insn (gen_extend<mode>xf2 (op2, operands[2]));
13231   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13232
13233   emit_label (label);
13234   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13235   ix86_emit_fp_unordered_jump (label);
13236   LABEL_NUSES (label) = 1;
13237
13238   /* Truncate the result properly for strict SSE math.  */
13239   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13240       && !TARGET_MIX_SSE_I387)
13241     gen_truncxf = gen_truncxf<mode>2;
13242   else
13243     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13244
13245   emit_insn (gen_truncxf (operands[0], op1));
13246   DONE;
13247 })
13248
13249 (define_insn "fprem1xf4_i387"
13250   [(set (match_operand:XF 0 "register_operand" "=f")
13251         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13252                     (match_operand:XF 3 "register_operand" "1")]
13253                    UNSPEC_FPREM1_F))
13254    (set (match_operand:XF 1 "register_operand" "=u")
13255         (unspec:XF [(match_dup 2) (match_dup 3)]
13256                    UNSPEC_FPREM1_U))
13257    (set (reg:CCFP FPSR_REG)
13258         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13259                      UNSPEC_C2_FLAG))]
13260   "TARGET_USE_FANCY_MATH_387"
13261   "fprem1"
13262   [(set_attr "type" "fpspc")
13263    (set_attr "mode" "XF")])
13264
13265 (define_expand "remainderxf3"
13266   [(use (match_operand:XF 0 "register_operand" ""))
13267    (use (match_operand:XF 1 "general_operand" ""))
13268    (use (match_operand:XF 2 "general_operand" ""))]
13269   "TARGET_USE_FANCY_MATH_387"
13270 {
13271   rtx label = gen_label_rtx ();
13272
13273   rtx op1 = gen_reg_rtx (XFmode);
13274   rtx op2 = gen_reg_rtx (XFmode);
13275
13276   emit_move_insn (op2, operands[2]);
13277   emit_move_insn (op1, operands[1]);
13278
13279   emit_label (label);
13280   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13281   ix86_emit_fp_unordered_jump (label);
13282   LABEL_NUSES (label) = 1;
13283
13284   emit_move_insn (operands[0], op1);
13285   DONE;
13286 })
13287
13288 (define_expand "remainder<mode>3"
13289   [(use (match_operand:MODEF 0 "register_operand" ""))
13290    (use (match_operand:MODEF 1 "general_operand" ""))
13291    (use (match_operand:MODEF 2 "general_operand" ""))]
13292   "TARGET_USE_FANCY_MATH_387"
13293 {
13294   rtx (*gen_truncxf) (rtx, rtx);
13295
13296   rtx label = gen_label_rtx ();
13297
13298   rtx op1 = gen_reg_rtx (XFmode);
13299   rtx op2 = gen_reg_rtx (XFmode);
13300
13301   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13302   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13303
13304   emit_label (label);
13305
13306   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13307   ix86_emit_fp_unordered_jump (label);
13308   LABEL_NUSES (label) = 1;
13309
13310   /* Truncate the result properly for strict SSE math.  */
13311   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13312       && !TARGET_MIX_SSE_I387)
13313     gen_truncxf = gen_truncxf<mode>2;
13314   else
13315     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13316
13317   emit_insn (gen_truncxf (operands[0], op1));
13318   DONE;
13319 })
13320
13321 (define_insn "*sinxf2_i387"
13322   [(set (match_operand:XF 0 "register_operand" "=f")
13323         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13324   "TARGET_USE_FANCY_MATH_387
13325    && flag_unsafe_math_optimizations"
13326   "fsin"
13327   [(set_attr "type" "fpspc")
13328    (set_attr "mode" "XF")])
13329
13330 (define_insn "*sin_extend<mode>xf2_i387"
13331   [(set (match_operand:XF 0 "register_operand" "=f")
13332         (unspec:XF [(float_extend:XF
13333                       (match_operand:MODEF 1 "register_operand" "0"))]
13334                    UNSPEC_SIN))]
13335   "TARGET_USE_FANCY_MATH_387
13336    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13337        || TARGET_MIX_SSE_I387)
13338    && flag_unsafe_math_optimizations"
13339   "fsin"
13340   [(set_attr "type" "fpspc")
13341    (set_attr "mode" "XF")])
13342
13343 (define_insn "*cosxf2_i387"
13344   [(set (match_operand:XF 0 "register_operand" "=f")
13345         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13346   "TARGET_USE_FANCY_MATH_387
13347    && flag_unsafe_math_optimizations"
13348   "fcos"
13349   [(set_attr "type" "fpspc")
13350    (set_attr "mode" "XF")])
13351
13352 (define_insn "*cos_extend<mode>xf2_i387"
13353   [(set (match_operand:XF 0 "register_operand" "=f")
13354         (unspec:XF [(float_extend:XF
13355                       (match_operand:MODEF 1 "register_operand" "0"))]
13356                    UNSPEC_COS))]
13357   "TARGET_USE_FANCY_MATH_387
13358    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13359        || TARGET_MIX_SSE_I387)
13360    && flag_unsafe_math_optimizations"
13361   "fcos"
13362   [(set_attr "type" "fpspc")
13363    (set_attr "mode" "XF")])
13364
13365 ;; When sincos pattern is defined, sin and cos builtin functions will be
13366 ;; expanded to sincos pattern with one of its outputs left unused.
13367 ;; CSE pass will figure out if two sincos patterns can be combined,
13368 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13369 ;; depending on the unused output.
13370
13371 (define_insn "sincosxf3"
13372   [(set (match_operand:XF 0 "register_operand" "=f")
13373         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13374                    UNSPEC_SINCOS_COS))
13375    (set (match_operand:XF 1 "register_operand" "=u")
13376         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13377   "TARGET_USE_FANCY_MATH_387
13378    && flag_unsafe_math_optimizations"
13379   "fsincos"
13380   [(set_attr "type" "fpspc")
13381    (set_attr "mode" "XF")])
13382
13383 (define_split
13384   [(set (match_operand:XF 0 "register_operand" "")
13385         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13386                    UNSPEC_SINCOS_COS))
13387    (set (match_operand:XF 1 "register_operand" "")
13388         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13389   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13390    && !(reload_completed || reload_in_progress)"
13391   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13392
13393 (define_split
13394   [(set (match_operand:XF 0 "register_operand" "")
13395         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13396                    UNSPEC_SINCOS_COS))
13397    (set (match_operand:XF 1 "register_operand" "")
13398         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13399   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13400    && !(reload_completed || reload_in_progress)"
13401   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13402
13403 (define_insn "sincos_extend<mode>xf3_i387"
13404   [(set (match_operand:XF 0 "register_operand" "=f")
13405         (unspec:XF [(float_extend:XF
13406                       (match_operand:MODEF 2 "register_operand" "0"))]
13407                    UNSPEC_SINCOS_COS))
13408    (set (match_operand:XF 1 "register_operand" "=u")
13409         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13410   "TARGET_USE_FANCY_MATH_387
13411    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13412        || TARGET_MIX_SSE_I387)
13413    && flag_unsafe_math_optimizations"
13414   "fsincos"
13415   [(set_attr "type" "fpspc")
13416    (set_attr "mode" "XF")])
13417
13418 (define_split
13419   [(set (match_operand:XF 0 "register_operand" "")
13420         (unspec:XF [(float_extend:XF
13421                       (match_operand:MODEF 2 "register_operand" ""))]
13422                    UNSPEC_SINCOS_COS))
13423    (set (match_operand:XF 1 "register_operand" "")
13424         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13425   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13426    && !(reload_completed || reload_in_progress)"
13427   [(set (match_dup 1)
13428         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13429
13430 (define_split
13431   [(set (match_operand:XF 0 "register_operand" "")
13432         (unspec:XF [(float_extend:XF
13433                       (match_operand:MODEF 2 "register_operand" ""))]
13434                    UNSPEC_SINCOS_COS))
13435    (set (match_operand:XF 1 "register_operand" "")
13436         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13437   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13438    && !(reload_completed || reload_in_progress)"
13439   [(set (match_dup 0)
13440         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13441
13442 (define_expand "sincos<mode>3"
13443   [(use (match_operand:MODEF 0 "register_operand" ""))
13444    (use (match_operand:MODEF 1 "register_operand" ""))
13445    (use (match_operand:MODEF 2 "register_operand" ""))]
13446   "TARGET_USE_FANCY_MATH_387
13447    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13448        || TARGET_MIX_SSE_I387)
13449    && flag_unsafe_math_optimizations"
13450 {
13451   rtx op0 = gen_reg_rtx (XFmode);
13452   rtx op1 = gen_reg_rtx (XFmode);
13453
13454   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13455   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13456   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13457   DONE;
13458 })
13459
13460 (define_insn "fptanxf4_i387"
13461   [(set (match_operand:XF 0 "register_operand" "=f")
13462         (match_operand:XF 3 "const_double_operand" "F"))
13463    (set (match_operand:XF 1 "register_operand" "=u")
13464         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13465                    UNSPEC_TAN))]
13466   "TARGET_USE_FANCY_MATH_387
13467    && flag_unsafe_math_optimizations
13468    && standard_80387_constant_p (operands[3]) == 2"
13469   "fptan"
13470   [(set_attr "type" "fpspc")
13471    (set_attr "mode" "XF")])
13472
13473 (define_insn "fptan_extend<mode>xf4_i387"
13474   [(set (match_operand:MODEF 0 "register_operand" "=f")
13475         (match_operand:MODEF 3 "const_double_operand" "F"))
13476    (set (match_operand:XF 1 "register_operand" "=u")
13477         (unspec:XF [(float_extend:XF
13478                       (match_operand:MODEF 2 "register_operand" "0"))]
13479                    UNSPEC_TAN))]
13480   "TARGET_USE_FANCY_MATH_387
13481    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13482        || TARGET_MIX_SSE_I387)
13483    && flag_unsafe_math_optimizations
13484    && standard_80387_constant_p (operands[3]) == 2"
13485   "fptan"
13486   [(set_attr "type" "fpspc")
13487    (set_attr "mode" "XF")])
13488
13489 (define_expand "tanxf2"
13490   [(use (match_operand:XF 0 "register_operand" ""))
13491    (use (match_operand:XF 1 "register_operand" ""))]
13492   "TARGET_USE_FANCY_MATH_387
13493    && flag_unsafe_math_optimizations"
13494 {
13495   rtx one = gen_reg_rtx (XFmode);
13496   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13497
13498   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13499   DONE;
13500 })
13501
13502 (define_expand "tan<mode>2"
13503   [(use (match_operand:MODEF 0 "register_operand" ""))
13504    (use (match_operand:MODEF 1 "register_operand" ""))]
13505   "TARGET_USE_FANCY_MATH_387
13506    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13507        || TARGET_MIX_SSE_I387)
13508    && flag_unsafe_math_optimizations"
13509 {
13510   rtx op0 = gen_reg_rtx (XFmode);
13511
13512   rtx one = gen_reg_rtx (<MODE>mode);
13513   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13514
13515   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13516                                              operands[1], op2));
13517   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13518   DONE;
13519 })
13520
13521 (define_insn "*fpatanxf3_i387"
13522   [(set (match_operand:XF 0 "register_operand" "=f")
13523         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13524                     (match_operand:XF 2 "register_operand" "u")]
13525                    UNSPEC_FPATAN))
13526    (clobber (match_scratch:XF 3 "=2"))]
13527   "TARGET_USE_FANCY_MATH_387
13528    && flag_unsafe_math_optimizations"
13529   "fpatan"
13530   [(set_attr "type" "fpspc")
13531    (set_attr "mode" "XF")])
13532
13533 (define_insn "fpatan_extend<mode>xf3_i387"
13534   [(set (match_operand:XF 0 "register_operand" "=f")
13535         (unspec:XF [(float_extend:XF
13536                       (match_operand:MODEF 1 "register_operand" "0"))
13537                     (float_extend:XF
13538                       (match_operand:MODEF 2 "register_operand" "u"))]
13539                    UNSPEC_FPATAN))
13540    (clobber (match_scratch:XF 3 "=2"))]
13541   "TARGET_USE_FANCY_MATH_387
13542    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13543        || TARGET_MIX_SSE_I387)
13544    && flag_unsafe_math_optimizations"
13545   "fpatan"
13546   [(set_attr "type" "fpspc")
13547    (set_attr "mode" "XF")])
13548
13549 (define_expand "atan2xf3"
13550   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13551                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13552                                (match_operand:XF 1 "register_operand" "")]
13553                               UNSPEC_FPATAN))
13554               (clobber (match_scratch:XF 3 ""))])]
13555   "TARGET_USE_FANCY_MATH_387
13556    && flag_unsafe_math_optimizations")
13557
13558 (define_expand "atan2<mode>3"
13559   [(use (match_operand:MODEF 0 "register_operand" ""))
13560    (use (match_operand:MODEF 1 "register_operand" ""))
13561    (use (match_operand:MODEF 2 "register_operand" ""))]
13562   "TARGET_USE_FANCY_MATH_387
13563    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13564        || TARGET_MIX_SSE_I387)
13565    && flag_unsafe_math_optimizations"
13566 {
13567   rtx op0 = gen_reg_rtx (XFmode);
13568
13569   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13570   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13571   DONE;
13572 })
13573
13574 (define_expand "atanxf2"
13575   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13576                    (unspec:XF [(match_dup 2)
13577                                (match_operand:XF 1 "register_operand" "")]
13578                               UNSPEC_FPATAN))
13579               (clobber (match_scratch:XF 3 ""))])]
13580   "TARGET_USE_FANCY_MATH_387
13581    && flag_unsafe_math_optimizations"
13582 {
13583   operands[2] = gen_reg_rtx (XFmode);
13584   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13585 })
13586
13587 (define_expand "atan<mode>2"
13588   [(use (match_operand:MODEF 0 "register_operand" ""))
13589    (use (match_operand:MODEF 1 "register_operand" ""))]
13590   "TARGET_USE_FANCY_MATH_387
13591    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13592        || TARGET_MIX_SSE_I387)
13593    && flag_unsafe_math_optimizations"
13594 {
13595   rtx op0 = gen_reg_rtx (XFmode);
13596
13597   rtx op2 = gen_reg_rtx (<MODE>mode);
13598   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13599
13600   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13601   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13602   DONE;
13603 })
13604
13605 (define_expand "asinxf2"
13606   [(set (match_dup 2)
13607         (mult:XF (match_operand:XF 1 "register_operand" "")
13608                  (match_dup 1)))
13609    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13610    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13611    (parallel [(set (match_operand:XF 0 "register_operand" "")
13612                    (unspec:XF [(match_dup 5) (match_dup 1)]
13613                               UNSPEC_FPATAN))
13614               (clobber (match_scratch:XF 6 ""))])]
13615   "TARGET_USE_FANCY_MATH_387
13616    && flag_unsafe_math_optimizations"
13617 {
13618   int i;
13619
13620   if (optimize_insn_for_size_p ())
13621     FAIL;
13622
13623   for (i = 2; i < 6; i++)
13624     operands[i] = gen_reg_rtx (XFmode);
13625
13626   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13627 })
13628
13629 (define_expand "asin<mode>2"
13630   [(use (match_operand:MODEF 0 "register_operand" ""))
13631    (use (match_operand:MODEF 1 "general_operand" ""))]
13632  "TARGET_USE_FANCY_MATH_387
13633    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13634        || TARGET_MIX_SSE_I387)
13635    && flag_unsafe_math_optimizations"
13636 {
13637   rtx op0 = gen_reg_rtx (XFmode);
13638   rtx op1 = gen_reg_rtx (XFmode);
13639
13640   if (optimize_insn_for_size_p ())
13641     FAIL;
13642
13643   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13644   emit_insn (gen_asinxf2 (op0, op1));
13645   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13646   DONE;
13647 })
13648
13649 (define_expand "acosxf2"
13650   [(set (match_dup 2)
13651         (mult:XF (match_operand:XF 1 "register_operand" "")
13652                  (match_dup 1)))
13653    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13654    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13655    (parallel [(set (match_operand:XF 0 "register_operand" "")
13656                    (unspec:XF [(match_dup 1) (match_dup 5)]
13657                               UNSPEC_FPATAN))
13658               (clobber (match_scratch:XF 6 ""))])]
13659   "TARGET_USE_FANCY_MATH_387
13660    && flag_unsafe_math_optimizations"
13661 {
13662   int i;
13663
13664   if (optimize_insn_for_size_p ())
13665     FAIL;
13666
13667   for (i = 2; i < 6; i++)
13668     operands[i] = gen_reg_rtx (XFmode);
13669
13670   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13671 })
13672
13673 (define_expand "acos<mode>2"
13674   [(use (match_operand:MODEF 0 "register_operand" ""))
13675    (use (match_operand:MODEF 1 "general_operand" ""))]
13676  "TARGET_USE_FANCY_MATH_387
13677    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13678        || TARGET_MIX_SSE_I387)
13679    && flag_unsafe_math_optimizations"
13680 {
13681   rtx op0 = gen_reg_rtx (XFmode);
13682   rtx op1 = gen_reg_rtx (XFmode);
13683
13684   if (optimize_insn_for_size_p ())
13685     FAIL;
13686
13687   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13688   emit_insn (gen_acosxf2 (op0, op1));
13689   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13690   DONE;
13691 })
13692
13693 (define_insn "fyl2xxf3_i387"
13694   [(set (match_operand:XF 0 "register_operand" "=f")
13695         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13696                     (match_operand:XF 2 "register_operand" "u")]
13697                    UNSPEC_FYL2X))
13698    (clobber (match_scratch:XF 3 "=2"))]
13699   "TARGET_USE_FANCY_MATH_387
13700    && flag_unsafe_math_optimizations"
13701   "fyl2x"
13702   [(set_attr "type" "fpspc")
13703    (set_attr "mode" "XF")])
13704
13705 (define_insn "fyl2x_extend<mode>xf3_i387"
13706   [(set (match_operand:XF 0 "register_operand" "=f")
13707         (unspec:XF [(float_extend:XF
13708                       (match_operand:MODEF 1 "register_operand" "0"))
13709                     (match_operand:XF 2 "register_operand" "u")]
13710                    UNSPEC_FYL2X))
13711    (clobber (match_scratch:XF 3 "=2"))]
13712   "TARGET_USE_FANCY_MATH_387
13713    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13714        || TARGET_MIX_SSE_I387)
13715    && flag_unsafe_math_optimizations"
13716   "fyl2x"
13717   [(set_attr "type" "fpspc")
13718    (set_attr "mode" "XF")])
13719
13720 (define_expand "logxf2"
13721   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13722                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13723                                (match_dup 2)] UNSPEC_FYL2X))
13724               (clobber (match_scratch:XF 3 ""))])]
13725   "TARGET_USE_FANCY_MATH_387
13726    && flag_unsafe_math_optimizations"
13727 {
13728   operands[2] = gen_reg_rtx (XFmode);
13729   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13730 })
13731
13732 (define_expand "log<mode>2"
13733   [(use (match_operand:MODEF 0 "register_operand" ""))
13734    (use (match_operand:MODEF 1 "register_operand" ""))]
13735   "TARGET_USE_FANCY_MATH_387
13736    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13737        || TARGET_MIX_SSE_I387)
13738    && flag_unsafe_math_optimizations"
13739 {
13740   rtx op0 = gen_reg_rtx (XFmode);
13741
13742   rtx op2 = gen_reg_rtx (XFmode);
13743   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13744
13745   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13746   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13747   DONE;
13748 })
13749
13750 (define_expand "log10xf2"
13751   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13752                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13753                                (match_dup 2)] UNSPEC_FYL2X))
13754               (clobber (match_scratch:XF 3 ""))])]
13755   "TARGET_USE_FANCY_MATH_387
13756    && flag_unsafe_math_optimizations"
13757 {
13758   operands[2] = gen_reg_rtx (XFmode);
13759   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13760 })
13761
13762 (define_expand "log10<mode>2"
13763   [(use (match_operand:MODEF 0 "register_operand" ""))
13764    (use (match_operand:MODEF 1 "register_operand" ""))]
13765   "TARGET_USE_FANCY_MATH_387
13766    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13767        || TARGET_MIX_SSE_I387)
13768    && flag_unsafe_math_optimizations"
13769 {
13770   rtx op0 = gen_reg_rtx (XFmode);
13771
13772   rtx op2 = gen_reg_rtx (XFmode);
13773   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13774
13775   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13776   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13777   DONE;
13778 })
13779
13780 (define_expand "log2xf2"
13781   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13782                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13783                                (match_dup 2)] UNSPEC_FYL2X))
13784               (clobber (match_scratch:XF 3 ""))])]
13785   "TARGET_USE_FANCY_MATH_387
13786    && flag_unsafe_math_optimizations"
13787 {
13788   operands[2] = gen_reg_rtx (XFmode);
13789   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13790 })
13791
13792 (define_expand "log2<mode>2"
13793   [(use (match_operand:MODEF 0 "register_operand" ""))
13794    (use (match_operand:MODEF 1 "register_operand" ""))]
13795   "TARGET_USE_FANCY_MATH_387
13796    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13797        || TARGET_MIX_SSE_I387)
13798    && flag_unsafe_math_optimizations"
13799 {
13800   rtx op0 = gen_reg_rtx (XFmode);
13801
13802   rtx op2 = gen_reg_rtx (XFmode);
13803   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13804
13805   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13806   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13807   DONE;
13808 })
13809
13810 (define_insn "fyl2xp1xf3_i387"
13811   [(set (match_operand:XF 0 "register_operand" "=f")
13812         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13813                     (match_operand:XF 2 "register_operand" "u")]
13814                    UNSPEC_FYL2XP1))
13815    (clobber (match_scratch:XF 3 "=2"))]
13816   "TARGET_USE_FANCY_MATH_387
13817    && flag_unsafe_math_optimizations"
13818   "fyl2xp1"
13819   [(set_attr "type" "fpspc")
13820    (set_attr "mode" "XF")])
13821
13822 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13823   [(set (match_operand:XF 0 "register_operand" "=f")
13824         (unspec:XF [(float_extend:XF
13825                       (match_operand:MODEF 1 "register_operand" "0"))
13826                     (match_operand:XF 2 "register_operand" "u")]
13827                    UNSPEC_FYL2XP1))
13828    (clobber (match_scratch:XF 3 "=2"))]
13829   "TARGET_USE_FANCY_MATH_387
13830    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13831        || TARGET_MIX_SSE_I387)
13832    && flag_unsafe_math_optimizations"
13833   "fyl2xp1"
13834   [(set_attr "type" "fpspc")
13835    (set_attr "mode" "XF")])
13836
13837 (define_expand "log1pxf2"
13838   [(use (match_operand:XF 0 "register_operand" ""))
13839    (use (match_operand:XF 1 "register_operand" ""))]
13840   "TARGET_USE_FANCY_MATH_387
13841    && flag_unsafe_math_optimizations"
13842 {
13843   if (optimize_insn_for_size_p ())
13844     FAIL;
13845
13846   ix86_emit_i387_log1p (operands[0], operands[1]);
13847   DONE;
13848 })
13849
13850 (define_expand "log1p<mode>2"
13851   [(use (match_operand:MODEF 0 "register_operand" ""))
13852    (use (match_operand:MODEF 1 "register_operand" ""))]
13853   "TARGET_USE_FANCY_MATH_387
13854    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13855        || TARGET_MIX_SSE_I387)
13856    && flag_unsafe_math_optimizations"
13857 {
13858   rtx op0;
13859
13860   if (optimize_insn_for_size_p ())
13861     FAIL;
13862
13863   op0 = gen_reg_rtx (XFmode);
13864
13865   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13866
13867   ix86_emit_i387_log1p (op0, operands[1]);
13868   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13869   DONE;
13870 })
13871
13872 (define_insn "fxtractxf3_i387"
13873   [(set (match_operand:XF 0 "register_operand" "=f")
13874         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13875                    UNSPEC_XTRACT_FRACT))
13876    (set (match_operand:XF 1 "register_operand" "=u")
13877         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13878   "TARGET_USE_FANCY_MATH_387
13879    && flag_unsafe_math_optimizations"
13880   "fxtract"
13881   [(set_attr "type" "fpspc")
13882    (set_attr "mode" "XF")])
13883
13884 (define_insn "fxtract_extend<mode>xf3_i387"
13885   [(set (match_operand:XF 0 "register_operand" "=f")
13886         (unspec:XF [(float_extend:XF
13887                       (match_operand:MODEF 2 "register_operand" "0"))]
13888                    UNSPEC_XTRACT_FRACT))
13889    (set (match_operand:XF 1 "register_operand" "=u")
13890         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13891   "TARGET_USE_FANCY_MATH_387
13892    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13893        || TARGET_MIX_SSE_I387)
13894    && flag_unsafe_math_optimizations"
13895   "fxtract"
13896   [(set_attr "type" "fpspc")
13897    (set_attr "mode" "XF")])
13898
13899 (define_expand "logbxf2"
13900   [(parallel [(set (match_dup 2)
13901                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13902                               UNSPEC_XTRACT_FRACT))
13903               (set (match_operand:XF 0 "register_operand" "")
13904                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13905   "TARGET_USE_FANCY_MATH_387
13906    && flag_unsafe_math_optimizations"
13907   "operands[2] = gen_reg_rtx (XFmode);")
13908
13909 (define_expand "logb<mode>2"
13910   [(use (match_operand:MODEF 0 "register_operand" ""))
13911    (use (match_operand:MODEF 1 "register_operand" ""))]
13912   "TARGET_USE_FANCY_MATH_387
13913    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13914        || TARGET_MIX_SSE_I387)
13915    && flag_unsafe_math_optimizations"
13916 {
13917   rtx op0 = gen_reg_rtx (XFmode);
13918   rtx op1 = gen_reg_rtx (XFmode);
13919
13920   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13921   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13922   DONE;
13923 })
13924
13925 (define_expand "ilogbxf2"
13926   [(use (match_operand:SI 0 "register_operand" ""))
13927    (use (match_operand:XF 1 "register_operand" ""))]
13928   "TARGET_USE_FANCY_MATH_387
13929    && flag_unsafe_math_optimizations"
13930 {
13931   rtx op0, op1;
13932
13933   if (optimize_insn_for_size_p ())
13934     FAIL;
13935
13936   op0 = gen_reg_rtx (XFmode);
13937   op1 = gen_reg_rtx (XFmode);
13938
13939   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13940   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13941   DONE;
13942 })
13943
13944 (define_expand "ilogb<mode>2"
13945   [(use (match_operand:SI 0 "register_operand" ""))
13946    (use (match_operand:MODEF 1 "register_operand" ""))]
13947   "TARGET_USE_FANCY_MATH_387
13948    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13949        || TARGET_MIX_SSE_I387)
13950    && flag_unsafe_math_optimizations"
13951 {
13952   rtx op0, op1;
13953
13954   if (optimize_insn_for_size_p ())
13955     FAIL;
13956
13957   op0 = gen_reg_rtx (XFmode);
13958   op1 = gen_reg_rtx (XFmode);
13959
13960   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13961   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13962   DONE;
13963 })
13964
13965 (define_insn "*f2xm1xf2_i387"
13966   [(set (match_operand:XF 0 "register_operand" "=f")
13967         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13968                    UNSPEC_F2XM1))]
13969   "TARGET_USE_FANCY_MATH_387
13970    && flag_unsafe_math_optimizations"
13971   "f2xm1"
13972   [(set_attr "type" "fpspc")
13973    (set_attr "mode" "XF")])
13974
13975 (define_insn "*fscalexf4_i387"
13976   [(set (match_operand:XF 0 "register_operand" "=f")
13977         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13978                     (match_operand:XF 3 "register_operand" "1")]
13979                    UNSPEC_FSCALE_FRACT))
13980    (set (match_operand:XF 1 "register_operand" "=u")
13981         (unspec:XF [(match_dup 2) (match_dup 3)]
13982                    UNSPEC_FSCALE_EXP))]
13983   "TARGET_USE_FANCY_MATH_387
13984    && flag_unsafe_math_optimizations"
13985   "fscale"
13986   [(set_attr "type" "fpspc")
13987    (set_attr "mode" "XF")])
13988
13989 (define_expand "expNcorexf3"
13990   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13991                                (match_operand:XF 2 "register_operand" "")))
13992    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13993    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13994    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13995    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13996    (parallel [(set (match_operand:XF 0 "register_operand" "")
13997                    (unspec:XF [(match_dup 8) (match_dup 4)]
13998                               UNSPEC_FSCALE_FRACT))
13999               (set (match_dup 9)
14000                    (unspec:XF [(match_dup 8) (match_dup 4)]
14001                               UNSPEC_FSCALE_EXP))])]
14002   "TARGET_USE_FANCY_MATH_387
14003    && flag_unsafe_math_optimizations"
14004 {
14005   int i;
14006
14007   if (optimize_insn_for_size_p ())
14008     FAIL;
14009
14010   for (i = 3; i < 10; i++)
14011     operands[i] = gen_reg_rtx (XFmode);
14012
14013   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14014 })
14015
14016 (define_expand "expxf2"
14017   [(use (match_operand:XF 0 "register_operand" ""))
14018    (use (match_operand:XF 1 "register_operand" ""))]
14019   "TARGET_USE_FANCY_MATH_387
14020    && flag_unsafe_math_optimizations"
14021 {
14022   rtx op2;
14023
14024   if (optimize_insn_for_size_p ())
14025     FAIL;
14026
14027   op2 = gen_reg_rtx (XFmode);
14028   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14029
14030   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14031   DONE;
14032 })
14033
14034 (define_expand "exp<mode>2"
14035   [(use (match_operand:MODEF 0 "register_operand" ""))
14036    (use (match_operand:MODEF 1 "general_operand" ""))]
14037  "TARGET_USE_FANCY_MATH_387
14038    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14039        || TARGET_MIX_SSE_I387)
14040    && flag_unsafe_math_optimizations"
14041 {
14042   rtx op0, op1;
14043
14044   if (optimize_insn_for_size_p ())
14045     FAIL;
14046
14047   op0 = gen_reg_rtx (XFmode);
14048   op1 = gen_reg_rtx (XFmode);
14049
14050   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14051   emit_insn (gen_expxf2 (op0, op1));
14052   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14053   DONE;
14054 })
14055
14056 (define_expand "exp10xf2"
14057   [(use (match_operand:XF 0 "register_operand" ""))
14058    (use (match_operand:XF 1 "register_operand" ""))]
14059   "TARGET_USE_FANCY_MATH_387
14060    && flag_unsafe_math_optimizations"
14061 {
14062   rtx op2;
14063
14064   if (optimize_insn_for_size_p ())
14065     FAIL;
14066
14067   op2 = gen_reg_rtx (XFmode);
14068   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14069
14070   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14071   DONE;
14072 })
14073
14074 (define_expand "exp10<mode>2"
14075   [(use (match_operand:MODEF 0 "register_operand" ""))
14076    (use (match_operand:MODEF 1 "general_operand" ""))]
14077  "TARGET_USE_FANCY_MATH_387
14078    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14079        || TARGET_MIX_SSE_I387)
14080    && flag_unsafe_math_optimizations"
14081 {
14082   rtx op0, op1;
14083
14084   if (optimize_insn_for_size_p ())
14085     FAIL;
14086
14087   op0 = gen_reg_rtx (XFmode);
14088   op1 = gen_reg_rtx (XFmode);
14089
14090   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14091   emit_insn (gen_exp10xf2 (op0, op1));
14092   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14093   DONE;
14094 })
14095
14096 (define_expand "exp2xf2"
14097   [(use (match_operand:XF 0 "register_operand" ""))
14098    (use (match_operand:XF 1 "register_operand" ""))]
14099   "TARGET_USE_FANCY_MATH_387
14100    && flag_unsafe_math_optimizations"
14101 {
14102   rtx op2;
14103
14104   if (optimize_insn_for_size_p ())
14105     FAIL;
14106
14107   op2 = gen_reg_rtx (XFmode);
14108   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14109
14110   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14111   DONE;
14112 })
14113
14114 (define_expand "exp2<mode>2"
14115   [(use (match_operand:MODEF 0 "register_operand" ""))
14116    (use (match_operand:MODEF 1 "general_operand" ""))]
14117  "TARGET_USE_FANCY_MATH_387
14118    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14119        || TARGET_MIX_SSE_I387)
14120    && flag_unsafe_math_optimizations"
14121 {
14122   rtx op0, op1;
14123
14124   if (optimize_insn_for_size_p ())
14125     FAIL;
14126
14127   op0 = gen_reg_rtx (XFmode);
14128   op1 = gen_reg_rtx (XFmode);
14129
14130   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14131   emit_insn (gen_exp2xf2 (op0, op1));
14132   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14133   DONE;
14134 })
14135
14136 (define_expand "expm1xf2"
14137   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14138                                (match_dup 2)))
14139    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14140    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14141    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14142    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14143    (parallel [(set (match_dup 7)
14144                    (unspec:XF [(match_dup 6) (match_dup 4)]
14145                               UNSPEC_FSCALE_FRACT))
14146               (set (match_dup 8)
14147                    (unspec:XF [(match_dup 6) (match_dup 4)]
14148                               UNSPEC_FSCALE_EXP))])
14149    (parallel [(set (match_dup 10)
14150                    (unspec:XF [(match_dup 9) (match_dup 8)]
14151                               UNSPEC_FSCALE_FRACT))
14152               (set (match_dup 11)
14153                    (unspec:XF [(match_dup 9) (match_dup 8)]
14154                               UNSPEC_FSCALE_EXP))])
14155    (set (match_dup 12) (minus:XF (match_dup 10)
14156                                  (float_extend:XF (match_dup 13))))
14157    (set (match_operand:XF 0 "register_operand" "")
14158         (plus:XF (match_dup 12) (match_dup 7)))]
14159   "TARGET_USE_FANCY_MATH_387
14160    && flag_unsafe_math_optimizations"
14161 {
14162   int i;
14163
14164   if (optimize_insn_for_size_p ())
14165     FAIL;
14166
14167   for (i = 2; i < 13; i++)
14168     operands[i] = gen_reg_rtx (XFmode);
14169
14170   operands[13]
14171     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14172
14173   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14174 })
14175
14176 (define_expand "expm1<mode>2"
14177   [(use (match_operand:MODEF 0 "register_operand" ""))
14178    (use (match_operand:MODEF 1 "general_operand" ""))]
14179  "TARGET_USE_FANCY_MATH_387
14180    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14181        || TARGET_MIX_SSE_I387)
14182    && flag_unsafe_math_optimizations"
14183 {
14184   rtx op0, op1;
14185
14186   if (optimize_insn_for_size_p ())
14187     FAIL;
14188
14189   op0 = gen_reg_rtx (XFmode);
14190   op1 = gen_reg_rtx (XFmode);
14191
14192   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14193   emit_insn (gen_expm1xf2 (op0, op1));
14194   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14195   DONE;
14196 })
14197
14198 (define_expand "ldexpxf3"
14199   [(set (match_dup 3)
14200         (float:XF (match_operand:SI 2 "register_operand" "")))
14201    (parallel [(set (match_operand:XF 0 " register_operand" "")
14202                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14203                                (match_dup 3)]
14204                               UNSPEC_FSCALE_FRACT))
14205               (set (match_dup 4)
14206                    (unspec:XF [(match_dup 1) (match_dup 3)]
14207                               UNSPEC_FSCALE_EXP))])]
14208   "TARGET_USE_FANCY_MATH_387
14209    && flag_unsafe_math_optimizations"
14210 {
14211   if (optimize_insn_for_size_p ())
14212     FAIL;
14213
14214   operands[3] = gen_reg_rtx (XFmode);
14215   operands[4] = gen_reg_rtx (XFmode);
14216 })
14217
14218 (define_expand "ldexp<mode>3"
14219   [(use (match_operand:MODEF 0 "register_operand" ""))
14220    (use (match_operand:MODEF 1 "general_operand" ""))
14221    (use (match_operand:SI 2 "register_operand" ""))]
14222  "TARGET_USE_FANCY_MATH_387
14223    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14224        || TARGET_MIX_SSE_I387)
14225    && flag_unsafe_math_optimizations"
14226 {
14227   rtx op0, op1;
14228
14229   if (optimize_insn_for_size_p ())
14230     FAIL;
14231
14232   op0 = gen_reg_rtx (XFmode);
14233   op1 = gen_reg_rtx (XFmode);
14234
14235   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14236   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14237   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14238   DONE;
14239 })
14240
14241 (define_expand "scalbxf3"
14242   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14243                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14244                                (match_operand:XF 2 "register_operand" "")]
14245                               UNSPEC_FSCALE_FRACT))
14246               (set (match_dup 3)
14247                    (unspec:XF [(match_dup 1) (match_dup 2)]
14248                               UNSPEC_FSCALE_EXP))])]
14249   "TARGET_USE_FANCY_MATH_387
14250    && flag_unsafe_math_optimizations"
14251 {
14252   if (optimize_insn_for_size_p ())
14253     FAIL;
14254
14255   operands[3] = gen_reg_rtx (XFmode);
14256 })
14257
14258 (define_expand "scalb<mode>3"
14259   [(use (match_operand:MODEF 0 "register_operand" ""))
14260    (use (match_operand:MODEF 1 "general_operand" ""))
14261    (use (match_operand:MODEF 2 "general_operand" ""))]
14262  "TARGET_USE_FANCY_MATH_387
14263    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14264        || TARGET_MIX_SSE_I387)
14265    && flag_unsafe_math_optimizations"
14266 {
14267   rtx op0, op1, op2;
14268
14269   if (optimize_insn_for_size_p ())
14270     FAIL;
14271
14272   op0 = gen_reg_rtx (XFmode);
14273   op1 = gen_reg_rtx (XFmode);
14274   op2 = gen_reg_rtx (XFmode);
14275
14276   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14277   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14278   emit_insn (gen_scalbxf3 (op0, op1, op2));
14279   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14280   DONE;
14281 })
14282
14283 (define_expand "significandxf2"
14284   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14285                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14286                               UNSPEC_XTRACT_FRACT))
14287               (set (match_dup 2)
14288                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14289   "TARGET_USE_FANCY_MATH_387
14290    && flag_unsafe_math_optimizations"
14291   "operands[2] = gen_reg_rtx (XFmode);")
14292
14293 (define_expand "significand<mode>2"
14294   [(use (match_operand:MODEF 0 "register_operand" ""))
14295    (use (match_operand:MODEF 1 "register_operand" ""))]
14296   "TARGET_USE_FANCY_MATH_387
14297    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14298        || TARGET_MIX_SSE_I387)
14299    && flag_unsafe_math_optimizations"
14300 {
14301   rtx op0 = gen_reg_rtx (XFmode);
14302   rtx op1 = gen_reg_rtx (XFmode);
14303
14304   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14305   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14306   DONE;
14307 })
14308 \f
14309
14310 (define_insn "sse4_1_round<mode>2"
14311   [(set (match_operand:MODEF 0 "register_operand" "=x")
14312         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14313                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14314                       UNSPEC_ROUND))]
14315   "TARGET_ROUND"
14316   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14317   [(set_attr "type" "ssecvt")
14318    (set_attr "prefix_extra" "1")
14319    (set_attr "prefix" "maybe_vex")
14320    (set_attr "mode" "<MODE>")])
14321
14322 (define_insn "rintxf2"
14323   [(set (match_operand:XF 0 "register_operand" "=f")
14324         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14325                    UNSPEC_FRNDINT))]
14326   "TARGET_USE_FANCY_MATH_387
14327    && flag_unsafe_math_optimizations"
14328   "frndint"
14329   [(set_attr "type" "fpspc")
14330    (set_attr "mode" "XF")])
14331
14332 (define_expand "rint<mode>2"
14333   [(use (match_operand:MODEF 0 "register_operand" ""))
14334    (use (match_operand:MODEF 1 "register_operand" ""))]
14335   "(TARGET_USE_FANCY_MATH_387
14336     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14337         || TARGET_MIX_SSE_I387)
14338     && flag_unsafe_math_optimizations)
14339    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14340        && !flag_trapping_math)"
14341 {
14342   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14343       && !flag_trapping_math)
14344     {
14345       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14346         FAIL;
14347       if (TARGET_ROUND)
14348         emit_insn (gen_sse4_1_round<mode>2
14349                    (operands[0], operands[1], GEN_INT (0x04)));
14350       else
14351         ix86_expand_rint (operand0, operand1);
14352     }
14353   else
14354     {
14355       rtx op0 = gen_reg_rtx (XFmode);
14356       rtx op1 = gen_reg_rtx (XFmode);
14357
14358       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14359       emit_insn (gen_rintxf2 (op0, op1));
14360
14361       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14362     }
14363   DONE;
14364 })
14365
14366 (define_expand "round<mode>2"
14367   [(match_operand:MODEF 0 "register_operand" "")
14368    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14369   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14370    && !flag_trapping_math && !flag_rounding_math"
14371 {
14372   if (optimize_insn_for_size_p ())
14373     FAIL;
14374   if (TARGET_64BIT || (<MODE>mode != DFmode))
14375     ix86_expand_round (operand0, operand1);
14376   else
14377     ix86_expand_rounddf_32 (operand0, operand1);
14378   DONE;
14379 })
14380
14381 (define_insn_and_split "*fistdi2_1"
14382   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14383         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14384                    UNSPEC_FIST))]
14385   "TARGET_USE_FANCY_MATH_387
14386    && can_create_pseudo_p ()"
14387   "#"
14388   "&& 1"
14389   [(const_int 0)]
14390 {
14391   if (memory_operand (operands[0], VOIDmode))
14392     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14393   else
14394     {
14395       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14396       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14397                                          operands[2]));
14398     }
14399   DONE;
14400 }
14401   [(set_attr "type" "fpspc")
14402    (set_attr "mode" "DI")])
14403
14404 (define_insn "fistdi2"
14405   [(set (match_operand:DI 0 "memory_operand" "=m")
14406         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14407                    UNSPEC_FIST))
14408    (clobber (match_scratch:XF 2 "=&1f"))]
14409   "TARGET_USE_FANCY_MATH_387"
14410   "* return output_fix_trunc (insn, operands, 0);"
14411   [(set_attr "type" "fpspc")
14412    (set_attr "mode" "DI")])
14413
14414 (define_insn "fistdi2_with_temp"
14415   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14416         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14417                    UNSPEC_FIST))
14418    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14419    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14420   "TARGET_USE_FANCY_MATH_387"
14421   "#"
14422   [(set_attr "type" "fpspc")
14423    (set_attr "mode" "DI")])
14424
14425 (define_split
14426   [(set (match_operand:DI 0 "register_operand" "")
14427         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14428                    UNSPEC_FIST))
14429    (clobber (match_operand:DI 2 "memory_operand" ""))
14430    (clobber (match_scratch 3 ""))]
14431   "reload_completed"
14432   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14433               (clobber (match_dup 3))])
14434    (set (match_dup 0) (match_dup 2))])
14435
14436 (define_split
14437   [(set (match_operand:DI 0 "memory_operand" "")
14438         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14439                    UNSPEC_FIST))
14440    (clobber (match_operand:DI 2 "memory_operand" ""))
14441    (clobber (match_scratch 3 ""))]
14442   "reload_completed"
14443   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14444               (clobber (match_dup 3))])])
14445
14446 (define_insn_and_split "*fist<mode>2_1"
14447   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14448         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14449                            UNSPEC_FIST))]
14450   "TARGET_USE_FANCY_MATH_387
14451    && can_create_pseudo_p ()"
14452   "#"
14453   "&& 1"
14454   [(const_int 0)]
14455 {
14456   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14457   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14458                                         operands[2]));
14459   DONE;
14460 }
14461   [(set_attr "type" "fpspc")
14462    (set_attr "mode" "<MODE>")])
14463
14464 (define_insn "fist<mode>2"
14465   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14466         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14467                            UNSPEC_FIST))]
14468   "TARGET_USE_FANCY_MATH_387"
14469   "* return output_fix_trunc (insn, operands, 0);"
14470   [(set_attr "type" "fpspc")
14471    (set_attr "mode" "<MODE>")])
14472
14473 (define_insn "fist<mode>2_with_temp"
14474   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14475         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14476                            UNSPEC_FIST))
14477    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14478   "TARGET_USE_FANCY_MATH_387"
14479   "#"
14480   [(set_attr "type" "fpspc")
14481    (set_attr "mode" "<MODE>")])
14482
14483 (define_split
14484   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14485         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14486                            UNSPEC_FIST))
14487    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14488   "reload_completed"
14489   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14490    (set (match_dup 0) (match_dup 2))])
14491
14492 (define_split
14493   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14494         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14495                            UNSPEC_FIST))
14496    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14497   "reload_completed"
14498   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14499
14500 (define_expand "lrintxf<mode>2"
14501   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14502      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14503                       UNSPEC_FIST))]
14504   "TARGET_USE_FANCY_MATH_387")
14505
14506 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14507   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14508      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14509                         UNSPEC_FIX_NOTRUNC))]
14510   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14511    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14512
14513 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14514   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14515    (match_operand:MODEF 1 "register_operand" "")]
14516   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14517    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14518    && !flag_trapping_math && !flag_rounding_math"
14519 {
14520   if (optimize_insn_for_size_p ())
14521     FAIL;
14522   ix86_expand_lround (operand0, operand1);
14523   DONE;
14524 })
14525
14526 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14527 (define_insn_and_split "frndintxf2_floor"
14528   [(set (match_operand:XF 0 "register_operand" "")
14529         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14530          UNSPEC_FRNDINT_FLOOR))
14531    (clobber (reg:CC FLAGS_REG))]
14532   "TARGET_USE_FANCY_MATH_387
14533    && flag_unsafe_math_optimizations
14534    && can_create_pseudo_p ()"
14535   "#"
14536   "&& 1"
14537   [(const_int 0)]
14538 {
14539   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14540
14541   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14542   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14543
14544   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14545                                         operands[2], operands[3]));
14546   DONE;
14547 }
14548   [(set_attr "type" "frndint")
14549    (set_attr "i387_cw" "floor")
14550    (set_attr "mode" "XF")])
14551
14552 (define_insn "frndintxf2_floor_i387"
14553   [(set (match_operand:XF 0 "register_operand" "=f")
14554         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14555          UNSPEC_FRNDINT_FLOOR))
14556    (use (match_operand:HI 2 "memory_operand" "m"))
14557    (use (match_operand:HI 3 "memory_operand" "m"))]
14558   "TARGET_USE_FANCY_MATH_387
14559    && flag_unsafe_math_optimizations"
14560   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14561   [(set_attr "type" "frndint")
14562    (set_attr "i387_cw" "floor")
14563    (set_attr "mode" "XF")])
14564
14565 (define_expand "floorxf2"
14566   [(use (match_operand:XF 0 "register_operand" ""))
14567    (use (match_operand:XF 1 "register_operand" ""))]
14568   "TARGET_USE_FANCY_MATH_387
14569    && flag_unsafe_math_optimizations"
14570 {
14571   if (optimize_insn_for_size_p ())
14572     FAIL;
14573   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14574   DONE;
14575 })
14576
14577 (define_expand "floor<mode>2"
14578   [(use (match_operand:MODEF 0 "register_operand" ""))
14579    (use (match_operand:MODEF 1 "register_operand" ""))]
14580   "(TARGET_USE_FANCY_MATH_387
14581     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14582         || TARGET_MIX_SSE_I387)
14583     && flag_unsafe_math_optimizations)
14584    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14585        && !flag_trapping_math)"
14586 {
14587   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14588       && !flag_trapping_math
14589       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14590     {
14591       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14592         FAIL;
14593       if (TARGET_ROUND)
14594         emit_insn (gen_sse4_1_round<mode>2
14595                    (operands[0], operands[1], GEN_INT (0x01)));
14596       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14597         ix86_expand_floorceil (operand0, operand1, true);
14598       else
14599         ix86_expand_floorceildf_32 (operand0, operand1, true);
14600     }
14601   else
14602     {
14603       rtx op0, op1;
14604
14605       if (optimize_insn_for_size_p ())
14606         FAIL;
14607
14608       op0 = gen_reg_rtx (XFmode);
14609       op1 = gen_reg_rtx (XFmode);
14610       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14611       emit_insn (gen_frndintxf2_floor (op0, op1));
14612
14613       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14614     }
14615   DONE;
14616 })
14617
14618 (define_insn_and_split "*fist<mode>2_floor_1"
14619   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14620         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14621          UNSPEC_FIST_FLOOR))
14622    (clobber (reg:CC FLAGS_REG))]
14623   "TARGET_USE_FANCY_MATH_387
14624    && flag_unsafe_math_optimizations
14625    && can_create_pseudo_p ()"
14626   "#"
14627   "&& 1"
14628   [(const_int 0)]
14629 {
14630   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14631
14632   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14633   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14634   if (memory_operand (operands[0], VOIDmode))
14635     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14636                                       operands[2], operands[3]));
14637   else
14638     {
14639       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14640       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14641                                                   operands[2], operands[3],
14642                                                   operands[4]));
14643     }
14644   DONE;
14645 }
14646   [(set_attr "type" "fistp")
14647    (set_attr "i387_cw" "floor")
14648    (set_attr "mode" "<MODE>")])
14649
14650 (define_insn "fistdi2_floor"
14651   [(set (match_operand:DI 0 "memory_operand" "=m")
14652         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14653          UNSPEC_FIST_FLOOR))
14654    (use (match_operand:HI 2 "memory_operand" "m"))
14655    (use (match_operand:HI 3 "memory_operand" "m"))
14656    (clobber (match_scratch:XF 4 "=&1f"))]
14657   "TARGET_USE_FANCY_MATH_387
14658    && flag_unsafe_math_optimizations"
14659   "* return output_fix_trunc (insn, operands, 0);"
14660   [(set_attr "type" "fistp")
14661    (set_attr "i387_cw" "floor")
14662    (set_attr "mode" "DI")])
14663
14664 (define_insn "fistdi2_floor_with_temp"
14665   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14666         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14667          UNSPEC_FIST_FLOOR))
14668    (use (match_operand:HI 2 "memory_operand" "m,m"))
14669    (use (match_operand:HI 3 "memory_operand" "m,m"))
14670    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14671    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14672   "TARGET_USE_FANCY_MATH_387
14673    && flag_unsafe_math_optimizations"
14674   "#"
14675   [(set_attr "type" "fistp")
14676    (set_attr "i387_cw" "floor")
14677    (set_attr "mode" "DI")])
14678
14679 (define_split
14680   [(set (match_operand:DI 0 "register_operand" "")
14681         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14682          UNSPEC_FIST_FLOOR))
14683    (use (match_operand:HI 2 "memory_operand" ""))
14684    (use (match_operand:HI 3 "memory_operand" ""))
14685    (clobber (match_operand:DI 4 "memory_operand" ""))
14686    (clobber (match_scratch 5 ""))]
14687   "reload_completed"
14688   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14689               (use (match_dup 2))
14690               (use (match_dup 3))
14691               (clobber (match_dup 5))])
14692    (set (match_dup 0) (match_dup 4))])
14693
14694 (define_split
14695   [(set (match_operand:DI 0 "memory_operand" "")
14696         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14697          UNSPEC_FIST_FLOOR))
14698    (use (match_operand:HI 2 "memory_operand" ""))
14699    (use (match_operand:HI 3 "memory_operand" ""))
14700    (clobber (match_operand:DI 4 "memory_operand" ""))
14701    (clobber (match_scratch 5 ""))]
14702   "reload_completed"
14703   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14704               (use (match_dup 2))
14705               (use (match_dup 3))
14706               (clobber (match_dup 5))])])
14707
14708 (define_insn "fist<mode>2_floor"
14709   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14710         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14711          UNSPEC_FIST_FLOOR))
14712    (use (match_operand:HI 2 "memory_operand" "m"))
14713    (use (match_operand:HI 3 "memory_operand" "m"))]
14714   "TARGET_USE_FANCY_MATH_387
14715    && flag_unsafe_math_optimizations"
14716   "* return output_fix_trunc (insn, operands, 0);"
14717   [(set_attr "type" "fistp")
14718    (set_attr "i387_cw" "floor")
14719    (set_attr "mode" "<MODE>")])
14720
14721 (define_insn "fist<mode>2_floor_with_temp"
14722   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14723         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14724          UNSPEC_FIST_FLOOR))
14725    (use (match_operand:HI 2 "memory_operand" "m,m"))
14726    (use (match_operand:HI 3 "memory_operand" "m,m"))
14727    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14728   "TARGET_USE_FANCY_MATH_387
14729    && flag_unsafe_math_optimizations"
14730   "#"
14731   [(set_attr "type" "fistp")
14732    (set_attr "i387_cw" "floor")
14733    (set_attr "mode" "<MODE>")])
14734
14735 (define_split
14736   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14737         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14738          UNSPEC_FIST_FLOOR))
14739    (use (match_operand:HI 2 "memory_operand" ""))
14740    (use (match_operand:HI 3 "memory_operand" ""))
14741    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14742   "reload_completed"
14743   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14744                                   UNSPEC_FIST_FLOOR))
14745               (use (match_dup 2))
14746               (use (match_dup 3))])
14747    (set (match_dup 0) (match_dup 4))])
14748
14749 (define_split
14750   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14751         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14752          UNSPEC_FIST_FLOOR))
14753    (use (match_operand:HI 2 "memory_operand" ""))
14754    (use (match_operand:HI 3 "memory_operand" ""))
14755    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14756   "reload_completed"
14757   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14758                                   UNSPEC_FIST_FLOOR))
14759               (use (match_dup 2))
14760               (use (match_dup 3))])])
14761
14762 (define_expand "lfloorxf<mode>2"
14763   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14764                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14765                     UNSPEC_FIST_FLOOR))
14766               (clobber (reg:CC FLAGS_REG))])]
14767   "TARGET_USE_FANCY_MATH_387
14768    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14769    && flag_unsafe_math_optimizations")
14770
14771 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14772   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14773    (match_operand:MODEF 1 "register_operand" "")]
14774   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14775    && !flag_trapping_math"
14776 {
14777   if (TARGET_64BIT && optimize_insn_for_size_p ())
14778     FAIL;
14779   ix86_expand_lfloorceil (operand0, operand1, true);
14780   DONE;
14781 })
14782
14783 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14784 (define_insn_and_split "frndintxf2_ceil"
14785   [(set (match_operand:XF 0 "register_operand" "")
14786         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14787          UNSPEC_FRNDINT_CEIL))
14788    (clobber (reg:CC FLAGS_REG))]
14789   "TARGET_USE_FANCY_MATH_387
14790    && flag_unsafe_math_optimizations
14791    && can_create_pseudo_p ()"
14792   "#"
14793   "&& 1"
14794   [(const_int 0)]
14795 {
14796   ix86_optimize_mode_switching[I387_CEIL] = 1;
14797
14798   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14799   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14800
14801   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14802                                        operands[2], operands[3]));
14803   DONE;
14804 }
14805   [(set_attr "type" "frndint")
14806    (set_attr "i387_cw" "ceil")
14807    (set_attr "mode" "XF")])
14808
14809 (define_insn "frndintxf2_ceil_i387"
14810   [(set (match_operand:XF 0 "register_operand" "=f")
14811         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14812          UNSPEC_FRNDINT_CEIL))
14813    (use (match_operand:HI 2 "memory_operand" "m"))
14814    (use (match_operand:HI 3 "memory_operand" "m"))]
14815   "TARGET_USE_FANCY_MATH_387
14816    && flag_unsafe_math_optimizations"
14817   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14818   [(set_attr "type" "frndint")
14819    (set_attr "i387_cw" "ceil")
14820    (set_attr "mode" "XF")])
14821
14822 (define_expand "ceilxf2"
14823   [(use (match_operand:XF 0 "register_operand" ""))
14824    (use (match_operand:XF 1 "register_operand" ""))]
14825   "TARGET_USE_FANCY_MATH_387
14826    && flag_unsafe_math_optimizations"
14827 {
14828   if (optimize_insn_for_size_p ())
14829     FAIL;
14830   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14831   DONE;
14832 })
14833
14834 (define_expand "ceil<mode>2"
14835   [(use (match_operand:MODEF 0 "register_operand" ""))
14836    (use (match_operand:MODEF 1 "register_operand" ""))]
14837   "(TARGET_USE_FANCY_MATH_387
14838     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14839         || TARGET_MIX_SSE_I387)
14840     && flag_unsafe_math_optimizations)
14841    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14842        && !flag_trapping_math)"
14843 {
14844   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14845       && !flag_trapping_math
14846       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14847     {
14848       if (TARGET_ROUND)
14849         emit_insn (gen_sse4_1_round<mode>2
14850                    (operands[0], operands[1], GEN_INT (0x02)));
14851       else if (optimize_insn_for_size_p ())
14852         FAIL;
14853       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14854         ix86_expand_floorceil (operand0, operand1, false);
14855       else
14856         ix86_expand_floorceildf_32 (operand0, operand1, false);
14857     }
14858   else
14859     {
14860       rtx op0, op1;
14861
14862       if (optimize_insn_for_size_p ())
14863         FAIL;
14864
14865       op0 = gen_reg_rtx (XFmode);
14866       op1 = gen_reg_rtx (XFmode);
14867       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14868       emit_insn (gen_frndintxf2_ceil (op0, op1));
14869
14870       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14871     }
14872   DONE;
14873 })
14874
14875 (define_insn_and_split "*fist<mode>2_ceil_1"
14876   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14877         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14878          UNSPEC_FIST_CEIL))
14879    (clobber (reg:CC FLAGS_REG))]
14880   "TARGET_USE_FANCY_MATH_387
14881    && flag_unsafe_math_optimizations
14882    && can_create_pseudo_p ()"
14883   "#"
14884   "&& 1"
14885   [(const_int 0)]
14886 {
14887   ix86_optimize_mode_switching[I387_CEIL] = 1;
14888
14889   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14890   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14891   if (memory_operand (operands[0], VOIDmode))
14892     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14893                                      operands[2], operands[3]));
14894   else
14895     {
14896       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14897       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14898                                                  operands[2], operands[3],
14899                                                  operands[4]));
14900     }
14901   DONE;
14902 }
14903   [(set_attr "type" "fistp")
14904    (set_attr "i387_cw" "ceil")
14905    (set_attr "mode" "<MODE>")])
14906
14907 (define_insn "fistdi2_ceil"
14908   [(set (match_operand:DI 0 "memory_operand" "=m")
14909         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14910          UNSPEC_FIST_CEIL))
14911    (use (match_operand:HI 2 "memory_operand" "m"))
14912    (use (match_operand:HI 3 "memory_operand" "m"))
14913    (clobber (match_scratch:XF 4 "=&1f"))]
14914   "TARGET_USE_FANCY_MATH_387
14915    && flag_unsafe_math_optimizations"
14916   "* return output_fix_trunc (insn, operands, 0);"
14917   [(set_attr "type" "fistp")
14918    (set_attr "i387_cw" "ceil")
14919    (set_attr "mode" "DI")])
14920
14921 (define_insn "fistdi2_ceil_with_temp"
14922   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14923         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14924          UNSPEC_FIST_CEIL))
14925    (use (match_operand:HI 2 "memory_operand" "m,m"))
14926    (use (match_operand:HI 3 "memory_operand" "m,m"))
14927    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14928    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14929   "TARGET_USE_FANCY_MATH_387
14930    && flag_unsafe_math_optimizations"
14931   "#"
14932   [(set_attr "type" "fistp")
14933    (set_attr "i387_cw" "ceil")
14934    (set_attr "mode" "DI")])
14935
14936 (define_split
14937   [(set (match_operand:DI 0 "register_operand" "")
14938         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14939          UNSPEC_FIST_CEIL))
14940    (use (match_operand:HI 2 "memory_operand" ""))
14941    (use (match_operand:HI 3 "memory_operand" ""))
14942    (clobber (match_operand:DI 4 "memory_operand" ""))
14943    (clobber (match_scratch 5 ""))]
14944   "reload_completed"
14945   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14946               (use (match_dup 2))
14947               (use (match_dup 3))
14948               (clobber (match_dup 5))])
14949    (set (match_dup 0) (match_dup 4))])
14950
14951 (define_split
14952   [(set (match_operand:DI 0 "memory_operand" "")
14953         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14954          UNSPEC_FIST_CEIL))
14955    (use (match_operand:HI 2 "memory_operand" ""))
14956    (use (match_operand:HI 3 "memory_operand" ""))
14957    (clobber (match_operand:DI 4 "memory_operand" ""))
14958    (clobber (match_scratch 5 ""))]
14959   "reload_completed"
14960   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14961               (use (match_dup 2))
14962               (use (match_dup 3))
14963               (clobber (match_dup 5))])])
14964
14965 (define_insn "fist<mode>2_ceil"
14966   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14967         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14968          UNSPEC_FIST_CEIL))
14969    (use (match_operand:HI 2 "memory_operand" "m"))
14970    (use (match_operand:HI 3 "memory_operand" "m"))]
14971   "TARGET_USE_FANCY_MATH_387
14972    && flag_unsafe_math_optimizations"
14973   "* return output_fix_trunc (insn, operands, 0);"
14974   [(set_attr "type" "fistp")
14975    (set_attr "i387_cw" "ceil")
14976    (set_attr "mode" "<MODE>")])
14977
14978 (define_insn "fist<mode>2_ceil_with_temp"
14979   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14980         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14981          UNSPEC_FIST_CEIL))
14982    (use (match_operand:HI 2 "memory_operand" "m,m"))
14983    (use (match_operand:HI 3 "memory_operand" "m,m"))
14984    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14985   "TARGET_USE_FANCY_MATH_387
14986    && flag_unsafe_math_optimizations"
14987   "#"
14988   [(set_attr "type" "fistp")
14989    (set_attr "i387_cw" "ceil")
14990    (set_attr "mode" "<MODE>")])
14991
14992 (define_split
14993   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14994         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14995          UNSPEC_FIST_CEIL))
14996    (use (match_operand:HI 2 "memory_operand" ""))
14997    (use (match_operand:HI 3 "memory_operand" ""))
14998    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14999   "reload_completed"
15000   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15001                                   UNSPEC_FIST_CEIL))
15002               (use (match_dup 2))
15003               (use (match_dup 3))])
15004    (set (match_dup 0) (match_dup 4))])
15005
15006 (define_split
15007   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15008         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15009          UNSPEC_FIST_CEIL))
15010    (use (match_operand:HI 2 "memory_operand" ""))
15011    (use (match_operand:HI 3 "memory_operand" ""))
15012    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15013   "reload_completed"
15014   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15015                                   UNSPEC_FIST_CEIL))
15016               (use (match_dup 2))
15017               (use (match_dup 3))])])
15018
15019 (define_expand "lceilxf<mode>2"
15020   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15021                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15022                     UNSPEC_FIST_CEIL))
15023               (clobber (reg:CC FLAGS_REG))])]
15024   "TARGET_USE_FANCY_MATH_387
15025    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15026    && flag_unsafe_math_optimizations")
15027
15028 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15029   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15030    (match_operand:MODEF 1 "register_operand" "")]
15031   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15032    && !flag_trapping_math"
15033 {
15034   ix86_expand_lfloorceil (operand0, operand1, false);
15035   DONE;
15036 })
15037
15038 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15039 (define_insn_and_split "frndintxf2_trunc"
15040   [(set (match_operand:XF 0 "register_operand" "")
15041         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15042          UNSPEC_FRNDINT_TRUNC))
15043    (clobber (reg:CC FLAGS_REG))]
15044   "TARGET_USE_FANCY_MATH_387
15045    && flag_unsafe_math_optimizations
15046    && can_create_pseudo_p ()"
15047   "#"
15048   "&& 1"
15049   [(const_int 0)]
15050 {
15051   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15052
15053   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15054   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15055
15056   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15057                                         operands[2], operands[3]));
15058   DONE;
15059 }
15060   [(set_attr "type" "frndint")
15061    (set_attr "i387_cw" "trunc")
15062    (set_attr "mode" "XF")])
15063
15064 (define_insn "frndintxf2_trunc_i387"
15065   [(set (match_operand:XF 0 "register_operand" "=f")
15066         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15067          UNSPEC_FRNDINT_TRUNC))
15068    (use (match_operand:HI 2 "memory_operand" "m"))
15069    (use (match_operand:HI 3 "memory_operand" "m"))]
15070   "TARGET_USE_FANCY_MATH_387
15071    && flag_unsafe_math_optimizations"
15072   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15073   [(set_attr "type" "frndint")
15074    (set_attr "i387_cw" "trunc")
15075    (set_attr "mode" "XF")])
15076
15077 (define_expand "btruncxf2"
15078   [(use (match_operand:XF 0 "register_operand" ""))
15079    (use (match_operand:XF 1 "register_operand" ""))]
15080   "TARGET_USE_FANCY_MATH_387
15081    && flag_unsafe_math_optimizations"
15082 {
15083   if (optimize_insn_for_size_p ())
15084     FAIL;
15085   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15086   DONE;
15087 })
15088
15089 (define_expand "btrunc<mode>2"
15090   [(use (match_operand:MODEF 0 "register_operand" ""))
15091    (use (match_operand:MODEF 1 "register_operand" ""))]
15092   "(TARGET_USE_FANCY_MATH_387
15093     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15094         || TARGET_MIX_SSE_I387)
15095     && flag_unsafe_math_optimizations)
15096    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15097        && !flag_trapping_math)"
15098 {
15099   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15100       && !flag_trapping_math
15101       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15102     {
15103       if (TARGET_ROUND)
15104         emit_insn (gen_sse4_1_round<mode>2
15105                    (operands[0], operands[1], GEN_INT (0x03)));
15106       else if (optimize_insn_for_size_p ())
15107         FAIL;
15108       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15109         ix86_expand_trunc (operand0, operand1);
15110       else
15111         ix86_expand_truncdf_32 (operand0, operand1);
15112     }
15113   else
15114     {
15115       rtx op0, op1;
15116
15117       if (optimize_insn_for_size_p ())
15118         FAIL;
15119
15120       op0 = gen_reg_rtx (XFmode);
15121       op1 = gen_reg_rtx (XFmode);
15122       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15123       emit_insn (gen_frndintxf2_trunc (op0, op1));
15124
15125       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15126     }
15127   DONE;
15128 })
15129
15130 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15131 (define_insn_and_split "frndintxf2_mask_pm"
15132   [(set (match_operand:XF 0 "register_operand" "")
15133         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15134          UNSPEC_FRNDINT_MASK_PM))
15135    (clobber (reg:CC FLAGS_REG))]
15136   "TARGET_USE_FANCY_MATH_387
15137    && flag_unsafe_math_optimizations
15138    && can_create_pseudo_p ()"
15139   "#"
15140   "&& 1"
15141   [(const_int 0)]
15142 {
15143   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15144
15145   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15146   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15147
15148   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15149                                           operands[2], operands[3]));
15150   DONE;
15151 }
15152   [(set_attr "type" "frndint")
15153    (set_attr "i387_cw" "mask_pm")
15154    (set_attr "mode" "XF")])
15155
15156 (define_insn "frndintxf2_mask_pm_i387"
15157   [(set (match_operand:XF 0 "register_operand" "=f")
15158         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15159          UNSPEC_FRNDINT_MASK_PM))
15160    (use (match_operand:HI 2 "memory_operand" "m"))
15161    (use (match_operand:HI 3 "memory_operand" "m"))]
15162   "TARGET_USE_FANCY_MATH_387
15163    && flag_unsafe_math_optimizations"
15164   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15165   [(set_attr "type" "frndint")
15166    (set_attr "i387_cw" "mask_pm")
15167    (set_attr "mode" "XF")])
15168
15169 (define_expand "nearbyintxf2"
15170   [(use (match_operand:XF 0 "register_operand" ""))
15171    (use (match_operand:XF 1 "register_operand" ""))]
15172   "TARGET_USE_FANCY_MATH_387
15173    && flag_unsafe_math_optimizations"
15174 {
15175   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15176   DONE;
15177 })
15178
15179 (define_expand "nearbyint<mode>2"
15180   [(use (match_operand:MODEF 0 "register_operand" ""))
15181    (use (match_operand:MODEF 1 "register_operand" ""))]
15182   "TARGET_USE_FANCY_MATH_387
15183    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15184        || TARGET_MIX_SSE_I387)
15185    && flag_unsafe_math_optimizations"
15186 {
15187   rtx op0 = gen_reg_rtx (XFmode);
15188   rtx op1 = gen_reg_rtx (XFmode);
15189
15190   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15191   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15192
15193   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15194   DONE;
15195 })
15196
15197 (define_insn "fxam<mode>2_i387"
15198   [(set (match_operand:HI 0 "register_operand" "=a")
15199         (unspec:HI
15200           [(match_operand:X87MODEF 1 "register_operand" "f")]
15201           UNSPEC_FXAM))]
15202   "TARGET_USE_FANCY_MATH_387"
15203   "fxam\n\tfnstsw\t%0"
15204   [(set_attr "type" "multi")
15205    (set_attr "length" "4")
15206    (set_attr "unit" "i387")
15207    (set_attr "mode" "<MODE>")])
15208
15209 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15210   [(set (match_operand:HI 0 "register_operand" "")
15211         (unspec:HI
15212           [(match_operand:MODEF 1 "memory_operand" "")]
15213           UNSPEC_FXAM_MEM))]
15214   "TARGET_USE_FANCY_MATH_387
15215    && can_create_pseudo_p ()"
15216   "#"
15217   "&& 1"
15218   [(set (match_dup 2)(match_dup 1))
15219    (set (match_dup 0)
15220         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15221 {
15222   operands[2] = gen_reg_rtx (<MODE>mode);
15223
15224   MEM_VOLATILE_P (operands[1]) = 1;
15225 }
15226   [(set_attr "type" "multi")
15227    (set_attr "unit" "i387")
15228    (set_attr "mode" "<MODE>")])
15229
15230 (define_expand "isinfxf2"
15231   [(use (match_operand:SI 0 "register_operand" ""))
15232    (use (match_operand:XF 1 "register_operand" ""))]
15233   "TARGET_USE_FANCY_MATH_387
15234    && TARGET_C99_FUNCTIONS"
15235 {
15236   rtx mask = GEN_INT (0x45);
15237   rtx val = GEN_INT (0x05);
15238
15239   rtx cond;
15240
15241   rtx scratch = gen_reg_rtx (HImode);
15242   rtx res = gen_reg_rtx (QImode);
15243
15244   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15245
15246   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15247   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15248   cond = gen_rtx_fmt_ee (EQ, QImode,
15249                          gen_rtx_REG (CCmode, FLAGS_REG),
15250                          const0_rtx);
15251   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15252   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15253   DONE;
15254 })
15255
15256 (define_expand "isinf<mode>2"
15257   [(use (match_operand:SI 0 "register_operand" ""))
15258    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15259   "TARGET_USE_FANCY_MATH_387
15260    && TARGET_C99_FUNCTIONS
15261    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15262 {
15263   rtx mask = GEN_INT (0x45);
15264   rtx val = GEN_INT (0x05);
15265
15266   rtx cond;
15267
15268   rtx scratch = gen_reg_rtx (HImode);
15269   rtx res = gen_reg_rtx (QImode);
15270
15271   /* Remove excess precision by forcing value through memory. */
15272   if (memory_operand (operands[1], VOIDmode))
15273     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15274   else
15275     {
15276       enum ix86_stack_slot slot = (virtuals_instantiated
15277                                    ? SLOT_TEMP
15278                                    : SLOT_VIRTUAL);
15279       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15280
15281       emit_move_insn (temp, operands[1]);
15282       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15283     }
15284
15285   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15286   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15287   cond = gen_rtx_fmt_ee (EQ, QImode,
15288                          gen_rtx_REG (CCmode, FLAGS_REG),
15289                          const0_rtx);
15290   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15291   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15292   DONE;
15293 })
15294
15295 (define_expand "signbitxf2"
15296   [(use (match_operand:SI 0 "register_operand" ""))
15297    (use (match_operand:XF 1 "register_operand" ""))]
15298   "TARGET_USE_FANCY_MATH_387"
15299 {
15300   rtx scratch = gen_reg_rtx (HImode);
15301
15302   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15303   emit_insn (gen_andsi3 (operands[0],
15304              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15305   DONE;
15306 })
15307
15308 (define_insn "movmsk_df"
15309   [(set (match_operand:SI 0 "register_operand" "=r")
15310         (unspec:SI
15311           [(match_operand:DF 1 "register_operand" "x")]
15312           UNSPEC_MOVMSK))]
15313   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15314   "%vmovmskpd\t{%1, %0|%0, %1}"
15315   [(set_attr "type" "ssemov")
15316    (set_attr "prefix" "maybe_vex")
15317    (set_attr "mode" "DF")])
15318
15319 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15320 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15321 (define_expand "signbitdf2"
15322   [(use (match_operand:SI 0 "register_operand" ""))
15323    (use (match_operand:DF 1 "register_operand" ""))]
15324   "TARGET_USE_FANCY_MATH_387
15325    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15326 {
15327   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15328     {
15329       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15330       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15331     }
15332   else
15333     {
15334       rtx scratch = gen_reg_rtx (HImode);
15335
15336       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15337       emit_insn (gen_andsi3 (operands[0],
15338                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15339     }
15340   DONE;
15341 })
15342
15343 (define_expand "signbitsf2"
15344   [(use (match_operand:SI 0 "register_operand" ""))
15345    (use (match_operand:SF 1 "register_operand" ""))]
15346   "TARGET_USE_FANCY_MATH_387
15347    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15348 {
15349   rtx scratch = gen_reg_rtx (HImode);
15350
15351   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15352   emit_insn (gen_andsi3 (operands[0],
15353              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15354   DONE;
15355 })
15356 \f
15357 ;; Block operation instructions
15358
15359 (define_insn "cld"
15360   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15361   ""
15362   "cld"
15363   [(set_attr "length" "1")
15364    (set_attr "length_immediate" "0")
15365    (set_attr "modrm" "0")])
15366
15367 (define_expand "movmem<mode>"
15368   [(use (match_operand:BLK 0 "memory_operand" ""))
15369    (use (match_operand:BLK 1 "memory_operand" ""))
15370    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15371    (use (match_operand:SWI48 3 "const_int_operand" ""))
15372    (use (match_operand:SI 4 "const_int_operand" ""))
15373    (use (match_operand:SI 5 "const_int_operand" ""))]
15374   ""
15375 {
15376  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15377                          operands[4], operands[5]))
15378    DONE;
15379  else
15380    FAIL;
15381 })
15382
15383 ;; Most CPUs don't like single string operations
15384 ;; Handle this case here to simplify previous expander.
15385
15386 (define_expand "strmov"
15387   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15388    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15389    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15390               (clobber (reg:CC FLAGS_REG))])
15391    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15392               (clobber (reg:CC FLAGS_REG))])]
15393   ""
15394 {
15395   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15396
15397   /* If .md ever supports :P for Pmode, these can be directly
15398      in the pattern above.  */
15399   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15400   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15401
15402   /* Can't use this if the user has appropriated esi or edi.  */
15403   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15404       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15405     {
15406       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15407                                       operands[2], operands[3],
15408                                       operands[5], operands[6]));
15409       DONE;
15410     }
15411
15412   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15413 })
15414
15415 (define_expand "strmov_singleop"
15416   [(parallel [(set (match_operand 1 "memory_operand" "")
15417                    (match_operand 3 "memory_operand" ""))
15418               (set (match_operand 0 "register_operand" "")
15419                    (match_operand 4 "" ""))
15420               (set (match_operand 2 "register_operand" "")
15421                    (match_operand 5 "" ""))])]
15422   ""
15423   "ix86_current_function_needs_cld = 1;")
15424
15425 (define_insn "*strmovdi_rex_1"
15426   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15427         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15428    (set (match_operand:DI 0 "register_operand" "=D")
15429         (plus:DI (match_dup 2)
15430                  (const_int 8)))
15431    (set (match_operand:DI 1 "register_operand" "=S")
15432         (plus:DI (match_dup 3)
15433                  (const_int 8)))]
15434   "TARGET_64BIT"
15435   "movsq"
15436   [(set_attr "type" "str")
15437    (set_attr "memory" "both")
15438    (set_attr "mode" "DI")])
15439
15440 (define_insn "*strmovsi_1"
15441   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15442         (mem:SI (match_operand:P 3 "register_operand" "1")))
15443    (set (match_operand:P 0 "register_operand" "=D")
15444         (plus:P (match_dup 2)
15445                 (const_int 4)))
15446    (set (match_operand:P 1 "register_operand" "=S")
15447         (plus:P (match_dup 3)
15448                 (const_int 4)))]
15449   ""
15450   "movs{l|d}"
15451   [(set_attr "type" "str")
15452    (set_attr "memory" "both")
15453    (set_attr "mode" "SI")])
15454
15455 (define_insn "*strmovhi_1"
15456   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15457         (mem:HI (match_operand:P 3 "register_operand" "1")))
15458    (set (match_operand:P 0 "register_operand" "=D")
15459         (plus:P (match_dup 2)
15460                 (const_int 2)))
15461    (set (match_operand:P 1 "register_operand" "=S")
15462         (plus:P (match_dup 3)
15463                 (const_int 2)))]
15464   ""
15465   "movsw"
15466   [(set_attr "type" "str")
15467    (set_attr "memory" "both")
15468    (set_attr "mode" "HI")])
15469
15470 (define_insn "*strmovqi_1"
15471   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15472         (mem:QI (match_operand:P 3 "register_operand" "1")))
15473    (set (match_operand:P 0 "register_operand" "=D")
15474         (plus:P (match_dup 2)
15475                 (const_int 1)))
15476    (set (match_operand:P 1 "register_operand" "=S")
15477         (plus:P (match_dup 3)
15478                 (const_int 1)))]
15479   ""
15480   "movsb"
15481   [(set_attr "type" "str")
15482    (set_attr "memory" "both")
15483    (set (attr "prefix_rex")
15484         (if_then_else
15485           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15486           (const_string "0")
15487           (const_string "*")))
15488    (set_attr "mode" "QI")])
15489
15490 (define_expand "rep_mov"
15491   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15492               (set (match_operand 0 "register_operand" "")
15493                    (match_operand 5 "" ""))
15494               (set (match_operand 2 "register_operand" "")
15495                    (match_operand 6 "" ""))
15496               (set (match_operand 1 "memory_operand" "")
15497                    (match_operand 3 "memory_operand" ""))
15498               (use (match_dup 4))])]
15499   ""
15500   "ix86_current_function_needs_cld = 1;")
15501
15502 (define_insn "*rep_movdi_rex64"
15503   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15504    (set (match_operand:DI 0 "register_operand" "=D")
15505         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15506                             (const_int 3))
15507                  (match_operand:DI 3 "register_operand" "0")))
15508    (set (match_operand:DI 1 "register_operand" "=S")
15509         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15510                  (match_operand:DI 4 "register_operand" "1")))
15511    (set (mem:BLK (match_dup 3))
15512         (mem:BLK (match_dup 4)))
15513    (use (match_dup 5))]
15514   "TARGET_64BIT"
15515   "rep{%;} movsq"
15516   [(set_attr "type" "str")
15517    (set_attr "prefix_rep" "1")
15518    (set_attr "memory" "both")
15519    (set_attr "mode" "DI")])
15520
15521 (define_insn "*rep_movsi"
15522   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15523    (set (match_operand:P 0 "register_operand" "=D")
15524         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15525                           (const_int 2))
15526                  (match_operand:P 3 "register_operand" "0")))
15527    (set (match_operand:P 1 "register_operand" "=S")
15528         (plus:P (ashift:P (match_dup 5) (const_int 2))
15529                 (match_operand:P 4 "register_operand" "1")))
15530    (set (mem:BLK (match_dup 3))
15531         (mem:BLK (match_dup 4)))
15532    (use (match_dup 5))]
15533   ""
15534   "rep{%;} movs{l|d}"
15535   [(set_attr "type" "str")
15536    (set_attr "prefix_rep" "1")
15537    (set_attr "memory" "both")
15538    (set_attr "mode" "SI")])
15539
15540 (define_insn "*rep_movqi"
15541   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15542    (set (match_operand:P 0 "register_operand" "=D")
15543         (plus:P (match_operand:P 3 "register_operand" "0")
15544                 (match_operand:P 5 "register_operand" "2")))
15545    (set (match_operand:P 1 "register_operand" "=S")
15546         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15547    (set (mem:BLK (match_dup 3))
15548         (mem:BLK (match_dup 4)))
15549    (use (match_dup 5))]
15550   ""
15551   "rep{%;} movsb"
15552   [(set_attr "type" "str")
15553    (set_attr "prefix_rep" "1")
15554    (set_attr "memory" "both")
15555    (set_attr "mode" "QI")])
15556
15557 (define_expand "setmem<mode>"
15558    [(use (match_operand:BLK 0 "memory_operand" ""))
15559     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15560     (use (match_operand 2 "const_int_operand" ""))
15561     (use (match_operand 3 "const_int_operand" ""))
15562     (use (match_operand:SI 4 "const_int_operand" ""))
15563     (use (match_operand:SI 5 "const_int_operand" ""))]
15564   ""
15565 {
15566  if (ix86_expand_setmem (operands[0], operands[1],
15567                          operands[2], operands[3],
15568                          operands[4], operands[5]))
15569    DONE;
15570  else
15571    FAIL;
15572 })
15573
15574 ;; Most CPUs don't like single string operations
15575 ;; Handle this case here to simplify previous expander.
15576
15577 (define_expand "strset"
15578   [(set (match_operand 1 "memory_operand" "")
15579         (match_operand 2 "register_operand" ""))
15580    (parallel [(set (match_operand 0 "register_operand" "")
15581                    (match_dup 3))
15582               (clobber (reg:CC FLAGS_REG))])]
15583   ""
15584 {
15585   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15586     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15587
15588   /* If .md ever supports :P for Pmode, this can be directly
15589      in the pattern above.  */
15590   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15591                               GEN_INT (GET_MODE_SIZE (GET_MODE
15592                                                       (operands[2]))));
15593   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15594     {
15595       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15596                                       operands[3]));
15597       DONE;
15598     }
15599 })
15600
15601 (define_expand "strset_singleop"
15602   [(parallel [(set (match_operand 1 "memory_operand" "")
15603                    (match_operand 2 "register_operand" ""))
15604               (set (match_operand 0 "register_operand" "")
15605                    (match_operand 3 "" ""))])]
15606   ""
15607   "ix86_current_function_needs_cld = 1;")
15608
15609 (define_insn "*strsetdi_rex_1"
15610   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15611         (match_operand:DI 2 "register_operand" "a"))
15612    (set (match_operand:DI 0 "register_operand" "=D")
15613         (plus:DI (match_dup 1)
15614                  (const_int 8)))]
15615   "TARGET_64BIT"
15616   "stosq"
15617   [(set_attr "type" "str")
15618    (set_attr "memory" "store")
15619    (set_attr "mode" "DI")])
15620
15621 (define_insn "*strsetsi_1"
15622   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15623         (match_operand:SI 2 "register_operand" "a"))
15624    (set (match_operand:P 0 "register_operand" "=D")
15625         (plus:P (match_dup 1)
15626                 (const_int 4)))]
15627   ""
15628   "stos{l|d}"
15629   [(set_attr "type" "str")
15630    (set_attr "memory" "store")
15631    (set_attr "mode" "SI")])
15632
15633 (define_insn "*strsethi_1"
15634   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15635         (match_operand:HI 2 "register_operand" "a"))
15636    (set (match_operand:P 0 "register_operand" "=D")
15637         (plus:P (match_dup 1)
15638                 (const_int 2)))]
15639   ""
15640   "stosw"
15641   [(set_attr "type" "str")
15642    (set_attr "memory" "store")
15643    (set_attr "mode" "HI")])
15644
15645 (define_insn "*strsetqi_1"
15646   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15647         (match_operand:QI 2 "register_operand" "a"))
15648    (set (match_operand:P 0 "register_operand" "=D")
15649         (plus:P (match_dup 1)
15650                 (const_int 1)))]
15651   ""
15652   "stosb"
15653   [(set_attr "type" "str")
15654    (set_attr "memory" "store")
15655    (set (attr "prefix_rex")
15656         (if_then_else
15657           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15658           (const_string "0")
15659           (const_string "*")))
15660    (set_attr "mode" "QI")])
15661
15662 (define_expand "rep_stos"
15663   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15664               (set (match_operand 0 "register_operand" "")
15665                    (match_operand 4 "" ""))
15666               (set (match_operand 2 "memory_operand" "") (const_int 0))
15667               (use (match_operand 3 "register_operand" ""))
15668               (use (match_dup 1))])]
15669   ""
15670   "ix86_current_function_needs_cld = 1;")
15671
15672 (define_insn "*rep_stosdi_rex64"
15673   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15674    (set (match_operand:DI 0 "register_operand" "=D")
15675         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15676                             (const_int 3))
15677                  (match_operand:DI 3 "register_operand" "0")))
15678    (set (mem:BLK (match_dup 3))
15679         (const_int 0))
15680    (use (match_operand:DI 2 "register_operand" "a"))
15681    (use (match_dup 4))]
15682   "TARGET_64BIT"
15683   "rep{%;} stosq"
15684   [(set_attr "type" "str")
15685    (set_attr "prefix_rep" "1")
15686    (set_attr "memory" "store")
15687    (set_attr "mode" "DI")])
15688
15689 (define_insn "*rep_stossi"
15690   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15691    (set (match_operand:P 0 "register_operand" "=D")
15692         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15693                           (const_int 2))
15694                  (match_operand:P 3 "register_operand" "0")))
15695    (set (mem:BLK (match_dup 3))
15696         (const_int 0))
15697    (use (match_operand:SI 2 "register_operand" "a"))
15698    (use (match_dup 4))]
15699   ""
15700   "rep{%;} stos{l|d}"
15701   [(set_attr "type" "str")
15702    (set_attr "prefix_rep" "1")
15703    (set_attr "memory" "store")
15704    (set_attr "mode" "SI")])
15705
15706 (define_insn "*rep_stosqi"
15707   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15708    (set (match_operand:P 0 "register_operand" "=D")
15709         (plus:P (match_operand:P 3 "register_operand" "0")
15710                 (match_operand:P 4 "register_operand" "1")))
15711    (set (mem:BLK (match_dup 3))
15712         (const_int 0))
15713    (use (match_operand:QI 2 "register_operand" "a"))
15714    (use (match_dup 4))]
15715   ""
15716   "rep{%;} stosb"
15717   [(set_attr "type" "str")
15718    (set_attr "prefix_rep" "1")
15719    (set_attr "memory" "store")
15720    (set (attr "prefix_rex")
15721         (if_then_else
15722           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15723           (const_string "0")
15724           (const_string "*")))
15725    (set_attr "mode" "QI")])
15726
15727 (define_expand "cmpstrnsi"
15728   [(set (match_operand:SI 0 "register_operand" "")
15729         (compare:SI (match_operand:BLK 1 "general_operand" "")
15730                     (match_operand:BLK 2 "general_operand" "")))
15731    (use (match_operand 3 "general_operand" ""))
15732    (use (match_operand 4 "immediate_operand" ""))]
15733   ""
15734 {
15735   rtx addr1, addr2, out, outlow, count, countreg, align;
15736
15737   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15738     FAIL;
15739
15740   /* Can't use this if the user has appropriated esi or edi.  */
15741   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15742     FAIL;
15743
15744   out = operands[0];
15745   if (!REG_P (out))
15746     out = gen_reg_rtx (SImode);
15747
15748   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15749   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15750   if (addr1 != XEXP (operands[1], 0))
15751     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15752   if (addr2 != XEXP (operands[2], 0))
15753     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15754
15755   count = operands[3];
15756   countreg = ix86_zero_extend_to_Pmode (count);
15757
15758   /* %%% Iff we are testing strict equality, we can use known alignment
15759      to good advantage.  This may be possible with combine, particularly
15760      once cc0 is dead.  */
15761   align = operands[4];
15762
15763   if (CONST_INT_P (count))
15764     {
15765       if (INTVAL (count) == 0)
15766         {
15767           emit_move_insn (operands[0], const0_rtx);
15768           DONE;
15769         }
15770       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15771                                      operands[1], operands[2]));
15772     }
15773   else
15774     {
15775       rtx (*gen_cmp) (rtx, rtx);
15776
15777       gen_cmp = (TARGET_64BIT
15778                  ? gen_cmpdi_1 : gen_cmpsi_1);
15779
15780       emit_insn (gen_cmp (countreg, countreg));
15781       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15782                                   operands[1], operands[2]));
15783     }
15784
15785   outlow = gen_lowpart (QImode, out);
15786   emit_insn (gen_cmpintqi (outlow));
15787   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15788
15789   if (operands[0] != out)
15790     emit_move_insn (operands[0], out);
15791
15792   DONE;
15793 })
15794
15795 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15796
15797 (define_expand "cmpintqi"
15798   [(set (match_dup 1)
15799         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15800    (set (match_dup 2)
15801         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15802    (parallel [(set (match_operand:QI 0 "register_operand" "")
15803                    (minus:QI (match_dup 1)
15804                              (match_dup 2)))
15805               (clobber (reg:CC FLAGS_REG))])]
15806   ""
15807 {
15808   operands[1] = gen_reg_rtx (QImode);
15809   operands[2] = gen_reg_rtx (QImode);
15810 })
15811
15812 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15813 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15814
15815 (define_expand "cmpstrnqi_nz_1"
15816   [(parallel [(set (reg:CC FLAGS_REG)
15817                    (compare:CC (match_operand 4 "memory_operand" "")
15818                                (match_operand 5 "memory_operand" "")))
15819               (use (match_operand 2 "register_operand" ""))
15820               (use (match_operand:SI 3 "immediate_operand" ""))
15821               (clobber (match_operand 0 "register_operand" ""))
15822               (clobber (match_operand 1 "register_operand" ""))
15823               (clobber (match_dup 2))])]
15824   ""
15825   "ix86_current_function_needs_cld = 1;")
15826
15827 (define_insn "*cmpstrnqi_nz_1"
15828   [(set (reg:CC FLAGS_REG)
15829         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15830                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15831    (use (match_operand:P 6 "register_operand" "2"))
15832    (use (match_operand:SI 3 "immediate_operand" "i"))
15833    (clobber (match_operand:P 0 "register_operand" "=S"))
15834    (clobber (match_operand:P 1 "register_operand" "=D"))
15835    (clobber (match_operand:P 2 "register_operand" "=c"))]
15836   ""
15837   "repz{%;} cmpsb"
15838   [(set_attr "type" "str")
15839    (set_attr "mode" "QI")
15840    (set (attr "prefix_rex")
15841         (if_then_else
15842           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15843           (const_string "0")
15844           (const_string "*")))
15845    (set_attr "prefix_rep" "1")])
15846
15847 ;; The same, but the count is not known to not be zero.
15848
15849 (define_expand "cmpstrnqi_1"
15850   [(parallel [(set (reg:CC FLAGS_REG)
15851                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15852                                      (const_int 0))
15853                   (compare:CC (match_operand 4 "memory_operand" "")
15854                               (match_operand 5 "memory_operand" ""))
15855                   (const_int 0)))
15856               (use (match_operand:SI 3 "immediate_operand" ""))
15857               (use (reg:CC FLAGS_REG))
15858               (clobber (match_operand 0 "register_operand" ""))
15859               (clobber (match_operand 1 "register_operand" ""))
15860               (clobber (match_dup 2))])]
15861   ""
15862   "ix86_current_function_needs_cld = 1;")
15863
15864 (define_insn "*cmpstrnqi_1"
15865   [(set (reg:CC FLAGS_REG)
15866         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15867                              (const_int 0))
15868           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15869                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15870           (const_int 0)))
15871    (use (match_operand:SI 3 "immediate_operand" "i"))
15872    (use (reg:CC FLAGS_REG))
15873    (clobber (match_operand:P 0 "register_operand" "=S"))
15874    (clobber (match_operand:P 1 "register_operand" "=D"))
15875    (clobber (match_operand:P 2 "register_operand" "=c"))]
15876   ""
15877   "repz{%;} cmpsb"
15878   [(set_attr "type" "str")
15879    (set_attr "mode" "QI")
15880    (set (attr "prefix_rex")
15881         (if_then_else
15882           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15883           (const_string "0")
15884           (const_string "*")))
15885    (set_attr "prefix_rep" "1")])
15886
15887 (define_expand "strlen<mode>"
15888   [(set (match_operand:SWI48x 0 "register_operand" "")
15889         (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15890                         (match_operand:QI 2 "immediate_operand" "")
15891                         (match_operand 3 "immediate_operand" "")]
15892                        UNSPEC_SCAS))]
15893   ""
15894 {
15895  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15896    DONE;
15897  else
15898    FAIL;
15899 })
15900
15901 (define_expand "strlenqi_1"
15902   [(parallel [(set (match_operand 0 "register_operand" "")
15903                    (match_operand 2 "" ""))
15904               (clobber (match_operand 1 "register_operand" ""))
15905               (clobber (reg:CC FLAGS_REG))])]
15906   ""
15907   "ix86_current_function_needs_cld = 1;")
15908
15909 (define_insn "*strlenqi_1"
15910   [(set (match_operand:P 0 "register_operand" "=&c")
15911         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15912                    (match_operand:QI 2 "register_operand" "a")
15913                    (match_operand:P 3 "immediate_operand" "i")
15914                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15915    (clobber (match_operand:P 1 "register_operand" "=D"))
15916    (clobber (reg:CC FLAGS_REG))]
15917   ""
15918   "repnz{%;} scasb"
15919   [(set_attr "type" "str")
15920    (set_attr "mode" "QI")
15921    (set (attr "prefix_rex")
15922         (if_then_else
15923           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15924           (const_string "0")
15925           (const_string "*")))
15926    (set_attr "prefix_rep" "1")])
15927
15928 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15929 ;; handled in combine, but it is not currently up to the task.
15930 ;; When used for their truth value, the cmpstrn* expanders generate
15931 ;; code like this:
15932 ;;
15933 ;;   repz cmpsb
15934 ;;   seta       %al
15935 ;;   setb       %dl
15936 ;;   cmpb       %al, %dl
15937 ;;   jcc        label
15938 ;;
15939 ;; The intermediate three instructions are unnecessary.
15940
15941 ;; This one handles cmpstrn*_nz_1...
15942 (define_peephole2
15943   [(parallel[
15944      (set (reg:CC FLAGS_REG)
15945           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15946                       (mem:BLK (match_operand 5 "register_operand" ""))))
15947      (use (match_operand 6 "register_operand" ""))
15948      (use (match_operand:SI 3 "immediate_operand" ""))
15949      (clobber (match_operand 0 "register_operand" ""))
15950      (clobber (match_operand 1 "register_operand" ""))
15951      (clobber (match_operand 2 "register_operand" ""))])
15952    (set (match_operand:QI 7 "register_operand" "")
15953         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15954    (set (match_operand:QI 8 "register_operand" "")
15955         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15956    (set (reg FLAGS_REG)
15957         (compare (match_dup 7) (match_dup 8)))
15958   ]
15959   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15960   [(parallel[
15961      (set (reg:CC FLAGS_REG)
15962           (compare:CC (mem:BLK (match_dup 4))
15963                       (mem:BLK (match_dup 5))))
15964      (use (match_dup 6))
15965      (use (match_dup 3))
15966      (clobber (match_dup 0))
15967      (clobber (match_dup 1))
15968      (clobber (match_dup 2))])])
15969
15970 ;; ...and this one handles cmpstrn*_1.
15971 (define_peephole2
15972   [(parallel[
15973      (set (reg:CC FLAGS_REG)
15974           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15975                                (const_int 0))
15976             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15977                         (mem:BLK (match_operand 5 "register_operand" "")))
15978             (const_int 0)))
15979      (use (match_operand:SI 3 "immediate_operand" ""))
15980      (use (reg:CC FLAGS_REG))
15981      (clobber (match_operand 0 "register_operand" ""))
15982      (clobber (match_operand 1 "register_operand" ""))
15983      (clobber (match_operand 2 "register_operand" ""))])
15984    (set (match_operand:QI 7 "register_operand" "")
15985         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15986    (set (match_operand:QI 8 "register_operand" "")
15987         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15988    (set (reg FLAGS_REG)
15989         (compare (match_dup 7) (match_dup 8)))
15990   ]
15991   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15992   [(parallel[
15993      (set (reg:CC FLAGS_REG)
15994           (if_then_else:CC (ne (match_dup 6)
15995                                (const_int 0))
15996             (compare:CC (mem:BLK (match_dup 4))
15997                         (mem:BLK (match_dup 5)))
15998             (const_int 0)))
15999      (use (match_dup 3))
16000      (use (reg:CC FLAGS_REG))
16001      (clobber (match_dup 0))
16002      (clobber (match_dup 1))
16003      (clobber (match_dup 2))])])
16004 \f
16005 ;; Conditional move instructions.
16006
16007 (define_expand "mov<mode>cc"
16008   [(set (match_operand:SWIM 0 "register_operand" "")
16009         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16010                            (match_operand:SWIM 2 "general_operand" "")
16011                            (match_operand:SWIM 3 "general_operand" "")))]
16012   ""
16013   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16014
16015 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16016 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16017 ;; So just document what we're doing explicitly.
16018
16019 (define_expand "x86_mov<mode>cc_0_m1"
16020   [(parallel
16021     [(set (match_operand:SWI48 0 "register_operand" "")
16022           (if_then_else:SWI48
16023             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16024              [(match_operand 1 "flags_reg_operand" "")
16025               (const_int 0)])
16026             (const_int -1)
16027             (const_int 0)))
16028      (clobber (reg:CC FLAGS_REG))])])
16029
16030 (define_insn "*x86_mov<mode>cc_0_m1"
16031   [(set (match_operand:SWI48 0 "register_operand" "=r")
16032         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16033                              [(reg FLAGS_REG) (const_int 0)])
16034           (const_int -1)
16035           (const_int 0)))
16036    (clobber (reg:CC FLAGS_REG))]
16037   ""
16038   "sbb{<imodesuffix>}\t%0, %0"
16039   ; Since we don't have the proper number of operands for an alu insn,
16040   ; fill in all the blanks.
16041   [(set_attr "type" "alu")
16042    (set_attr "use_carry" "1")
16043    (set_attr "pent_pair" "pu")
16044    (set_attr "memory" "none")
16045    (set_attr "imm_disp" "false")
16046    (set_attr "mode" "<MODE>")
16047    (set_attr "length_immediate" "0")])
16048
16049 (define_insn "*x86_mov<mode>cc_0_m1_se"
16050   [(set (match_operand:SWI48 0 "register_operand" "=r")
16051         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16052                              [(reg FLAGS_REG) (const_int 0)])
16053                             (const_int 1)
16054                             (const_int 0)))
16055    (clobber (reg:CC FLAGS_REG))]
16056   ""
16057   "sbb{<imodesuffix>}\t%0, %0"
16058   [(set_attr "type" "alu")
16059    (set_attr "use_carry" "1")
16060    (set_attr "pent_pair" "pu")
16061    (set_attr "memory" "none")
16062    (set_attr "imm_disp" "false")
16063    (set_attr "mode" "<MODE>")
16064    (set_attr "length_immediate" "0")])
16065
16066 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16067   [(set (match_operand:SWI48 0 "register_operand" "=r")
16068         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16069                     [(reg FLAGS_REG) (const_int 0)])))]
16070   ""
16071   "sbb{<imodesuffix>}\t%0, %0"
16072   [(set_attr "type" "alu")
16073    (set_attr "use_carry" "1")
16074    (set_attr "pent_pair" "pu")
16075    (set_attr "memory" "none")
16076    (set_attr "imm_disp" "false")
16077    (set_attr "mode" "<MODE>")
16078    (set_attr "length_immediate" "0")])
16079
16080 (define_insn "*mov<mode>cc_noc"
16081   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16082         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16083                                [(reg FLAGS_REG) (const_int 0)])
16084           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16085           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16086   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16087   "@
16088    cmov%O2%C1\t{%2, %0|%0, %2}
16089    cmov%O2%c1\t{%3, %0|%0, %3}"
16090   [(set_attr "type" "icmov")
16091    (set_attr "mode" "<MODE>")])
16092
16093 (define_insn_and_split "*movqicc_noc"
16094   [(set (match_operand:QI 0 "register_operand" "=r,r")
16095         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16096                            [(match_operand 4 "flags_reg_operand" "")
16097                             (const_int 0)])
16098                       (match_operand:QI 2 "register_operand" "r,0")
16099                       (match_operand:QI 3 "register_operand" "0,r")))]
16100   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16101   "#"
16102   "&& reload_completed"
16103   [(set (match_dup 0)
16104         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16105                       (match_dup 2)
16106                       (match_dup 3)))]
16107   "operands[0] = gen_lowpart (SImode, operands[0]);
16108    operands[2] = gen_lowpart (SImode, operands[2]);
16109    operands[3] = gen_lowpart (SImode, operands[3]);"
16110   [(set_attr "type" "icmov")
16111    (set_attr "mode" "SI")])
16112
16113 (define_expand "mov<mode>cc"
16114   [(set (match_operand:X87MODEF 0 "register_operand" "")
16115         (if_then_else:X87MODEF
16116           (match_operand 1 "ix86_fp_comparison_operator" "")
16117           (match_operand:X87MODEF 2 "register_operand" "")
16118           (match_operand:X87MODEF 3 "register_operand" "")))]
16119   "(TARGET_80387 && TARGET_CMOVE)
16120    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16121   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16122
16123 (define_insn "*movxfcc_1"
16124   [(set (match_operand:XF 0 "register_operand" "=f,f")
16125         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16126                                 [(reg FLAGS_REG) (const_int 0)])
16127                       (match_operand:XF 2 "register_operand" "f,0")
16128                       (match_operand:XF 3 "register_operand" "0,f")))]
16129   "TARGET_80387 && TARGET_CMOVE"
16130   "@
16131    fcmov%F1\t{%2, %0|%0, %2}
16132    fcmov%f1\t{%3, %0|%0, %3}"
16133   [(set_attr "type" "fcmov")
16134    (set_attr "mode" "XF")])
16135
16136 (define_insn "*movdfcc_1_rex64"
16137   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16138         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16139                                 [(reg FLAGS_REG) (const_int 0)])
16140                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16141                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16142   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16143    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16144   "@
16145    fcmov%F1\t{%2, %0|%0, %2}
16146    fcmov%f1\t{%3, %0|%0, %3}
16147    cmov%O2%C1\t{%2, %0|%0, %2}
16148    cmov%O2%c1\t{%3, %0|%0, %3}"
16149   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16150    (set_attr "mode" "DF,DF,DI,DI")])
16151
16152 (define_insn "*movdfcc_1"
16153   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16154         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16155                                 [(reg FLAGS_REG) (const_int 0)])
16156                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16157                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16158   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16159    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16160   "@
16161    fcmov%F1\t{%2, %0|%0, %2}
16162    fcmov%f1\t{%3, %0|%0, %3}
16163    #
16164    #"
16165   [(set_attr "type" "fcmov,fcmov,multi,multi")
16166    (set_attr "mode" "DF,DF,DI,DI")])
16167
16168 (define_split
16169   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16170         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16171                                 [(match_operand 4 "flags_reg_operand" "")
16172                                  (const_int 0)])
16173                       (match_operand:DF 2 "nonimmediate_operand" "")
16174                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16175   "!TARGET_64BIT && reload_completed"
16176   [(set (match_dup 2)
16177         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16178                       (match_dup 5)
16179                       (match_dup 6)))
16180    (set (match_dup 3)
16181         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16182                       (match_dup 7)
16183                       (match_dup 8)))]
16184 {
16185   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16186   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16187 })
16188
16189 (define_insn "*movsfcc_1_387"
16190   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16191         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16192                                 [(reg FLAGS_REG) (const_int 0)])
16193                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16194                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16195   "TARGET_80387 && TARGET_CMOVE
16196    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16197   "@
16198    fcmov%F1\t{%2, %0|%0, %2}
16199    fcmov%f1\t{%3, %0|%0, %3}
16200    cmov%O2%C1\t{%2, %0|%0, %2}
16201    cmov%O2%c1\t{%3, %0|%0, %3}"
16202   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16203    (set_attr "mode" "SF,SF,SI,SI")])
16204
16205 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16206 ;; the scalar versions to have only XMM registers as operands.
16207
16208 ;; XOP conditional move
16209 (define_insn "*xop_pcmov_<mode>"
16210   [(set (match_operand:MODEF 0 "register_operand" "=x")
16211         (if_then_else:MODEF
16212           (match_operand:MODEF 1 "register_operand" "x")
16213           (match_operand:MODEF 2 "register_operand" "x")
16214           (match_operand:MODEF 3 "register_operand" "x")))]
16215   "TARGET_XOP"
16216   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16217   [(set_attr "type" "sse4arg")])
16218
16219 ;; These versions of the min/max patterns are intentionally ignorant of
16220 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16221 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16222 ;; are undefined in this condition, we're certain this is correct.
16223
16224 (define_insn "*avx_<code><mode>3"
16225   [(set (match_operand:MODEF 0 "register_operand" "=x")
16226         (smaxmin:MODEF
16227           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16228           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16229   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16230   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16231   [(set_attr "type" "sseadd")
16232    (set_attr "prefix" "vex")
16233    (set_attr "mode" "<MODE>")])
16234
16235 (define_insn "<code><mode>3"
16236   [(set (match_operand:MODEF 0 "register_operand" "=x")
16237         (smaxmin:MODEF
16238           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16239           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16240   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16241   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16242   [(set_attr "type" "sseadd")
16243    (set_attr "mode" "<MODE>")])
16244
16245 ;; These versions of the min/max patterns implement exactly the operations
16246 ;;   min = (op1 < op2 ? op1 : op2)
16247 ;;   max = (!(op1 < op2) ? op1 : op2)
16248 ;; Their operands are not commutative, and thus they may be used in the
16249 ;; presence of -0.0 and NaN.
16250
16251 (define_insn "*avx_ieee_smin<mode>3"
16252   [(set (match_operand:MODEF 0 "register_operand" "=x")
16253         (unspec:MODEF
16254           [(match_operand:MODEF 1 "register_operand" "x")
16255            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16256          UNSPEC_IEEE_MIN))]
16257   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16258   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16259   [(set_attr "type" "sseadd")
16260    (set_attr "prefix" "vex")
16261    (set_attr "mode" "<MODE>")])
16262
16263 (define_insn "*ieee_smin<mode>3"
16264   [(set (match_operand:MODEF 0 "register_operand" "=x")
16265         (unspec:MODEF
16266           [(match_operand:MODEF 1 "register_operand" "0")
16267            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16268          UNSPEC_IEEE_MIN))]
16269   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16270   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16271   [(set_attr "type" "sseadd")
16272    (set_attr "mode" "<MODE>")])
16273
16274 (define_insn "*avx_ieee_smax<mode>3"
16275   [(set (match_operand:MODEF 0 "register_operand" "=x")
16276         (unspec:MODEF
16277           [(match_operand:MODEF 1 "register_operand" "0")
16278            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16279          UNSPEC_IEEE_MAX))]
16280   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16281   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16282   [(set_attr "type" "sseadd")
16283    (set_attr "prefix" "vex")
16284    (set_attr "mode" "<MODE>")])
16285
16286 (define_insn "*ieee_smax<mode>3"
16287   [(set (match_operand:MODEF 0 "register_operand" "=x")
16288         (unspec:MODEF
16289           [(match_operand:MODEF 1 "register_operand" "0")
16290            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16291          UNSPEC_IEEE_MAX))]
16292   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16293   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16294   [(set_attr "type" "sseadd")
16295    (set_attr "mode" "<MODE>")])
16296
16297 ;; Make two stack loads independent:
16298 ;;   fld aa              fld aa
16299 ;;   fld %st(0)     ->   fld bb
16300 ;;   fmul bb             fmul %st(1), %st
16301 ;;
16302 ;; Actually we only match the last two instructions for simplicity.
16303 (define_peephole2
16304   [(set (match_operand 0 "fp_register_operand" "")
16305         (match_operand 1 "fp_register_operand" ""))
16306    (set (match_dup 0)
16307         (match_operator 2 "binary_fp_operator"
16308            [(match_dup 0)
16309             (match_operand 3 "memory_operand" "")]))]
16310   "REGNO (operands[0]) != REGNO (operands[1])"
16311   [(set (match_dup 0) (match_dup 3))
16312    (set (match_dup 0) (match_dup 4))]
16313
16314   ;; The % modifier is not operational anymore in peephole2's, so we have to
16315   ;; swap the operands manually in the case of addition and multiplication.
16316   "if (COMMUTATIVE_ARITH_P (operands[2]))
16317      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16318                                    GET_MODE (operands[2]),
16319                                    operands[0], operands[1]);
16320    else
16321      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16322                                    GET_MODE (operands[2]),
16323                                    operands[1], operands[0]);")
16324
16325 ;; Conditional addition patterns
16326 (define_expand "add<mode>cc"
16327   [(match_operand:SWI 0 "register_operand" "")
16328    (match_operand 1 "ordered_comparison_operator" "")
16329    (match_operand:SWI 2 "register_operand" "")
16330    (match_operand:SWI 3 "const_int_operand" "")]
16331   ""
16332   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16333 \f
16334 ;; Misc patterns (?)
16335
16336 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16337 ;; Otherwise there will be nothing to keep
16338 ;;
16339 ;; [(set (reg ebp) (reg esp))]
16340 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16341 ;;  (clobber (eflags)]
16342 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16343 ;;
16344 ;; in proper program order.
16345
16346 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16347   [(set (match_operand:P 0 "register_operand" "=r,r")
16348         (plus:P (match_operand:P 1 "register_operand" "0,r")
16349                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16350    (clobber (reg:CC FLAGS_REG))
16351    (clobber (mem:BLK (scratch)))]
16352   ""
16353 {
16354   switch (get_attr_type (insn))
16355     {
16356     case TYPE_IMOV:
16357       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16358
16359     case TYPE_ALU:
16360       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16361       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16362         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16363
16364       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16365
16366     default:
16367       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16368       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16369     }
16370 }
16371   [(set (attr "type")
16372         (cond [(and (eq_attr "alternative" "0")
16373                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16374                  (const_string "alu")
16375                (match_operand:<MODE> 2 "const0_operand" "")
16376                  (const_string "imov")
16377               ]
16378               (const_string "lea")))
16379    (set (attr "length_immediate")
16380         (cond [(eq_attr "type" "imov")
16381                  (const_string "0")
16382                (and (eq_attr "type" "alu")
16383                     (match_operand 2 "const128_operand" ""))
16384                  (const_string "1")
16385               ]
16386               (const_string "*")))
16387    (set_attr "mode" "<MODE>")])
16388
16389 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16390   [(set (match_operand:P 0 "register_operand" "=r")
16391         (minus:P (match_operand:P 1 "register_operand" "0")
16392                  (match_operand:P 2 "register_operand" "r")))
16393    (clobber (reg:CC FLAGS_REG))
16394    (clobber (mem:BLK (scratch)))]
16395   ""
16396   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16397   [(set_attr "type" "alu")
16398    (set_attr "mode" "<MODE>")])
16399
16400 (define_insn "allocate_stack_worker_probe_<mode>"
16401   [(set (match_operand:P 0 "register_operand" "=a")
16402         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16403                             UNSPECV_STACK_PROBE))
16404    (clobber (reg:CC FLAGS_REG))]
16405   "ix86_target_stack_probe ()"
16406   "call\t___chkstk_ms"
16407   [(set_attr "type" "multi")
16408    (set_attr "length" "5")])
16409
16410 (define_expand "allocate_stack"
16411   [(match_operand 0 "register_operand" "")
16412    (match_operand 1 "general_operand" "")]
16413   "ix86_target_stack_probe ()"
16414 {
16415   rtx x;
16416
16417 #ifndef CHECK_STACK_LIMIT
16418 #define CHECK_STACK_LIMIT 0
16419 #endif
16420
16421   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16422       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16423     {
16424       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16425                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16426       if (x != stack_pointer_rtx)
16427         emit_move_insn (stack_pointer_rtx, x);
16428     }
16429   else
16430     {
16431       x = copy_to_mode_reg (Pmode, operands[1]);
16432       if (TARGET_64BIT)
16433         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16434       else
16435         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16436       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16437                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16438       if (x != stack_pointer_rtx)
16439         emit_move_insn (stack_pointer_rtx, x);
16440     }
16441
16442   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16443   DONE;
16444 })
16445
16446 ;; Use IOR for stack probes, this is shorter.
16447 (define_expand "probe_stack"
16448   [(match_operand 0 "memory_operand" "")]
16449   ""
16450 {
16451   rtx (*gen_ior3) (rtx, rtx, rtx);
16452
16453   gen_ior3 = (GET_MODE (operands[0]) == DImode
16454               ? gen_iordi3 : gen_iorsi3);
16455
16456   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16457   DONE;
16458 })
16459
16460 (define_insn "adjust_stack_and_probe<mode>"
16461   [(set (match_operand:P 0 "register_operand" "=r")
16462         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16463                             UNSPECV_PROBE_STACK_RANGE))
16464    (set (reg:P SP_REG)
16465         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16466    (clobber (reg:CC FLAGS_REG))
16467    (clobber (mem:BLK (scratch)))]
16468   ""
16469   "* return output_adjust_stack_and_probe (operands[0]);"
16470   [(set_attr "type" "multi")])
16471
16472 (define_insn "probe_stack_range<mode>"
16473   [(set (match_operand:P 0 "register_operand" "=r")
16474         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16475                             (match_operand:P 2 "const_int_operand" "n")]
16476                             UNSPECV_PROBE_STACK_RANGE))
16477    (clobber (reg:CC FLAGS_REG))]
16478   ""
16479   "* return output_probe_stack_range (operands[0], operands[2]);"
16480   [(set_attr "type" "multi")])
16481
16482 (define_expand "builtin_setjmp_receiver"
16483   [(label_ref (match_operand 0 "" ""))]
16484   "!TARGET_64BIT && flag_pic"
16485 {
16486 #if TARGET_MACHO
16487   if (TARGET_MACHO)
16488     {
16489       rtx xops[3];
16490       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16491       rtx label_rtx = gen_label_rtx ();
16492       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16493       xops[0] = xops[1] = picreg;
16494       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16495       ix86_expand_binary_operator (MINUS, SImode, xops);
16496     }
16497   else
16498 #endif
16499     emit_insn (gen_set_got (pic_offset_table_rtx));
16500   DONE;
16501 })
16502 \f
16503 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16504
16505 (define_split
16506   [(set (match_operand 0 "register_operand" "")
16507         (match_operator 3 "promotable_binary_operator"
16508            [(match_operand 1 "register_operand" "")
16509             (match_operand 2 "aligned_operand" "")]))
16510    (clobber (reg:CC FLAGS_REG))]
16511   "! TARGET_PARTIAL_REG_STALL && reload_completed
16512    && ((GET_MODE (operands[0]) == HImode
16513         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16514             /* ??? next two lines just !satisfies_constraint_K (...) */
16515             || !CONST_INT_P (operands[2])
16516             || satisfies_constraint_K (operands[2])))
16517        || (GET_MODE (operands[0]) == QImode
16518            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16519   [(parallel [(set (match_dup 0)
16520                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16521               (clobber (reg:CC FLAGS_REG))])]
16522   "operands[0] = gen_lowpart (SImode, operands[0]);
16523    operands[1] = gen_lowpart (SImode, operands[1]);
16524    if (GET_CODE (operands[3]) != ASHIFT)
16525      operands[2] = gen_lowpart (SImode, operands[2]);
16526    PUT_MODE (operands[3], SImode);")
16527
16528 ; Promote the QImode tests, as i386 has encoding of the AND
16529 ; instruction with 32-bit sign-extended immediate and thus the
16530 ; instruction size is unchanged, except in the %eax case for
16531 ; which it is increased by one byte, hence the ! optimize_size.
16532 (define_split
16533   [(set (match_operand 0 "flags_reg_operand" "")
16534         (match_operator 2 "compare_operator"
16535           [(and (match_operand 3 "aligned_operand" "")
16536                 (match_operand 4 "const_int_operand" ""))
16537            (const_int 0)]))
16538    (set (match_operand 1 "register_operand" "")
16539         (and (match_dup 3) (match_dup 4)))]
16540   "! TARGET_PARTIAL_REG_STALL && reload_completed
16541    && optimize_insn_for_speed_p ()
16542    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16543        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16544    /* Ensure that the operand will remain sign-extended immediate.  */
16545    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16546   [(parallel [(set (match_dup 0)
16547                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16548                                     (const_int 0)]))
16549               (set (match_dup 1)
16550                    (and:SI (match_dup 3) (match_dup 4)))])]
16551 {
16552   operands[4]
16553     = gen_int_mode (INTVAL (operands[4])
16554                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16555   operands[1] = gen_lowpart (SImode, operands[1]);
16556   operands[3] = gen_lowpart (SImode, operands[3]);
16557 })
16558
16559 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16560 ; the TEST instruction with 32-bit sign-extended immediate and thus
16561 ; the instruction size would at least double, which is not what we
16562 ; want even with ! optimize_size.
16563 (define_split
16564   [(set (match_operand 0 "flags_reg_operand" "")
16565         (match_operator 1 "compare_operator"
16566           [(and (match_operand:HI 2 "aligned_operand" "")
16567                 (match_operand:HI 3 "const_int_operand" ""))
16568            (const_int 0)]))]
16569   "! TARGET_PARTIAL_REG_STALL && reload_completed
16570    && ! TARGET_FAST_PREFIX
16571    && optimize_insn_for_speed_p ()
16572    /* Ensure that the operand will remain sign-extended immediate.  */
16573    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16574   [(set (match_dup 0)
16575         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16576                          (const_int 0)]))]
16577 {
16578   operands[3]
16579     = gen_int_mode (INTVAL (operands[3])
16580                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16581   operands[2] = gen_lowpart (SImode, operands[2]);
16582 })
16583
16584 (define_split
16585   [(set (match_operand 0 "register_operand" "")
16586         (neg (match_operand 1 "register_operand" "")))
16587    (clobber (reg:CC FLAGS_REG))]
16588   "! TARGET_PARTIAL_REG_STALL && reload_completed
16589    && (GET_MODE (operands[0]) == HImode
16590        || (GET_MODE (operands[0]) == QImode
16591            && (TARGET_PROMOTE_QImode
16592                || optimize_insn_for_size_p ())))"
16593   [(parallel [(set (match_dup 0)
16594                    (neg:SI (match_dup 1)))
16595               (clobber (reg:CC FLAGS_REG))])]
16596   "operands[0] = gen_lowpart (SImode, operands[0]);
16597    operands[1] = gen_lowpart (SImode, operands[1]);")
16598
16599 (define_split
16600   [(set (match_operand 0 "register_operand" "")
16601         (not (match_operand 1 "register_operand" "")))]
16602   "! TARGET_PARTIAL_REG_STALL && reload_completed
16603    && (GET_MODE (operands[0]) == HImode
16604        || (GET_MODE (operands[0]) == QImode
16605            && (TARGET_PROMOTE_QImode
16606                || optimize_insn_for_size_p ())))"
16607   [(set (match_dup 0)
16608         (not:SI (match_dup 1)))]
16609   "operands[0] = gen_lowpart (SImode, operands[0]);
16610    operands[1] = gen_lowpart (SImode, operands[1]);")
16611
16612 (define_split
16613   [(set (match_operand 0 "register_operand" "")
16614         (if_then_else (match_operator 1 "ordered_comparison_operator"
16615                                 [(reg FLAGS_REG) (const_int 0)])
16616                       (match_operand 2 "register_operand" "")
16617                       (match_operand 3 "register_operand" "")))]
16618   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16619    && (GET_MODE (operands[0]) == HImode
16620        || (GET_MODE (operands[0]) == QImode
16621            && (TARGET_PROMOTE_QImode
16622                || optimize_insn_for_size_p ())))"
16623   [(set (match_dup 0)
16624         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16625   "operands[0] = gen_lowpart (SImode, operands[0]);
16626    operands[2] = gen_lowpart (SImode, operands[2]);
16627    operands[3] = gen_lowpart (SImode, operands[3]);")
16628 \f
16629 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16630 ;; transform a complex memory operation into two memory to register operations.
16631
16632 ;; Don't push memory operands
16633 (define_peephole2
16634   [(set (match_operand:SWI 0 "push_operand" "")
16635         (match_operand:SWI 1 "memory_operand" ""))
16636    (match_scratch:SWI 2 "<r>")]
16637   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16638    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16639   [(set (match_dup 2) (match_dup 1))
16640    (set (match_dup 0) (match_dup 2))])
16641
16642 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16643 ;; SImode pushes.
16644 (define_peephole2
16645   [(set (match_operand:SF 0 "push_operand" "")
16646         (match_operand:SF 1 "memory_operand" ""))
16647    (match_scratch:SF 2 "r")]
16648   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16649    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16650   [(set (match_dup 2) (match_dup 1))
16651    (set (match_dup 0) (match_dup 2))])
16652
16653 ;; Don't move an immediate directly to memory when the instruction
16654 ;; gets too big.
16655 (define_peephole2
16656   [(match_scratch:SWI124 1 "<r>")
16657    (set (match_operand:SWI124 0 "memory_operand" "")
16658         (const_int 0))]
16659   "optimize_insn_for_speed_p ()
16660    && !TARGET_USE_MOV0
16661    && TARGET_SPLIT_LONG_MOVES
16662    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16663    && peep2_regno_dead_p (0, FLAGS_REG)"
16664   [(parallel [(set (match_dup 2) (const_int 0))
16665               (clobber (reg:CC FLAGS_REG))])
16666    (set (match_dup 0) (match_dup 1))]
16667   "operands[2] = gen_lowpart (SImode, operands[1]);")
16668
16669 (define_peephole2
16670   [(match_scratch:SWI124 2 "<r>")
16671    (set (match_operand:SWI124 0 "memory_operand" "")
16672         (match_operand:SWI124 1 "immediate_operand" ""))]
16673   "optimize_insn_for_speed_p ()
16674    && TARGET_SPLIT_LONG_MOVES
16675    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16676   [(set (match_dup 2) (match_dup 1))
16677    (set (match_dup 0) (match_dup 2))])
16678
16679 ;; Don't compare memory with zero, load and use a test instead.
16680 (define_peephole2
16681   [(set (match_operand 0 "flags_reg_operand" "")
16682         (match_operator 1 "compare_operator"
16683           [(match_operand:SI 2 "memory_operand" "")
16684            (const_int 0)]))
16685    (match_scratch:SI 3 "r")]
16686   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16687   [(set (match_dup 3) (match_dup 2))
16688    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16689
16690 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16691 ;; Don't split NOTs with a displacement operand, because resulting XOR
16692 ;; will not be pairable anyway.
16693 ;;
16694 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16695 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16696 ;; so this split helps here as well.
16697 ;;
16698 ;; Note: Can't do this as a regular split because we can't get proper
16699 ;; lifetime information then.
16700
16701 (define_peephole2
16702   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16703         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16704   "optimize_insn_for_speed_p ()
16705    && ((TARGET_NOT_UNPAIRABLE
16706         && (!MEM_P (operands[0])
16707             || !memory_displacement_operand (operands[0], <MODE>mode)))
16708        || (TARGET_NOT_VECTORMODE
16709            && long_memory_operand (operands[0], <MODE>mode)))
16710    && peep2_regno_dead_p (0, FLAGS_REG)"
16711   [(parallel [(set (match_dup 0)
16712                    (xor:SWI124 (match_dup 1) (const_int -1)))
16713               (clobber (reg:CC FLAGS_REG))])])
16714
16715 ;; Non pairable "test imm, reg" instructions can be translated to
16716 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16717 ;; byte opcode instead of two, have a short form for byte operands),
16718 ;; so do it for other CPUs as well.  Given that the value was dead,
16719 ;; this should not create any new dependencies.  Pass on the sub-word
16720 ;; versions if we're concerned about partial register stalls.
16721
16722 (define_peephole2
16723   [(set (match_operand 0 "flags_reg_operand" "")
16724         (match_operator 1 "compare_operator"
16725           [(and:SI (match_operand:SI 2 "register_operand" "")
16726                    (match_operand:SI 3 "immediate_operand" ""))
16727            (const_int 0)]))]
16728   "ix86_match_ccmode (insn, CCNOmode)
16729    && (true_regnum (operands[2]) != AX_REG
16730        || satisfies_constraint_K (operands[3]))
16731    && peep2_reg_dead_p (1, operands[2])"
16732   [(parallel
16733      [(set (match_dup 0)
16734            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16735                             (const_int 0)]))
16736       (set (match_dup 2)
16737            (and:SI (match_dup 2) (match_dup 3)))])])
16738
16739 ;; We don't need to handle HImode case, because it will be promoted to SImode
16740 ;; on ! TARGET_PARTIAL_REG_STALL
16741
16742 (define_peephole2
16743   [(set (match_operand 0 "flags_reg_operand" "")
16744         (match_operator 1 "compare_operator"
16745           [(and:QI (match_operand:QI 2 "register_operand" "")
16746                    (match_operand:QI 3 "immediate_operand" ""))
16747            (const_int 0)]))]
16748   "! TARGET_PARTIAL_REG_STALL
16749    && ix86_match_ccmode (insn, CCNOmode)
16750    && true_regnum (operands[2]) != AX_REG
16751    && peep2_reg_dead_p (1, operands[2])"
16752   [(parallel
16753      [(set (match_dup 0)
16754            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16755                             (const_int 0)]))
16756       (set (match_dup 2)
16757            (and:QI (match_dup 2) (match_dup 3)))])])
16758
16759 (define_peephole2
16760   [(set (match_operand 0 "flags_reg_operand" "")
16761         (match_operator 1 "compare_operator"
16762           [(and:SI
16763              (zero_extract:SI
16764                (match_operand 2 "ext_register_operand" "")
16765                (const_int 8)
16766                (const_int 8))
16767              (match_operand 3 "const_int_operand" ""))
16768            (const_int 0)]))]
16769   "! TARGET_PARTIAL_REG_STALL
16770    && ix86_match_ccmode (insn, CCNOmode)
16771    && true_regnum (operands[2]) != AX_REG
16772    && peep2_reg_dead_p (1, operands[2])"
16773   [(parallel [(set (match_dup 0)
16774                    (match_op_dup 1
16775                      [(and:SI
16776                         (zero_extract:SI
16777                           (match_dup 2)
16778                           (const_int 8)
16779                           (const_int 8))
16780                         (match_dup 3))
16781                       (const_int 0)]))
16782               (set (zero_extract:SI (match_dup 2)
16783                                     (const_int 8)
16784                                     (const_int 8))
16785                    (and:SI
16786                      (zero_extract:SI
16787                        (match_dup 2)
16788                        (const_int 8)
16789                        (const_int 8))
16790                      (match_dup 3)))])])
16791
16792 ;; Don't do logical operations with memory inputs.
16793 (define_peephole2
16794   [(match_scratch:SI 2 "r")
16795    (parallel [(set (match_operand:SI 0 "register_operand" "")
16796                    (match_operator:SI 3 "arith_or_logical_operator"
16797                      [(match_dup 0)
16798                       (match_operand:SI 1 "memory_operand" "")]))
16799               (clobber (reg:CC FLAGS_REG))])]
16800   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16801   [(set (match_dup 2) (match_dup 1))
16802    (parallel [(set (match_dup 0)
16803                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16804               (clobber (reg:CC FLAGS_REG))])])
16805
16806 (define_peephole2
16807   [(match_scratch:SI 2 "r")
16808    (parallel [(set (match_operand:SI 0 "register_operand" "")
16809                    (match_operator:SI 3 "arith_or_logical_operator"
16810                      [(match_operand:SI 1 "memory_operand" "")
16811                       (match_dup 0)]))
16812               (clobber (reg:CC FLAGS_REG))])]
16813   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16814   [(set (match_dup 2) (match_dup 1))
16815    (parallel [(set (match_dup 0)
16816                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16817               (clobber (reg:CC FLAGS_REG))])])
16818
16819 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16820 ;; refers to the destination of the load!
16821
16822 (define_peephole2
16823   [(set (match_operand:SI 0 "register_operand" "")
16824         (match_operand:SI 1 "register_operand" ""))
16825    (parallel [(set (match_dup 0)
16826                    (match_operator:SI 3 "commutative_operator"
16827                      [(match_dup 0)
16828                       (match_operand:SI 2 "memory_operand" "")]))
16829               (clobber (reg:CC FLAGS_REG))])]
16830   "REGNO (operands[0]) != REGNO (operands[1])
16831    && GENERAL_REGNO_P (REGNO (operands[0]))
16832    && GENERAL_REGNO_P (REGNO (operands[1]))"
16833   [(set (match_dup 0) (match_dup 4))
16834    (parallel [(set (match_dup 0)
16835                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16836               (clobber (reg:CC FLAGS_REG))])]
16837   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16838
16839 (define_peephole2
16840   [(set (match_operand 0 "register_operand" "")
16841         (match_operand 1 "register_operand" ""))
16842    (set (match_dup 0)
16843                    (match_operator 3 "commutative_operator"
16844                      [(match_dup 0)
16845                       (match_operand 2 "memory_operand" "")]))]
16846   "REGNO (operands[0]) != REGNO (operands[1])
16847    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16848        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16849   [(set (match_dup 0) (match_dup 2))
16850    (set (match_dup 0)
16851         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16852
16853 ; Don't do logical operations with memory outputs
16854 ;
16855 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16856 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16857 ; the same decoder scheduling characteristics as the original.
16858
16859 (define_peephole2
16860   [(match_scratch:SI 2 "r")
16861    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16862                    (match_operator:SI 3 "arith_or_logical_operator"
16863                      [(match_dup 0)
16864                       (match_operand:SI 1 "nonmemory_operand" "")]))
16865               (clobber (reg:CC FLAGS_REG))])]
16866   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16867    /* Do not split stack checking probes.  */
16868    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16869   [(set (match_dup 2) (match_dup 0))
16870    (parallel [(set (match_dup 2)
16871                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16872               (clobber (reg:CC FLAGS_REG))])
16873    (set (match_dup 0) (match_dup 2))])
16874
16875 (define_peephole2
16876   [(match_scratch:SI 2 "r")
16877    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16878                    (match_operator:SI 3 "arith_or_logical_operator"
16879                      [(match_operand:SI 1 "nonmemory_operand" "")
16880                       (match_dup 0)]))
16881               (clobber (reg:CC FLAGS_REG))])]
16882   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16883    /* Do not split stack checking probes.  */
16884    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16885   [(set (match_dup 2) (match_dup 0))
16886    (parallel [(set (match_dup 2)
16887                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16888               (clobber (reg:CC FLAGS_REG))])
16889    (set (match_dup 0) (match_dup 2))])
16890
16891 ;; Attempt to always use XOR for zeroing registers.
16892 (define_peephole2
16893   [(set (match_operand 0 "register_operand" "")
16894         (match_operand 1 "const0_operand" ""))]
16895   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16896    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16897    && GENERAL_REG_P (operands[0])
16898    && peep2_regno_dead_p (0, FLAGS_REG)"
16899   [(parallel [(set (match_dup 0) (const_int 0))
16900               (clobber (reg:CC FLAGS_REG))])]
16901   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16902
16903 (define_peephole2
16904   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16905         (const_int 0))]
16906   "(GET_MODE (operands[0]) == QImode
16907     || GET_MODE (operands[0]) == HImode)
16908    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16909    && peep2_regno_dead_p (0, FLAGS_REG)"
16910   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16911               (clobber (reg:CC FLAGS_REG))])])
16912
16913 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16914 (define_peephole2
16915   [(set (match_operand:SWI248 0 "register_operand" "")
16916         (const_int -1))]
16917   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16918    && peep2_regno_dead_p (0, FLAGS_REG)"
16919   [(parallel [(set (match_dup 0) (const_int -1))
16920               (clobber (reg:CC FLAGS_REG))])]
16921 {
16922   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16923     operands[0] = gen_lowpart (SImode, operands[0]);
16924 })
16925
16926 ;; Attempt to convert simple lea to add/shift.
16927 ;; These can be created by move expanders.
16928
16929 (define_peephole2
16930   [(set (match_operand:SWI48 0 "register_operand" "")
16931         (plus:SWI48 (match_dup 0)
16932                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16933   "peep2_regno_dead_p (0, FLAGS_REG)"
16934   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16935               (clobber (reg:CC FLAGS_REG))])])
16936
16937 (define_peephole2
16938   [(set (match_operand:SI 0 "register_operand" "")
16939         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16940                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16941   "TARGET_64BIT
16942    && peep2_regno_dead_p (0, FLAGS_REG)
16943    && REGNO (operands[0]) == REGNO (operands[1])"
16944   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16945               (clobber (reg:CC FLAGS_REG))])]
16946   "operands[2] = gen_lowpart (SImode, operands[2]);")
16947
16948 (define_peephole2
16949   [(set (match_operand:SWI48 0 "register_operand" "")
16950         (mult:SWI48 (match_dup 0)
16951                     (match_operand:SWI48 1 "const_int_operand" "")))]
16952   "exact_log2 (INTVAL (operands[1])) >= 0
16953    && peep2_regno_dead_p (0, FLAGS_REG)"
16954   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16955               (clobber (reg:CC FLAGS_REG))])]
16956   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16957
16958 (define_peephole2
16959   [(set (match_operand:SI 0 "register_operand" "")
16960         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16961                    (match_operand:DI 2 "const_int_operand" "")) 0))]
16962   "TARGET_64BIT
16963    && exact_log2 (INTVAL (operands[2])) >= 0
16964    && REGNO (operands[0]) == REGNO (operands[1])
16965    && peep2_regno_dead_p (0, FLAGS_REG)"
16966   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16967               (clobber (reg:CC FLAGS_REG))])]
16968   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16969
16970 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16971 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16972 ;; On many CPUs it is also faster, since special hardware to avoid esp
16973 ;; dependencies is present.
16974
16975 ;; While some of these conversions may be done using splitters, we use
16976 ;; peepholes in order to allow combine_stack_adjustments pass to see
16977 ;; nonobfuscated RTL.
16978
16979 ;; Convert prologue esp subtractions to push.
16980 ;; We need register to push.  In order to keep verify_flow_info happy we have
16981 ;; two choices
16982 ;; - use scratch and clobber it in order to avoid dependencies
16983 ;; - use already live register
16984 ;; We can't use the second way right now, since there is no reliable way how to
16985 ;; verify that given register is live.  First choice will also most likely in
16986 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16987 ;; call clobbered registers are dead.  We may want to use base pointer as an
16988 ;; alternative when no register is available later.
16989
16990 (define_peephole2
16991   [(match_scratch:P 1 "r")
16992    (parallel [(set (reg:P SP_REG)
16993                    (plus:P (reg:P SP_REG)
16994                            (match_operand:P 0 "const_int_operand" "")))
16995               (clobber (reg:CC FLAGS_REG))
16996               (clobber (mem:BLK (scratch)))])]
16997   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16998    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16999   [(clobber (match_dup 1))
17000    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17001               (clobber (mem:BLK (scratch)))])])
17002
17003 (define_peephole2
17004   [(match_scratch:P 1 "r")
17005    (parallel [(set (reg:P SP_REG)
17006                    (plus:P (reg:P SP_REG)
17007                            (match_operand:P 0 "const_int_operand" "")))
17008               (clobber (reg:CC FLAGS_REG))
17009               (clobber (mem:BLK (scratch)))])]
17010   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17011    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17012   [(clobber (match_dup 1))
17013    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17014    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17015               (clobber (mem:BLK (scratch)))])])
17016
17017 ;; Convert esp subtractions to push.
17018 (define_peephole2
17019   [(match_scratch:P 1 "r")
17020    (parallel [(set (reg:P SP_REG)
17021                    (plus:P (reg:P SP_REG)
17022                            (match_operand:P 0 "const_int_operand" "")))
17023               (clobber (reg:CC FLAGS_REG))])]
17024   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17025    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17026   [(clobber (match_dup 1))
17027    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17028
17029 (define_peephole2
17030   [(match_scratch:P 1 "r")
17031    (parallel [(set (reg:P SP_REG)
17032                    (plus:P (reg:P SP_REG)
17033                            (match_operand:P 0 "const_int_operand" "")))
17034               (clobber (reg:CC FLAGS_REG))])]
17035   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17036    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17037   [(clobber (match_dup 1))
17038    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17039    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17040
17041 ;; Convert epilogue deallocator to pop.
17042 (define_peephole2
17043   [(match_scratch:P 1 "r")
17044    (parallel [(set (reg:P SP_REG)
17045                    (plus:P (reg:P SP_REG)
17046                            (match_operand:P 0 "const_int_operand" "")))
17047               (clobber (reg:CC FLAGS_REG))
17048               (clobber (mem:BLK (scratch)))])]
17049   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17050    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17051   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17052               (clobber (mem:BLK (scratch)))])])
17053
17054 ;; Two pops case is tricky, since pop causes dependency
17055 ;; on destination register.  We use two registers if available.
17056 (define_peephole2
17057   [(match_scratch:P 1 "r")
17058    (match_scratch:P 2 "r")
17059    (parallel [(set (reg:P SP_REG)
17060                    (plus:P (reg:P SP_REG)
17061                            (match_operand:P 0 "const_int_operand" "")))
17062               (clobber (reg:CC FLAGS_REG))
17063               (clobber (mem:BLK (scratch)))])]
17064   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17065    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17066   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17067               (clobber (mem:BLK (scratch)))])
17068    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17069
17070 (define_peephole2
17071   [(match_scratch:P 1 "r")
17072    (parallel [(set (reg:P SP_REG)
17073                    (plus:P (reg:P SP_REG)
17074                            (match_operand:P 0 "const_int_operand" "")))
17075               (clobber (reg:CC FLAGS_REG))
17076               (clobber (mem:BLK (scratch)))])]
17077   "optimize_insn_for_size_p ()
17078    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17079   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17080               (clobber (mem:BLK (scratch)))])
17081    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17082
17083 ;; Convert esp additions to pop.
17084 (define_peephole2
17085   [(match_scratch:P 1 "r")
17086    (parallel [(set (reg:P SP_REG)
17087                    (plus:P (reg:P SP_REG)
17088                            (match_operand:P 0 "const_int_operand" "")))
17089               (clobber (reg:CC FLAGS_REG))])]
17090   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17091   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17092
17093 ;; Two pops case is tricky, since pop causes dependency
17094 ;; on destination register.  We use two registers if available.
17095 (define_peephole2
17096   [(match_scratch:P 1 "r")
17097    (match_scratch:P 2 "r")
17098    (parallel [(set (reg:P SP_REG)
17099                    (plus:P (reg:P SP_REG)
17100                            (match_operand:P 0 "const_int_operand" "")))
17101               (clobber (reg:CC FLAGS_REG))])]
17102   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17103   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17104    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17105
17106 (define_peephole2
17107   [(match_scratch:P 1 "r")
17108    (parallel [(set (reg:P SP_REG)
17109                    (plus:P (reg:P SP_REG)
17110                            (match_operand:P 0 "const_int_operand" "")))
17111               (clobber (reg:CC FLAGS_REG))])]
17112   "optimize_insn_for_size_p ()
17113    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17114   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17115    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17116 \f
17117 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17118 ;; required and register dies.  Similarly for 128 to -128.
17119 (define_peephole2
17120   [(set (match_operand 0 "flags_reg_operand" "")
17121         (match_operator 1 "compare_operator"
17122           [(match_operand 2 "register_operand" "")
17123            (match_operand 3 "const_int_operand" "")]))]
17124   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17125      && incdec_operand (operands[3], GET_MODE (operands[3])))
17126     || (!TARGET_FUSE_CMP_AND_BRANCH
17127         && INTVAL (operands[3]) == 128))
17128    && ix86_match_ccmode (insn, CCGCmode)
17129    && peep2_reg_dead_p (1, operands[2])"
17130   [(parallel [(set (match_dup 0)
17131                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17132               (clobber (match_dup 2))])])
17133 \f
17134 ;; Convert imul by three, five and nine into lea
17135 (define_peephole2
17136   [(parallel
17137     [(set (match_operand:SWI48 0 "register_operand" "")
17138           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17139                       (match_operand:SWI48 2 "const_int_operand" "")))
17140      (clobber (reg:CC FLAGS_REG))])]
17141   "INTVAL (operands[2]) == 3
17142    || INTVAL (operands[2]) == 5
17143    || INTVAL (operands[2]) == 9"
17144   [(set (match_dup 0)
17145         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17146                     (match_dup 1)))]
17147   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17148
17149 (define_peephole2
17150   [(parallel
17151     [(set (match_operand:SWI48 0 "register_operand" "")
17152           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17153                       (match_operand:SWI48 2 "const_int_operand" "")))
17154      (clobber (reg:CC FLAGS_REG))])]
17155   "optimize_insn_for_speed_p ()
17156    && (INTVAL (operands[2]) == 3
17157        || INTVAL (operands[2]) == 5
17158        || INTVAL (operands[2]) == 9)"
17159   [(set (match_dup 0) (match_dup 1))
17160    (set (match_dup 0)
17161         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17162                     (match_dup 0)))]
17163   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17164
17165 ;; imul $32bit_imm, mem, reg is vector decoded, while
17166 ;; imul $32bit_imm, reg, reg is direct decoded.
17167 (define_peephole2
17168   [(match_scratch:SWI48 3 "r")
17169    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17170                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17171                                (match_operand:SWI48 2 "immediate_operand" "")))
17172               (clobber (reg:CC FLAGS_REG))])]
17173   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17174    && !satisfies_constraint_K (operands[2])"
17175   [(set (match_dup 3) (match_dup 1))
17176    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17177               (clobber (reg:CC FLAGS_REG))])])
17178
17179 (define_peephole2
17180   [(match_scratch:SI 3 "r")
17181    (parallel [(set (match_operand:DI 0 "register_operand" "")
17182                    (zero_extend:DI
17183                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17184                               (match_operand:SI 2 "immediate_operand" ""))))
17185               (clobber (reg:CC FLAGS_REG))])]
17186   "TARGET_64BIT
17187    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17188    && !satisfies_constraint_K (operands[2])"
17189   [(set (match_dup 3) (match_dup 1))
17190    (parallel [(set (match_dup 0)
17191                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17192               (clobber (reg:CC FLAGS_REG))])])
17193
17194 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17195 ;; Convert it into imul reg, reg
17196 ;; It would be better to force assembler to encode instruction using long
17197 ;; immediate, but there is apparently no way to do so.
17198 (define_peephole2
17199   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17200                    (mult:SWI248
17201                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17202                     (match_operand:SWI248 2 "const_int_operand" "")))
17203               (clobber (reg:CC FLAGS_REG))])
17204    (match_scratch:SWI248 3 "r")]
17205   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17206    && satisfies_constraint_K (operands[2])"
17207   [(set (match_dup 3) (match_dup 2))
17208    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17209               (clobber (reg:CC FLAGS_REG))])]
17210 {
17211   if (!rtx_equal_p (operands[0], operands[1]))
17212     emit_move_insn (operands[0], operands[1]);
17213 })
17214
17215 ;; After splitting up read-modify operations, array accesses with memory
17216 ;; operands might end up in form:
17217 ;;  sall    $2, %eax
17218 ;;  movl    4(%esp), %edx
17219 ;;  addl    %edx, %eax
17220 ;; instead of pre-splitting:
17221 ;;  sall    $2, %eax
17222 ;;  addl    4(%esp), %eax
17223 ;; Turn it into:
17224 ;;  movl    4(%esp), %edx
17225 ;;  leal    (%edx,%eax,4), %eax
17226
17227 (define_peephole2
17228   [(match_scratch:P 5 "r")
17229    (parallel [(set (match_operand 0 "register_operand" "")
17230                    (ashift (match_operand 1 "register_operand" "")
17231                            (match_operand 2 "const_int_operand" "")))
17232                (clobber (reg:CC FLAGS_REG))])
17233    (parallel [(set (match_operand 3 "register_operand" "")
17234                    (plus (match_dup 0)
17235                          (match_operand 4 "x86_64_general_operand" "")))
17236                    (clobber (reg:CC FLAGS_REG))])]
17237   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17238    /* Validate MODE for lea.  */
17239    && ((!TARGET_PARTIAL_REG_STALL
17240         && (GET_MODE (operands[0]) == QImode
17241             || GET_MODE (operands[0]) == HImode))
17242        || GET_MODE (operands[0]) == SImode
17243        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17244    && (rtx_equal_p (operands[0], operands[3])
17245        || peep2_reg_dead_p (2, operands[0]))
17246    /* We reorder load and the shift.  */
17247    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17248   [(set (match_dup 5) (match_dup 4))
17249    (set (match_dup 0) (match_dup 1))]
17250 {
17251   enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17252   int scale = 1 << INTVAL (operands[2]);
17253   rtx index = gen_lowpart (Pmode, operands[1]);
17254   rtx base = gen_lowpart (Pmode, operands[5]);
17255   rtx dest = gen_lowpart (mode, operands[3]);
17256
17257   operands[1] = gen_rtx_PLUS (Pmode, base,
17258                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17259   operands[5] = base;
17260   if (mode != Pmode)
17261     {
17262       operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17263       operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17264     }
17265   operands[0] = dest;
17266 })
17267 \f
17268 ;; Call-value patterns last so that the wildcard operand does not
17269 ;; disrupt insn-recog's switch tables.
17270
17271 (define_insn_and_split "*call_value_pop_0_vzeroupper"
17272   [(set (match_operand 0 "" "")
17273         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17274               (match_operand:SI 2 "" "")))
17275    (set (reg:SI SP_REG)
17276         (plus:SI (reg:SI SP_REG)
17277                  (match_operand:SI 3 "immediate_operand" "")))
17278    (unspec [(match_operand 4 "const_int_operand" "")]
17279            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17280   "TARGET_VZEROUPPER && !TARGET_64BIT"
17281   "#"
17282   "&& reload_completed"
17283   [(const_int 0)]
17284   "ix86_split_call_pop_vzeroupper (curr_insn, operands[4]); DONE;"
17285   [(set_attr "type" "callv")])
17286
17287 (define_insn "*call_value_pop_0"
17288   [(set (match_operand 0 "" "")
17289         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17290               (match_operand:SI 2 "" "")))
17291    (set (reg:SI SP_REG)
17292         (plus:SI (reg:SI SP_REG)
17293                  (match_operand:SI 3 "immediate_operand" "")))]
17294   "!TARGET_64BIT"
17295   { return ix86_output_call_insn (insn, operands[1], 1); }
17296   [(set_attr "type" "callv")])
17297
17298 (define_insn_and_split "*call_value_pop_1_vzeroupper"
17299   [(set (match_operand 0 "" "")
17300         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17301               (match_operand:SI 2 "" "")))
17302    (set (reg:SI SP_REG)
17303         (plus:SI (reg:SI SP_REG)
17304                  (match_operand:SI 3 "immediate_operand" "i")))
17305    (unspec [(match_operand 4 "const_int_operand" "")]
17306            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17307   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17308   "#"
17309   "&& reload_completed"
17310   [(const_int 0)]
17311   "ix86_split_call_pop_vzeroupper (curr_insn, operands[4]); DONE;"
17312   [(set_attr "type" "callv")])
17313
17314 (define_insn "*call_value_pop_1"
17315   [(set (match_operand 0 "" "")
17316         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17317               (match_operand:SI 2 "" "")))
17318    (set (reg:SI SP_REG)
17319         (plus:SI (reg:SI SP_REG)
17320                  (match_operand:SI 3 "immediate_operand" "i")))]
17321   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17322   { return ix86_output_call_insn (insn, operands[1], 1); }
17323   [(set_attr "type" "callv")])
17324
17325 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
17326   [(set (match_operand 0 "" "")
17327         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17328               (match_operand:SI 2 "" "")))
17329    (set (reg:SI SP_REG)
17330         (plus:SI (reg:SI SP_REG)
17331                  (match_operand:SI 3 "immediate_operand" "i,i")))
17332    (unspec [(match_operand 4 "const_int_operand" "")]
17333            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17334   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17335   "#"
17336   "&& reload_completed"
17337   [(const_int 0)]
17338   "ix86_split_call_pop_vzeroupper (curr_insn, operands[4]); DONE;"
17339   [(set_attr "type" "callv")])
17340
17341 (define_insn "*sibcall_value_pop_1"
17342   [(set (match_operand 0 "" "")
17343         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17344               (match_operand:SI 2 "" "")))
17345    (set (reg:SI SP_REG)
17346         (plus:SI (reg:SI SP_REG)
17347                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17348   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17349   { return ix86_output_call_insn (insn, operands[1], 1); }
17350   [(set_attr "type" "callv")])
17351
17352 (define_insn_and_split "*call_value_0_vzeroupper"
17353   [(set (match_operand 0 "" "")
17354         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17355               (match_operand:SI 2 "" "")))
17356    (unspec [(match_operand 3 "const_int_operand" "")]
17357            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17358   "TARGET_VZEROUPPER && !TARGET_64BIT"
17359   "#"
17360   "&& reload_completed"
17361   [(const_int 0)]
17362   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17363   [(set_attr "type" "callv")])
17364
17365 (define_insn "*call_value_0"
17366   [(set (match_operand 0 "" "")
17367         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17368               (match_operand:SI 2 "" "")))]
17369   "!TARGET_64BIT"
17370   { return ix86_output_call_insn (insn, operands[1], 1); }
17371   [(set_attr "type" "callv")])
17372
17373 (define_insn_and_split "*call_value_0_rex64_vzeroupper"
17374   [(set (match_operand 0 "" "")
17375         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17376               (match_operand:DI 2 "const_int_operand" "")))
17377    (unspec [(match_operand 3 "const_int_operand" "")]
17378            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17379   "TARGET_VZEROUPPER && TARGET_64BIT"
17380   "#"
17381   "&& reload_completed"
17382   [(const_int 0)]
17383   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17384   [(set_attr "type" "callv")])
17385
17386 (define_insn "*call_value_0_rex64"
17387   [(set (match_operand 0 "" "")
17388         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17389               (match_operand:DI 2 "const_int_operand" "")))]
17390   "TARGET_64BIT"
17391   { return ix86_output_call_insn (insn, operands[1], 1); }
17392   [(set_attr "type" "callv")])
17393
17394 (define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper"
17395   [(parallel
17396     [(set (match_operand 0 "" "")
17397           (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17398                 (match_operand:DI 2 "const_int_operand" "")))
17399      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17400      (clobber (reg:TI XMM6_REG))
17401      (clobber (reg:TI XMM7_REG))
17402      (clobber (reg:TI XMM8_REG))
17403      (clobber (reg:TI XMM9_REG))
17404      (clobber (reg:TI XMM10_REG))
17405      (clobber (reg:TI XMM11_REG))
17406      (clobber (reg:TI XMM12_REG))
17407      (clobber (reg:TI XMM13_REG))
17408      (clobber (reg:TI XMM14_REG))
17409      (clobber (reg:TI XMM15_REG))
17410      (clobber (reg:DI SI_REG))
17411      (clobber (reg:DI DI_REG))])
17412    (unspec [(match_operand 3 "const_int_operand" "")]
17413            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17414   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17415   "#"
17416   "&& reload_completed"
17417   [(const_int 0)]
17418   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17419   [(set_attr "type" "callv")])
17420
17421 (define_insn "*call_value_0_rex64_ms_sysv"
17422   [(set (match_operand 0 "" "")
17423         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17424               (match_operand:DI 2 "const_int_operand" "")))
17425    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17426    (clobber (reg:TI XMM6_REG))
17427    (clobber (reg:TI XMM7_REG))
17428    (clobber (reg:TI XMM8_REG))
17429    (clobber (reg:TI XMM9_REG))
17430    (clobber (reg:TI XMM10_REG))
17431    (clobber (reg:TI XMM11_REG))
17432    (clobber (reg:TI XMM12_REG))
17433    (clobber (reg:TI XMM13_REG))
17434    (clobber (reg:TI XMM14_REG))
17435    (clobber (reg:TI XMM15_REG))
17436    (clobber (reg:DI SI_REG))
17437    (clobber (reg:DI DI_REG))]
17438   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17439   { return ix86_output_call_insn (insn, operands[1], 1); }
17440   [(set_attr "type" "callv")])
17441
17442 (define_insn_and_split "*call_value_1_vzeroupper"
17443   [(set (match_operand 0 "" "")
17444         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17445               (match_operand:SI 2 "" "")))
17446    (unspec [(match_operand 3 "const_int_operand" "")]
17447            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17448   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
17449   "#"
17450   "&& reload_completed"
17451   [(const_int 0)]
17452   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17453   [(set_attr "type" "callv")])
17454
17455 (define_insn "*call_value_1"
17456   [(set (match_operand 0 "" "")
17457         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17458               (match_operand:SI 2 "" "")))]
17459   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17460   { return ix86_output_call_insn (insn, operands[1], 1); }
17461   [(set_attr "type" "callv")])
17462
17463 (define_insn_and_split "*sibcall_value_1_vzeroupper"
17464   [(set (match_operand 0 "" "")
17465         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17466               (match_operand:SI 2 "" "")))
17467    (unspec [(match_operand 3 "const_int_operand" "")]
17468            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17469   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
17470   "#"
17471   "&& reload_completed"
17472   [(const_int 0)]
17473   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17474   [(set_attr "type" "callv")])
17475
17476 (define_insn "*sibcall_value_1"
17477   [(set (match_operand 0 "" "")
17478         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17479               (match_operand:SI 2 "" "")))]
17480   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17481   { return ix86_output_call_insn (insn, operands[1], 1); }
17482   [(set_attr "type" "callv")])
17483
17484 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
17485   [(set (match_operand 0 "" "")
17486         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17487               (match_operand:DI 2 "" "")))
17488    (unspec [(match_operand 3 "const_int_operand" "")]
17489            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17490   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)
17491    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17492   "#"
17493   "&& reload_completed"
17494   [(const_int 0)]
17495   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17496   [(set_attr "type" "callv")])
17497
17498 (define_insn "*call_value_1_rex64"
17499   [(set (match_operand 0 "" "")
17500         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17501               (match_operand:DI 2 "" "")))]
17502   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17503    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17504   { return ix86_output_call_insn (insn, operands[1], 1); }
17505   [(set_attr "type" "callv")])
17506
17507 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
17508   [(parallel
17509     [(set (match_operand 0 "" "")
17510           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17511                 (match_operand:DI 2 "" "")))
17512      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17513      (clobber (reg:TI XMM6_REG))
17514      (clobber (reg:TI XMM7_REG))
17515      (clobber (reg:TI XMM8_REG))
17516      (clobber (reg:TI XMM9_REG))
17517      (clobber (reg:TI XMM10_REG))
17518      (clobber (reg:TI XMM11_REG))
17519      (clobber (reg:TI XMM12_REG))
17520      (clobber (reg:TI XMM13_REG))
17521      (clobber (reg:TI XMM14_REG))
17522      (clobber (reg:TI XMM15_REG))
17523      (clobber (reg:DI SI_REG))
17524      (clobber (reg:DI DI_REG))])
17525    (unspec [(match_operand 3 "const_int_operand" "")]
17526            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17527   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17528   "#"
17529   "&& reload_completed"
17530   [(const_int 0)]
17531   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17532   [(set_attr "type" "callv")])
17533
17534 (define_insn "*call_value_1_rex64_ms_sysv"
17535   [(set (match_operand 0 "" "")
17536         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17537               (match_operand:DI 2 "" "")))
17538    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17539    (clobber (reg:TI XMM6_REG))
17540    (clobber (reg:TI XMM7_REG))
17541    (clobber (reg:TI XMM8_REG))
17542    (clobber (reg:TI XMM9_REG))
17543    (clobber (reg:TI XMM10_REG))
17544    (clobber (reg:TI XMM11_REG))
17545    (clobber (reg:TI XMM12_REG))
17546    (clobber (reg:TI XMM13_REG))
17547    (clobber (reg:TI XMM14_REG))
17548    (clobber (reg:TI XMM15_REG))
17549    (clobber (reg:DI SI_REG))
17550    (clobber (reg:DI DI_REG))]
17551   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17552   { return ix86_output_call_insn (insn, operands[1], 1); }
17553   [(set_attr "type" "callv")])
17554
17555 (define_insn_and_split "*call_value_1_rex64_large_vzeroupper"
17556   [(set (match_operand 0 "" "")
17557         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17558               (match_operand:DI 2 "" "")))
17559    (unspec [(match_operand 3 "const_int_operand" "")]
17560            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17561   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
17562   "#"
17563   "&& reload_completed"
17564   [(const_int 0)]
17565   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17566   [(set_attr "type" "callv")])
17567
17568 (define_insn "*call_value_1_rex64_large"
17569   [(set (match_operand 0 "" "")
17570         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17571               (match_operand:DI 2 "" "")))]
17572   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17573   { return ix86_output_call_insn (insn, operands[1], 1); }
17574   [(set_attr "type" "callv")])
17575
17576 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
17577   [(set (match_operand 0 "" "")
17578         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17579               (match_operand:DI 2 "" "")))
17580    (unspec [(match_operand 3 "const_int_operand" "")]
17581            UNSPEC_CALL_NEEDS_VZEROUPPER)]
17582   "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)"
17583   "#"
17584   "&& reload_completed"
17585   [(const_int 0)]
17586   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
17587   [(set_attr "type" "callv")])
17588
17589 (define_insn "*sibcall_value_1_rex64"
17590   [(set (match_operand 0 "" "")
17591         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17592               (match_operand:DI 2 "" "")))]
17593   "TARGET_64BIT && SIBLING_CALL_P (insn)"
17594   { return ix86_output_call_insn (insn, operands[1], 1); }
17595   [(set_attr "type" "callv")])
17596 \f
17597 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17598 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17599 ;; caught for use by garbage collectors and the like.  Using an insn that
17600 ;; maps to SIGILL makes it more likely the program will rightfully die.
17601 ;; Keeping with tradition, "6" is in honor of #UD.
17602 (define_insn "trap"
17603   [(trap_if (const_int 1) (const_int 6))]
17604   ""
17605   { return ASM_SHORT "0x0b0f"; }
17606   [(set_attr "length" "2")])
17607
17608 (define_expand "prefetch"
17609   [(prefetch (match_operand 0 "address_operand" "")
17610              (match_operand:SI 1 "const_int_operand" "")
17611              (match_operand:SI 2 "const_int_operand" ""))]
17612   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17613 {
17614   int rw = INTVAL (operands[1]);
17615   int locality = INTVAL (operands[2]);
17616
17617   gcc_assert (rw == 0 || rw == 1);
17618   gcc_assert (locality >= 0 && locality <= 3);
17619   gcc_assert (GET_MODE (operands[0]) == Pmode
17620               || GET_MODE (operands[0]) == VOIDmode);
17621
17622   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17623      supported by SSE counterpart or the SSE prefetch is not available
17624      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17625      of locality.  */
17626   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17627     operands[2] = GEN_INT (3);
17628   else
17629     operands[1] = const0_rtx;
17630 })
17631
17632 (define_insn "*prefetch_sse_<mode>"
17633   [(prefetch (match_operand:P 0 "address_operand" "p")
17634              (const_int 0)
17635              (match_operand:SI 1 "const_int_operand" ""))]
17636   "TARGET_PREFETCH_SSE"
17637 {
17638   static const char * const patterns[4] = {
17639    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17640   };
17641
17642   int locality = INTVAL (operands[1]);
17643   gcc_assert (locality >= 0 && locality <= 3);
17644
17645   return patterns[locality];
17646 }
17647   [(set_attr "type" "sse")
17648    (set_attr "atom_sse_attr" "prefetch")
17649    (set (attr "length_address")
17650         (symbol_ref "memory_address_length (operands[0])"))
17651    (set_attr "memory" "none")])
17652
17653 (define_insn "*prefetch_3dnow_<mode>"
17654   [(prefetch (match_operand:P 0 "address_operand" "p")
17655              (match_operand:SI 1 "const_int_operand" "n")
17656              (const_int 3))]
17657   "TARGET_3DNOW"
17658 {
17659   if (INTVAL (operands[1]) == 0)
17660     return "prefetch\t%a0";
17661   else
17662     return "prefetchw\t%a0";
17663 }
17664   [(set_attr "type" "mmx")
17665    (set (attr "length_address")
17666         (symbol_ref "memory_address_length (operands[0])"))
17667    (set_attr "memory" "none")])
17668
17669 (define_expand "stack_protect_set"
17670   [(match_operand 0 "memory_operand" "")
17671    (match_operand 1 "memory_operand" "")]
17672   ""
17673 {
17674   rtx (*insn)(rtx, rtx);
17675
17676 #ifdef TARGET_THREAD_SSP_OFFSET
17677   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17678   insn = (TARGET_64BIT
17679           ? gen_stack_tls_protect_set_di
17680           : gen_stack_tls_protect_set_si);
17681 #else
17682   insn = (TARGET_64BIT
17683           ? gen_stack_protect_set_di
17684           : gen_stack_protect_set_si);
17685 #endif
17686
17687   emit_insn (insn (operands[0], operands[1]));
17688   DONE;
17689 })
17690
17691 (define_insn "stack_protect_set_<mode>"
17692   [(set (match_operand:P 0 "memory_operand" "=m")
17693         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17694    (set (match_scratch:P 2 "=&r") (const_int 0))
17695    (clobber (reg:CC FLAGS_REG))]
17696   ""
17697   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17698   [(set_attr "type" "multi")])
17699
17700 (define_insn "stack_tls_protect_set_<mode>"
17701   [(set (match_operand:P 0 "memory_operand" "=m")
17702         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17703                   UNSPEC_SP_TLS_SET))
17704    (set (match_scratch:P 2 "=&r") (const_int 0))
17705    (clobber (reg:CC FLAGS_REG))]
17706   ""
17707   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17708   [(set_attr "type" "multi")])
17709
17710 (define_expand "stack_protect_test"
17711   [(match_operand 0 "memory_operand" "")
17712    (match_operand 1 "memory_operand" "")
17713    (match_operand 2 "" "")]
17714   ""
17715 {
17716   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17717
17718   rtx (*insn)(rtx, rtx, rtx);
17719
17720 #ifdef TARGET_THREAD_SSP_OFFSET
17721   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17722   insn = (TARGET_64BIT
17723           ? gen_stack_tls_protect_test_di
17724           : gen_stack_tls_protect_test_si);
17725 #else
17726   insn = (TARGET_64BIT
17727           ? gen_stack_protect_test_di
17728           : gen_stack_protect_test_si);
17729 #endif
17730
17731   emit_insn (insn (flags, operands[0], operands[1]));
17732
17733   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17734                                   flags, const0_rtx, operands[2]));
17735   DONE;
17736 })
17737
17738 (define_insn "stack_protect_test_<mode>"
17739   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17740         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17741                      (match_operand:P 2 "memory_operand" "m")]
17742                     UNSPEC_SP_TEST))
17743    (clobber (match_scratch:P 3 "=&r"))]
17744   ""
17745   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17746   [(set_attr "type" "multi")])
17747
17748 (define_insn "stack_tls_protect_test_<mode>"
17749   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17750         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17751                      (match_operand:P 2 "const_int_operand" "i")]
17752                     UNSPEC_SP_TLS_TEST))
17753    (clobber (match_scratch:P 3 "=r"))]
17754   ""
17755   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17756   [(set_attr "type" "multi")])
17757
17758 (define_insn "sse4_2_crc32<mode>"
17759   [(set (match_operand:SI 0 "register_operand" "=r")
17760         (unspec:SI
17761           [(match_operand:SI 1 "register_operand" "0")
17762            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17763           UNSPEC_CRC32))]
17764   "TARGET_SSE4_2 || TARGET_CRC32"
17765   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17766   [(set_attr "type" "sselog1")
17767    (set_attr "prefix_rep" "1")
17768    (set_attr "prefix_extra" "1")
17769    (set (attr "prefix_data16")
17770      (if_then_else (match_operand:HI 2 "" "")
17771        (const_string "1")
17772        (const_string "*")))
17773    (set (attr "prefix_rex")
17774      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17775        (const_string "1")
17776        (const_string "*")))
17777    (set_attr "mode" "SI")])
17778
17779 (define_insn "sse4_2_crc32di"
17780   [(set (match_operand:DI 0 "register_operand" "=r")
17781         (unspec:DI
17782           [(match_operand:DI 1 "register_operand" "0")
17783            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17784           UNSPEC_CRC32))]
17785   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17786   "crc32{q}\t{%2, %0|%0, %2}"
17787   [(set_attr "type" "sselog1")
17788    (set_attr "prefix_rep" "1")
17789    (set_attr "prefix_extra" "1")
17790    (set_attr "mode" "DI")])
17791
17792 (define_expand "rdpmc"
17793   [(match_operand:DI 0 "register_operand" "")
17794    (match_operand:SI 1 "register_operand" "")]
17795   ""
17796 {
17797   rtx reg = gen_reg_rtx (DImode);
17798   rtx si;
17799
17800   /* Force operand 1 into ECX.  */
17801   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17802   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17803   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17804                                 UNSPECV_RDPMC);
17805
17806   if (TARGET_64BIT)
17807     {
17808       rtvec vec = rtvec_alloc (2);
17809       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17810       rtx upper = gen_reg_rtx (DImode);
17811       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17812                                         gen_rtvec (1, const0_rtx),
17813                                         UNSPECV_RDPMC);
17814       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17815       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17816       emit_insn (load);
17817       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17818                                    NULL, 1, OPTAB_DIRECT);
17819       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17820                                  OPTAB_DIRECT);
17821     }
17822   else
17823     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17824   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17825   DONE;
17826 })
17827
17828 (define_insn "*rdpmc"
17829   [(set (match_operand:DI 0 "register_operand" "=A")
17830         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17831                             UNSPECV_RDPMC))]
17832   "!TARGET_64BIT"
17833   "rdpmc"
17834   [(set_attr "type" "other")
17835    (set_attr "length" "2")])
17836
17837 (define_insn "*rdpmc_rex64"
17838   [(set (match_operand:DI 0 "register_operand" "=a")
17839         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17840                             UNSPECV_RDPMC))
17841   (set (match_operand:DI 1 "register_operand" "=d")
17842        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17843   "TARGET_64BIT"
17844   "rdpmc"
17845   [(set_attr "type" "other")
17846    (set_attr "length" "2")])
17847
17848 (define_expand "rdtsc"
17849   [(set (match_operand:DI 0 "register_operand" "")
17850         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17851   ""
17852 {
17853   if (TARGET_64BIT)
17854     {
17855       rtvec vec = rtvec_alloc (2);
17856       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17857       rtx upper = gen_reg_rtx (DImode);
17858       rtx lower = gen_reg_rtx (DImode);
17859       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17860                                          gen_rtvec (1, const0_rtx),
17861                                          UNSPECV_RDTSC);
17862       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17863       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17864       emit_insn (load);
17865       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17866                                    NULL, 1, OPTAB_DIRECT);
17867       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17868                                    OPTAB_DIRECT);
17869       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17870       DONE;
17871     }
17872 })
17873
17874 (define_insn "*rdtsc"
17875   [(set (match_operand:DI 0 "register_operand" "=A")
17876         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17877   "!TARGET_64BIT"
17878   "rdtsc"
17879   [(set_attr "type" "other")
17880    (set_attr "length" "2")])
17881
17882 (define_insn "*rdtsc_rex64"
17883   [(set (match_operand:DI 0 "register_operand" "=a")
17884         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17885    (set (match_operand:DI 1 "register_operand" "=d")
17886         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17887   "TARGET_64BIT"
17888   "rdtsc"
17889   [(set_attr "type" "other")
17890    (set_attr "length" "2")])
17891
17892 (define_expand "rdtscp"
17893   [(match_operand:DI 0 "register_operand" "")
17894    (match_operand:SI 1 "memory_operand" "")]
17895   ""
17896 {
17897   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17898                                     gen_rtvec (1, const0_rtx),
17899                                     UNSPECV_RDTSCP);
17900   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17901                                     gen_rtvec (1, const0_rtx),
17902                                     UNSPECV_RDTSCP);
17903   rtx reg = gen_reg_rtx (DImode);
17904   rtx tmp = gen_reg_rtx (SImode);
17905
17906   if (TARGET_64BIT)
17907     {
17908       rtvec vec = rtvec_alloc (3);
17909       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17910       rtx upper = gen_reg_rtx (DImode);
17911       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17912       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17913       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17914       emit_insn (load);
17915       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17916                                    NULL, 1, OPTAB_DIRECT);
17917       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17918                                  OPTAB_DIRECT);
17919     }
17920   else
17921     {
17922       rtvec vec = rtvec_alloc (2);
17923       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17924       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17925       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17926       emit_insn (load);
17927     }
17928   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17929   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17930   DONE;
17931 })
17932
17933 (define_insn "*rdtscp"
17934   [(set (match_operand:DI 0 "register_operand" "=A")
17935         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17936    (set (match_operand:SI 1 "register_operand" "=c")
17937         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17938   "!TARGET_64BIT"
17939   "rdtscp"
17940   [(set_attr "type" "other")
17941    (set_attr "length" "3")])
17942
17943 (define_insn "*rdtscp_rex64"
17944   [(set (match_operand:DI 0 "register_operand" "=a")
17945         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17946    (set (match_operand:DI 1 "register_operand" "=d")
17947         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17948    (set (match_operand:SI 2 "register_operand" "=c")
17949         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17950   "TARGET_64BIT"
17951   "rdtscp"
17952   [(set_attr "type" "other")
17953    (set_attr "length" "3")])
17954
17955 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17956 ;;
17957 ;; LWP instructions
17958 ;;
17959 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17960
17961 (define_expand "lwp_llwpcb"
17962   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17963                     UNSPECV_LLWP_INTRINSIC)]
17964   "TARGET_LWP")
17965
17966 (define_insn "*lwp_llwpcb<mode>1"
17967   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17968                     UNSPECV_LLWP_INTRINSIC)]
17969   "TARGET_LWP"
17970   "llwpcb\t%0"
17971   [(set_attr "type" "lwp")
17972    (set_attr "mode" "<MODE>")
17973    (set_attr "length" "5")])
17974
17975 (define_expand "lwp_slwpcb"
17976   [(set (match_operand 0 "register_operand" "=r")
17977         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17978   "TARGET_LWP"
17979 {
17980   if (TARGET_64BIT)
17981     emit_insn (gen_lwp_slwpcbdi (operands[0]));
17982   else
17983     emit_insn (gen_lwp_slwpcbsi (operands[0]));
17984   DONE;
17985 })
17986
17987 (define_insn "lwp_slwpcb<mode>"
17988   [(set (match_operand:P 0 "register_operand" "=r")
17989         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17990   "TARGET_LWP"
17991   "slwpcb\t%0"
17992   [(set_attr "type" "lwp")
17993    (set_attr "mode" "<MODE>")
17994    (set_attr "length" "5")])
17995
17996 (define_expand "lwp_lwpval<mode>3"
17997   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17998                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17999                      (match_operand:SI 3 "const_int_operand" "i")]
18000                     UNSPECV_LWPVAL_INTRINSIC)]
18001   "TARGET_LWP"
18002   "/* Avoid unused variable warning.  */
18003    (void) operand0;")
18004
18005 (define_insn "*lwp_lwpval<mode>3_1"
18006   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18007                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18008                      (match_operand:SI 2 "const_int_operand" "i")]
18009                     UNSPECV_LWPVAL_INTRINSIC)]
18010   "TARGET_LWP"
18011   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18012   [(set_attr "type" "lwp")
18013    (set_attr "mode" "<MODE>")
18014    (set (attr "length")
18015         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18016
18017 (define_expand "lwp_lwpins<mode>3"
18018   [(set (reg:CCC FLAGS_REG)
18019         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18020                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18021                               (match_operand:SI 3 "const_int_operand" "i")]
18022                              UNSPECV_LWPINS_INTRINSIC))
18023    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18024         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18025   "TARGET_LWP")
18026
18027 (define_insn "*lwp_lwpins<mode>3_1"
18028   [(set (reg:CCC FLAGS_REG)
18029         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18030                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18031                               (match_operand:SI 2 "const_int_operand" "i")]
18032                              UNSPECV_LWPINS_INTRINSIC))]
18033   "TARGET_LWP"
18034   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18035   [(set_attr "type" "lwp")
18036    (set_attr "mode" "<MODE>")
18037    (set (attr "length")
18038         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18039
18040 (define_insn "rdfsbase<mode>"
18041   [(set (match_operand:SWI48 0 "register_operand" "=r")
18042         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18043   "TARGET_64BIT && TARGET_FSGSBASE"
18044   "rdfsbase %0"
18045   [(set_attr "type" "other")
18046    (set_attr "prefix_extra" "2")])
18047
18048 (define_insn "rdgsbase<mode>"
18049   [(set (match_operand:SWI48 0 "register_operand" "=r")
18050         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18051   "TARGET_64BIT && TARGET_FSGSBASE"
18052   "rdgsbase %0"
18053   [(set_attr "type" "other")
18054    (set_attr "prefix_extra" "2")])
18055
18056 (define_insn "wrfsbase<mode>"
18057   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18058                     UNSPECV_WRFSBASE)]
18059   "TARGET_64BIT && TARGET_FSGSBASE"
18060   "wrfsbase %0"
18061   [(set_attr "type" "other")
18062    (set_attr "prefix_extra" "2")])
18063
18064 (define_insn "wrgsbase<mode>"
18065   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18066                     UNSPECV_WRGSBASE)]
18067   "TARGET_64BIT && TARGET_FSGSBASE"
18068   "wrgsbase %0"
18069   [(set_attr "type" "other")
18070    (set_attr "prefix_extra" "2")])
18071
18072 (define_expand "rdrand<mode>"
18073   [(set (match_operand:SWI248 0 "register_operand" "=r")
18074         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18075   "TARGET_RDRND"
18076 {
18077   rtx retry_label, insn, ccc;
18078
18079   retry_label = gen_label_rtx ();
18080
18081   emit_label (retry_label);
18082
18083   /* Generate rdrand.  */
18084   emit_insn (gen_rdrand<mode>_1 (operands[0]));
18085
18086   /* Retry if the carry flag isn't valid.  */
18087   ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
18088   ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
18089   ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
18090                               gen_rtx_LABEL_REF (VOIDmode, retry_label));
18091   insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
18092   JUMP_LABEL (insn) = retry_label;
18093
18094   DONE;
18095 })
18096
18097 (define_insn "rdrand<mode>_1"
18098   [(set (match_operand:SWI248 0 "register_operand" "=r")
18099         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18100   "TARGET_RDRND"
18101   "rdrand %0"
18102   [(set_attr "type" "other")
18103    (set_attr "prefix_extra" "1")])
18104
18105 (include "mmx.md")
18106 (include "sse.md")
18107 (include "sync.md")