OSDN Git Service

* config/i386/i386.md: Use SWI248x instead of X87MODEI, SWI24 instead
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
64
65 ;; UNSPEC usage:
66
67 (define_c_enum "unspec" [
68   ;; Relocation specifiers
69   UNSPEC_GOT
70   UNSPEC_GOTOFF
71   UNSPEC_GOTPCREL
72   UNSPEC_GOTTPOFF
73   UNSPEC_TPOFF
74   UNSPEC_NTPOFF
75   UNSPEC_DTPOFF
76   UNSPEC_GOTNTPOFF
77   UNSPEC_INDNTPOFF
78   UNSPEC_PLTOFF
79   UNSPEC_MACHOPIC_OFFSET
80   UNSPEC_PCREL
81
82   ;; Prologue support
83   UNSPEC_STACK_ALLOC
84   UNSPEC_SET_GOT
85   UNSPEC_REG_SAVE
86   UNSPEC_DEF_CFA
87   UNSPEC_SET_RIP
88   UNSPEC_SET_GOT_OFFSET
89   UNSPEC_MEMORY_BLOCKAGE
90   UNSPEC_STACK_CHECK
91
92   ;; TLS support
93   UNSPEC_TP
94   UNSPEC_TLS_GD
95   UNSPEC_TLS_LD_BASE
96   UNSPEC_TLSDESC
97   UNSPEC_TLS_IE_SUN
98
99   ;; Other random patterns
100   UNSPEC_SCAS
101   UNSPEC_FNSTSW
102   UNSPEC_SAHF
103   UNSPEC_PARITY
104   UNSPEC_FSTCW
105   UNSPEC_ADD_CARRY
106   UNSPEC_FLDCW
107   UNSPEC_REP
108   UNSPEC_LD_MPIC        ; load_macho_picbase
109   UNSPEC_TRUNC_NOOP
110   UNSPEC_DIV_ALREADY_SPLIT
111   UNSPEC_CALL_NEEDS_VZEROUPPER
112   UNSPEC_PAUSE
113
114   ;; For SSE/MMX support:
115   UNSPEC_FIX_NOTRUNC
116   UNSPEC_MASKMOV
117   UNSPEC_MOVMSK
118   UNSPEC_MOVNT
119   UNSPEC_MOVU
120   UNSPEC_RCP
121   UNSPEC_RSQRT
122   UNSPEC_SFENCE
123   UNSPEC_PFRCP
124   UNSPEC_PFRCPIT1
125   UNSPEC_PFRCPIT2
126   UNSPEC_PFRSQRT
127   UNSPEC_PFRSQIT1
128   UNSPEC_MFENCE
129   UNSPEC_LFENCE
130   UNSPEC_PSADBW
131   UNSPEC_LDDQU
132   UNSPEC_MS_TO_SYSV_CALL
133
134   ;; Generic math support
135   UNSPEC_COPYSIGN
136   UNSPEC_IEEE_MIN       ; not commutative
137   UNSPEC_IEEE_MAX       ; not commutative
138
139   ;; x87 Floating point
140   UNSPEC_SIN
141   UNSPEC_COS
142   UNSPEC_FPATAN
143   UNSPEC_FYL2X
144   UNSPEC_FYL2XP1
145   UNSPEC_FRNDINT
146   UNSPEC_FIST
147   UNSPEC_F2XM1
148   UNSPEC_TAN
149   UNSPEC_FXAM
150
151   ;; x87 Rounding
152   UNSPEC_FRNDINT_FLOOR
153   UNSPEC_FRNDINT_CEIL
154   UNSPEC_FRNDINT_TRUNC
155   UNSPEC_FRNDINT_MASK_PM
156   UNSPEC_FIST_FLOOR
157   UNSPEC_FIST_CEIL
158
159   ;; x87 Double output FP
160   UNSPEC_SINCOS_COS
161   UNSPEC_SINCOS_SIN
162   UNSPEC_XTRACT_FRACT
163   UNSPEC_XTRACT_EXP
164   UNSPEC_FSCALE_FRACT
165   UNSPEC_FSCALE_EXP
166   UNSPEC_FPREM_F
167   UNSPEC_FPREM_U
168   UNSPEC_FPREM1_F
169   UNSPEC_FPREM1_U
170
171   UNSPEC_C2_FLAG
172   UNSPEC_FXAM_MEM
173
174   ;; SSP patterns
175   UNSPEC_SP_SET
176   UNSPEC_SP_TEST
177   UNSPEC_SP_TLS_SET
178   UNSPEC_SP_TLS_TEST
179
180   ;; SSSE3
181   UNSPEC_PSHUFB
182   UNSPEC_PSIGN
183   UNSPEC_PALIGNR
184
185   ;; For SSE4A support
186   UNSPEC_EXTRQI
187   UNSPEC_EXTRQ
188   UNSPEC_INSERTQI
189   UNSPEC_INSERTQ
190
191   ;; For SSE4.1 support
192   UNSPEC_BLENDV
193   UNSPEC_INSERTPS
194   UNSPEC_DP
195   UNSPEC_MOVNTDQA
196   UNSPEC_MPSADBW
197   UNSPEC_PHMINPOSUW
198   UNSPEC_PTEST
199   UNSPEC_ROUND
200
201   ;; For SSE4.2 support
202   UNSPEC_CRC32
203   UNSPEC_PCMPESTR
204   UNSPEC_PCMPISTR
205
206   ;; For FMA4 support
207   UNSPEC_FMADDSUB
208   UNSPEC_XOP_UNSIGNED_CMP
209   UNSPEC_XOP_TRUEFALSE
210   UNSPEC_XOP_PERMUTE
211   UNSPEC_FRCZ
212
213   ;; For AES support
214   UNSPEC_AESENC
215   UNSPEC_AESENCLAST
216   UNSPEC_AESDEC
217   UNSPEC_AESDECLAST
218   UNSPEC_AESIMC
219   UNSPEC_AESKEYGENASSIST
220
221   ;; For PCLMUL support
222   UNSPEC_PCLMUL
223
224   ;; For AVX support
225   UNSPEC_PCMP
226   UNSPEC_VPERMIL
227   UNSPEC_VPERMIL2
228   UNSPEC_VPERMIL2F128
229   UNSPEC_CAST
230   UNSPEC_VTESTP
231   UNSPEC_VCVTPH2PS
232   UNSPEC_VCVTPS2PH
233
234   ;; For BMI support
235   UNSPEC_BEXTR
236
237   ;; For RDRAND support
238   UNSPEC_RDRAND
239 ])
240
241 (define_c_enum "unspecv" [
242   UNSPECV_BLOCKAGE
243   UNSPECV_STACK_PROBE
244   UNSPECV_PROBE_STACK_RANGE
245   UNSPECV_EMMS
246   UNSPECV_LDMXCSR
247   UNSPECV_STMXCSR
248   UNSPECV_FEMMS
249   UNSPECV_CLFLUSH
250   UNSPECV_ALIGN
251   UNSPECV_MONITOR
252   UNSPECV_MWAIT
253   UNSPECV_CMPXCHG
254   UNSPECV_XCHG
255   UNSPECV_LOCK
256   UNSPECV_PROLOGUE_USE
257   UNSPECV_CLD
258   UNSPECV_NOPS
259   UNSPECV_VZEROALL
260   UNSPECV_VZEROUPPER
261   UNSPECV_RDTSC
262   UNSPECV_RDTSCP
263   UNSPECV_RDPMC
264   UNSPECV_LLWP_INTRINSIC
265   UNSPECV_SLWP_INTRINSIC
266   UNSPECV_LWPVAL_INTRINSIC
267   UNSPECV_LWPINS_INTRINSIC
268   UNSPECV_RDFSBASE
269   UNSPECV_RDGSBASE
270   UNSPECV_WRFSBASE
271   UNSPECV_WRGSBASE
272   UNSPECV_SPLIT_STACK_RETURN
273 ])
274
275 ;; Constants to represent rounding modes in the ROUND instruction
276 (define_constants
277   [(ROUND_FLOOR                 0x1)
278    (ROUND_CEIL                  0x2)
279    (ROUND_TRUNC                 0x3)
280    (ROUND_MXCSR                 0x4)
281    (ROUND_NO_EXC                0x8)
282   ])
283
284 ;; Constants to represent pcomtrue/pcomfalse variants
285 (define_constants
286   [(PCOM_FALSE                  0)
287    (PCOM_TRUE                   1)
288    (COM_FALSE_S                 2)
289    (COM_FALSE_P                 3)
290    (COM_TRUE_S                  4)
291    (COM_TRUE_P                  5)
292   ])
293
294 ;; Constants used in the XOP pperm instruction
295 (define_constants
296   [(PPERM_SRC                   0x00)   /* copy source */
297    (PPERM_INVERT                0x20)   /* invert source */
298    (PPERM_REVERSE               0x40)   /* bit reverse source */
299    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
300    (PPERM_ZERO                  0x80)   /* all 0's */
301    (PPERM_ONES                  0xa0)   /* all 1's */
302    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
303    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
304    (PPERM_SRC1                  0x00)   /* use first source byte */
305    (PPERM_SRC2                  0x10)   /* use second source byte */
306    ])
307
308 ;; Registers by name.
309 (define_constants
310   [(AX_REG                       0)
311    (DX_REG                       1)
312    (CX_REG                       2)
313    (BX_REG                       3)
314    (SI_REG                       4)
315    (DI_REG                       5)
316    (BP_REG                       6)
317    (SP_REG                       7)
318    (ST0_REG                      8)
319    (ST1_REG                      9)
320    (ST2_REG                     10)
321    (ST3_REG                     11)
322    (ST4_REG                     12)
323    (ST5_REG                     13)
324    (ST6_REG                     14)
325    (ST7_REG                     15)
326    (FLAGS_REG                   17)
327    (FPSR_REG                    18)
328    (FPCR_REG                    19)
329    (XMM0_REG                    21)
330    (XMM1_REG                    22)
331    (XMM2_REG                    23)
332    (XMM3_REG                    24)
333    (XMM4_REG                    25)
334    (XMM5_REG                    26)
335    (XMM6_REG                    27)
336    (XMM7_REG                    28)
337    (MM0_REG                     29)
338    (MM1_REG                     30)
339    (MM2_REG                     31)
340    (MM3_REG                     32)
341    (MM4_REG                     33)
342    (MM5_REG                     34)
343    (MM6_REG                     35)
344    (MM7_REG                     36)
345    (R8_REG                      37)
346    (R9_REG                      38)
347    (R10_REG                     39)
348    (R11_REG                     40)
349    (R12_REG                     41)
350    (R13_REG                     42)
351    (XMM8_REG                    45)
352    (XMM9_REG                    46)
353    (XMM10_REG                   47)
354    (XMM11_REG                   48)
355    (XMM12_REG                   49)
356    (XMM13_REG                   50)
357    (XMM14_REG                   51)
358    (XMM15_REG                   52)
359   ])
360
361 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
362 ;; from i386.c.
363
364 ;; In C guard expressions, put expressions which may be compile-time
365 ;; constants first.  This allows for better optimization.  For
366 ;; example, write "TARGET_64BIT && reload_completed", not
367 ;; "reload_completed && TARGET_64BIT".
368
369 \f
370 ;; Processor type.
371 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
372                     atom,generic64,amdfam10,bdver1,btver1"
373   (const (symbol_ref "ix86_schedule")))
374
375 ;; A basic instruction type.  Refinements due to arguments to be
376 ;; provided in other attributes.
377 (define_attr "type"
378   "other,multi,
379    alu,alu1,negnot,imov,imovx,lea,
380    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
381    icmp,test,ibr,setcc,icmov,
382    push,pop,call,callv,leave,
383    str,bitmanip,
384    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
385    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
386    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
387    ssemuladd,sse4arg,lwp,
388    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
389   (const_string "other"))
390
391 ;; Main data type used by the insn
392 (define_attr "mode"
393   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
394   (const_string "unknown"))
395
396 ;; The CPU unit operations uses.
397 (define_attr "unit" "integer,i387,sse,mmx,unknown"
398   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
399            (const_string "i387")
400          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
401                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
402                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
403            (const_string "sse")
404          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
405            (const_string "mmx")
406          (eq_attr "type" "other")
407            (const_string "unknown")]
408          (const_string "integer")))
409
410 ;; The (bounding maximum) length of an instruction immediate.
411 (define_attr "length_immediate" ""
412   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
413                           bitmanip")
414            (const_int 0)
415          (eq_attr "unit" "i387,sse,mmx")
416            (const_int 0)
417          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
418                           imul,icmp,push,pop")
419            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
420          (eq_attr "type" "imov,test")
421            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
422          (eq_attr "type" "call")
423            (if_then_else (match_operand 0 "constant_call_address_operand" "")
424              (const_int 4)
425              (const_int 0))
426          (eq_attr "type" "callv")
427            (if_then_else (match_operand 1 "constant_call_address_operand" "")
428              (const_int 4)
429              (const_int 0))
430          ;; We don't know the size before shorten_branches.  Expect
431          ;; the instruction to fit for better scheduling.
432          (eq_attr "type" "ibr")
433            (const_int 1)
434          ]
435          (symbol_ref "/* Update immediate_length and other attributes! */
436                       gcc_unreachable (),1")))
437
438 ;; The (bounding maximum) length of an instruction address.
439 (define_attr "length_address" ""
440   (cond [(eq_attr "type" "str,other,multi,fxch")
441            (const_int 0)
442          (and (eq_attr "type" "call")
443               (match_operand 0 "constant_call_address_operand" ""))
444              (const_int 0)
445          (and (eq_attr "type" "callv")
446               (match_operand 1 "constant_call_address_operand" ""))
447              (const_int 0)
448          ]
449          (symbol_ref "ix86_attr_length_address_default (insn)")))
450
451 ;; Set when length prefix is used.
452 (define_attr "prefix_data16" ""
453   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
454            (const_int 0)
455          (eq_attr "mode" "HI")
456            (const_int 1)
457          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
458            (const_int 1)
459         ]
460         (const_int 0)))
461
462 ;; Set when string REP prefix is used.
463 (define_attr "prefix_rep" ""
464   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
465            (const_int 0)
466          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
467            (const_int 1)
468         ]
469         (const_int 0)))
470
471 ;; Set when 0f opcode prefix is used.
472 (define_attr "prefix_0f" ""
473   (if_then_else
474     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
475          (eq_attr "unit" "sse,mmx"))
476     (const_int 1)
477     (const_int 0)))
478
479 ;; Set when REX opcode prefix is used.
480 (define_attr "prefix_rex" ""
481   (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
482            (const_int 0)
483          (and (eq_attr "mode" "DI")
484               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
485                    (eq_attr "unit" "!mmx")))
486            (const_int 1)
487          (and (eq_attr "mode" "QI")
488               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
489                   (const_int 0)))
490            (const_int 1)
491          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
492              (const_int 0))
493            (const_int 1)
494          (and (eq_attr "type" "imovx")
495               (match_operand:QI 1 "ext_QIreg_operand" ""))
496            (const_int 1)
497         ]
498         (const_int 0)))
499
500 ;; There are also additional prefixes in 3DNOW, SSSE3.
501 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
502 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
503 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
504 (define_attr "prefix_extra" ""
505   (cond [(eq_attr "type" "ssemuladd,sse4arg")
506            (const_int 2)
507          (eq_attr "type" "sseiadd1,ssecvt1")
508            (const_int 1)
509         ]
510         (const_int 0)))
511
512 ;; Prefix used: original, VEX or maybe VEX.
513 (define_attr "prefix" "orig,vex,maybe_vex"
514   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
515     (const_string "vex")
516     (const_string "orig")))
517
518 ;; VEX W bit is used.
519 (define_attr "prefix_vex_w" "" (const_int 0))
520
521 ;; The length of VEX prefix
522 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
523 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
524 ;; still prefix_0f 1, with prefix_extra 1.
525 (define_attr "length_vex" ""
526   (if_then_else (and (eq_attr "prefix_0f" "1")
527                      (eq_attr "prefix_extra" "0"))
528     (if_then_else (eq_attr "prefix_vex_w" "1")
529       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
530       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
531     (if_then_else (eq_attr "prefix_vex_w" "1")
532       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
533       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
534
535 ;; Set when modrm byte is used.
536 (define_attr "modrm" ""
537   (cond [(eq_attr "type" "str,leave")
538            (const_int 0)
539          (eq_attr "unit" "i387")
540            (const_int 0)
541          (and (eq_attr "type" "incdec")
542               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
543                    (ior (match_operand:SI 1 "register_operand" "")
544                         (match_operand:HI 1 "register_operand" ""))))
545            (const_int 0)
546          (and (eq_attr "type" "push")
547               (not (match_operand 1 "memory_operand" "")))
548            (const_int 0)
549          (and (eq_attr "type" "pop")
550               (not (match_operand 0 "memory_operand" "")))
551            (const_int 0)
552          (and (eq_attr "type" "imov")
553               (and (not (eq_attr "mode" "DI"))
554                    (ior (and (match_operand 0 "register_operand" "")
555                              (match_operand 1 "immediate_operand" ""))
556                         (ior (and (match_operand 0 "ax_reg_operand" "")
557                                   (match_operand 1 "memory_displacement_only_operand" ""))
558                              (and (match_operand 0 "memory_displacement_only_operand" "")
559                                   (match_operand 1 "ax_reg_operand" ""))))))
560            (const_int 0)
561          (and (eq_attr "type" "call")
562               (match_operand 0 "constant_call_address_operand" ""))
563              (const_int 0)
564          (and (eq_attr "type" "callv")
565               (match_operand 1 "constant_call_address_operand" ""))
566              (const_int 0)
567          (and (eq_attr "type" "alu,alu1,icmp,test")
568               (match_operand 0 "ax_reg_operand" ""))
569              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
570          ]
571          (const_int 1)))
572
573 ;; The (bounding maximum) length of an instruction in bytes.
574 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
575 ;; Later we may want to split them and compute proper length as for
576 ;; other insns.
577 (define_attr "length" ""
578   (cond [(eq_attr "type" "other,multi,fistp,frndint")
579            (const_int 16)
580          (eq_attr "type" "fcmp")
581            (const_int 4)
582          (eq_attr "unit" "i387")
583            (plus (const_int 2)
584                  (plus (attr "prefix_data16")
585                        (attr "length_address")))
586          (ior (eq_attr "prefix" "vex")
587               (and (eq_attr "prefix" "maybe_vex")
588                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
589            (plus (attr "length_vex")
590                  (plus (attr "length_immediate")
591                        (plus (attr "modrm")
592                              (attr "length_address"))))]
593          (plus (plus (attr "modrm")
594                      (plus (attr "prefix_0f")
595                            (plus (attr "prefix_rex")
596                                  (plus (attr "prefix_extra")
597                                        (const_int 1)))))
598                (plus (attr "prefix_rep")
599                      (plus (attr "prefix_data16")
600                            (plus (attr "length_immediate")
601                                  (attr "length_address")))))))
602
603 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
604 ;; `store' if there is a simple memory reference therein, or `unknown'
605 ;; if the instruction is complex.
606
607 (define_attr "memory" "none,load,store,both,unknown"
608   (cond [(eq_attr "type" "other,multi,str,lwp")
609            (const_string "unknown")
610          (eq_attr "type" "lea,fcmov,fpspc")
611            (const_string "none")
612          (eq_attr "type" "fistp,leave")
613            (const_string "both")
614          (eq_attr "type" "frndint")
615            (const_string "load")
616          (eq_attr "type" "push")
617            (if_then_else (match_operand 1 "memory_operand" "")
618              (const_string "both")
619              (const_string "store"))
620          (eq_attr "type" "pop")
621            (if_then_else (match_operand 0 "memory_operand" "")
622              (const_string "both")
623              (const_string "load"))
624          (eq_attr "type" "setcc")
625            (if_then_else (match_operand 0 "memory_operand" "")
626              (const_string "store")
627              (const_string "none"))
628          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
629            (if_then_else (ior (match_operand 0 "memory_operand" "")
630                               (match_operand 1 "memory_operand" ""))
631              (const_string "load")
632              (const_string "none"))
633          (eq_attr "type" "ibr")
634            (if_then_else (match_operand 0 "memory_operand" "")
635              (const_string "load")
636              (const_string "none"))
637          (eq_attr "type" "call")
638            (if_then_else (match_operand 0 "constant_call_address_operand" "")
639              (const_string "none")
640              (const_string "load"))
641          (eq_attr "type" "callv")
642            (if_then_else (match_operand 1 "constant_call_address_operand" "")
643              (const_string "none")
644              (const_string "load"))
645          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
646               (match_operand 1 "memory_operand" ""))
647            (const_string "both")
648          (and (match_operand 0 "memory_operand" "")
649               (match_operand 1 "memory_operand" ""))
650            (const_string "both")
651          (match_operand 0 "memory_operand" "")
652            (const_string "store")
653          (match_operand 1 "memory_operand" "")
654            (const_string "load")
655          (and (eq_attr "type"
656                  "!alu1,negnot,ishift1,
657                    imov,imovx,icmp,test,bitmanip,
658                    fmov,fcmp,fsgn,
659                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
660                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
661               (match_operand 2 "memory_operand" ""))
662            (const_string "load")
663          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
664               (match_operand 3 "memory_operand" ""))
665            (const_string "load")
666         ]
667         (const_string "none")))
668
669 ;; Indicates if an instruction has both an immediate and a displacement.
670
671 (define_attr "imm_disp" "false,true,unknown"
672   (cond [(eq_attr "type" "other,multi")
673            (const_string "unknown")
674          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
675               (and (match_operand 0 "memory_displacement_operand" "")
676                    (match_operand 1 "immediate_operand" "")))
677            (const_string "true")
678          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
679               (and (match_operand 0 "memory_displacement_operand" "")
680                    (match_operand 2 "immediate_operand" "")))
681            (const_string "true")
682         ]
683         (const_string "false")))
684
685 ;; Indicates if an FP operation has an integer source.
686
687 (define_attr "fp_int_src" "false,true"
688   (const_string "false"))
689
690 ;; Defines rounding mode of an FP operation.
691
692 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
693   (const_string "any"))
694
695 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
696 (define_attr "use_carry" "0,1" (const_string "0"))
697
698 ;; Define attribute to indicate unaligned ssemov insns
699 (define_attr "movu" "0,1" (const_string "0"))
700
701 ;; Used to control the "enabled" attribute on a per-instruction basis.
702 (define_attr "isa" "base,noavx,avx"
703   (const_string "base"))
704
705 (define_attr "enabled" ""
706   (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
707          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
708         ]
709         (const_int 1)))
710
711 ;; Describe a user's asm statement.
712 (define_asm_attributes
713   [(set_attr "length" "128")
714    (set_attr "type" "multi")])
715
716 (define_code_iterator plusminus [plus minus])
717
718 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
719
720 ;; Base name for define_insn
721 (define_code_attr plusminus_insn
722   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
723    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
724
725 ;; Base name for insn mnemonic.
726 (define_code_attr plusminus_mnemonic
727   [(plus "add") (ss_plus "adds") (us_plus "addus")
728    (minus "sub") (ss_minus "subs") (us_minus "subus")])
729 (define_code_attr plusminus_carry_mnemonic
730   [(plus "adc") (minus "sbb")])
731
732 ;; Mark commutative operators as such in constraints.
733 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
734                         (minus "") (ss_minus "") (us_minus "")])
735
736 ;; Mapping of signed max and min
737 (define_code_iterator smaxmin [smax smin])
738
739 ;; Mapping of unsigned max and min
740 (define_code_iterator umaxmin [umax umin])
741
742 ;; Base name for integer and FP insn mnemonic
743 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
744                               (umax "maxu") (umin "minu")])
745 (define_code_attr maxmin_float [(smax "max") (smin "min")])
746
747 ;; Mapping of logic operators
748 (define_code_iterator any_logic [and ior xor])
749 (define_code_iterator any_or [ior xor])
750
751 ;; Base name for insn mnemonic.
752 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
753
754 ;; Mapping of shift-right operators
755 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
756
757 ;; Base name for define_insn
758 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
759
760 ;; Base name for insn mnemonic.
761 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
762
763 ;; Mapping of rotate operators
764 (define_code_iterator any_rotate [rotate rotatert])
765
766 ;; Base name for define_insn
767 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
768
769 ;; Base name for insn mnemonic.
770 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
771
772 ;; Mapping of abs neg operators
773 (define_code_iterator absneg [abs neg])
774
775 ;; Base name for x87 insn mnemonic.
776 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
777
778 ;; Used in signed and unsigned widening multiplications.
779 (define_code_iterator any_extend [sign_extend zero_extend])
780
781 ;; Various insn prefixes for signed and unsigned operations.
782 (define_code_attr u [(sign_extend "") (zero_extend "u")
783                      (div "") (udiv "u")])
784 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
785
786 ;; Used in signed and unsigned divisions.
787 (define_code_iterator any_div [div udiv])
788
789 ;; Instruction prefix for signed and unsigned operations.
790 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
791                              (div "i") (udiv "")])
792
793 ;; All integer modes.
794 (define_mode_iterator SWI1248x [QI HI SI DI])
795
796 ;; All integer modes without QImode.
797 (define_mode_iterator SWI248x [HI SI DI])
798
799 ;; All integer modes without QImode and HImode.
800 (define_mode_iterator SWI48x [SI DI])
801
802 ;; All integer modes without SImode and DImode.
803 (define_mode_iterator SWI12 [QI HI])
804
805 ;; All integer modes without DImode.
806 (define_mode_iterator SWI124 [QI HI SI])
807
808 ;; All integer modes without QImode and DImode.
809 (define_mode_iterator SWI24 [HI SI])
810
811 ;; Single word integer modes.
812 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
813
814 ;; Single word integer modes without QImode.
815 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
816
817 ;; Single word integer modes without QImode and HImode.
818 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
819
820 ;; All math-dependant single and double word integer modes.
821 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
822                              (HI "TARGET_HIMODE_MATH")
823                              SI DI (TI "TARGET_64BIT")])
824
825 ;; Math-dependant single word integer modes.
826 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
827                             (HI "TARGET_HIMODE_MATH")
828                             SI (DI "TARGET_64BIT")])
829
830 ;; Math-dependant integer modes without DImode.
831 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
832                                (HI "TARGET_HIMODE_MATH")
833                                SI])
834
835 ;; Math-dependant single word integer modes without QImode.
836 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
837                                SI (DI "TARGET_64BIT")])
838
839 ;; Double word integer modes.
840 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
841                            (TI "TARGET_64BIT")])
842
843 ;; Double word integer modes as mode attribute.
844 (define_mode_attr DWI [(SI "DI") (DI "TI")])
845 (define_mode_attr dwi [(SI "di") (DI "ti")])
846
847 ;; Half mode for double word integer modes.
848 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
849                             (DI "TARGET_64BIT")])
850
851 ;; Instruction suffix for integer modes.
852 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
853
854 ;; Pointer size prefix for integer modes (Intel asm dialect)
855 (define_mode_attr iptrsize [(QI "BYTE")
856                             (HI "WORD")
857                             (SI "DWORD")
858                             (DI "QWORD")])
859
860 ;; Register class for integer modes.
861 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
862
863 ;; Immediate operand constraint for integer modes.
864 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
865
866 ;; General operand constraint for word modes.
867 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
868
869 ;; Immediate operand constraint for double integer modes.
870 (define_mode_attr di [(SI "iF") (DI "e")])
871
872 ;; Immediate operand constraint for shifts.
873 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
874
875 ;; General operand predicate for integer modes.
876 (define_mode_attr general_operand
877         [(QI "general_operand")
878          (HI "general_operand")
879          (SI "general_operand")
880          (DI "x86_64_general_operand")
881          (TI "x86_64_general_operand")])
882
883 ;; General sign/zero extend operand predicate for integer modes.
884 (define_mode_attr general_szext_operand
885         [(QI "general_operand")
886          (HI "general_operand")
887          (SI "general_operand")
888          (DI "x86_64_szext_general_operand")])
889
890 ;; Immediate operand predicate for integer modes.
891 (define_mode_attr immediate_operand
892         [(QI "immediate_operand")
893          (HI "immediate_operand")
894          (SI "immediate_operand")
895          (DI "x86_64_immediate_operand")])
896
897 ;; Nonmemory operand predicate for integer modes.
898 (define_mode_attr nonmemory_operand
899         [(QI "nonmemory_operand")
900          (HI "nonmemory_operand")
901          (SI "nonmemory_operand")
902          (DI "x86_64_nonmemory_operand")])
903
904 ;; Operand predicate for shifts.
905 (define_mode_attr shift_operand
906         [(QI "nonimmediate_operand")
907          (HI "nonimmediate_operand")
908          (SI "nonimmediate_operand")
909          (DI "shiftdi_operand")
910          (TI "register_operand")])
911
912 ;; Operand predicate for shift argument.
913 (define_mode_attr shift_immediate_operand
914         [(QI "const_1_to_31_operand")
915          (HI "const_1_to_31_operand")
916          (SI "const_1_to_31_operand")
917          (DI "const_1_to_63_operand")])
918
919 ;; Input operand predicate for arithmetic left shifts.
920 (define_mode_attr ashl_input_operand
921         [(QI "nonimmediate_operand")
922          (HI "nonimmediate_operand")
923          (SI "nonimmediate_operand")
924          (DI "ashldi_input_operand")
925          (TI "reg_or_pm1_operand")])
926
927 ;; SSE and x87 SFmode and DFmode floating point modes
928 (define_mode_iterator MODEF [SF DF])
929
930 ;; All x87 floating point modes
931 (define_mode_iterator X87MODEF [SF DF XF])
932
933 ;; SSE instruction suffix for various modes
934 (define_mode_attr ssemodesuffix
935   [(SF "ss") (DF "sd")
936    (V8SF "ps") (V4DF "pd")
937    (V4SF "ps") (V2DF "pd")
938    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
939    (V8SI "si")])
940
941 ;; SSE vector suffix for floating point modes
942 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
943
944 ;; SSE vector mode corresponding to a scalar mode
945 (define_mode_attr ssevecmode
946   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
947
948 ;; Instruction suffix for REX 64bit operators.
949 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
950
951 ;; This mode iterator allows :P to be used for patterns that operate on
952 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
953 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
954 \f
955 ;; Scheduling descriptions
956
957 (include "pentium.md")
958 (include "ppro.md")
959 (include "k6.md")
960 (include "athlon.md")
961 (include "bdver1.md")
962 (include "geode.md")
963 (include "atom.md")
964 (include "core2.md")
965
966 \f
967 ;; Operand and operator predicates and constraints
968
969 (include "predicates.md")
970 (include "constraints.md")
971
972 \f
973 ;; Compare and branch/compare and store instructions.
974
975 (define_expand "cbranch<mode>4"
976   [(set (reg:CC FLAGS_REG)
977         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
978                     (match_operand:SDWIM 2 "<general_operand>" "")))
979    (set (pc) (if_then_else
980                (match_operator 0 "ordered_comparison_operator"
981                 [(reg:CC FLAGS_REG) (const_int 0)])
982                (label_ref (match_operand 3 "" ""))
983                (pc)))]
984   ""
985 {
986   if (MEM_P (operands[1]) && MEM_P (operands[2]))
987     operands[1] = force_reg (<MODE>mode, operands[1]);
988   ix86_expand_branch (GET_CODE (operands[0]),
989                       operands[1], operands[2], operands[3]);
990   DONE;
991 })
992
993 (define_expand "cstore<mode>4"
994   [(set (reg:CC FLAGS_REG)
995         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
996                     (match_operand:SWIM 3 "<general_operand>" "")))
997    (set (match_operand:QI 0 "register_operand" "")
998         (match_operator 1 "ordered_comparison_operator"
999           [(reg:CC FLAGS_REG) (const_int 0)]))]
1000   ""
1001 {
1002   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1003     operands[2] = force_reg (<MODE>mode, operands[2]);
1004   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1005                      operands[2], operands[3]);
1006   DONE;
1007 })
1008
1009 (define_expand "cmp<mode>_1"
1010   [(set (reg:CC FLAGS_REG)
1011         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1012                     (match_operand:SWI48 1 "<general_operand>" "")))])
1013
1014 (define_insn "*cmp<mode>_ccno_1"
1015   [(set (reg FLAGS_REG)
1016         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1017                  (match_operand:SWI 1 "const0_operand" "")))]
1018   "ix86_match_ccmode (insn, CCNOmode)"
1019   "@
1020    test{<imodesuffix>}\t%0, %0
1021    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1022   [(set_attr "type" "test,icmp")
1023    (set_attr "length_immediate" "0,1")
1024    (set_attr "mode" "<MODE>")])
1025
1026 (define_insn "*cmp<mode>_1"
1027   [(set (reg FLAGS_REG)
1028         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1029                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1030   "ix86_match_ccmode (insn, CCmode)"
1031   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1032   [(set_attr "type" "icmp")
1033    (set_attr "mode" "<MODE>")])
1034
1035 (define_insn "*cmp<mode>_minus_1"
1036   [(set (reg FLAGS_REG)
1037         (compare
1038           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1039                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1040           (const_int 0)))]
1041   "ix86_match_ccmode (insn, CCGOCmode)"
1042   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1043   [(set_attr "type" "icmp")
1044    (set_attr "mode" "<MODE>")])
1045
1046 (define_insn "*cmpqi_ext_1"
1047   [(set (reg FLAGS_REG)
1048         (compare
1049           (match_operand:QI 0 "general_operand" "Qm")
1050           (subreg:QI
1051             (zero_extract:SI
1052               (match_operand 1 "ext_register_operand" "Q")
1053               (const_int 8)
1054               (const_int 8)) 0)))]
1055   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056   "cmp{b}\t{%h1, %0|%0, %h1}"
1057   [(set_attr "type" "icmp")
1058    (set_attr "mode" "QI")])
1059
1060 (define_insn "*cmpqi_ext_1_rex64"
1061   [(set (reg FLAGS_REG)
1062         (compare
1063           (match_operand:QI 0 "register_operand" "Q")
1064           (subreg:QI
1065             (zero_extract:SI
1066               (match_operand 1 "ext_register_operand" "Q")
1067               (const_int 8)
1068               (const_int 8)) 0)))]
1069   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1070   "cmp{b}\t{%h1, %0|%0, %h1}"
1071   [(set_attr "type" "icmp")
1072    (set_attr "mode" "QI")])
1073
1074 (define_insn "*cmpqi_ext_2"
1075   [(set (reg FLAGS_REG)
1076         (compare
1077           (subreg:QI
1078             (zero_extract:SI
1079               (match_operand 0 "ext_register_operand" "Q")
1080               (const_int 8)
1081               (const_int 8)) 0)
1082           (match_operand:QI 1 "const0_operand" "")))]
1083   "ix86_match_ccmode (insn, CCNOmode)"
1084   "test{b}\t%h0, %h0"
1085   [(set_attr "type" "test")
1086    (set_attr "length_immediate" "0")
1087    (set_attr "mode" "QI")])
1088
1089 (define_expand "cmpqi_ext_3"
1090   [(set (reg:CC FLAGS_REG)
1091         (compare:CC
1092           (subreg:QI
1093             (zero_extract:SI
1094               (match_operand 0 "ext_register_operand" "")
1095               (const_int 8)
1096               (const_int 8)) 0)
1097           (match_operand:QI 1 "immediate_operand" "")))])
1098
1099 (define_insn "*cmpqi_ext_3_insn"
1100   [(set (reg FLAGS_REG)
1101         (compare
1102           (subreg:QI
1103             (zero_extract:SI
1104               (match_operand 0 "ext_register_operand" "Q")
1105               (const_int 8)
1106               (const_int 8)) 0)
1107           (match_operand:QI 1 "general_operand" "Qmn")))]
1108   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1109   "cmp{b}\t{%1, %h0|%h0, %1}"
1110   [(set_attr "type" "icmp")
1111    (set_attr "modrm" "1")
1112    (set_attr "mode" "QI")])
1113
1114 (define_insn "*cmpqi_ext_3_insn_rex64"
1115   [(set (reg FLAGS_REG)
1116         (compare
1117           (subreg:QI
1118             (zero_extract:SI
1119               (match_operand 0 "ext_register_operand" "Q")
1120               (const_int 8)
1121               (const_int 8)) 0)
1122           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1123   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1124   "cmp{b}\t{%1, %h0|%h0, %1}"
1125   [(set_attr "type" "icmp")
1126    (set_attr "modrm" "1")
1127    (set_attr "mode" "QI")])
1128
1129 (define_insn "*cmpqi_ext_4"
1130   [(set (reg FLAGS_REG)
1131         (compare
1132           (subreg:QI
1133             (zero_extract:SI
1134               (match_operand 0 "ext_register_operand" "Q")
1135               (const_int 8)
1136               (const_int 8)) 0)
1137           (subreg:QI
1138             (zero_extract:SI
1139               (match_operand 1 "ext_register_operand" "Q")
1140               (const_int 8)
1141               (const_int 8)) 0)))]
1142   "ix86_match_ccmode (insn, CCmode)"
1143   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1144   [(set_attr "type" "icmp")
1145    (set_attr "mode" "QI")])
1146
1147 ;; These implement float point compares.
1148 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1149 ;; which would allow mix and match FP modes on the compares.  Which is what
1150 ;; the old patterns did, but with many more of them.
1151
1152 (define_expand "cbranchxf4"
1153   [(set (reg:CC FLAGS_REG)
1154         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1155                     (match_operand:XF 2 "nonmemory_operand" "")))
1156    (set (pc) (if_then_else
1157               (match_operator 0 "ix86_fp_comparison_operator"
1158                [(reg:CC FLAGS_REG)
1159                 (const_int 0)])
1160               (label_ref (match_operand 3 "" ""))
1161               (pc)))]
1162   "TARGET_80387"
1163 {
1164   ix86_expand_branch (GET_CODE (operands[0]),
1165                       operands[1], operands[2], operands[3]);
1166   DONE;
1167 })
1168
1169 (define_expand "cstorexf4"
1170   [(set (reg:CC FLAGS_REG)
1171         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1172                     (match_operand:XF 3 "nonmemory_operand" "")))
1173    (set (match_operand:QI 0 "register_operand" "")
1174               (match_operator 1 "ix86_fp_comparison_operator"
1175                [(reg:CC FLAGS_REG)
1176                 (const_int 0)]))]
1177   "TARGET_80387"
1178 {
1179   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1180                      operands[2], operands[3]);
1181   DONE;
1182 })
1183
1184 (define_expand "cbranch<mode>4"
1185   [(set (reg:CC FLAGS_REG)
1186         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1187                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1188    (set (pc) (if_then_else
1189               (match_operator 0 "ix86_fp_comparison_operator"
1190                [(reg:CC FLAGS_REG)
1191                 (const_int 0)])
1192               (label_ref (match_operand 3 "" ""))
1193               (pc)))]
1194   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1195 {
1196   ix86_expand_branch (GET_CODE (operands[0]),
1197                       operands[1], operands[2], operands[3]);
1198   DONE;
1199 })
1200
1201 (define_expand "cstore<mode>4"
1202   [(set (reg:CC FLAGS_REG)
1203         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1204                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1205    (set (match_operand:QI 0 "register_operand" "")
1206               (match_operator 1 "ix86_fp_comparison_operator"
1207                [(reg:CC FLAGS_REG)
1208                 (const_int 0)]))]
1209   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1210 {
1211   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212                      operands[2], operands[3]);
1213   DONE;
1214 })
1215
1216 (define_expand "cbranchcc4"
1217   [(set (pc) (if_then_else
1218               (match_operator 0 "comparison_operator"
1219                [(match_operand 1 "flags_reg_operand" "")
1220                 (match_operand 2 "const0_operand" "")])
1221               (label_ref (match_operand 3 "" ""))
1222               (pc)))]
1223   ""
1224 {
1225   ix86_expand_branch (GET_CODE (operands[0]),
1226                       operands[1], operands[2], operands[3]);
1227   DONE;
1228 })
1229
1230 (define_expand "cstorecc4"
1231   [(set (match_operand:QI 0 "register_operand" "")
1232               (match_operator 1 "comparison_operator"
1233                [(match_operand 2 "flags_reg_operand" "")
1234                 (match_operand 3 "const0_operand" "")]))]
1235   ""
1236 {
1237   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1238                      operands[2], operands[3]);
1239   DONE;
1240 })
1241
1242
1243 ;; FP compares, step 1:
1244 ;; Set the FP condition codes.
1245 ;;
1246 ;; CCFPmode     compare with exceptions
1247 ;; CCFPUmode    compare with no exceptions
1248
1249 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1250 ;; used to manage the reg stack popping would not be preserved.
1251
1252 (define_insn "*cmpfp_0"
1253   [(set (match_operand:HI 0 "register_operand" "=a")
1254         (unspec:HI
1255           [(compare:CCFP
1256              (match_operand 1 "register_operand" "f")
1257              (match_operand 2 "const0_operand" ""))]
1258         UNSPEC_FNSTSW))]
1259   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1260    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1261   "* return output_fp_compare (insn, operands, false, false);"
1262   [(set_attr "type" "multi")
1263    (set_attr "unit" "i387")
1264    (set (attr "mode")
1265      (cond [(match_operand:SF 1 "" "")
1266               (const_string "SF")
1267             (match_operand:DF 1 "" "")
1268               (const_string "DF")
1269            ]
1270            (const_string "XF")))])
1271
1272 (define_insn_and_split "*cmpfp_0_cc"
1273   [(set (reg:CCFP FLAGS_REG)
1274         (compare:CCFP
1275           (match_operand 1 "register_operand" "f")
1276           (match_operand 2 "const0_operand" "")))
1277    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1278   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1279    && TARGET_SAHF && !TARGET_CMOVE
1280    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1281   "#"
1282   "&& reload_completed"
1283   [(set (match_dup 0)
1284         (unspec:HI
1285           [(compare:CCFP (match_dup 1)(match_dup 2))]
1286         UNSPEC_FNSTSW))
1287    (set (reg:CC FLAGS_REG)
1288         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1289   ""
1290   [(set_attr "type" "multi")
1291    (set_attr "unit" "i387")
1292    (set (attr "mode")
1293      (cond [(match_operand:SF 1 "" "")
1294               (const_string "SF")
1295             (match_operand:DF 1 "" "")
1296               (const_string "DF")
1297            ]
1298            (const_string "XF")))])
1299
1300 (define_insn "*cmpfp_xf"
1301   [(set (match_operand:HI 0 "register_operand" "=a")
1302         (unspec:HI
1303           [(compare:CCFP
1304              (match_operand:XF 1 "register_operand" "f")
1305              (match_operand:XF 2 "register_operand" "f"))]
1306           UNSPEC_FNSTSW))]
1307   "TARGET_80387"
1308   "* return output_fp_compare (insn, operands, false, false);"
1309   [(set_attr "type" "multi")
1310    (set_attr "unit" "i387")
1311    (set_attr "mode" "XF")])
1312
1313 (define_insn_and_split "*cmpfp_xf_cc"
1314   [(set (reg:CCFP FLAGS_REG)
1315         (compare:CCFP
1316           (match_operand:XF 1 "register_operand" "f")
1317           (match_operand:XF 2 "register_operand" "f")))
1318    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1319   "TARGET_80387
1320    && TARGET_SAHF && !TARGET_CMOVE"
1321   "#"
1322   "&& reload_completed"
1323   [(set (match_dup 0)
1324         (unspec:HI
1325           [(compare:CCFP (match_dup 1)(match_dup 2))]
1326         UNSPEC_FNSTSW))
1327    (set (reg:CC FLAGS_REG)
1328         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1329   ""
1330   [(set_attr "type" "multi")
1331    (set_attr "unit" "i387")
1332    (set_attr "mode" "XF")])
1333
1334 (define_insn "*cmpfp_<mode>"
1335   [(set (match_operand:HI 0 "register_operand" "=a")
1336         (unspec:HI
1337           [(compare:CCFP
1338              (match_operand:MODEF 1 "register_operand" "f")
1339              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1340           UNSPEC_FNSTSW))]
1341   "TARGET_80387"
1342   "* return output_fp_compare (insn, operands, false, false);"
1343   [(set_attr "type" "multi")
1344    (set_attr "unit" "i387")
1345    (set_attr "mode" "<MODE>")])
1346
1347 (define_insn_and_split "*cmpfp_<mode>_cc"
1348   [(set (reg:CCFP FLAGS_REG)
1349         (compare:CCFP
1350           (match_operand:MODEF 1 "register_operand" "f")
1351           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1352    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1353   "TARGET_80387
1354    && TARGET_SAHF && !TARGET_CMOVE"
1355   "#"
1356   "&& reload_completed"
1357   [(set (match_dup 0)
1358         (unspec:HI
1359           [(compare:CCFP (match_dup 1)(match_dup 2))]
1360         UNSPEC_FNSTSW))
1361    (set (reg:CC FLAGS_REG)
1362         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1363   ""
1364   [(set_attr "type" "multi")
1365    (set_attr "unit" "i387")
1366    (set_attr "mode" "<MODE>")])
1367
1368 (define_insn "*cmpfp_u"
1369   [(set (match_operand:HI 0 "register_operand" "=a")
1370         (unspec:HI
1371           [(compare:CCFPU
1372              (match_operand 1 "register_operand" "f")
1373              (match_operand 2 "register_operand" "f"))]
1374           UNSPEC_FNSTSW))]
1375   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1377   "* return output_fp_compare (insn, operands, false, true);"
1378   [(set_attr "type" "multi")
1379    (set_attr "unit" "i387")
1380    (set (attr "mode")
1381      (cond [(match_operand:SF 1 "" "")
1382               (const_string "SF")
1383             (match_operand:DF 1 "" "")
1384               (const_string "DF")
1385            ]
1386            (const_string "XF")))])
1387
1388 (define_insn_and_split "*cmpfp_u_cc"
1389   [(set (reg:CCFPU FLAGS_REG)
1390         (compare:CCFPU
1391           (match_operand 1 "register_operand" "f")
1392           (match_operand 2 "register_operand" "f")))
1393    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395    && TARGET_SAHF && !TARGET_CMOVE
1396    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1397   "#"
1398   "&& reload_completed"
1399   [(set (match_dup 0)
1400         (unspec:HI
1401           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1402         UNSPEC_FNSTSW))
1403    (set (reg:CC FLAGS_REG)
1404         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1405   ""
1406   [(set_attr "type" "multi")
1407    (set_attr "unit" "i387")
1408    (set (attr "mode")
1409      (cond [(match_operand:SF 1 "" "")
1410               (const_string "SF")
1411             (match_operand:DF 1 "" "")
1412               (const_string "DF")
1413            ]
1414            (const_string "XF")))])
1415
1416 (define_insn "*cmpfp_<mode>"
1417   [(set (match_operand:HI 0 "register_operand" "=a")
1418         (unspec:HI
1419           [(compare:CCFP
1420              (match_operand 1 "register_operand" "f")
1421              (match_operator 3 "float_operator"
1422                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1423           UNSPEC_FNSTSW))]
1424   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1425    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1426    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1427   "* return output_fp_compare (insn, operands, false, false);"
1428   [(set_attr "type" "multi")
1429    (set_attr "unit" "i387")
1430    (set_attr "fp_int_src" "true")
1431    (set_attr "mode" "<MODE>")])
1432
1433 (define_insn_and_split "*cmpfp_<mode>_cc"
1434   [(set (reg:CCFP FLAGS_REG)
1435         (compare:CCFP
1436           (match_operand 1 "register_operand" "f")
1437           (match_operator 3 "float_operator"
1438             [(match_operand:SWI24 2 "memory_operand" "m")])))
1439    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1440   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1441    && TARGET_SAHF && !TARGET_CMOVE
1442    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1443    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1444   "#"
1445   "&& reload_completed"
1446   [(set (match_dup 0)
1447         (unspec:HI
1448           [(compare:CCFP
1449              (match_dup 1)
1450              (match_op_dup 3 [(match_dup 2)]))]
1451         UNSPEC_FNSTSW))
1452    (set (reg:CC FLAGS_REG)
1453         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1454   ""
1455   [(set_attr "type" "multi")
1456    (set_attr "unit" "i387")
1457    (set_attr "fp_int_src" "true")
1458    (set_attr "mode" "<MODE>")])
1459
1460 ;; FP compares, step 2
1461 ;; Move the fpsw to ax.
1462
1463 (define_insn "x86_fnstsw_1"
1464   [(set (match_operand:HI 0 "register_operand" "=a")
1465         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1466   "TARGET_80387"
1467   "fnstsw\t%0"
1468   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1469    (set_attr "mode" "SI")
1470    (set_attr "unit" "i387")])
1471
1472 ;; FP compares, step 3
1473 ;; Get ax into flags, general case.
1474
1475 (define_insn "x86_sahf_1"
1476   [(set (reg:CC FLAGS_REG)
1477         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1478                    UNSPEC_SAHF))]
1479   "TARGET_SAHF"
1480 {
1481 #ifndef HAVE_AS_IX86_SAHF
1482   if (TARGET_64BIT)
1483     return ASM_BYTE "0x9e";
1484   else
1485 #endif
1486   return "sahf";
1487 }
1488   [(set_attr "length" "1")
1489    (set_attr "athlon_decode" "vector")
1490    (set_attr "amdfam10_decode" "direct")
1491    (set_attr "bdver1_decode" "direct")
1492    (set_attr "mode" "SI")])
1493
1494 ;; Pentium Pro can do steps 1 through 3 in one go.
1495 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1496 (define_insn "*cmpfp_i_mixed"
1497   [(set (reg:CCFP FLAGS_REG)
1498         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1499                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1500   "TARGET_MIX_SSE_I387
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, true, false);"
1504   [(set_attr "type" "fcmp,ssecomi")
1505    (set_attr "prefix" "orig,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")
1511         (if_then_else (eq_attr "type" "ssecomi")
1512                       (const_string "0")
1513                       (const_string "*")))
1514    (set (attr "prefix_data16")
1515         (cond [(eq_attr "type" "fcmp")
1516                  (const_string "*")
1517                (eq_attr "mode" "DF")
1518                  (const_string "1")
1519               ]
1520               (const_string "0")))
1521    (set_attr "athlon_decode" "vector")
1522    (set_attr "amdfam10_decode" "direct")
1523    (set_attr "bdver1_decode" "double")])
1524
1525 (define_insn "*cmpfp_i_sse"
1526   [(set (reg:CCFP FLAGS_REG)
1527         (compare:CCFP (match_operand 0 "register_operand" "x")
1528                       (match_operand 1 "nonimmediate_operand" "xm")))]
1529   "TARGET_SSE_MATH
1530    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532   "* return output_fp_compare (insn, operands, true, false);"
1533   [(set_attr "type" "ssecomi")
1534    (set_attr "prefix" "maybe_vex")
1535    (set (attr "mode")
1536      (if_then_else (match_operand:SF 1 "" "")
1537         (const_string "SF")
1538         (const_string "DF")))
1539    (set_attr "prefix_rep" "0")
1540    (set (attr "prefix_data16")
1541         (if_then_else (eq_attr "mode" "DF")
1542                       (const_string "1")
1543                       (const_string "0")))
1544    (set_attr "athlon_decode" "vector")
1545    (set_attr "amdfam10_decode" "direct")
1546    (set_attr "bdver1_decode" "double")])
1547
1548 (define_insn "*cmpfp_i_i387"
1549   [(set (reg:CCFP FLAGS_REG)
1550         (compare:CCFP (match_operand 0 "register_operand" "f")
1551                       (match_operand 1 "register_operand" "f")))]
1552   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1553    && TARGET_CMOVE
1554    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1555    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556   "* return output_fp_compare (insn, operands, true, false);"
1557   [(set_attr "type" "fcmp")
1558    (set (attr "mode")
1559      (cond [(match_operand:SF 1 "" "")
1560               (const_string "SF")
1561             (match_operand:DF 1 "" "")
1562               (const_string "DF")
1563            ]
1564            (const_string "XF")))
1565    (set_attr "athlon_decode" "vector")
1566    (set_attr "amdfam10_decode" "direct")
1567    (set_attr "bdver1_decode" "double")])
1568
1569 (define_insn "*cmpfp_iu_mixed"
1570   [(set (reg:CCFPU FLAGS_REG)
1571         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1572                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1573   "TARGET_MIX_SSE_I387
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, true, true);"
1577   [(set_attr "type" "fcmp,ssecomi")
1578    (set_attr "prefix" "orig,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")
1584         (if_then_else (eq_attr "type" "ssecomi")
1585                       (const_string "0")
1586                       (const_string "*")))
1587    (set (attr "prefix_data16")
1588         (cond [(eq_attr "type" "fcmp")
1589                  (const_string "*")
1590                (eq_attr "mode" "DF")
1591                  (const_string "1")
1592               ]
1593               (const_string "0")))
1594    (set_attr "athlon_decode" "vector")
1595    (set_attr "amdfam10_decode" "direct")
1596    (set_attr "bdver1_decode" "double")])
1597
1598 (define_insn "*cmpfp_iu_sse"
1599   [(set (reg:CCFPU FLAGS_REG)
1600         (compare:CCFPU (match_operand 0 "register_operand" "x")
1601                        (match_operand 1 "nonimmediate_operand" "xm")))]
1602   "TARGET_SSE_MATH
1603    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1604    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1605   "* return output_fp_compare (insn, operands, true, true);"
1606   [(set_attr "type" "ssecomi")
1607    (set_attr "prefix" "maybe_vex")
1608    (set (attr "mode")
1609      (if_then_else (match_operand:SF 1 "" "")
1610         (const_string "SF")
1611         (const_string "DF")))
1612    (set_attr "prefix_rep" "0")
1613    (set (attr "prefix_data16")
1614         (if_then_else (eq_attr "mode" "DF")
1615                       (const_string "1")
1616                       (const_string "0")))
1617    (set_attr "athlon_decode" "vector")
1618    (set_attr "amdfam10_decode" "direct")
1619    (set_attr "bdver1_decode" "double")])
1620
1621 (define_insn "*cmpfp_iu_387"
1622   [(set (reg:CCFPU FLAGS_REG)
1623         (compare:CCFPU (match_operand 0 "register_operand" "f")
1624                        (match_operand 1 "register_operand" "f")))]
1625   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1626    && TARGET_CMOVE
1627    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1628    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1629   "* return output_fp_compare (insn, operands, true, true);"
1630   [(set_attr "type" "fcmp")
1631    (set (attr "mode")
1632      (cond [(match_operand:SF 1 "" "")
1633               (const_string "SF")
1634             (match_operand:DF 1 "" "")
1635               (const_string "DF")
1636            ]
1637            (const_string "XF")))
1638    (set_attr "athlon_decode" "vector")
1639    (set_attr "amdfam10_decode" "direct")
1640    (set_attr "bdver1_decode" "direct")])
1641 \f
1642 ;; Push/pop instructions.
1643
1644 (define_insn "*push<mode>2"
1645   [(set (match_operand:DWI 0 "push_operand" "=<")
1646         (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1647   ""
1648   "#")
1649
1650 (define_split
1651   [(set (match_operand:TI 0 "push_operand" "")
1652         (match_operand:TI 1 "general_operand" ""))]
1653   "TARGET_64BIT && reload_completed
1654    && !SSE_REG_P (operands[1])"
1655   [(const_int 0)]
1656   "ix86_split_long_move (operands); DONE;")
1657
1658 (define_insn "*pushdi2_rex64"
1659   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1660         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1661   "TARGET_64BIT"
1662   "@
1663    push{q}\t%1
1664    #"
1665   [(set_attr "type" "push,multi")
1666    (set_attr "mode" "DI")])
1667
1668 ;; Convert impossible pushes of immediate to existing instructions.
1669 ;; First try to get scratch register and go through it.  In case this
1670 ;; fails, push sign extended lower part first and then overwrite
1671 ;; upper part by 32bit move.
1672 (define_peephole2
1673   [(match_scratch:DI 2 "r")
1674    (set (match_operand:DI 0 "push_operand" "")
1675         (match_operand:DI 1 "immediate_operand" ""))]
1676   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1677    && !x86_64_immediate_operand (operands[1], DImode)"
1678   [(set (match_dup 2) (match_dup 1))
1679    (set (match_dup 0) (match_dup 2))])
1680
1681 ;; We need to define this as both peepholer and splitter for case
1682 ;; peephole2 pass is not run.
1683 ;; "&& 1" is needed to keep it from matching the previous pattern.
1684 (define_peephole2
1685   [(set (match_operand:DI 0 "push_operand" "")
1686         (match_operand:DI 1 "immediate_operand" ""))]
1687   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1688    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1689   [(set (match_dup 0) (match_dup 1))
1690    (set (match_dup 2) (match_dup 3))]
1691 {
1692   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1693
1694   operands[1] = gen_lowpart (DImode, operands[2]);
1695   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1696                                                    GEN_INT (4)));
1697 })
1698
1699 (define_split
1700   [(set (match_operand:DI 0 "push_operand" "")
1701         (match_operand:DI 1 "immediate_operand" ""))]
1702   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1703                     ? epilogue_completed : reload_completed)
1704    && !symbolic_operand (operands[1], DImode)
1705    && !x86_64_immediate_operand (operands[1], DImode)"
1706   [(set (match_dup 0) (match_dup 1))
1707    (set (match_dup 2) (match_dup 3))]
1708 {
1709   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1710
1711   operands[1] = gen_lowpart (DImode, operands[2]);
1712   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1713                                                    GEN_INT (4)));
1714 })
1715
1716 (define_split
1717   [(set (match_operand:DI 0 "push_operand" "")
1718         (match_operand:DI 1 "general_operand" ""))]
1719   "!TARGET_64BIT && reload_completed
1720    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1721   [(const_int 0)]
1722   "ix86_split_long_move (operands); DONE;")
1723
1724 (define_insn "*pushsi2"
1725   [(set (match_operand:SI 0 "push_operand" "=<")
1726         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1727   "!TARGET_64BIT"
1728   "push{l}\t%1"
1729   [(set_attr "type" "push")
1730    (set_attr "mode" "SI")])
1731
1732 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1733 ;; "push a byte/word".  But actually we use pushl, which has the effect
1734 ;; of rounding the amount pushed up to a word.
1735
1736 ;; For TARGET_64BIT we always round up to 8 bytes.
1737 (define_insn "*push<mode>2_rex64"
1738   [(set (match_operand:SWI124 0 "push_operand" "=X")
1739         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1740   "TARGET_64BIT"
1741   "push{q}\t%q1"
1742   [(set_attr "type" "push")
1743    (set_attr "mode" "DI")])
1744
1745 (define_insn "*push<mode>2"
1746   [(set (match_operand:SWI12 0 "push_operand" "=X")
1747         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1748   "!TARGET_64BIT"
1749   "push{l}\t%k1"
1750   [(set_attr "type" "push")
1751    (set_attr "mode" "SI")])
1752
1753 (define_insn "*push<mode>2_prologue"
1754   [(set (match_operand:P 0 "push_operand" "=<")
1755         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1756    (clobber (mem:BLK (scratch)))]
1757   ""
1758   "push{<imodesuffix>}\t%1"
1759   [(set_attr "type" "push")
1760    (set_attr "mode" "<MODE>")])
1761
1762 (define_insn "*pop<mode>1"
1763   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1764         (match_operand:P 1 "pop_operand" ">"))]
1765   ""
1766   "pop{<imodesuffix>}\t%0"
1767   [(set_attr "type" "pop")
1768    (set_attr "mode" "<MODE>")])
1769
1770 (define_insn "*pop<mode>1_epilogue"
1771   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1772         (match_operand:P 1 "pop_operand" ">"))
1773    (clobber (mem:BLK (scratch)))]
1774   ""
1775   "pop{<imodesuffix>}\t%0"
1776   [(set_attr "type" "pop")
1777    (set_attr "mode" "<MODE>")])
1778 \f
1779 ;; Move instructions.
1780
1781 (define_expand "movoi"
1782   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1783         (match_operand:OI 1 "general_operand" ""))]
1784   "TARGET_AVX"
1785   "ix86_expand_move (OImode, operands); DONE;")
1786
1787 (define_expand "movti"
1788   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1789         (match_operand:TI 1 "nonimmediate_operand" ""))]
1790   "TARGET_64BIT || TARGET_SSE"
1791 {
1792   if (TARGET_64BIT)
1793     ix86_expand_move (TImode, operands);
1794   else if (push_operand (operands[0], TImode))
1795     ix86_expand_push (TImode, operands[1]);
1796   else
1797     ix86_expand_vector_move (TImode, operands);
1798   DONE;
1799 })
1800
1801 ;; This expands to what emit_move_complex would generate if we didn't
1802 ;; have a movti pattern.  Having this avoids problems with reload on
1803 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1804 ;; to have around all the time.
1805 (define_expand "movcdi"
1806   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1807         (match_operand:CDI 1 "general_operand" ""))]
1808   ""
1809 {
1810   if (push_operand (operands[0], CDImode))
1811     emit_move_complex_push (CDImode, operands[0], operands[1]);
1812   else
1813     emit_move_complex_parts (operands[0], operands[1]);
1814   DONE;
1815 })
1816
1817 (define_expand "mov<mode>"
1818   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1819         (match_operand:SWI1248x 1 "general_operand" ""))]
1820   ""
1821   "ix86_expand_move (<MODE>mode, operands); DONE;")
1822
1823 (define_insn "*mov<mode>_xor"
1824   [(set (match_operand:SWI48 0 "register_operand" "=r")
1825         (match_operand:SWI48 1 "const0_operand" ""))
1826    (clobber (reg:CC FLAGS_REG))]
1827   "reload_completed"
1828   "xor{l}\t%k0, %k0"
1829   [(set_attr "type" "alu1")
1830    (set_attr "mode" "SI")
1831    (set_attr "length_immediate" "0")])
1832
1833 (define_insn "*mov<mode>_or"
1834   [(set (match_operand:SWI48 0 "register_operand" "=r")
1835         (match_operand:SWI48 1 "const_int_operand" ""))
1836    (clobber (reg:CC FLAGS_REG))]
1837   "reload_completed
1838    && operands[1] == constm1_rtx"
1839   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1840   [(set_attr "type" "alu1")
1841    (set_attr "mode" "<MODE>")
1842    (set_attr "length_immediate" "1")])
1843
1844 (define_insn "*movoi_internal_avx"
1845   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1846         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1847   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1848 {
1849   switch (which_alternative)
1850     {
1851     case 0:
1852       return standard_sse_constant_opcode (insn, operands[1]);
1853     case 1:
1854     case 2:
1855       if (misaligned_operand (operands[0], OImode)
1856           || misaligned_operand (operands[1], OImode))
1857         return "vmovdqu\t{%1, %0|%0, %1}";
1858       else
1859         return "vmovdqa\t{%1, %0|%0, %1}";
1860     default:
1861       gcc_unreachable ();
1862     }
1863 }
1864   [(set_attr "type" "sselog1,ssemov,ssemov")
1865    (set_attr "prefix" "vex")
1866    (set_attr "mode" "OI")])
1867
1868 (define_insn "*movti_internal_rex64"
1869   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1870         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1871   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1872 {
1873   switch (which_alternative)
1874     {
1875     case 0:
1876     case 1:
1877       return "#";
1878     case 2:
1879       return standard_sse_constant_opcode (insn, operands[1]);
1880     case 3:
1881     case 4:
1882       /* TDmode values are passed as TImode on the stack.  Moving them
1883          to stack may result in unaligned memory access.  */
1884       if (misaligned_operand (operands[0], TImode)
1885           || misaligned_operand (operands[1], TImode))
1886         {
1887           if (get_attr_mode (insn) == MODE_V4SF)
1888             return "%vmovups\t{%1, %0|%0, %1}";
1889           else
1890             return "%vmovdqu\t{%1, %0|%0, %1}";
1891         }
1892       else
1893         {
1894           if (get_attr_mode (insn) == MODE_V4SF)
1895             return "%vmovaps\t{%1, %0|%0, %1}";
1896           else
1897             return "%vmovdqa\t{%1, %0|%0, %1}";
1898         }
1899     default:
1900       gcc_unreachable ();
1901     }
1902 }
1903   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1904    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1905    (set (attr "mode")
1906         (cond [(eq_attr "alternative" "2,3")
1907                  (if_then_else
1908                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1909                        (const_int 0))
1910                    (const_string "V4SF")
1911                    (const_string "TI"))
1912                (eq_attr "alternative" "4")
1913                  (if_then_else
1914                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1915                             (const_int 0))
1916                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1917                             (const_int 0)))
1918                    (const_string "V4SF")
1919                    (const_string "TI"))]
1920                (const_string "DI")))])
1921
1922 (define_split
1923   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1924         (match_operand:TI 1 "general_operand" ""))]
1925   "reload_completed
1926    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1927   [(const_int 0)]
1928   "ix86_split_long_move (operands); DONE;")
1929
1930 (define_insn "*movti_internal_sse"
1931   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1932         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1933   "TARGET_SSE && !TARGET_64BIT
1934    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935 {
1936   switch (which_alternative)
1937     {
1938     case 0:
1939       return standard_sse_constant_opcode (insn, operands[1]);
1940     case 1:
1941     case 2:
1942       /* TDmode values are passed as TImode on the stack.  Moving them
1943          to stack may result in unaligned memory access.  */
1944       if (misaligned_operand (operands[0], TImode)
1945           || misaligned_operand (operands[1], TImode))
1946         {
1947           if (get_attr_mode (insn) == MODE_V4SF)
1948             return "%vmovups\t{%1, %0|%0, %1}";
1949           else
1950             return "%vmovdqu\t{%1, %0|%0, %1}";
1951         }
1952       else
1953         {
1954           if (get_attr_mode (insn) == MODE_V4SF)
1955             return "%vmovaps\t{%1, %0|%0, %1}";
1956           else
1957             return "%vmovdqa\t{%1, %0|%0, %1}";
1958         }
1959     default:
1960       gcc_unreachable ();
1961     }
1962 }
1963   [(set_attr "type" "sselog1,ssemov,ssemov")
1964    (set_attr "prefix" "maybe_vex")
1965    (set (attr "mode")
1966         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1967                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1968                         (const_int 0)))
1969                  (const_string "V4SF")
1970                (and (eq_attr "alternative" "2")
1971                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1972                         (const_int 0)))
1973                  (const_string "V4SF")]
1974               (const_string "TI")))])
1975
1976 (define_insn "*movdi_internal_rex64"
1977   [(set (match_operand:DI 0 "nonimmediate_operand"
1978           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1979         (match_operand:DI 1 "general_operand"
1980           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1981   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1982 {
1983   switch (get_attr_type (insn))
1984     {
1985     case TYPE_SSECVT:
1986       if (SSE_REG_P (operands[0]))
1987         return "movq2dq\t{%1, %0|%0, %1}";
1988       else
1989         return "movdq2q\t{%1, %0|%0, %1}";
1990
1991     case TYPE_SSEMOV:
1992       if (get_attr_mode (insn) == MODE_TI)
1993         return "%vmovdqa\t{%1, %0|%0, %1}";
1994       /* Handle broken assemblers that require movd instead of movq.  */
1995       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1996         return "%vmovd\t{%1, %0|%0, %1}";
1997       else
1998         return "%vmovq\t{%1, %0|%0, %1}";
1999
2000     case TYPE_MMXMOV:
2001       /* Handle broken assemblers that require movd instead of movq.  */
2002       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2003         return "movd\t{%1, %0|%0, %1}";
2004       else
2005         return "movq\t{%1, %0|%0, %1}";
2006
2007     case TYPE_SSELOG1:
2008       return standard_sse_constant_opcode (insn, operands[1]);
2009
2010     case TYPE_MMX:
2011       return "pxor\t%0, %0";
2012
2013     case TYPE_MULTI:
2014       return "#";
2015
2016     case TYPE_LEA:
2017       return "lea{q}\t{%a1, %0|%0, %a1}";
2018
2019     default:
2020       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2021       if (get_attr_mode (insn) == MODE_SI)
2022         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2023       else if (which_alternative == 2)
2024         return "movabs{q}\t{%1, %0|%0, %1}";
2025       else
2026         return "mov{q}\t{%1, %0|%0, %1}";
2027     }
2028 }
2029   [(set (attr "type")
2030      (cond [(eq_attr "alternative" "5")
2031               (const_string "mmx")
2032             (eq_attr "alternative" "6,7,8,9,10")
2033               (const_string "mmxmov")
2034             (eq_attr "alternative" "11")
2035               (const_string "sselog1")
2036             (eq_attr "alternative" "12,13,14,15,16")
2037               (const_string "ssemov")
2038             (eq_attr "alternative" "17,18")
2039               (const_string "ssecvt")
2040             (eq_attr "alternative" "4")
2041               (const_string "multi")
2042             (match_operand:DI 1 "pic_32bit_operand" "")
2043               (const_string "lea")
2044            ]
2045            (const_string "imov")))
2046    (set (attr "modrm")
2047      (if_then_else
2048        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2049          (const_string "0")
2050          (const_string "*")))
2051    (set (attr "length_immediate")
2052      (if_then_else
2053        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2054          (const_string "8")
2055          (const_string "*")))
2056    (set (attr "prefix_rex")
2057      (if_then_else (eq_attr "alternative" "7,9")
2058        (const_string "1")
2059        (const_string "*")))
2060    (set (attr "prefix_data16")
2061      (if_then_else (eq_attr "alternative" "15")
2062        (const_string "1")
2063        (const_string "*")))
2064    (set (attr "prefix")
2065      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2066        (const_string "maybe_vex")
2067        (const_string "orig")))
2068    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2069
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it.  In case this
2072 ;; fails, move by 32bit parts.
2073 (define_peephole2
2074   [(match_scratch:DI 2 "r")
2075    (set (match_operand:DI 0 "memory_operand" "")
2076         (match_operand:DI 1 "immediate_operand" ""))]
2077   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078    && !x86_64_immediate_operand (operands[1], DImode)"
2079   [(set (match_dup 2) (match_dup 1))
2080    (set (match_dup 0) (match_dup 2))])
2081
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 ;; "&& 1" is needed to keep it from matching the previous pattern.
2085 (define_peephole2
2086   [(set (match_operand:DI 0 "memory_operand" "")
2087         (match_operand:DI 1 "immediate_operand" ""))]
2088   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090   [(set (match_dup 2) (match_dup 3))
2091    (set (match_dup 4) (match_dup 5))]
2092   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2093
2094 (define_split
2095   [(set (match_operand:DI 0 "memory_operand" "")
2096         (match_operand:DI 1 "immediate_operand" ""))]
2097   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2098                     ? epilogue_completed : reload_completed)
2099    && !symbolic_operand (operands[1], DImode)
2100    && !x86_64_immediate_operand (operands[1], DImode)"
2101   [(set (match_dup 2) (match_dup 3))
2102    (set (match_dup 4) (match_dup 5))]
2103   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2104
2105 (define_insn "*movdi_internal"
2106   [(set (match_operand:DI 0 "nonimmediate_operand"
2107           "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2108         (match_operand:DI 1 "general_operand"
2109           "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m ,*Ym ,*Y2"))]
2110   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2111 {
2112   switch (get_attr_type (insn))
2113     {
2114     case TYPE_SSECVT:
2115       if (SSE_REG_P (operands[0]))
2116         return "movq2dq\t{%1, %0|%0, %1}";
2117       else
2118         return "movdq2q\t{%1, %0|%0, %1}";
2119
2120     case TYPE_SSEMOV:
2121       switch (get_attr_mode (insn))
2122         {
2123         case MODE_TI:
2124           return "%vmovdqa\t{%1, %0|%0, %1}";
2125         case MODE_DI:
2126            return "%vmovq\t{%1, %0|%0, %1}";
2127         case MODE_V4SF:
2128           return "movaps\t{%1, %0|%0, %1}";
2129         case MODE_V2SF:
2130           return "movlps\t{%1, %0|%0, %1}";
2131         default:
2132           gcc_unreachable ();
2133         }
2134
2135     case TYPE_MMXMOV:
2136       return "movq\t{%1, %0|%0, %1}";
2137
2138     case TYPE_SSELOG1:
2139       return standard_sse_constant_opcode (insn, operands[1]);
2140
2141     case TYPE_MMX:
2142       return "pxor\t%0, %0";
2143
2144     case TYPE_MULTI:
2145       return "#";
2146
2147     default:
2148       gcc_unreachable ();
2149     }
2150 }
2151   [(set (attr "isa")
2152      (if_then_else (eq_attr "alternative" "9,10,11,12")
2153        (const_string "noavx")
2154        (const_string "base")))
2155    (set (attr "type")
2156      (cond [(eq_attr "alternative" "0,1")
2157               (const_string "multi")
2158             (eq_attr "alternative" "2")
2159               (const_string "mmx")
2160             (eq_attr "alternative" "3,4")
2161               (const_string "mmxmov")
2162             (eq_attr "alternative" "5,9")
2163               (const_string "sselog1")
2164             (eq_attr "alternative" "13,14")
2165               (const_string "ssecvt")
2166            ]
2167            (const_string "ssemov")))
2168    (set (attr "prefix")
2169      (if_then_else (eq_attr "alternative" "5,6,7,8")
2170        (const_string "maybe_vex")
2171        (const_string "orig")))
2172    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2173
2174 (define_split
2175   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2176         (match_operand:DI 1 "general_operand" ""))]
2177   "!TARGET_64BIT && reload_completed
2178    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2179    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2180   [(const_int 0)]
2181   "ix86_split_long_move (operands); DONE;")
2182
2183 (define_insn "*movsi_internal"
2184   [(set (match_operand:SI 0 "nonimmediate_operand"
2185                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2186         (match_operand:SI 1 "general_operand"
2187                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2188   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189 {
2190   switch (get_attr_type (insn))
2191     {
2192     case TYPE_SSELOG1:
2193       return standard_sse_constant_opcode (insn, operands[1]);
2194
2195     case TYPE_SSEMOV:
2196       switch (get_attr_mode (insn))
2197         {
2198         case MODE_TI:
2199           return "%vmovdqa\t{%1, %0|%0, %1}";
2200         case MODE_V4SF:
2201           return "%vmovaps\t{%1, %0|%0, %1}";
2202         case MODE_SI:
2203           return "%vmovd\t{%1, %0|%0, %1}";
2204         case MODE_SF:
2205           return "%vmovss\t{%1, %0|%0, %1}";
2206         default:
2207           gcc_unreachable ();
2208         }
2209
2210     case TYPE_MMX:
2211       return "pxor\t%0, %0";
2212
2213     case TYPE_MMXMOV:
2214       if (get_attr_mode (insn) == MODE_DI)
2215         return "movq\t{%1, %0|%0, %1}";
2216       return "movd\t{%1, %0|%0, %1}";
2217
2218     case TYPE_LEA:
2219       return "lea{l}\t{%a1, %0|%0, %a1}";
2220
2221     default:
2222       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2223       return "mov{l}\t{%1, %0|%0, %1}";
2224     }
2225 }
2226   [(set (attr "type")
2227      (cond [(eq_attr "alternative" "2")
2228               (const_string "mmx")
2229             (eq_attr "alternative" "3,4,5")
2230               (const_string "mmxmov")
2231             (eq_attr "alternative" "6")
2232               (const_string "sselog1")
2233             (eq_attr "alternative" "7,8,9,10,11")
2234               (const_string "ssemov")
2235             (match_operand:DI 1 "pic_32bit_operand" "")
2236               (const_string "lea")
2237            ]
2238            (const_string "imov")))
2239    (set (attr "prefix")
2240      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2241        (const_string "orig")
2242        (const_string "maybe_vex")))
2243    (set (attr "prefix_data16")
2244      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2245        (const_string "1")
2246        (const_string "*")))
2247    (set (attr "mode")
2248      (cond [(eq_attr "alternative" "2,3")
2249               (const_string "DI")
2250             (eq_attr "alternative" "6,7")
2251               (if_then_else
2252                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2253                 (const_string "V4SF")
2254                 (const_string "TI"))
2255             (and (eq_attr "alternative" "8,9,10,11")
2256                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2257               (const_string "SF")
2258            ]
2259            (const_string "SI")))])
2260
2261 (define_insn "*movhi_internal"
2262   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2263         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2264   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2265 {
2266   switch (get_attr_type (insn))
2267     {
2268     case TYPE_IMOVX:
2269       /* movzwl is faster than movw on p2 due to partial word stalls,
2270          though not as fast as an aligned movl.  */
2271       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2272     default:
2273       if (get_attr_mode (insn) == MODE_SI)
2274         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2275       else
2276         return "mov{w}\t{%1, %0|%0, %1}";
2277     }
2278 }
2279   [(set (attr "type")
2280      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2281                 (const_int 0))
2282               (const_string "imov")
2283             (and (eq_attr "alternative" "0")
2284                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2285                           (const_int 0))
2286                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2287                           (const_int 0))))
2288               (const_string "imov")
2289             (and (eq_attr "alternative" "1,2")
2290                  (match_operand:HI 1 "aligned_operand" ""))
2291               (const_string "imov")
2292             (and (ne (symbol_ref "TARGET_MOVX")
2293                      (const_int 0))
2294                  (eq_attr "alternative" "0,2"))
2295               (const_string "imovx")
2296            ]
2297            (const_string "imov")))
2298     (set (attr "mode")
2299       (cond [(eq_attr "type" "imovx")
2300                (const_string "SI")
2301              (and (eq_attr "alternative" "1,2")
2302                   (match_operand:HI 1 "aligned_operand" ""))
2303                (const_string "SI")
2304              (and (eq_attr "alternative" "0")
2305                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2306                            (const_int 0))
2307                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2308                            (const_int 0))))
2309                (const_string "SI")
2310             ]
2311             (const_string "HI")))])
2312
2313 ;; Situation is quite tricky about when to choose full sized (SImode) move
2314 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2315 ;; partial register dependency machines (such as AMD Athlon), where QImode
2316 ;; moves issue extra dependency and for partial register stalls machines
2317 ;; that don't use QImode patterns (and QImode move cause stall on the next
2318 ;; instruction).
2319 ;;
2320 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2321 ;; register stall machines with, where we use QImode instructions, since
2322 ;; partial register stall can be caused there.  Then we use movzx.
2323 (define_insn "*movqi_internal"
2324   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2325         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2326   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2327 {
2328   switch (get_attr_type (insn))
2329     {
2330     case TYPE_IMOVX:
2331       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2332       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2333     default:
2334       if (get_attr_mode (insn) == MODE_SI)
2335         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2336       else
2337         return "mov{b}\t{%1, %0|%0, %1}";
2338     }
2339 }
2340   [(set (attr "type")
2341      (cond [(and (eq_attr "alternative" "5")
2342                  (not (match_operand:QI 1 "aligned_operand" "")))
2343               (const_string "imovx")
2344             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2345                 (const_int 0))
2346               (const_string "imov")
2347             (and (eq_attr "alternative" "3")
2348                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2349                           (const_int 0))
2350                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2351                           (const_int 0))))
2352               (const_string "imov")
2353             (eq_attr "alternative" "3,5")
2354               (const_string "imovx")
2355             (and (ne (symbol_ref "TARGET_MOVX")
2356                      (const_int 0))
2357                  (eq_attr "alternative" "2"))
2358               (const_string "imovx")
2359            ]
2360            (const_string "imov")))
2361    (set (attr "mode")
2362       (cond [(eq_attr "alternative" "3,4,5")
2363                (const_string "SI")
2364              (eq_attr "alternative" "6")
2365                (const_string "QI")
2366              (eq_attr "type" "imovx")
2367                (const_string "SI")
2368              (and (eq_attr "type" "imov")
2369                   (and (eq_attr "alternative" "0,1")
2370                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2371                                 (const_int 0))
2372                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2373                                      (const_int 0))
2374                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2375                                      (const_int 0))))))
2376                (const_string "SI")
2377              ;; Avoid partial register stalls when not using QImode arithmetic
2378              (and (eq_attr "type" "imov")
2379                   (and (eq_attr "alternative" "0,1")
2380                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2381                                 (const_int 0))
2382                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2383                                 (const_int 0)))))
2384                (const_string "SI")
2385            ]
2386            (const_string "QI")))])
2387
2388 ;; Stores and loads of ax to arbitrary constant address.
2389 ;; We fake an second form of instruction to force reload to load address
2390 ;; into register when rax is not available
2391 (define_insn "*movabs<mode>_1"
2392   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2393         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2394   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2395   "@
2396    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2397    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2398   [(set_attr "type" "imov")
2399    (set_attr "modrm" "0,*")
2400    (set_attr "length_address" "8,0")
2401    (set_attr "length_immediate" "0,*")
2402    (set_attr "memory" "store")
2403    (set_attr "mode" "<MODE>")])
2404
2405 (define_insn "*movabs<mode>_2"
2406   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2407         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2408   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2409   "@
2410    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2411    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2412   [(set_attr "type" "imov")
2413    (set_attr "modrm" "0,*")
2414    (set_attr "length_address" "8,0")
2415    (set_attr "length_immediate" "0")
2416    (set_attr "memory" "load")
2417    (set_attr "mode" "<MODE>")])
2418
2419 (define_insn "*swap<mode>"
2420   [(set (match_operand:SWI48 0 "register_operand" "+r")
2421         (match_operand:SWI48 1 "register_operand" "+r"))
2422    (set (match_dup 1)
2423         (match_dup 0))]
2424   ""
2425   "xchg{<imodesuffix>}\t%1, %0"
2426   [(set_attr "type" "imov")
2427    (set_attr "mode" "<MODE>")
2428    (set_attr "pent_pair" "np")
2429    (set_attr "athlon_decode" "vector")
2430    (set_attr "amdfam10_decode" "double")
2431    (set_attr "bdver1_decode" "double")])
2432
2433 (define_insn "*swap<mode>_1"
2434   [(set (match_operand:SWI12 0 "register_operand" "+r")
2435         (match_operand:SWI12 1 "register_operand" "+r"))
2436    (set (match_dup 1)
2437         (match_dup 0))]
2438   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2439   "xchg{l}\t%k1, %k0"
2440   [(set_attr "type" "imov")
2441    (set_attr "mode" "SI")
2442    (set_attr "pent_pair" "np")
2443    (set_attr "athlon_decode" "vector")
2444    (set_attr "amdfam10_decode" "double")
2445    (set_attr "bdver1_decode" "double")])
2446
2447 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2448 ;; is disabled for AMDFAM10
2449 (define_insn "*swap<mode>_2"
2450   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2451         (match_operand:SWI12 1 "register_operand" "+<r>"))
2452    (set (match_dup 1)
2453         (match_dup 0))]
2454   "TARGET_PARTIAL_REG_STALL"
2455   "xchg{<imodesuffix>}\t%1, %0"
2456   [(set_attr "type" "imov")
2457    (set_attr "mode" "<MODE>")
2458    (set_attr "pent_pair" "np")
2459    (set_attr "athlon_decode" "vector")])
2460
2461 (define_expand "movstrict<mode>"
2462   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2463         (match_operand:SWI12 1 "general_operand" ""))]
2464   ""
2465 {
2466   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2467     FAIL;
2468   if (GET_CODE (operands[0]) == SUBREG
2469       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2470     FAIL;
2471   /* Don't generate memory->memory moves, go through a register */
2472   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2473     operands[1] = force_reg (<MODE>mode, operands[1]);
2474 })
2475
2476 (define_insn "*movstrict<mode>_1"
2477   [(set (strict_low_part
2478           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2479         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2480   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2481    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2482   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2483   [(set_attr "type" "imov")
2484    (set_attr "mode" "<MODE>")])
2485
2486 (define_insn "*movstrict<mode>_xor"
2487   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2488         (match_operand:SWI12 1 "const0_operand" ""))
2489    (clobber (reg:CC FLAGS_REG))]
2490   "reload_completed"
2491   "xor{<imodesuffix>}\t%0, %0"
2492   [(set_attr "type" "alu1")
2493    (set_attr "mode" "<MODE>")
2494    (set_attr "length_immediate" "0")])
2495
2496 (define_insn "*mov<mode>_extv_1"
2497   [(set (match_operand:SWI24 0 "register_operand" "=R")
2498         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2499                             (const_int 8)
2500                             (const_int 8)))]
2501   ""
2502   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2503   [(set_attr "type" "imovx")
2504    (set_attr "mode" "SI")])
2505
2506 (define_insn "*movqi_extv_1_rex64"
2507   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2508         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2509                          (const_int 8)
2510                          (const_int 8)))]
2511   "TARGET_64BIT"
2512 {
2513   switch (get_attr_type (insn))
2514     {
2515     case TYPE_IMOVX:
2516       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2517     default:
2518       return "mov{b}\t{%h1, %0|%0, %h1}";
2519     }
2520 }
2521   [(set (attr "type")
2522      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2523                         (ne (symbol_ref "TARGET_MOVX")
2524                             (const_int 0)))
2525         (const_string "imovx")
2526         (const_string "imov")))
2527    (set (attr "mode")
2528      (if_then_else (eq_attr "type" "imovx")
2529         (const_string "SI")
2530         (const_string "QI")))])
2531
2532 (define_insn "*movqi_extv_1"
2533   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2534         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2535                          (const_int 8)
2536                          (const_int 8)))]
2537   "!TARGET_64BIT"
2538 {
2539   switch (get_attr_type (insn))
2540     {
2541     case TYPE_IMOVX:
2542       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2543     default:
2544       return "mov{b}\t{%h1, %0|%0, %h1}";
2545     }
2546 }
2547   [(set (attr "type")
2548      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2549                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2550                              (ne (symbol_ref "TARGET_MOVX")
2551                                  (const_int 0))))
2552         (const_string "imovx")
2553         (const_string "imov")))
2554    (set (attr "mode")
2555      (if_then_else (eq_attr "type" "imovx")
2556         (const_string "SI")
2557         (const_string "QI")))])
2558
2559 (define_insn "*mov<mode>_extzv_1"
2560   [(set (match_operand:SWI48 0 "register_operand" "=R")
2561         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2562                             (const_int 8)
2563                             (const_int 8)))]
2564   ""
2565   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2566   [(set_attr "type" "imovx")
2567    (set_attr "mode" "SI")])
2568
2569 (define_insn "*movqi_extzv_2_rex64"
2570   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2571         (subreg:QI
2572           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2573                            (const_int 8)
2574                            (const_int 8)) 0))]
2575   "TARGET_64BIT"
2576 {
2577   switch (get_attr_type (insn))
2578     {
2579     case TYPE_IMOVX:
2580       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2581     default:
2582       return "mov{b}\t{%h1, %0|%0, %h1}";
2583     }
2584 }
2585   [(set (attr "type")
2586      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2587                         (ne (symbol_ref "TARGET_MOVX")
2588                             (const_int 0)))
2589         (const_string "imovx")
2590         (const_string "imov")))
2591    (set (attr "mode")
2592      (if_then_else (eq_attr "type" "imovx")
2593         (const_string "SI")
2594         (const_string "QI")))])
2595
2596 (define_insn "*movqi_extzv_2"
2597   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2598         (subreg:QI
2599           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2600                            (const_int 8)
2601                            (const_int 8)) 0))]
2602   "!TARGET_64BIT"
2603 {
2604   switch (get_attr_type (insn))
2605     {
2606     case TYPE_IMOVX:
2607       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2608     default:
2609       return "mov{b}\t{%h1, %0|%0, %h1}";
2610     }
2611 }
2612   [(set (attr "type")
2613      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2614                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2615                              (ne (symbol_ref "TARGET_MOVX")
2616                                  (const_int 0))))
2617         (const_string "imovx")
2618         (const_string "imov")))
2619    (set (attr "mode")
2620      (if_then_else (eq_attr "type" "imovx")
2621         (const_string "SI")
2622         (const_string "QI")))])
2623
2624 (define_expand "mov<mode>_insv_1"
2625   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2626                             (const_int 8)
2627                             (const_int 8))
2628         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2629
2630 (define_insn "*mov<mode>_insv_1_rex64"
2631   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2632                              (const_int 8)
2633                              (const_int 8))
2634         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2635   "TARGET_64BIT"
2636   "mov{b}\t{%b1, %h0|%h0, %b1}"
2637   [(set_attr "type" "imov")
2638    (set_attr "mode" "QI")])
2639
2640 (define_insn "*movsi_insv_1"
2641   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2642                          (const_int 8)
2643                          (const_int 8))
2644         (match_operand:SI 1 "general_operand" "Qmn"))]
2645   "!TARGET_64BIT"
2646   "mov{b}\t{%b1, %h0|%h0, %b1}"
2647   [(set_attr "type" "imov")
2648    (set_attr "mode" "QI")])
2649
2650 (define_insn "*movqi_insv_2"
2651   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2652                          (const_int 8)
2653                          (const_int 8))
2654         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2655                      (const_int 8)))]
2656   ""
2657   "mov{b}\t{%h1, %h0|%h0, %h1}"
2658   [(set_attr "type" "imov")
2659    (set_attr "mode" "QI")])
2660 \f
2661 ;; Floating point push instructions.
2662
2663 (define_insn "*pushtf"
2664   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2665         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2666   "TARGET_SSE2"
2667 {
2668   /* This insn should be already split before reg-stack.  */
2669   gcc_unreachable ();
2670 }
2671   [(set_attr "type" "multi")
2672    (set_attr "unit" "sse,*,*")
2673    (set_attr "mode" "TF,SI,SI")])
2674
2675 ;; %%% Kill this when call knows how to work this out.
2676 (define_split
2677   [(set (match_operand:TF 0 "push_operand" "")
2678         (match_operand:TF 1 "sse_reg_operand" ""))]
2679   "TARGET_SSE2 && reload_completed"
2680   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2681    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2682
2683 (define_insn "*pushxf"
2684   [(set (match_operand:XF 0 "push_operand" "=<,<")
2685         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2686   "optimize_function_for_speed_p (cfun)"
2687 {
2688   /* This insn should be already split before reg-stack.  */
2689   gcc_unreachable ();
2690 }
2691   [(set_attr "type" "multi")
2692    (set_attr "unit" "i387,*")
2693    (set_attr "mode" "XF,SI")])
2694
2695 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2696 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2697 ;; Pushing using integer instructions is longer except for constants
2698 ;; and direct memory references (assuming that any given constant is pushed
2699 ;; only once, but this ought to be handled elsewhere).
2700
2701 (define_insn "*pushxf_nointeger"
2702   [(set (match_operand:XF 0 "push_operand" "=X,X")
2703         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2704   "optimize_function_for_size_p (cfun)"
2705 {
2706   /* This insn should be already split before reg-stack.  */
2707   gcc_unreachable ();
2708 }
2709   [(set_attr "type" "multi")
2710    (set_attr "unit" "i387,*")
2711    (set_attr "mode" "XF,SI")])
2712
2713 ;; %%% Kill this when call knows how to work this out.
2714 (define_split
2715   [(set (match_operand:XF 0 "push_operand" "")
2716         (match_operand:XF 1 "fp_register_operand" ""))]
2717   "reload_completed"
2718   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2719    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2720   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2721
2722 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2723 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2724 ;; On the average, pushdf using integers can be still shorter.
2725
2726 (define_insn "*pushdf"
2727   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2728         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2729   ""
2730 {
2731   /* This insn should be already split before reg-stack.  */
2732   gcc_unreachable ();
2733 }
2734   [(set_attr "type" "multi")
2735    (set_attr "unit" "i387,*,*")
2736    (set_attr "mode" "DF,SI,DF")])
2737
2738 ;; %%% Kill this when call knows how to work this out.
2739 (define_split
2740   [(set (match_operand:DF 0 "push_operand" "")
2741         (match_operand:DF 1 "any_fp_register_operand" ""))]
2742   "reload_completed"
2743   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2744    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2745
2746 (define_insn "*pushsf_rex64"
2747   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2748         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2749   "TARGET_64BIT"
2750 {
2751   /* Anything else should be already split before reg-stack.  */
2752   gcc_assert (which_alternative == 1);
2753   return "push{q}\t%q1";
2754 }
2755   [(set_attr "type" "multi,push,multi")
2756    (set_attr "unit" "i387,*,*")
2757    (set_attr "mode" "SF,DI,SF")])
2758
2759 (define_insn "*pushsf"
2760   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2761         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2762   "!TARGET_64BIT"
2763 {
2764   /* Anything else should be already split before reg-stack.  */
2765   gcc_assert (which_alternative == 1);
2766   return "push{l}\t%1";
2767 }
2768   [(set_attr "type" "multi,push,multi")
2769    (set_attr "unit" "i387,*,*")
2770    (set_attr "mode" "SF,SI,SF")])
2771
2772 ;; %%% Kill this when call knows how to work this out.
2773 (define_split
2774   [(set (match_operand:SF 0 "push_operand" "")
2775         (match_operand:SF 1 "any_fp_register_operand" ""))]
2776   "reload_completed"
2777   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2780
2781 (define_split
2782   [(set (match_operand:SF 0 "push_operand" "")
2783         (match_operand:SF 1 "memory_operand" ""))]
2784   "reload_completed
2785    && (operands[2] = find_constant_src (insn))"
2786   [(set (match_dup 0) (match_dup 2))])
2787
2788 (define_split
2789   [(set (match_operand 0 "push_operand" "")
2790         (match_operand 1 "general_operand" ""))]
2791   "reload_completed
2792    && (GET_MODE (operands[0]) == TFmode
2793        || GET_MODE (operands[0]) == XFmode
2794        || GET_MODE (operands[0]) == DFmode)
2795    && !ANY_FP_REG_P (operands[1])"
2796   [(const_int 0)]
2797   "ix86_split_long_move (operands); DONE;")
2798 \f
2799 ;; Floating point move instructions.
2800
2801 (define_expand "movtf"
2802   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2803         (match_operand:TF 1 "nonimmediate_operand" ""))]
2804   "TARGET_SSE2"
2805 {
2806   ix86_expand_move (TFmode, operands);
2807   DONE;
2808 })
2809
2810 (define_expand "mov<mode>"
2811   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2812         (match_operand:X87MODEF 1 "general_operand" ""))]
2813   ""
2814   "ix86_expand_move (<MODE>mode, operands); DONE;")
2815
2816 (define_insn "*movtf_internal"
2817   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2818         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,F*r"))]
2819   "TARGET_SSE2
2820    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2821    && (!can_create_pseudo_p ()
2822        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2823        || GET_CODE (operands[1]) != CONST_DOUBLE
2824        || (optimize_function_for_size_p (cfun)
2825            && standard_sse_constant_p (operands[1])
2826            && !memory_operand (operands[0], TFmode))
2827        || (!TARGET_MEMORY_MISMATCH_STALL
2828            && memory_operand (operands[0], TFmode)))"
2829 {
2830   switch (which_alternative)
2831     {
2832     case 0:
2833     case 1:
2834       /* Handle misaligned load/store since we
2835          don't have movmisaligntf pattern. */
2836       if (misaligned_operand (operands[0], TFmode)
2837           || misaligned_operand (operands[1], TFmode))
2838         {
2839           if (get_attr_mode (insn) == MODE_V4SF)
2840             return "%vmovups\t{%1, %0|%0, %1}";
2841           else
2842             return "%vmovdqu\t{%1, %0|%0, %1}";
2843         }
2844       else
2845         {
2846           if (get_attr_mode (insn) == MODE_V4SF)
2847             return "%vmovaps\t{%1, %0|%0, %1}";
2848           else
2849             return "%vmovdqa\t{%1, %0|%0, %1}";
2850         }
2851
2852     case 2:
2853       return standard_sse_constant_opcode (insn, operands[1]);
2854
2855     case 3:
2856     case 4:
2857         return "#";
2858
2859     default:
2860       gcc_unreachable ();
2861     }
2862 }
2863   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2864    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2865    (set (attr "mode")
2866         (cond [(eq_attr "alternative" "0,2")
2867                  (if_then_else
2868                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2869                        (const_int 0))
2870                    (const_string "V4SF")
2871                    (const_string "TI"))
2872                (eq_attr "alternative" "1")
2873                  (if_then_else
2874                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2875                             (const_int 0))
2876                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2877                             (const_int 0)))
2878                    (const_string "V4SF")
2879                    (const_string "TI"))]
2880                (const_string "DI")))])
2881
2882 ;; Possible store forwarding (partial memory) stall in alternative 4.
2883 (define_insn "*movxf_internal"
2884   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2885         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2886   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2887    && (!can_create_pseudo_p ()
2888        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889        || GET_CODE (operands[1]) != CONST_DOUBLE
2890        || (optimize_function_for_size_p (cfun)
2891            && standard_80387_constant_p (operands[1]) > 0
2892            && !memory_operand (operands[0], XFmode))
2893        || (!TARGET_MEMORY_MISMATCH_STALL
2894            && memory_operand (operands[0], XFmode)))"
2895 {
2896   switch (which_alternative)
2897     {
2898     case 0:
2899     case 1:
2900       return output_387_reg_move (insn, operands);
2901
2902     case 2:
2903       return standard_80387_constant_opcode (operands[1]);
2904
2905     case 3:
2906     case 4:
2907       return "#";
2908
2909     default:
2910       gcc_unreachable ();
2911     }
2912 }
2913   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2914    (set_attr "mode" "XF,XF,XF,SI,SI")])
2915
2916 (define_insn "*movdf_internal_rex64"
2917   [(set (match_operand:DF 0 "nonimmediate_operand"
2918                 "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2919         (match_operand:DF 1 "general_operand"
2920                 "fm,f,G,rm,r ,F ,F ,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2921   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922    && (!can_create_pseudo_p ()
2923        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2924        || GET_CODE (operands[1]) != CONST_DOUBLE
2925        || (optimize_function_for_size_p (cfun)
2926            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2927                 && standard_80387_constant_p (operands[1]) > 0)
2928                || (TARGET_SSE2 && TARGET_SSE_MATH
2929                    && standard_sse_constant_p (operands[1]))))
2930        || memory_operand (operands[0], DFmode))"
2931 {
2932   switch (which_alternative)
2933     {
2934     case 0:
2935     case 1:
2936       return output_387_reg_move (insn, operands);
2937
2938     case 2:
2939       return standard_80387_constant_opcode (operands[1]);
2940
2941     case 3:
2942     case 4:
2943       return "mov{q}\t{%1, %0|%0, %1}";
2944
2945     case 5:
2946       return "movabs{q}\t{%1, %0|%0, %1}";
2947
2948     case 6:
2949       return "#";
2950
2951     case 7:
2952       return standard_sse_constant_opcode (insn, operands[1]);
2953
2954     case 8:
2955     case 9:
2956     case 10:
2957       switch (get_attr_mode (insn))
2958         {
2959         case MODE_V4SF:
2960           return "%vmovaps\t{%1, %0|%0, %1}";
2961         case MODE_V2DF:
2962           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2963             return "%vmovaps\t{%1, %0|%0, %1}";
2964           else
2965             return "%vmovapd\t{%1, %0|%0, %1}";
2966         case MODE_TI:
2967           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2968             return "%vmovaps\t{%1, %0|%0, %1}";
2969           else
2970             return "%vmovdqa\t{%1, %0|%0, %1}";
2971         case MODE_DI:
2972           return "%vmovq\t{%1, %0|%0, %1}";
2973         case MODE_DF:
2974           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2975             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2976           else
2977             return "%vmovsd\t{%1, %0|%0, %1}";
2978         case MODE_V1DF:
2979           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2980         case MODE_V2SF:
2981           return "%vmovlps\t{%1, %d0|%d0, %1}";
2982         default:
2983           gcc_unreachable ();
2984         }
2985
2986     case 11:
2987     case 12:
2988       /* Handle broken assemblers that require movd instead of movq.  */
2989       return "%vmovd\t{%1, %0|%0, %1}";
2990
2991     default:
2992       gcc_unreachable();
2993     }
2994 }
2995   [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2996    (set (attr "modrm")
2997      (if_then_else
2998        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2999          (const_string "0")
3000          (const_string "*")))
3001    (set (attr "length_immediate")
3002      (if_then_else
3003        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3004          (const_string "8")
3005          (const_string "*")))
3006    (set (attr "prefix")
3007      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3008        (const_string "orig")
3009        (const_string "maybe_vex")))
3010    (set (attr "prefix_data16")
3011      (if_then_else (eq_attr "mode" "V1DF")
3012        (const_string "1")
3013        (const_string "*")))
3014    (set (attr "mode")
3015         (cond [(eq_attr "alternative" "0,1,2")
3016                  (const_string "DF")
3017                (eq_attr "alternative" "3,4,5,6,11,12")
3018                  (const_string "DI")
3019
3020                /* For SSE1, we have many fewer alternatives.  */
3021                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3022                  (cond [(eq_attr "alternative" "7,8")
3023                           (const_string "V4SF")
3024                        ]
3025                    (const_string "V2SF"))
3026
3027                /* xorps is one byte shorter.  */
3028                (eq_attr "alternative" "7")
3029                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3030                             (const_int 0))
3031                           (const_string "V4SF")
3032                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3033                             (const_int 0))
3034                           (const_string "TI")
3035                        ]
3036                        (const_string "V2DF"))
3037
3038                /* For architectures resolving dependencies on
3039                   whole SSE registers use APD move to break dependency
3040                   chains, otherwise use short move to avoid extra work.
3041
3042                   movaps encodes one byte shorter.  */
3043                (eq_attr "alternative" "8")
3044                  (cond
3045                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3046                         (const_int 0))
3047                       (const_string "V4SF")
3048                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3049                         (const_int 0))
3050                       (const_string "V2DF")
3051                    ]
3052                    (const_string "DF"))
3053                /* For architectures resolving dependencies on register
3054                   parts we may avoid extra work to zero out upper part
3055                   of register.  */
3056                (eq_attr "alternative" "9")
3057                  (if_then_else
3058                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3059                        (const_int 0))
3060                    (const_string "V1DF")
3061                    (const_string "DF"))
3062               ]
3063               (const_string "DF")))])
3064
3065 ;; Possible store forwarding (partial memory) stall in alternative 4.
3066 (define_insn "*movdf_internal"
3067   [(set (match_operand:DF 0 "nonimmediate_operand"
3068                 "=f,m,f,?Yd*r ,!o   ,Y2*x,Y2*x,Y2*x,m  ")
3069         (match_operand:DF 1 "general_operand"
3070                 "fm,f,G,Yd*roF,FYd*r,C   ,Y2*x,m   ,Y2*x"))]
3071   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3072    && (!can_create_pseudo_p ()
3073        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3074        || GET_CODE (operands[1]) != CONST_DOUBLE
3075        || (optimize_function_for_size_p (cfun)
3076            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3077                 && standard_80387_constant_p (operands[1]) > 0)
3078                || (TARGET_SSE2 && TARGET_SSE_MATH
3079                    && standard_sse_constant_p (operands[1])))
3080            && !memory_operand (operands[0], DFmode))
3081        || (!TARGET_MEMORY_MISMATCH_STALL
3082            && memory_operand (operands[0], DFmode)))"
3083 {
3084   switch (which_alternative)
3085     {
3086     case 0:
3087     case 1:
3088       return output_387_reg_move (insn, operands);
3089
3090     case 2:
3091       return standard_80387_constant_opcode (operands[1]);
3092
3093     case 3:
3094     case 4:
3095       return "#";
3096
3097     case 5:
3098       return standard_sse_constant_opcode (insn, operands[1]);
3099
3100     case 6:
3101     case 7:
3102     case 8:
3103       switch (get_attr_mode (insn))
3104         {
3105         case MODE_V4SF:
3106           return "%vmovaps\t{%1, %0|%0, %1}";
3107         case MODE_V2DF:
3108           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3109             return "%vmovaps\t{%1, %0|%0, %1}";
3110           else
3111             return "%vmovapd\t{%1, %0|%0, %1}";
3112         case MODE_TI:
3113           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3114             return "%vmovaps\t{%1, %0|%0, %1}";
3115           else
3116             return "%vmovdqa\t{%1, %0|%0, %1}";
3117         case MODE_DI:
3118           return "%vmovq\t{%1, %0|%0, %1}";
3119         case MODE_DF:
3120           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3121             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3122           else
3123             return "%vmovsd\t{%1, %0|%0, %1}";
3124         case MODE_V1DF:
3125           if (TARGET_AVX && REG_P (operands[0]))
3126             return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3127           else
3128             return "%vmovlpd\t{%1, %0|%0, %1}";
3129         case MODE_V2SF:
3130           if (TARGET_AVX && REG_P (operands[0]))
3131             return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3132           else
3133             return "%vmovlps\t{%1, %0|%0, %1}";
3134         default:
3135           gcc_unreachable ();
3136         }
3137
3138     default:
3139       gcc_unreachable ();
3140     }
3141 }
3142   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3143    (set (attr "prefix")
3144      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3145        (const_string "orig")
3146        (const_string "maybe_vex")))
3147    (set (attr "prefix_data16")
3148      (if_then_else (eq_attr "mode" "V1DF")
3149        (const_string "1")
3150        (const_string "*")))
3151    (set (attr "mode")
3152         (cond [(eq_attr "alternative" "0,1,2")
3153                  (const_string "DF")
3154                (eq_attr "alternative" "3,4")
3155                  (const_string "SI")
3156
3157                /* For SSE1, we have many fewer alternatives.  */
3158                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3159                  (cond [(eq_attr "alternative" "5,6")
3160                           (const_string "V4SF")
3161                        ]
3162                    (const_string "V2SF"))
3163
3164                /* xorps is one byte shorter.  */
3165                (eq_attr "alternative" "5")
3166                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3167                             (const_int 0))
3168                           (const_string "V4SF")
3169                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3170                             (const_int 0))
3171                           (const_string "TI")
3172                        ]
3173                        (const_string "V2DF"))
3174
3175                /* For architectures resolving dependencies on
3176                   whole SSE registers use APD move to break dependency
3177                   chains, otherwise use short move to avoid extra work.
3178
3179                   movaps encodes one byte shorter.  */
3180                (eq_attr "alternative" "6")
3181                  (cond
3182                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3183                         (const_int 0))
3184                       (const_string "V4SF")
3185                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3186                         (const_int 0))
3187                       (const_string "V2DF")
3188                    ]
3189                    (const_string "DF"))
3190                /* For architectures resolving dependencies on register
3191                   parts we may avoid extra work to zero out upper part
3192                   of register.  */
3193                (eq_attr "alternative" "7")
3194                  (if_then_else
3195                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3196                        (const_int 0))
3197                    (const_string "V1DF")
3198                    (const_string "DF"))
3199               ]
3200               (const_string "DF")))])
3201
3202 (define_insn "*movsf_internal"
3203   [(set (match_operand:SF 0 "nonimmediate_operand"
3204           "=f,m,f,?r ,?m,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3205         (match_operand:SF 1 "general_operand"
3206           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3207   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3208    && (!can_create_pseudo_p ()
3209        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3210        || GET_CODE (operands[1]) != CONST_DOUBLE
3211        || (optimize_function_for_size_p (cfun)
3212            && ((!TARGET_SSE_MATH
3213                 && standard_80387_constant_p (operands[1]) > 0)
3214                || (TARGET_SSE_MATH
3215                    && standard_sse_constant_p (operands[1]))))
3216        || memory_operand (operands[0], SFmode))"
3217 {
3218   switch (which_alternative)
3219     {
3220     case 0:
3221     case 1:
3222       return output_387_reg_move (insn, operands);
3223
3224     case 2:
3225       return standard_80387_constant_opcode (operands[1]);
3226
3227     case 3:
3228     case 4:
3229       return "mov{l}\t{%1, %0|%0, %1}";
3230
3231     case 5:
3232       return standard_sse_constant_opcode (insn, operands[1]);
3233
3234     case 6:
3235       if (get_attr_mode (insn) == MODE_V4SF)
3236         return "%vmovaps\t{%1, %0|%0, %1}";
3237       else
3238         return "%vmovss\t{%1, %d0|%d0, %1}";
3239     case 7:
3240       if (TARGET_AVX && REG_P (operands[1]))
3241         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3242       else
3243         return "%vmovss\t{%1, %0|%0, %1}";
3244     case 8:
3245       return "%vmovss\t{%1, %0|%0, %1}";
3246
3247     case 9: case 10: case 14: case 15:
3248       return "movd\t{%1, %0|%0, %1}";
3249
3250     case 11:
3251       return "movq\t{%1, %0|%0, %1}";
3252
3253     case 12: case 13:
3254       return "%vmovd\t{%1, %0|%0, %1}";
3255
3256     default:
3257       gcc_unreachable ();
3258     }
3259 }
3260   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3261    (set (attr "prefix")
3262      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3263        (const_string "maybe_vex")
3264        (const_string "orig")))
3265    (set (attr "mode")
3266         (cond [(eq_attr "alternative" "3,4,9,10")
3267                  (const_string "SI")
3268                (eq_attr "alternative" "5")
3269                  (if_then_else
3270                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3271                                  (const_int 0))
3272                              (ne (symbol_ref "TARGET_SSE2")
3273                                  (const_int 0)))
3274                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3275                             (const_int 0)))
3276                    (const_string "TI")
3277                    (const_string "V4SF"))
3278                /* For architectures resolving dependencies on
3279                   whole SSE registers use APS move to break dependency
3280                   chains, otherwise use short move to avoid extra work.
3281
3282                   Do the same for architectures resolving dependencies on
3283                   the parts.  While in DF mode it is better to always handle
3284                   just register parts, the SF mode is different due to lack
3285                   of instructions to load just part of the register.  It is
3286                   better to maintain the whole registers in single format
3287                   to avoid problems on using packed logical operations.  */
3288                (eq_attr "alternative" "6")
3289                  (if_then_else
3290                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3291                             (const_int 0))
3292                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3293                             (const_int 0)))
3294                    (const_string "V4SF")
3295                    (const_string "SF"))
3296                (eq_attr "alternative" "11")
3297                  (const_string "DI")]
3298                (const_string "SF")))])
3299
3300 (define_split
3301   [(set (match_operand 0 "any_fp_register_operand" "")
3302         (match_operand 1 "memory_operand" ""))]
3303   "reload_completed
3304    && (GET_MODE (operands[0]) == TFmode
3305        || GET_MODE (operands[0]) == XFmode
3306        || GET_MODE (operands[0]) == DFmode
3307        || GET_MODE (operands[0]) == SFmode)
3308    && (operands[2] = find_constant_src (insn))"
3309   [(set (match_dup 0) (match_dup 2))]
3310 {
3311   rtx c = operands[2];
3312   int r = REGNO (operands[0]);
3313
3314   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3315       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3316     FAIL;
3317 })
3318
3319 (define_split
3320   [(set (match_operand 0 "any_fp_register_operand" "")
3321         (float_extend (match_operand 1 "memory_operand" "")))]
3322   "reload_completed
3323    && (GET_MODE (operands[0]) == TFmode
3324        || GET_MODE (operands[0]) == XFmode
3325        || GET_MODE (operands[0]) == DFmode)
3326    && (operands[2] = find_constant_src (insn))"
3327   [(set (match_dup 0) (match_dup 2))]
3328 {
3329   rtx c = operands[2];
3330   int r = REGNO (operands[0]);
3331
3332   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3333       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3334     FAIL;
3335 })
3336
3337 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3338 (define_split
3339   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3340         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3341   "reload_completed
3342    && (standard_80387_constant_p (operands[1]) == 8
3343        || standard_80387_constant_p (operands[1]) == 9)"
3344   [(set (match_dup 0)(match_dup 1))
3345    (set (match_dup 0)
3346         (neg:X87MODEF (match_dup 0)))]
3347 {
3348   REAL_VALUE_TYPE r;
3349
3350   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3351   if (real_isnegzero (&r))
3352     operands[1] = CONST0_RTX (<MODE>mode);
3353   else
3354     operands[1] = CONST1_RTX (<MODE>mode);
3355 })
3356
3357 (define_split
3358   [(set (match_operand 0 "nonimmediate_operand" "")
3359         (match_operand 1 "general_operand" ""))]
3360   "reload_completed
3361    && (GET_MODE (operands[0]) == TFmode
3362        || GET_MODE (operands[0]) == XFmode
3363        || GET_MODE (operands[0]) == DFmode)
3364    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3365   [(const_int 0)]
3366   "ix86_split_long_move (operands); DONE;")
3367
3368 (define_insn "swapxf"
3369   [(set (match_operand:XF 0 "register_operand" "+f")
3370         (match_operand:XF 1 "register_operand" "+f"))
3371    (set (match_dup 1)
3372         (match_dup 0))]
3373   "TARGET_80387"
3374 {
3375   if (STACK_TOP_P (operands[0]))
3376     return "fxch\t%1";
3377   else
3378     return "fxch\t%0";
3379 }
3380   [(set_attr "type" "fxch")
3381    (set_attr "mode" "XF")])
3382
3383 (define_insn "*swap<mode>"
3384   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3385         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3386    (set (match_dup 1)
3387         (match_dup 0))]
3388   "TARGET_80387 || reload_completed"
3389 {
3390   if (STACK_TOP_P (operands[0]))
3391     return "fxch\t%1";
3392   else
3393     return "fxch\t%0";
3394 }
3395   [(set_attr "type" "fxch")
3396    (set_attr "mode" "<MODE>")])
3397 \f
3398 ;; Zero extension instructions
3399
3400 (define_expand "zero_extendsidi2"
3401   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3402         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3403   ""
3404 {
3405   if (!TARGET_64BIT)
3406     {
3407       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3408       DONE;
3409     }
3410 })
3411
3412 (define_insn "*zero_extendsidi2_rex64"
3413   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3414         (zero_extend:DI
3415          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3416   "TARGET_64BIT"
3417   "@
3418    mov\t{%k1, %k0|%k0, %k1}
3419    #
3420    movd\t{%1, %0|%0, %1}
3421    movd\t{%1, %0|%0, %1}
3422    %vmovd\t{%1, %0|%0, %1}
3423    %vmovd\t{%1, %0|%0, %1}"
3424   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3425    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3426    (set_attr "prefix_0f" "0,*,*,*,*,*")
3427    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3428
3429 (define_split
3430   [(set (match_operand:DI 0 "memory_operand" "")
3431         (zero_extend:DI (match_dup 0)))]
3432   "TARGET_64BIT"
3433   [(set (match_dup 4) (const_int 0))]
3434   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3435
3436 ;; %%% Kill me once multi-word ops are sane.
3437 (define_insn "zero_extendsidi2_1"
3438   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3439         (zero_extend:DI
3440          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3441    (clobber (reg:CC FLAGS_REG))]
3442   "!TARGET_64BIT"
3443   "@
3444    #
3445    #
3446    #
3447    movd\t{%1, %0|%0, %1}
3448    movd\t{%1, %0|%0, %1}
3449    %vmovd\t{%1, %0|%0, %1}
3450    %vmovd\t{%1, %0|%0, %1}"
3451   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3452    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3453    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3454
3455 (define_split
3456   [(set (match_operand:DI 0 "register_operand" "")
3457         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3458    (clobber (reg:CC FLAGS_REG))]
3459   "!TARGET_64BIT && reload_completed
3460    && true_regnum (operands[0]) == true_regnum (operands[1])"
3461   [(set (match_dup 4) (const_int 0))]
3462   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3463
3464 (define_split
3465   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3466         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3467    (clobber (reg:CC FLAGS_REG))]
3468   "!TARGET_64BIT && reload_completed
3469    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3470   [(set (match_dup 3) (match_dup 1))
3471    (set (match_dup 4) (const_int 0))]
3472   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3473
3474 (define_insn "zero_extend<mode>di2"
3475   [(set (match_operand:DI 0 "register_operand" "=r")
3476         (zero_extend:DI
3477          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3478   "TARGET_64BIT"
3479   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3480   [(set_attr "type" "imovx")
3481    (set_attr "mode" "SI")])
3482
3483 (define_expand "zero_extendhisi2"
3484   [(set (match_operand:SI 0 "register_operand" "")
3485         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3486   ""
3487 {
3488   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3489     {
3490       operands[1] = force_reg (HImode, operands[1]);
3491       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3492       DONE;
3493     }
3494 })
3495
3496 (define_insn_and_split "zero_extendhisi2_and"
3497   [(set (match_operand:SI 0 "register_operand" "=r")
3498         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3499    (clobber (reg:CC FLAGS_REG))]
3500   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3501   "#"
3502   "&& reload_completed"
3503   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3504               (clobber (reg:CC FLAGS_REG))])]
3505   ""
3506   [(set_attr "type" "alu1")
3507    (set_attr "mode" "SI")])
3508
3509 (define_insn "*zero_extendhisi2_movzwl"
3510   [(set (match_operand:SI 0 "register_operand" "=r")
3511         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3512   "!TARGET_ZERO_EXTEND_WITH_AND
3513    || optimize_function_for_size_p (cfun)"
3514   "movz{wl|x}\t{%1, %0|%0, %1}"
3515   [(set_attr "type" "imovx")
3516    (set_attr "mode" "SI")])
3517
3518 (define_expand "zero_extendqi<mode>2"
3519   [(parallel
3520     [(set (match_operand:SWI24 0 "register_operand" "")
3521           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3522      (clobber (reg:CC FLAGS_REG))])])
3523
3524 (define_insn "*zero_extendqi<mode>2_and"
3525   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3526         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3527    (clobber (reg:CC FLAGS_REG))]
3528   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3529   "#"
3530   [(set_attr "type" "alu1")
3531    (set_attr "mode" "<MODE>")])
3532
3533 ;; When source and destination does not overlap, clear destination
3534 ;; first and then do the movb
3535 (define_split
3536   [(set (match_operand:SWI24 0 "register_operand" "")
3537         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3538    (clobber (reg:CC FLAGS_REG))]
3539   "reload_completed
3540    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3541    && ANY_QI_REG_P (operands[0])
3542    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3543    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3544   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3545 {
3546   operands[2] = gen_lowpart (QImode, operands[0]);
3547   ix86_expand_clear (operands[0]);
3548 })
3549
3550 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3551   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3552         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3553    (clobber (reg:CC FLAGS_REG))]
3554   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3555   "#"
3556   [(set_attr "type" "imovx,alu1")
3557    (set_attr "mode" "<MODE>")])
3558
3559 ;; For the movzbl case strip only the clobber
3560 (define_split
3561   [(set (match_operand:SWI24 0 "register_operand" "")
3562         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3563    (clobber (reg:CC FLAGS_REG))]
3564   "reload_completed
3565    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3566    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3567   [(set (match_dup 0)
3568         (zero_extend:SWI24 (match_dup 1)))])
3569
3570 ; zero extend to SImode to avoid partial register stalls
3571 (define_insn "*zero_extendqi<mode>2_movzbl"
3572   [(set (match_operand:SWI24 0 "register_operand" "=r")
3573         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3574   "reload_completed
3575    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3576   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3577   [(set_attr "type" "imovx")
3578    (set_attr "mode" "SI")])
3579
3580 ;; Rest is handled by single and.
3581 (define_split
3582   [(set (match_operand:SWI24 0 "register_operand" "")
3583         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3584    (clobber (reg:CC FLAGS_REG))]
3585   "reload_completed
3586    && true_regnum (operands[0]) == true_regnum (operands[1])"
3587   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3588               (clobber (reg:CC FLAGS_REG))])])
3589 \f
3590 ;; Sign extension instructions
3591
3592 (define_expand "extendsidi2"
3593   [(set (match_operand:DI 0 "register_operand" "")
3594         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3595   ""
3596 {
3597   if (!TARGET_64BIT)
3598     {
3599       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3600       DONE;
3601     }
3602 })
3603
3604 (define_insn "*extendsidi2_rex64"
3605   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3606         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3607   "TARGET_64BIT"
3608   "@
3609    {cltq|cdqe}
3610    movs{lq|x}\t{%1, %0|%0, %1}"
3611   [(set_attr "type" "imovx")
3612    (set_attr "mode" "DI")
3613    (set_attr "prefix_0f" "0")
3614    (set_attr "modrm" "0,1")])
3615
3616 (define_insn "extendsidi2_1"
3617   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3618         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3619    (clobber (reg:CC FLAGS_REG))
3620    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3621   "!TARGET_64BIT"
3622   "#")
3623
3624 ;; Extend to memory case when source register does die.
3625 (define_split
3626   [(set (match_operand:DI 0 "memory_operand" "")
3627         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3628    (clobber (reg:CC FLAGS_REG))
3629    (clobber (match_operand:SI 2 "register_operand" ""))]
3630   "(reload_completed
3631     && dead_or_set_p (insn, operands[1])
3632     && !reg_mentioned_p (operands[1], operands[0]))"
3633   [(set (match_dup 3) (match_dup 1))
3634    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3635               (clobber (reg:CC FLAGS_REG))])
3636    (set (match_dup 4) (match_dup 1))]
3637   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3638
3639 ;; Extend to memory case when source register does not die.
3640 (define_split
3641   [(set (match_operand:DI 0 "memory_operand" "")
3642         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3643    (clobber (reg:CC FLAGS_REG))
3644    (clobber (match_operand:SI 2 "register_operand" ""))]
3645   "reload_completed"
3646   [(const_int 0)]
3647 {
3648   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3649
3650   emit_move_insn (operands[3], operands[1]);
3651
3652   /* Generate a cltd if possible and doing so it profitable.  */
3653   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3654       && true_regnum (operands[1]) == AX_REG
3655       && true_regnum (operands[2]) == DX_REG)
3656     {
3657       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3658     }
3659   else
3660     {
3661       emit_move_insn (operands[2], operands[1]);
3662       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3663     }
3664   emit_move_insn (operands[4], operands[2]);
3665   DONE;
3666 })
3667
3668 ;; Extend to register case.  Optimize case where source and destination
3669 ;; registers match and cases where we can use cltd.
3670 (define_split
3671   [(set (match_operand:DI 0 "register_operand" "")
3672         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3673    (clobber (reg:CC FLAGS_REG))
3674    (clobber (match_scratch:SI 2 ""))]
3675   "reload_completed"
3676   [(const_int 0)]
3677 {
3678   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3679
3680   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3681     emit_move_insn (operands[3], operands[1]);
3682
3683   /* Generate a cltd if possible and doing so it profitable.  */
3684   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3685       && true_regnum (operands[3]) == AX_REG
3686       && true_regnum (operands[4]) == DX_REG)
3687     {
3688       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3689       DONE;
3690     }
3691
3692   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3693     emit_move_insn (operands[4], operands[1]);
3694
3695   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3696   DONE;
3697 })
3698
3699 (define_insn "extend<mode>di2"
3700   [(set (match_operand:DI 0 "register_operand" "=r")
3701         (sign_extend:DI
3702          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3703   "TARGET_64BIT"
3704   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3705   [(set_attr "type" "imovx")
3706    (set_attr "mode" "DI")])
3707
3708 (define_insn "extendhisi2"
3709   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3710         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3711   ""
3712 {
3713   switch (get_attr_prefix_0f (insn))
3714     {
3715     case 0:
3716       return "{cwtl|cwde}";
3717     default:
3718       return "movs{wl|x}\t{%1, %0|%0, %1}";
3719     }
3720 }
3721   [(set_attr "type" "imovx")
3722    (set_attr "mode" "SI")
3723    (set (attr "prefix_0f")
3724      ;; movsx is short decodable while cwtl is vector decoded.
3725      (if_then_else (and (eq_attr "cpu" "!k6")
3726                         (eq_attr "alternative" "0"))
3727         (const_string "0")
3728         (const_string "1")))
3729    (set (attr "modrm")
3730      (if_then_else (eq_attr "prefix_0f" "0")
3731         (const_string "0")
3732         (const_string "1")))])
3733
3734 (define_insn "*extendhisi2_zext"
3735   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3736         (zero_extend:DI
3737          (sign_extend:SI
3738           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3739   "TARGET_64BIT"
3740 {
3741   switch (get_attr_prefix_0f (insn))
3742     {
3743     case 0:
3744       return "{cwtl|cwde}";
3745     default:
3746       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3747     }
3748 }
3749   [(set_attr "type" "imovx")
3750    (set_attr "mode" "SI")
3751    (set (attr "prefix_0f")
3752      ;; movsx is short decodable while cwtl is vector decoded.
3753      (if_then_else (and (eq_attr "cpu" "!k6")
3754                         (eq_attr "alternative" "0"))
3755         (const_string "0")
3756         (const_string "1")))
3757    (set (attr "modrm")
3758      (if_then_else (eq_attr "prefix_0f" "0")
3759         (const_string "0")
3760         (const_string "1")))])
3761
3762 (define_insn "extendqisi2"
3763   [(set (match_operand:SI 0 "register_operand" "=r")
3764         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3765   ""
3766   "movs{bl|x}\t{%1, %0|%0, %1}"
3767    [(set_attr "type" "imovx")
3768     (set_attr "mode" "SI")])
3769
3770 (define_insn "*extendqisi2_zext"
3771   [(set (match_operand:DI 0 "register_operand" "=r")
3772         (zero_extend:DI
3773           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3774   "TARGET_64BIT"
3775   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3776    [(set_attr "type" "imovx")
3777     (set_attr "mode" "SI")])
3778
3779 (define_insn "extendqihi2"
3780   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3781         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3782   ""
3783 {
3784   switch (get_attr_prefix_0f (insn))
3785     {
3786     case 0:
3787       return "{cbtw|cbw}";
3788     default:
3789       return "movs{bw|x}\t{%1, %0|%0, %1}";
3790     }
3791 }
3792   [(set_attr "type" "imovx")
3793    (set_attr "mode" "HI")
3794    (set (attr "prefix_0f")
3795      ;; movsx is short decodable while cwtl is vector decoded.
3796      (if_then_else (and (eq_attr "cpu" "!k6")
3797                         (eq_attr "alternative" "0"))
3798         (const_string "0")
3799         (const_string "1")))
3800    (set (attr "modrm")
3801      (if_then_else (eq_attr "prefix_0f" "0")
3802         (const_string "0")
3803         (const_string "1")))])
3804 \f
3805 ;; Conversions between float and double.
3806
3807 ;; These are all no-ops in the model used for the 80387.
3808 ;; So just emit moves.
3809
3810 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3811 (define_split
3812   [(set (match_operand:DF 0 "push_operand" "")
3813         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3814   "reload_completed"
3815   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3816    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3817
3818 (define_split
3819   [(set (match_operand:XF 0 "push_operand" "")
3820         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3821   "reload_completed"
3822   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3823    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3824   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3825
3826 (define_expand "extendsfdf2"
3827   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3828         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3829   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3830 {
3831   /* ??? Needed for compress_float_constant since all fp constants
3832      are TARGET_LEGITIMATE_CONSTANT_P.  */
3833   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3834     {
3835       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3836           && standard_80387_constant_p (operands[1]) > 0)
3837         {
3838           operands[1] = simplify_const_unary_operation
3839             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3840           emit_move_insn_1 (operands[0], operands[1]);
3841           DONE;
3842         }
3843       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3844     }
3845 })
3846
3847 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3848    cvtss2sd:
3849       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3850       cvtps2pd xmm2,xmm1
3851    We do the conversion post reload to avoid producing of 128bit spills
3852    that might lead to ICE on 32bit target.  The sequence unlikely combine
3853    anyway.  */
3854 (define_split
3855   [(set (match_operand:DF 0 "register_operand" "")
3856         (float_extend:DF
3857           (match_operand:SF 1 "nonimmediate_operand" "")))]
3858   "TARGET_USE_VECTOR_FP_CONVERTS
3859    && optimize_insn_for_speed_p ()
3860    && reload_completed && SSE_REG_P (operands[0])"
3861    [(set (match_dup 2)
3862          (float_extend:V2DF
3863            (vec_select:V2SF
3864              (match_dup 3)
3865              (parallel [(const_int 0) (const_int 1)]))))]
3866 {
3867   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3868   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3869   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3870      Try to avoid move when unpacking can be done in source.  */
3871   if (REG_P (operands[1]))
3872     {
3873       /* If it is unsafe to overwrite upper half of source, we need
3874          to move to destination and unpack there.  */
3875       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3876            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3877           && true_regnum (operands[0]) != true_regnum (operands[1]))
3878         {
3879           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3880           emit_move_insn (tmp, operands[1]);
3881         }
3882       else
3883         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3884       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3885                                              operands[3]));
3886     }
3887   else
3888     emit_insn (gen_vec_setv4sf_0 (operands[3],
3889                                   CONST0_RTX (V4SFmode), operands[1]));
3890 })
3891
3892 (define_insn "*extendsfdf2_mixed"
3893   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3894         (float_extend:DF
3895           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3896   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3897 {
3898   switch (which_alternative)
3899     {
3900     case 0:
3901     case 1:
3902       return output_387_reg_move (insn, operands);
3903
3904     case 2:
3905       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3906
3907     default:
3908       gcc_unreachable ();
3909     }
3910 }
3911   [(set_attr "type" "fmov,fmov,ssecvt")
3912    (set_attr "prefix" "orig,orig,maybe_vex")
3913    (set_attr "mode" "SF,XF,DF")])
3914
3915 (define_insn "*extendsfdf2_sse"
3916   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3917         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3918   "TARGET_SSE2 && TARGET_SSE_MATH"
3919   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3920   [(set_attr "type" "ssecvt")
3921    (set_attr "prefix" "maybe_vex")
3922    (set_attr "mode" "DF")])
3923
3924 (define_insn "*extendsfdf2_i387"
3925   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3926         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3927   "TARGET_80387"
3928   "* return output_387_reg_move (insn, operands);"
3929   [(set_attr "type" "fmov")
3930    (set_attr "mode" "SF,XF")])
3931
3932 (define_expand "extend<mode>xf2"
3933   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3934         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3935   "TARGET_80387"
3936 {
3937   /* ??? Needed for compress_float_constant since all fp constants
3938      are TARGET_LEGITIMATE_CONSTANT_P.  */
3939   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3940     {
3941       if (standard_80387_constant_p (operands[1]) > 0)
3942         {
3943           operands[1] = simplify_const_unary_operation
3944             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3945           emit_move_insn_1 (operands[0], operands[1]);
3946           DONE;
3947         }
3948       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3949     }
3950 })
3951
3952 (define_insn "*extend<mode>xf2_i387"
3953   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3954         (float_extend:XF
3955           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3956   "TARGET_80387"
3957   "* return output_387_reg_move (insn, operands);"
3958   [(set_attr "type" "fmov")
3959    (set_attr "mode" "<MODE>,XF")])
3960
3961 ;; %%% This seems bad bad news.
3962 ;; This cannot output into an f-reg because there is no way to be sure
3963 ;; of truncating in that case.  Otherwise this is just like a simple move
3964 ;; insn.  So we pretend we can output to a reg in order to get better
3965 ;; register preferencing, but we really use a stack slot.
3966
3967 ;; Conversion from DFmode to SFmode.
3968
3969 (define_expand "truncdfsf2"
3970   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3971         (float_truncate:SF
3972           (match_operand:DF 1 "nonimmediate_operand" "")))]
3973   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3974 {
3975   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3976     ;
3977   else if (flag_unsafe_math_optimizations)
3978     ;
3979   else
3980     {
3981       enum ix86_stack_slot slot = (virtuals_instantiated
3982                                    ? SLOT_TEMP
3983                                    : SLOT_VIRTUAL);
3984       rtx temp = assign_386_stack_local (SFmode, slot);
3985       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3986       DONE;
3987     }
3988 })
3989
3990 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3991    cvtsd2ss:
3992       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3993       cvtpd2ps xmm2,xmm1
3994    We do the conversion post reload to avoid producing of 128bit spills
3995    that might lead to ICE on 32bit target.  The sequence unlikely combine
3996    anyway.  */
3997 (define_split
3998   [(set (match_operand:SF 0 "register_operand" "")
3999         (float_truncate:SF
4000           (match_operand:DF 1 "nonimmediate_operand" "")))]
4001   "TARGET_USE_VECTOR_FP_CONVERTS
4002    && optimize_insn_for_speed_p ()
4003    && reload_completed && SSE_REG_P (operands[0])"
4004    [(set (match_dup 2)
4005          (vec_concat:V4SF
4006            (float_truncate:V2SF
4007              (match_dup 4))
4008            (match_dup 3)))]
4009 {
4010   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4011   operands[3] = CONST0_RTX (V2SFmode);
4012   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4013   /* Use movsd for loading from memory, unpcklpd for registers.
4014      Try to avoid move when unpacking can be done in source, or SSE3
4015      movddup is available.  */
4016   if (REG_P (operands[1]))
4017     {
4018       if (!TARGET_SSE3
4019           && true_regnum (operands[0]) != true_regnum (operands[1])
4020           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4021               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4022         {
4023           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4024           emit_move_insn (tmp, operands[1]);
4025           operands[1] = tmp;
4026         }
4027       else if (!TARGET_SSE3)
4028         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4029       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4030     }
4031   else
4032     emit_insn (gen_sse2_loadlpd (operands[4],
4033                                  CONST0_RTX (V2DFmode), operands[1]));
4034 })
4035
4036 (define_expand "truncdfsf2_with_temp"
4037   [(parallel [(set (match_operand:SF 0 "" "")
4038                    (float_truncate:SF (match_operand:DF 1 "" "")))
4039               (clobber (match_operand:SF 2 "" ""))])])
4040
4041 (define_insn "*truncdfsf_fast_mixed"
4042   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4043         (float_truncate:SF
4044           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4045   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4046 {
4047   switch (which_alternative)
4048     {
4049     case 0:
4050       return output_387_reg_move (insn, operands);
4051     case 1:
4052       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4053     default:
4054       gcc_unreachable ();
4055     }
4056 }
4057   [(set_attr "type" "fmov,ssecvt")
4058    (set_attr "prefix" "orig,maybe_vex")
4059    (set_attr "mode" "SF")])
4060
4061 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4062 ;; because nothing we do here is unsafe.
4063 (define_insn "*truncdfsf_fast_sse"
4064   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4065         (float_truncate:SF
4066           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4067   "TARGET_SSE2 && TARGET_SSE_MATH"
4068   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4069   [(set_attr "type" "ssecvt")
4070    (set_attr "prefix" "maybe_vex")
4071    (set_attr "mode" "SF")])
4072
4073 (define_insn "*truncdfsf_fast_i387"
4074   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4075         (float_truncate:SF
4076           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4077   "TARGET_80387 && flag_unsafe_math_optimizations"
4078   "* return output_387_reg_move (insn, operands);"
4079   [(set_attr "type" "fmov")
4080    (set_attr "mode" "SF")])
4081
4082 (define_insn "*truncdfsf_mixed"
4083   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4084         (float_truncate:SF
4085           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4086    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4087   "TARGET_MIX_SSE_I387"
4088 {
4089   switch (which_alternative)
4090     {
4091     case 0:
4092       return output_387_reg_move (insn, operands);
4093     case 1:
4094       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4095
4096     default:
4097       return "#";
4098     }
4099 }
4100   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4101    (set_attr "unit" "*,*,i387,i387,i387")
4102    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4103    (set_attr "mode" "SF")])
4104
4105 (define_insn "*truncdfsf_i387"
4106   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4107         (float_truncate:SF
4108           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4109    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4110   "TARGET_80387"
4111 {
4112   switch (which_alternative)
4113     {
4114     case 0:
4115       return output_387_reg_move (insn, operands);
4116
4117     default:
4118       return "#";
4119     }
4120 }
4121   [(set_attr "type" "fmov,multi,multi,multi")
4122    (set_attr "unit" "*,i387,i387,i387")
4123    (set_attr "mode" "SF")])
4124
4125 (define_insn "*truncdfsf2_i387_1"
4126   [(set (match_operand:SF 0 "memory_operand" "=m")
4127         (float_truncate:SF
4128           (match_operand:DF 1 "register_operand" "f")))]
4129   "TARGET_80387
4130    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4131    && !TARGET_MIX_SSE_I387"
4132   "* return output_387_reg_move (insn, operands);"
4133   [(set_attr "type" "fmov")
4134    (set_attr "mode" "SF")])
4135
4136 (define_split
4137   [(set (match_operand:SF 0 "register_operand" "")
4138         (float_truncate:SF
4139          (match_operand:DF 1 "fp_register_operand" "")))
4140    (clobber (match_operand 2 "" ""))]
4141   "reload_completed"
4142   [(set (match_dup 2) (match_dup 1))
4143    (set (match_dup 0) (match_dup 2))]
4144   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4145
4146 ;; Conversion from XFmode to {SF,DF}mode
4147
4148 (define_expand "truncxf<mode>2"
4149   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4150                    (float_truncate:MODEF
4151                      (match_operand:XF 1 "register_operand" "")))
4152               (clobber (match_dup 2))])]
4153   "TARGET_80387"
4154 {
4155   if (flag_unsafe_math_optimizations)
4156     {
4157       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4158       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4159       if (reg != operands[0])
4160         emit_move_insn (operands[0], reg);
4161       DONE;
4162     }
4163   else
4164     {
4165       enum ix86_stack_slot slot = (virtuals_instantiated
4166                                    ? SLOT_TEMP
4167                                    : SLOT_VIRTUAL);
4168       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4169     }
4170 })
4171
4172 (define_insn "*truncxfsf2_mixed"
4173   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4174         (float_truncate:SF
4175           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4176    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4177   "TARGET_80387"
4178 {
4179   gcc_assert (!which_alternative);
4180   return output_387_reg_move (insn, operands);
4181 }
4182   [(set_attr "type" "fmov,multi,multi,multi")
4183    (set_attr "unit" "*,i387,i387,i387")
4184    (set_attr "mode" "SF")])
4185
4186 (define_insn "*truncxfdf2_mixed"
4187   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4188         (float_truncate:DF
4189           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4190    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4191   "TARGET_80387"
4192 {
4193   gcc_assert (!which_alternative);
4194   return output_387_reg_move (insn, operands);
4195 }
4196   [(set_attr "type" "fmov,multi,multi,multi")
4197    (set_attr "unit" "*,i387,i387,i387")
4198    (set_attr "mode" "DF")])
4199
4200 (define_insn "truncxf<mode>2_i387_noop"
4201   [(set (match_operand:MODEF 0 "register_operand" "=f")
4202         (float_truncate:MODEF
4203           (match_operand:XF 1 "register_operand" "f")))]
4204   "TARGET_80387 && flag_unsafe_math_optimizations"
4205   "* return output_387_reg_move (insn, operands);"
4206   [(set_attr "type" "fmov")
4207    (set_attr "mode" "<MODE>")])
4208
4209 (define_insn "*truncxf<mode>2_i387"
4210   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4211         (float_truncate:MODEF
4212           (match_operand:XF 1 "register_operand" "f")))]
4213   "TARGET_80387"
4214   "* return output_387_reg_move (insn, operands);"
4215   [(set_attr "type" "fmov")
4216    (set_attr "mode" "<MODE>")])
4217
4218 (define_split
4219   [(set (match_operand:MODEF 0 "register_operand" "")
4220         (float_truncate:MODEF
4221           (match_operand:XF 1 "register_operand" "")))
4222    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4223   "TARGET_80387 && reload_completed"
4224   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4225    (set (match_dup 0) (match_dup 2))])
4226
4227 (define_split
4228   [(set (match_operand:MODEF 0 "memory_operand" "")
4229         (float_truncate:MODEF
4230           (match_operand:XF 1 "register_operand" "")))
4231    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4232   "TARGET_80387"
4233   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4234 \f
4235 ;; Signed conversion to DImode.
4236
4237 (define_expand "fix_truncxfdi2"
4238   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4239                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4240               (clobber (reg:CC FLAGS_REG))])]
4241   "TARGET_80387"
4242 {
4243   if (TARGET_FISTTP)
4244    {
4245      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4246      DONE;
4247    }
4248 })
4249
4250 (define_expand "fix_trunc<mode>di2"
4251   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4252                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4253               (clobber (reg:CC FLAGS_REG))])]
4254   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4255 {
4256   if (TARGET_FISTTP
4257       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4258    {
4259      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4260      DONE;
4261    }
4262   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4263    {
4264      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4265      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4266      if (out != operands[0])
4267         emit_move_insn (operands[0], out);
4268      DONE;
4269    }
4270 })
4271
4272 ;; Signed conversion to SImode.
4273
4274 (define_expand "fix_truncxfsi2"
4275   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4276                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4277               (clobber (reg:CC FLAGS_REG))])]
4278   "TARGET_80387"
4279 {
4280   if (TARGET_FISTTP)
4281    {
4282      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4283      DONE;
4284    }
4285 })
4286
4287 (define_expand "fix_trunc<mode>si2"
4288   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4289                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4290               (clobber (reg:CC FLAGS_REG))])]
4291   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4292 {
4293   if (TARGET_FISTTP
4294       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4295    {
4296      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4297      DONE;
4298    }
4299   if (SSE_FLOAT_MODE_P (<MODE>mode))
4300    {
4301      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4302      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4303      if (out != operands[0])
4304         emit_move_insn (operands[0], out);
4305      DONE;
4306    }
4307 })
4308
4309 ;; Signed conversion to HImode.
4310
4311 (define_expand "fix_trunc<mode>hi2"
4312   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4313                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4314               (clobber (reg:CC FLAGS_REG))])]
4315   "TARGET_80387
4316    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4317 {
4318   if (TARGET_FISTTP)
4319    {
4320      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4321      DONE;
4322    }
4323 })
4324
4325 ;; Unsigned conversion to SImode.
4326
4327 (define_expand "fixuns_trunc<mode>si2"
4328   [(parallel
4329     [(set (match_operand:SI 0 "register_operand" "")
4330           (unsigned_fix:SI
4331             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4332      (use (match_dup 2))
4333      (clobber (match_scratch:<ssevecmode> 3 ""))
4334      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4335   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4336 {
4337   enum machine_mode mode = <MODE>mode;
4338   enum machine_mode vecmode = <ssevecmode>mode;
4339   REAL_VALUE_TYPE TWO31r;
4340   rtx two31;
4341
4342   if (optimize_insn_for_size_p ())
4343     FAIL;
4344
4345   real_ldexp (&TWO31r, &dconst1, 31);
4346   two31 = const_double_from_real_value (TWO31r, mode);
4347   two31 = ix86_build_const_vector (vecmode, true, two31);
4348   operands[2] = force_reg (vecmode, two31);
4349 })
4350
4351 (define_insn_and_split "*fixuns_trunc<mode>_1"
4352   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4353         (unsigned_fix:SI
4354           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4355    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4356    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4357    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4358   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4359    && optimize_function_for_speed_p (cfun)"
4360   "#"
4361   "&& reload_completed"
4362   [(const_int 0)]
4363 {
4364   ix86_split_convert_uns_si_sse (operands);
4365   DONE;
4366 })
4367
4368 ;; Unsigned conversion to HImode.
4369 ;; Without these patterns, we'll try the unsigned SI conversion which
4370 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4371
4372 (define_expand "fixuns_trunc<mode>hi2"
4373   [(set (match_dup 2)
4374         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4375    (set (match_operand:HI 0 "nonimmediate_operand" "")
4376         (subreg:HI (match_dup 2) 0))]
4377   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4378   "operands[2] = gen_reg_rtx (SImode);")
4379
4380 ;; When SSE is available, it is always faster to use it!
4381 (define_insn "fix_trunc<mode>di_sse"
4382   [(set (match_operand:DI 0 "register_operand" "=r,r")
4383         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4384   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4385    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4386   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4387   [(set_attr "type" "sseicvt")
4388    (set_attr "prefix" "maybe_vex")
4389    (set_attr "prefix_rex" "1")
4390    (set_attr "mode" "<MODE>")
4391    (set_attr "athlon_decode" "double,vector")
4392    (set_attr "amdfam10_decode" "double,double")
4393    (set_attr "bdver1_decode" "double,double")])
4394
4395 (define_insn "fix_trunc<mode>si_sse"
4396   [(set (match_operand:SI 0 "register_operand" "=r,r")
4397         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4398   "SSE_FLOAT_MODE_P (<MODE>mode)
4399    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4400   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4401   [(set_attr "type" "sseicvt")
4402    (set_attr "prefix" "maybe_vex")
4403    (set_attr "mode" "<MODE>")
4404    (set_attr "athlon_decode" "double,vector")
4405    (set_attr "amdfam10_decode" "double,double")
4406    (set_attr "bdver1_decode" "double,double")])
4407
4408 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4409 (define_peephole2
4410   [(set (match_operand:MODEF 0 "register_operand" "")
4411         (match_operand:MODEF 1 "memory_operand" ""))
4412    (set (match_operand:SWI48x 2 "register_operand" "")
4413         (fix:SWI48x (match_dup 0)))]
4414   "TARGET_SHORTEN_X87_SSE
4415    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4416    && peep2_reg_dead_p (2, operands[0])"
4417   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4418
4419 ;; Avoid vector decoded forms of the instruction.
4420 (define_peephole2
4421   [(match_scratch:DF 2 "Y2")
4422    (set (match_operand:SWI48x 0 "register_operand" "")
4423         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4424   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4425   [(set (match_dup 2) (match_dup 1))
4426    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4427
4428 (define_peephole2
4429   [(match_scratch:SF 2 "x")
4430    (set (match_operand:SWI48x 0 "register_operand" "")
4431         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4432   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4433   [(set (match_dup 2) (match_dup 1))
4434    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4435
4436 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4437   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4438         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4439   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4440    && TARGET_FISTTP
4441    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4442          && (TARGET_64BIT || <MODE>mode != DImode))
4443         && TARGET_SSE_MATH)
4444    && can_create_pseudo_p ()"
4445   "#"
4446   "&& 1"
4447   [(const_int 0)]
4448 {
4449   if (memory_operand (operands[0], VOIDmode))
4450     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4451   else
4452     {
4453       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4454       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4455                                                             operands[1],
4456                                                             operands[2]));
4457     }
4458   DONE;
4459 }
4460   [(set_attr "type" "fisttp")
4461    (set_attr "mode" "<MODE>")])
4462
4463 (define_insn "fix_trunc<mode>_i387_fisttp"
4464   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4465         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4466    (clobber (match_scratch:XF 2 "=&1f"))]
4467   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4468    && TARGET_FISTTP
4469    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4470          && (TARGET_64BIT || <MODE>mode != DImode))
4471         && TARGET_SSE_MATH)"
4472   "* return output_fix_trunc (insn, operands, true);"
4473   [(set_attr "type" "fisttp")
4474    (set_attr "mode" "<MODE>")])
4475
4476 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4477   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4478         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4479    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4480    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4481   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4482    && TARGET_FISTTP
4483    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4484         && (TARGET_64BIT || <MODE>mode != DImode))
4485         && TARGET_SSE_MATH)"
4486   "#"
4487   [(set_attr "type" "fisttp")
4488    (set_attr "mode" "<MODE>")])
4489
4490 (define_split
4491   [(set (match_operand:SWI248x 0 "register_operand" "")
4492         (fix:SWI248x (match_operand 1 "register_operand" "")))
4493    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4494    (clobber (match_scratch 3 ""))]
4495   "reload_completed"
4496   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4497               (clobber (match_dup 3))])
4498    (set (match_dup 0) (match_dup 2))])
4499
4500 (define_split
4501   [(set (match_operand:SWI248x 0 "memory_operand" "")
4502         (fix:SWI248x (match_operand 1 "register_operand" "")))
4503    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4504    (clobber (match_scratch 3 ""))]
4505   "reload_completed"
4506   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4507               (clobber (match_dup 3))])])
4508
4509 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4510 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4511 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4512 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4513 ;; function in i386.c.
4514 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4515   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4516         (fix:SWI248x (match_operand 1 "register_operand" "")))
4517    (clobber (reg:CC FLAGS_REG))]
4518   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4519    && !TARGET_FISTTP
4520    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4521          && (TARGET_64BIT || <MODE>mode != DImode))
4522    && can_create_pseudo_p ()"
4523   "#"
4524   "&& 1"
4525   [(const_int 0)]
4526 {
4527   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4528
4529   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4530   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4531   if (memory_operand (operands[0], VOIDmode))
4532     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4533                                          operands[2], operands[3]));
4534   else
4535     {
4536       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4537       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4538                                                      operands[2], operands[3],
4539                                                      operands[4]));
4540     }
4541   DONE;
4542 }
4543   [(set_attr "type" "fistp")
4544    (set_attr "i387_cw" "trunc")
4545    (set_attr "mode" "<MODE>")])
4546
4547 (define_insn "fix_truncdi_i387"
4548   [(set (match_operand:DI 0 "memory_operand" "=m")
4549         (fix:DI (match_operand 1 "register_operand" "f")))
4550    (use (match_operand:HI 2 "memory_operand" "m"))
4551    (use (match_operand:HI 3 "memory_operand" "m"))
4552    (clobber (match_scratch:XF 4 "=&1f"))]
4553   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4554    && !TARGET_FISTTP
4555    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4556   "* return output_fix_trunc (insn, operands, false);"
4557   [(set_attr "type" "fistp")
4558    (set_attr "i387_cw" "trunc")
4559    (set_attr "mode" "DI")])
4560
4561 (define_insn "fix_truncdi_i387_with_temp"
4562   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4563         (fix:DI (match_operand 1 "register_operand" "f,f")))
4564    (use (match_operand:HI 2 "memory_operand" "m,m"))
4565    (use (match_operand:HI 3 "memory_operand" "m,m"))
4566    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4567    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4568   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4569    && !TARGET_FISTTP
4570    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4571   "#"
4572   [(set_attr "type" "fistp")
4573    (set_attr "i387_cw" "trunc")
4574    (set_attr "mode" "DI")])
4575
4576 (define_split
4577   [(set (match_operand:DI 0 "register_operand" "")
4578         (fix:DI (match_operand 1 "register_operand" "")))
4579    (use (match_operand:HI 2 "memory_operand" ""))
4580    (use (match_operand:HI 3 "memory_operand" ""))
4581    (clobber (match_operand:DI 4 "memory_operand" ""))
4582    (clobber (match_scratch 5 ""))]
4583   "reload_completed"
4584   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4585               (use (match_dup 2))
4586               (use (match_dup 3))
4587               (clobber (match_dup 5))])
4588    (set (match_dup 0) (match_dup 4))])
4589
4590 (define_split
4591   [(set (match_operand:DI 0 "memory_operand" "")
4592         (fix:DI (match_operand 1 "register_operand" "")))
4593    (use (match_operand:HI 2 "memory_operand" ""))
4594    (use (match_operand:HI 3 "memory_operand" ""))
4595    (clobber (match_operand:DI 4 "memory_operand" ""))
4596    (clobber (match_scratch 5 ""))]
4597   "reload_completed"
4598   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4599               (use (match_dup 2))
4600               (use (match_dup 3))
4601               (clobber (match_dup 5))])])
4602
4603 (define_insn "fix_trunc<mode>_i387"
4604   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4605         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4606    (use (match_operand:HI 2 "memory_operand" "m"))
4607    (use (match_operand:HI 3 "memory_operand" "m"))]
4608   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4609    && !TARGET_FISTTP
4610    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4611   "* return output_fix_trunc (insn, operands, false);"
4612   [(set_attr "type" "fistp")
4613    (set_attr "i387_cw" "trunc")
4614    (set_attr "mode" "<MODE>")])
4615
4616 (define_insn "fix_trunc<mode>_i387_with_temp"
4617   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4618         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4619    (use (match_operand:HI 2 "memory_operand" "m,m"))
4620    (use (match_operand:HI 3 "memory_operand" "m,m"))
4621    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4622   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4623    && !TARGET_FISTTP
4624    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4625   "#"
4626   [(set_attr "type" "fistp")
4627    (set_attr "i387_cw" "trunc")
4628    (set_attr "mode" "<MODE>")])
4629
4630 (define_split
4631   [(set (match_operand:SWI24 0 "register_operand" "")
4632         (fix:SWI24 (match_operand 1 "register_operand" "")))
4633    (use (match_operand:HI 2 "memory_operand" ""))
4634    (use (match_operand:HI 3 "memory_operand" ""))
4635    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4636   "reload_completed"
4637   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4638               (use (match_dup 2))
4639               (use (match_dup 3))])
4640    (set (match_dup 0) (match_dup 4))])
4641
4642 (define_split
4643   [(set (match_operand:SWI24 0 "memory_operand" "")
4644         (fix:SWI24 (match_operand 1 "register_operand" "")))
4645    (use (match_operand:HI 2 "memory_operand" ""))
4646    (use (match_operand:HI 3 "memory_operand" ""))
4647    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4648   "reload_completed"
4649   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4650               (use (match_dup 2))
4651               (use (match_dup 3))])])
4652
4653 (define_insn "x86_fnstcw_1"
4654   [(set (match_operand:HI 0 "memory_operand" "=m")
4655         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4656   "TARGET_80387"
4657   "fnstcw\t%0"
4658   [(set (attr "length")
4659         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4660    (set_attr "mode" "HI")
4661    (set_attr "unit" "i387")
4662    (set_attr "bdver1_decode" "vector")])
4663
4664 (define_insn "x86_fldcw_1"
4665   [(set (reg:HI FPCR_REG)
4666         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4667   "TARGET_80387"
4668   "fldcw\t%0"
4669   [(set (attr "length")
4670         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4671    (set_attr "mode" "HI")
4672    (set_attr "unit" "i387")
4673    (set_attr "athlon_decode" "vector")
4674    (set_attr "amdfam10_decode" "vector")
4675    (set_attr "bdver1_decode" "vector")])
4676 \f
4677 ;; Conversion between fixed point and floating point.
4678
4679 ;; Even though we only accept memory inputs, the backend _really_
4680 ;; wants to be able to do this between registers.
4681
4682 (define_expand "floathi<mode>2"
4683   [(set (match_operand:X87MODEF 0 "register_operand" "")
4684         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4685   "TARGET_80387
4686    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4687        || TARGET_MIX_SSE_I387)")
4688
4689 ;; Pre-reload splitter to add memory clobber to the pattern.
4690 (define_insn_and_split "*floathi<mode>2_1"
4691   [(set (match_operand:X87MODEF 0 "register_operand" "")
4692         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4693   "TARGET_80387
4694    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4695        || TARGET_MIX_SSE_I387)
4696    && can_create_pseudo_p ()"
4697   "#"
4698   "&& 1"
4699   [(parallel [(set (match_dup 0)
4700               (float:X87MODEF (match_dup 1)))
4701    (clobber (match_dup 2))])]
4702   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4703
4704 (define_insn "*floathi<mode>2_i387_with_temp"
4705   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4706         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4707   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4708   "TARGET_80387
4709    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4710        || TARGET_MIX_SSE_I387)"
4711   "#"
4712   [(set_attr "type" "fmov,multi")
4713    (set_attr "mode" "<MODE>")
4714    (set_attr "unit" "*,i387")
4715    (set_attr "fp_int_src" "true")])
4716
4717 (define_insn "*floathi<mode>2_i387"
4718   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4719         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4720   "TARGET_80387
4721    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4722        || TARGET_MIX_SSE_I387)"
4723   "fild%Z1\t%1"
4724   [(set_attr "type" "fmov")
4725    (set_attr "mode" "<MODE>")
4726    (set_attr "fp_int_src" "true")])
4727
4728 (define_split
4729   [(set (match_operand:X87MODEF 0 "register_operand" "")
4730         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4731    (clobber (match_operand:HI 2 "memory_operand" ""))]
4732   "TARGET_80387
4733    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4734        || TARGET_MIX_SSE_I387)
4735    && reload_completed"
4736   [(set (match_dup 2) (match_dup 1))
4737    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4738
4739 (define_split
4740   [(set (match_operand:X87MODEF 0 "register_operand" "")
4741         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4742    (clobber (match_operand:HI 2 "memory_operand" ""))]
4743    "TARGET_80387
4744     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4745         || TARGET_MIX_SSE_I387)
4746     && reload_completed"
4747   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4748
4749 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4750   [(set (match_operand:X87MODEF 0 "register_operand" "")
4751         (float:X87MODEF
4752           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4753   "TARGET_80387
4754    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4755        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4756 {
4757   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4758         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4759       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4760     {
4761       rtx reg = gen_reg_rtx (XFmode);
4762       rtx (*insn)(rtx, rtx);
4763
4764       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4765
4766       if (<X87MODEF:MODE>mode == SFmode)
4767         insn = gen_truncxfsf2;
4768       else if (<X87MODEF:MODE>mode == DFmode)
4769         insn = gen_truncxfdf2;
4770       else
4771         gcc_unreachable ();
4772
4773       emit_insn (insn (operands[0], reg));
4774       DONE;
4775     }
4776 })
4777
4778 ;; Pre-reload splitter to add memory clobber to the pattern.
4779 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4780   [(set (match_operand:X87MODEF 0 "register_operand" "")
4781         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4782   "((TARGET_80387
4783      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4784      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4785            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4786          || TARGET_MIX_SSE_I387))
4787     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4788         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4789         && ((<SWI48x:MODE>mode == SImode
4790              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4791              && optimize_function_for_speed_p (cfun)
4792              && flag_trapping_math)
4793             || !(TARGET_INTER_UNIT_CONVERSIONS
4794                  || optimize_function_for_size_p (cfun)))))
4795    && can_create_pseudo_p ()"
4796   "#"
4797   "&& 1"
4798   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4799               (clobber (match_dup 2))])]
4800 {
4801   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4802
4803   /* Avoid store forwarding (partial memory) stall penalty
4804      by passing DImode value through XMM registers.  */
4805   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4806       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4807       && optimize_function_for_speed_p (cfun))
4808     {
4809       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4810                                                             operands[1],
4811                                                             operands[2]));
4812       DONE;
4813     }
4814 })
4815
4816 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4817   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4818         (float:MODEF
4819           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4820    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4821   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4822    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4823   "#"
4824   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4825    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4826    (set_attr "unit" "*,i387,*,*,*")
4827    (set_attr "athlon_decode" "*,*,double,direct,double")
4828    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4829    (set_attr "bdver1_decode" "*,*,double,direct,double")
4830    (set_attr "fp_int_src" "true")])
4831
4832 (define_insn "*floatsi<mode>2_vector_mixed"
4833   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4834         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4835   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4836    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4837   "@
4838    fild%Z1\t%1
4839    #"
4840   [(set_attr "type" "fmov,sseicvt")
4841    (set_attr "mode" "<MODE>,<ssevecmode>")
4842    (set_attr "unit" "i387,*")
4843    (set_attr "athlon_decode" "*,direct")
4844    (set_attr "amdfam10_decode" "*,double")
4845    (set_attr "bdver1_decode" "*,direct")
4846    (set_attr "fp_int_src" "true")])
4847
4848 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4849   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4850         (float:MODEF
4851           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4852    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4853   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4854    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4855   "#"
4856   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4857    (set_attr "mode" "<MODEF:MODE>")
4858    (set_attr "unit" "*,i387,*,*")
4859    (set_attr "athlon_decode" "*,*,double,direct")
4860    (set_attr "amdfam10_decode" "*,*,vector,double")
4861    (set_attr "bdver1_decode" "*,*,double,direct")
4862    (set_attr "fp_int_src" "true")])
4863
4864 (define_split
4865   [(set (match_operand:MODEF 0 "register_operand" "")
4866         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4867    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4868   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4869    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4870    && TARGET_INTER_UNIT_CONVERSIONS
4871    && reload_completed
4872    && (SSE_REG_P (operands[0])
4873        || (GET_CODE (operands[0]) == SUBREG
4874            && SSE_REG_P (operands[0])))"
4875   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4876
4877 (define_split
4878   [(set (match_operand:MODEF 0 "register_operand" "")
4879         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4880    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4881   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4882    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4883    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4884    && reload_completed
4885    && (SSE_REG_P (operands[0])
4886        || (GET_CODE (operands[0]) == SUBREG
4887            && SSE_REG_P (operands[0])))"
4888   [(set (match_dup 2) (match_dup 1))
4889    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4890
4891 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4892   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4893         (float:MODEF
4894           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4895   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4896    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4897    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4898   "@
4899    fild%Z1\t%1
4900    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4901    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4902   [(set_attr "type" "fmov,sseicvt,sseicvt")
4903    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4904    (set_attr "mode" "<MODEF:MODE>")
4905    (set (attr "prefix_rex")
4906      (if_then_else
4907        (and (eq_attr "prefix" "maybe_vex")
4908             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4909        (const_string "1")
4910        (const_string "*")))
4911    (set_attr "unit" "i387,*,*")
4912    (set_attr "athlon_decode" "*,double,direct")
4913    (set_attr "amdfam10_decode" "*,vector,double")
4914    (set_attr "bdver1_decode" "*,double,direct")
4915    (set_attr "fp_int_src" "true")])
4916
4917 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4918   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4919         (float:MODEF
4920           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4921   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4922    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4923    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4924   "@
4925    fild%Z1\t%1
4926    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4927   [(set_attr "type" "fmov,sseicvt")
4928    (set_attr "prefix" "orig,maybe_vex")
4929    (set_attr "mode" "<MODEF:MODE>")
4930    (set (attr "prefix_rex")
4931      (if_then_else
4932        (and (eq_attr "prefix" "maybe_vex")
4933             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4934        (const_string "1")
4935        (const_string "*")))
4936    (set_attr "athlon_decode" "*,direct")
4937    (set_attr "amdfam10_decode" "*,double")
4938    (set_attr "bdver1_decode" "*,direct")
4939    (set_attr "fp_int_src" "true")])
4940
4941 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4942   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4943         (float:MODEF
4944           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4945    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4946   "TARGET_SSE2 && TARGET_SSE_MATH
4947    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4948   "#"
4949   [(set_attr "type" "sseicvt")
4950    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4951    (set_attr "athlon_decode" "double,direct,double")
4952    (set_attr "amdfam10_decode" "vector,double,double")
4953    (set_attr "bdver1_decode" "double,direct,double")
4954    (set_attr "fp_int_src" "true")])
4955
4956 (define_insn "*floatsi<mode>2_vector_sse"
4957   [(set (match_operand:MODEF 0 "register_operand" "=x")
4958         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4959   "TARGET_SSE2 && TARGET_SSE_MATH
4960    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4961   "#"
4962   [(set_attr "type" "sseicvt")
4963    (set_attr "mode" "<MODE>")
4964    (set_attr "athlon_decode" "direct")
4965    (set_attr "amdfam10_decode" "double")
4966    (set_attr "bdver1_decode" "direct")
4967    (set_attr "fp_int_src" "true")])
4968
4969 (define_split
4970   [(set (match_operand:MODEF 0 "register_operand" "")
4971         (float:MODEF (match_operand:SI 1 "register_operand" "")))
4972    (clobber (match_operand:SI 2 "memory_operand" ""))]
4973   "TARGET_SSE2 && TARGET_SSE_MATH
4974    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4975    && reload_completed
4976    && (SSE_REG_P (operands[0])
4977        || (GET_CODE (operands[0]) == SUBREG
4978            && SSE_REG_P (operands[0])))"
4979   [(const_int 0)]
4980 {
4981   rtx op1 = operands[1];
4982
4983   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4984                                      <MODE>mode, 0);
4985   if (GET_CODE (op1) == SUBREG)
4986     op1 = SUBREG_REG (op1);
4987
4988   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4989     {
4990       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4991       emit_insn (gen_sse2_loadld (operands[4],
4992                                   CONST0_RTX (V4SImode), operands[1]));
4993     }
4994   /* We can ignore possible trapping value in the
4995      high part of SSE register for non-trapping math. */
4996   else if (SSE_REG_P (op1) && !flag_trapping_math)
4997     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4998   else
4999     {
5000       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5001       emit_move_insn (operands[2], operands[1]);
5002       emit_insn (gen_sse2_loadld (operands[4],
5003                                   CONST0_RTX (V4SImode), operands[2]));
5004     }
5005   emit_insn
5006     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5007   DONE;
5008 })
5009
5010 (define_split
5011   [(set (match_operand:MODEF 0 "register_operand" "")
5012         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5013    (clobber (match_operand:SI 2 "memory_operand" ""))]
5014   "TARGET_SSE2 && TARGET_SSE_MATH
5015    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5016    && reload_completed
5017    && (SSE_REG_P (operands[0])
5018        || (GET_CODE (operands[0]) == SUBREG
5019            && SSE_REG_P (operands[0])))"
5020   [(const_int 0)]
5021 {
5022   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5023                                      <MODE>mode, 0);
5024   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5025
5026   emit_insn (gen_sse2_loadld (operands[4],
5027                               CONST0_RTX (V4SImode), operands[1]));
5028   emit_insn
5029     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5030   DONE;
5031 })
5032
5033 (define_split
5034   [(set (match_operand:MODEF 0 "register_operand" "")
5035         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5036   "TARGET_SSE2 && TARGET_SSE_MATH
5037    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5038    && reload_completed
5039    && (SSE_REG_P (operands[0])
5040        || (GET_CODE (operands[0]) == SUBREG
5041            && SSE_REG_P (operands[0])))"
5042   [(const_int 0)]
5043 {
5044   rtx op1 = operands[1];
5045
5046   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5047                                      <MODE>mode, 0);
5048   if (GET_CODE (op1) == SUBREG)
5049     op1 = SUBREG_REG (op1);
5050
5051   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5052     {
5053       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5054       emit_insn (gen_sse2_loadld (operands[4],
5055                                   CONST0_RTX (V4SImode), operands[1]));
5056     }
5057   /* We can ignore possible trapping value in the
5058      high part of SSE register for non-trapping math. */
5059   else if (SSE_REG_P (op1) && !flag_trapping_math)
5060     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5061   else
5062     gcc_unreachable ();
5063   emit_insn
5064     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5065   DONE;
5066 })
5067
5068 (define_split
5069   [(set (match_operand:MODEF 0 "register_operand" "")
5070         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5071   "TARGET_SSE2 && TARGET_SSE_MATH
5072    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5073    && reload_completed
5074    && (SSE_REG_P (operands[0])
5075        || (GET_CODE (operands[0]) == SUBREG
5076            && SSE_REG_P (operands[0])))"
5077   [(const_int 0)]
5078 {
5079   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5080                                      <MODE>mode, 0);
5081   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5082
5083   emit_insn (gen_sse2_loadld (operands[4],
5084                               CONST0_RTX (V4SImode), operands[1]));
5085   emit_insn
5086     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5087   DONE;
5088 })
5089
5090 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5091   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5092         (float:MODEF
5093           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5094   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5095   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5096    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5097   "#"
5098   [(set_attr "type" "sseicvt")
5099    (set_attr "mode" "<MODEF:MODE>")
5100    (set_attr "athlon_decode" "double,direct")
5101    (set_attr "amdfam10_decode" "vector,double")
5102    (set_attr "bdver1_decode" "double,direct")
5103    (set_attr "fp_int_src" "true")])
5104
5105 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5106   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5107         (float:MODEF
5108           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5109   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5110    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5111    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5112   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5113   [(set_attr "type" "sseicvt")
5114    (set_attr "prefix" "maybe_vex")
5115    (set_attr "mode" "<MODEF:MODE>")
5116    (set (attr "prefix_rex")
5117      (if_then_else
5118        (and (eq_attr "prefix" "maybe_vex")
5119             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5120        (const_string "1")
5121        (const_string "*")))
5122    (set_attr "athlon_decode" "double,direct")
5123    (set_attr "amdfam10_decode" "vector,double")
5124    (set_attr "bdver1_decode" "double,direct")
5125    (set_attr "fp_int_src" "true")])
5126
5127 (define_split
5128   [(set (match_operand:MODEF 0 "register_operand" "")
5129         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5130    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5131   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5132    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5133    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5134    && reload_completed
5135    && (SSE_REG_P (operands[0])
5136        || (GET_CODE (operands[0]) == SUBREG
5137            && SSE_REG_P (operands[0])))"
5138   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5139
5140 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5141   [(set (match_operand:MODEF 0 "register_operand" "=x")
5142         (float:MODEF
5143           (match_operand:SWI48x 1 "memory_operand" "m")))]
5144   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5145    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5146    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5147   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5148   [(set_attr "type" "sseicvt")
5149    (set_attr "prefix" "maybe_vex")
5150    (set_attr "mode" "<MODEF:MODE>")
5151    (set (attr "prefix_rex")
5152      (if_then_else
5153        (and (eq_attr "prefix" "maybe_vex")
5154             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5155        (const_string "1")
5156        (const_string "*")))
5157    (set_attr "athlon_decode" "direct")
5158    (set_attr "amdfam10_decode" "double")
5159    (set_attr "bdver1_decode" "direct")
5160    (set_attr "fp_int_src" "true")])
5161
5162 (define_split
5163   [(set (match_operand:MODEF 0 "register_operand" "")
5164         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5165    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5166   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5167    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5168    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5169    && reload_completed
5170    && (SSE_REG_P (operands[0])
5171        || (GET_CODE (operands[0]) == SUBREG
5172            && SSE_REG_P (operands[0])))"
5173   [(set (match_dup 2) (match_dup 1))
5174    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5175
5176 (define_split
5177   [(set (match_operand:MODEF 0 "register_operand" "")
5178         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5179    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5180   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5181    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5182    && reload_completed
5183    && (SSE_REG_P (operands[0])
5184        || (GET_CODE (operands[0]) == SUBREG
5185            && SSE_REG_P (operands[0])))"
5186   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5187
5188 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5189   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5190         (float:X87MODEF
5191           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5192   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5193   "TARGET_80387
5194    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5195   "@
5196    fild%Z1\t%1
5197    #"
5198   [(set_attr "type" "fmov,multi")
5199    (set_attr "mode" "<X87MODEF:MODE>")
5200    (set_attr "unit" "*,i387")
5201    (set_attr "fp_int_src" "true")])
5202
5203 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5204   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5205         (float:X87MODEF
5206           (match_operand:SWI48x 1 "memory_operand" "m")))]
5207   "TARGET_80387
5208    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5209   "fild%Z1\t%1"
5210   [(set_attr "type" "fmov")
5211    (set_attr "mode" "<X87MODEF:MODE>")
5212    (set_attr "fp_int_src" "true")])
5213
5214 (define_split
5215   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5216         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5217    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5218   "TARGET_80387
5219    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5220    && reload_completed"
5221   [(set (match_dup 2) (match_dup 1))
5222    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5223
5224 (define_split
5225   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5226         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5227    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5228   "TARGET_80387
5229    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5230    && reload_completed"
5231   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5232
5233 ;; Avoid store forwarding (partial memory) stall penalty
5234 ;; by passing DImode value through XMM registers.  */
5235
5236 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5237   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5238         (float:X87MODEF
5239           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5240    (clobber (match_scratch:V4SI 3 "=X,x"))
5241    (clobber (match_scratch:V4SI 4 "=X,x"))
5242    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5243   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5244    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5245    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5246   "#"
5247   [(set_attr "type" "multi")
5248    (set_attr "mode" "<X87MODEF:MODE>")
5249    (set_attr "unit" "i387")
5250    (set_attr "fp_int_src" "true")])
5251
5252 (define_split
5253   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5254         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5255    (clobber (match_scratch:V4SI 3 ""))
5256    (clobber (match_scratch:V4SI 4 ""))
5257    (clobber (match_operand:DI 2 "memory_operand" ""))]
5258   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5259    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5260    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5261    && reload_completed"
5262   [(set (match_dup 2) (match_dup 3))
5263    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5264 {
5265   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5266      Assemble the 64-bit DImode value in an xmm register.  */
5267   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5268                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5269   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5270                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5271   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5272                                          operands[4]));
5273
5274   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5275 })
5276
5277 (define_split
5278   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5279         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5280    (clobber (match_scratch:V4SI 3 ""))
5281    (clobber (match_scratch:V4SI 4 ""))
5282    (clobber (match_operand:DI 2 "memory_operand" ""))]
5283   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5284    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5285    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5286    && reload_completed"
5287   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5288
5289 ;; Avoid store forwarding (partial memory) stall penalty by extending
5290 ;; SImode value to DImode through XMM register instead of pushing two
5291 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5292 ;; targets benefit from this optimization. Also note that fild
5293 ;; loads from memory only.
5294
5295 (define_insn "*floatunssi<mode>2_1"
5296   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5297         (unsigned_float:X87MODEF
5298           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5299    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5300    (clobber (match_scratch:SI 3 "=X,x"))]
5301   "!TARGET_64BIT
5302    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5303    && TARGET_SSE"
5304   "#"
5305   [(set_attr "type" "multi")
5306    (set_attr "mode" "<MODE>")])
5307
5308 (define_split
5309   [(set (match_operand:X87MODEF 0 "register_operand" "")
5310         (unsigned_float:X87MODEF
5311           (match_operand:SI 1 "register_operand" "")))
5312    (clobber (match_operand:DI 2 "memory_operand" ""))
5313    (clobber (match_scratch:SI 3 ""))]
5314   "!TARGET_64BIT
5315    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5316    && TARGET_SSE
5317    && reload_completed"
5318   [(set (match_dup 2) (match_dup 1))
5319    (set (match_dup 0)
5320         (float:X87MODEF (match_dup 2)))]
5321   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5322
5323 (define_split
5324   [(set (match_operand:X87MODEF 0 "register_operand" "")
5325         (unsigned_float:X87MODEF
5326           (match_operand:SI 1 "memory_operand" "")))
5327    (clobber (match_operand:DI 2 "memory_operand" ""))
5328    (clobber (match_scratch:SI 3 ""))]
5329   "!TARGET_64BIT
5330    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5331    && TARGET_SSE
5332    && reload_completed"
5333   [(set (match_dup 2) (match_dup 3))
5334    (set (match_dup 0)
5335         (float:X87MODEF (match_dup 2)))]
5336 {
5337   emit_move_insn (operands[3], operands[1]);
5338   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5339 })
5340
5341 (define_expand "floatunssi<mode>2"
5342   [(parallel
5343      [(set (match_operand:X87MODEF 0 "register_operand" "")
5344            (unsigned_float:X87MODEF
5345              (match_operand:SI 1 "nonimmediate_operand" "")))
5346       (clobber (match_dup 2))
5347       (clobber (match_scratch:SI 3 ""))])]
5348   "!TARGET_64BIT
5349    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5350         && TARGET_SSE)
5351        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5352 {
5353   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5354     {
5355       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5356       DONE;
5357     }
5358   else
5359     {
5360       enum ix86_stack_slot slot = (virtuals_instantiated
5361                                    ? SLOT_TEMP
5362                                    : SLOT_VIRTUAL);
5363       operands[2] = assign_386_stack_local (DImode, slot);
5364     }
5365 })
5366
5367 (define_expand "floatunsdisf2"
5368   [(use (match_operand:SF 0 "register_operand" ""))
5369    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5370   "TARGET_64BIT && TARGET_SSE_MATH"
5371   "x86_emit_floatuns (operands); DONE;")
5372
5373 (define_expand "floatunsdidf2"
5374   [(use (match_operand:DF 0 "register_operand" ""))
5375    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5376   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5377    && TARGET_SSE2 && TARGET_SSE_MATH"
5378 {
5379   if (TARGET_64BIT)
5380     x86_emit_floatuns (operands);
5381   else
5382     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5383   DONE;
5384 })
5385 \f
5386 ;; Add instructions
5387
5388 (define_expand "add<mode>3"
5389   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5390         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5391                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5392   ""
5393   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5394
5395 (define_insn_and_split "*add<dwi>3_doubleword"
5396   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5397         (plus:<DWI>
5398           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5399           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5400    (clobber (reg:CC FLAGS_REG))]
5401   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5402   "#"
5403   "reload_completed"
5404   [(parallel [(set (reg:CC FLAGS_REG)
5405                    (unspec:CC [(match_dup 1) (match_dup 2)]
5406                               UNSPEC_ADD_CARRY))
5407               (set (match_dup 0)
5408                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5409    (parallel [(set (match_dup 3)
5410                    (plus:DWIH
5411                      (match_dup 4)
5412                      (plus:DWIH
5413                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5414                        (match_dup 5))))
5415               (clobber (reg:CC FLAGS_REG))])]
5416   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5417
5418 (define_insn "*add<mode>3_cc"
5419   [(set (reg:CC FLAGS_REG)
5420         (unspec:CC
5421           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5422            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5423           UNSPEC_ADD_CARRY))
5424    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5425         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5426   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5427   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5428   [(set_attr "type" "alu")
5429    (set_attr "mode" "<MODE>")])
5430
5431 (define_insn "addqi3_cc"
5432   [(set (reg:CC FLAGS_REG)
5433         (unspec:CC
5434           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5435            (match_operand:QI 2 "general_operand" "qn,qm")]
5436           UNSPEC_ADD_CARRY))
5437    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5438         (plus:QI (match_dup 1) (match_dup 2)))]
5439   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5440   "add{b}\t{%2, %0|%0, %2}"
5441   [(set_attr "type" "alu")
5442    (set_attr "mode" "QI")])
5443
5444 (define_insn "*lea_1"
5445   [(set (match_operand:P 0 "register_operand" "=r")
5446         (match_operand:P 1 "no_seg_address_operand" "p"))]
5447   ""
5448   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5449   [(set_attr "type" "lea")
5450    (set_attr "mode" "<MODE>")])
5451
5452 (define_insn "*lea_2"
5453   [(set (match_operand:SI 0 "register_operand" "=r")
5454         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5455   "TARGET_64BIT"
5456   "lea{l}\t{%a1, %0|%0, %a1}"
5457   [(set_attr "type" "lea")
5458    (set_attr "mode" "SI")])
5459
5460 (define_insn "*lea_2_zext"
5461   [(set (match_operand:DI 0 "register_operand" "=r")
5462         (zero_extend:DI
5463           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5464   "TARGET_64BIT"
5465   "lea{l}\t{%a1, %k0|%k0, %a1}"
5466   [(set_attr "type" "lea")
5467    (set_attr "mode" "SI")])
5468
5469 (define_insn "*add<mode>_1"
5470   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5471         (plus:SWI48
5472           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5473           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5474    (clobber (reg:CC FLAGS_REG))]
5475   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5476 {
5477   switch (get_attr_type (insn))
5478     {
5479     case TYPE_LEA:
5480       return "#";
5481
5482     case TYPE_INCDEC:
5483       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5484       if (operands[2] == const1_rtx)
5485         return "inc{<imodesuffix>}\t%0";
5486       else
5487         {
5488           gcc_assert (operands[2] == constm1_rtx);
5489           return "dec{<imodesuffix>}\t%0";
5490         }
5491
5492     default:
5493       /* For most processors, ADD is faster than LEA.  This alternative
5494          was added to use ADD as much as possible.  */
5495       if (which_alternative == 2)
5496         {
5497           rtx tmp;
5498           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5499         }
5500         
5501       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5502       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5503         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5504
5505       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5506     }
5507 }
5508   [(set (attr "type")
5509      (cond [(eq_attr "alternative" "3")
5510               (const_string "lea")
5511             (match_operand:SWI48 2 "incdec_operand" "")
5512               (const_string "incdec")
5513            ]
5514            (const_string "alu")))
5515    (set (attr "length_immediate")
5516       (if_then_else
5517         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5518         (const_string "1")
5519         (const_string "*")))
5520    (set_attr "mode" "<MODE>")])
5521
5522 ;; It may seem that nonimmediate operand is proper one for operand 1.
5523 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5524 ;; we take care in ix86_binary_operator_ok to not allow two memory
5525 ;; operands so proper swapping will be done in reload.  This allow
5526 ;; patterns constructed from addsi_1 to match.
5527
5528 (define_insn "*addsi_1_zext"
5529   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5530         (zero_extend:DI
5531           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5532                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5533    (clobber (reg:CC FLAGS_REG))]
5534   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5535 {
5536   switch (get_attr_type (insn))
5537     {
5538     case TYPE_LEA:
5539       return "#";
5540
5541     case TYPE_INCDEC:
5542       if (operands[2] == const1_rtx)
5543         return "inc{l}\t%k0";
5544       else
5545         {
5546           gcc_assert (operands[2] == constm1_rtx);
5547           return "dec{l}\t%k0";
5548         }
5549
5550     default:
5551       /* For most processors, ADD is faster than LEA.  This alternative
5552          was added to use ADD as much as possible.  */
5553       if (which_alternative == 1)
5554         {
5555           rtx tmp;
5556           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5557         }
5558
5559       if (x86_maybe_negate_const_int (&operands[2], SImode))
5560         return "sub{l}\t{%2, %k0|%k0, %2}";
5561
5562       return "add{l}\t{%2, %k0|%k0, %2}";
5563     }
5564 }
5565   [(set (attr "type")
5566      (cond [(eq_attr "alternative" "2")
5567               (const_string "lea")
5568             (match_operand:SI 2 "incdec_operand" "")
5569               (const_string "incdec")
5570            ]
5571            (const_string "alu")))
5572    (set (attr "length_immediate")
5573       (if_then_else
5574         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5575         (const_string "1")
5576         (const_string "*")))
5577    (set_attr "mode" "SI")])
5578
5579 (define_insn "*addhi_1"
5580   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5581         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5582                  (match_operand:HI 2 "general_operand" "rn,rm")))
5583    (clobber (reg:CC FLAGS_REG))]
5584   "TARGET_PARTIAL_REG_STALL
5585    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5586 {
5587   switch (get_attr_type (insn))
5588     {
5589     case TYPE_INCDEC:
5590       if (operands[2] == const1_rtx)
5591         return "inc{w}\t%0";
5592       else
5593         {
5594           gcc_assert (operands[2] == constm1_rtx);
5595           return "dec{w}\t%0";
5596         }
5597
5598     default:
5599       if (x86_maybe_negate_const_int (&operands[2], HImode))
5600         return "sub{w}\t{%2, %0|%0, %2}";
5601
5602       return "add{w}\t{%2, %0|%0, %2}";
5603     }
5604 }
5605   [(set (attr "type")
5606      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5607         (const_string "incdec")
5608         (const_string "alu")))
5609    (set (attr "length_immediate")
5610       (if_then_else
5611         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5612         (const_string "1")
5613         (const_string "*")))
5614    (set_attr "mode" "HI")])
5615
5616 (define_insn "*addhi_1_lea"
5617   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5618         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5619                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5620    (clobber (reg:CC FLAGS_REG))]
5621   "!TARGET_PARTIAL_REG_STALL
5622    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5623 {
5624   switch (get_attr_type (insn))
5625     {
5626     case TYPE_LEA:
5627       return "#";
5628
5629     case TYPE_INCDEC:
5630       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5631       if (operands[2] == const1_rtx)
5632         return "inc{w}\t%0";
5633       else
5634         {
5635           gcc_assert (operands[2] == constm1_rtx);
5636           return "dec{w}\t%0";
5637         }
5638
5639     default:
5640       /* For most processors, ADD is faster than LEA.  This alternative
5641          was added to use ADD as much as possible.  */
5642       if (which_alternative == 2)
5643         {
5644           rtx tmp;
5645           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5646         }
5647
5648       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5649       if (x86_maybe_negate_const_int (&operands[2], HImode))
5650         return "sub{w}\t{%2, %0|%0, %2}";
5651
5652       return "add{w}\t{%2, %0|%0, %2}";
5653     }
5654 }
5655   [(set (attr "type")
5656      (cond [(eq_attr "alternative" "3")
5657               (const_string "lea")
5658             (match_operand:HI 2 "incdec_operand" "")
5659               (const_string "incdec")
5660            ]
5661            (const_string "alu")))
5662    (set (attr "length_immediate")
5663       (if_then_else
5664         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5665         (const_string "1")
5666         (const_string "*")))
5667    (set_attr "mode" "HI,HI,HI,SI")])
5668
5669 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5670 (define_insn "*addqi_1"
5671   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5672         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5673                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5674    (clobber (reg:CC FLAGS_REG))]
5675   "TARGET_PARTIAL_REG_STALL
5676    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5677 {
5678   int widen = (which_alternative == 2);
5679   switch (get_attr_type (insn))
5680     {
5681     case TYPE_INCDEC:
5682       if (operands[2] == const1_rtx)
5683         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5684       else
5685         {
5686           gcc_assert (operands[2] == constm1_rtx);
5687           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5688         }
5689
5690     default:
5691       if (x86_maybe_negate_const_int (&operands[2], QImode))
5692         {
5693           if (widen)
5694             return "sub{l}\t{%2, %k0|%k0, %2}";
5695           else
5696             return "sub{b}\t{%2, %0|%0, %2}";
5697         }
5698       if (widen)
5699         return "add{l}\t{%k2, %k0|%k0, %k2}";
5700       else
5701         return "add{b}\t{%2, %0|%0, %2}";
5702     }
5703 }
5704   [(set (attr "type")
5705      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5706         (const_string "incdec")
5707         (const_string "alu")))
5708    (set (attr "length_immediate")
5709       (if_then_else
5710         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5711         (const_string "1")
5712         (const_string "*")))
5713    (set_attr "mode" "QI,QI,SI")])
5714
5715 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5716 (define_insn "*addqi_1_lea"
5717   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5718         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5719                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5720    (clobber (reg:CC FLAGS_REG))]
5721   "!TARGET_PARTIAL_REG_STALL
5722    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5723 {
5724   int widen = (which_alternative == 3 || which_alternative == 4);
5725
5726   switch (get_attr_type (insn))
5727     {
5728     case TYPE_LEA:
5729       return "#";
5730
5731     case TYPE_INCDEC:
5732       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5733       if (operands[2] == const1_rtx)
5734         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5735       else
5736         {
5737           gcc_assert (operands[2] == constm1_rtx);
5738           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5739         }
5740
5741     default:
5742       /* For most processors, ADD is faster than LEA.  These alternatives
5743          were added to use ADD as much as possible.  */
5744       if (which_alternative == 2 || which_alternative == 4)
5745         {
5746           rtx tmp;
5747           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5748         }
5749
5750       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5751       if (x86_maybe_negate_const_int (&operands[2], QImode))
5752         {
5753           if (widen)
5754             return "sub{l}\t{%2, %k0|%k0, %2}";
5755           else
5756             return "sub{b}\t{%2, %0|%0, %2}";
5757         }
5758       if (widen)
5759         return "add{l}\t{%k2, %k0|%k0, %k2}";
5760       else
5761         return "add{b}\t{%2, %0|%0, %2}";
5762     }
5763 }
5764   [(set (attr "type")
5765      (cond [(eq_attr "alternative" "5")
5766               (const_string "lea")
5767             (match_operand:QI 2 "incdec_operand" "")
5768               (const_string "incdec")
5769            ]
5770            (const_string "alu")))
5771    (set (attr "length_immediate")
5772       (if_then_else
5773         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5774         (const_string "1")
5775         (const_string "*")))
5776    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5777
5778 (define_insn "*addqi_1_slp"
5779   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5780         (plus:QI (match_dup 0)
5781                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5782    (clobber (reg:CC FLAGS_REG))]
5783   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5784    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5785 {
5786   switch (get_attr_type (insn))
5787     {
5788     case TYPE_INCDEC:
5789       if (operands[1] == const1_rtx)
5790         return "inc{b}\t%0";
5791       else
5792         {
5793           gcc_assert (operands[1] == constm1_rtx);
5794           return "dec{b}\t%0";
5795         }
5796
5797     default:
5798       if (x86_maybe_negate_const_int (&operands[1], QImode))
5799         return "sub{b}\t{%1, %0|%0, %1}";
5800
5801       return "add{b}\t{%1, %0|%0, %1}";
5802     }
5803 }
5804   [(set (attr "type")
5805      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5806         (const_string "incdec")
5807         (const_string "alu1")))
5808    (set (attr "memory")
5809      (if_then_else (match_operand 1 "memory_operand" "")
5810         (const_string "load")
5811         (const_string "none")))
5812    (set_attr "mode" "QI")])
5813
5814 ;; Convert lea to the lea pattern to avoid flags dependency.
5815 (define_split
5816   [(set (match_operand 0 "register_operand" "")
5817         (plus (match_operand 1 "register_operand" "")
5818               (match_operand 2 "nonmemory_operand" "")))
5819    (clobber (reg:CC FLAGS_REG))]
5820   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5821   [(const_int 0)]
5822 {
5823   rtx pat;
5824   enum machine_mode mode = GET_MODE (operands[0]);
5825
5826   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5827      may confuse gen_lowpart.  */
5828   if (mode != Pmode)
5829     {
5830       operands[1] = gen_lowpart (Pmode, operands[1]);
5831       operands[2] = gen_lowpart (Pmode, operands[2]);
5832     }
5833
5834   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5835
5836   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5837     operands[0] = gen_lowpart (SImode, operands[0]);
5838
5839   if (TARGET_64BIT && mode != Pmode)
5840     pat = gen_rtx_SUBREG (SImode, pat, 0);
5841
5842   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5843   DONE;
5844 })
5845
5846 ;; Convert lea to the lea pattern to avoid flags dependency.
5847 ;; ??? This pattern handles immediate operands that do not satisfy immediate
5848 ;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern.
5849 (define_split
5850   [(set (match_operand:DI 0 "register_operand" "")
5851         (plus:DI (match_operand:DI 1 "register_operand" "")
5852                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
5853    (clobber (reg:CC FLAGS_REG))]
5854   "TARGET_64BIT && reload_completed 
5855    && true_regnum (operands[0]) != true_regnum (operands[1])"
5856   [(set (match_dup 0)
5857         (plus:DI (match_dup 1) (match_dup 2)))])
5858
5859 ;; Convert lea to the lea pattern to avoid flags dependency.
5860 (define_split
5861   [(set (match_operand:DI 0 "register_operand" "")
5862         (zero_extend:DI
5863           (plus:SI (match_operand:SI 1 "register_operand" "")
5864                    (match_operand:SI 2 "nonmemory_operand" ""))))
5865    (clobber (reg:CC FLAGS_REG))]
5866   "TARGET_64BIT && reload_completed
5867    && ix86_lea_for_add_ok (insn, operands)"
5868   [(set (match_dup 0)
5869         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5870 {
5871   operands[1] = gen_lowpart (DImode, operands[1]);
5872   operands[2] = gen_lowpart (DImode, operands[2]);
5873 })
5874
5875 (define_insn "*add<mode>_2"
5876   [(set (reg FLAGS_REG)
5877         (compare
5878           (plus:SWI
5879             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5880             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5881           (const_int 0)))
5882    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5883         (plus:SWI (match_dup 1) (match_dup 2)))]
5884   "ix86_match_ccmode (insn, CCGOCmode)
5885    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5886 {
5887   switch (get_attr_type (insn))
5888     {
5889     case TYPE_INCDEC:
5890       if (operands[2] == const1_rtx)
5891         return "inc{<imodesuffix>}\t%0";
5892       else
5893         {
5894           gcc_assert (operands[2] == constm1_rtx);
5895           return "dec{<imodesuffix>}\t%0";
5896         }
5897
5898     default:
5899       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5900         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5901
5902       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5903     }
5904 }
5905   [(set (attr "type")
5906      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5907         (const_string "incdec")
5908         (const_string "alu")))
5909    (set (attr "length_immediate")
5910       (if_then_else
5911         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5912         (const_string "1")
5913         (const_string "*")))
5914    (set_attr "mode" "<MODE>")])
5915
5916 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5917 (define_insn "*addsi_2_zext"
5918   [(set (reg FLAGS_REG)
5919         (compare
5920           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5921                    (match_operand:SI 2 "general_operand" "g"))
5922           (const_int 0)))
5923    (set (match_operand:DI 0 "register_operand" "=r")
5924         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5925   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5926    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5927 {
5928   switch (get_attr_type (insn))
5929     {
5930     case TYPE_INCDEC:
5931       if (operands[2] == const1_rtx)
5932         return "inc{l}\t%k0";
5933       else
5934         {
5935           gcc_assert (operands[2] == constm1_rtx);
5936           return "dec{l}\t%k0";
5937         }
5938
5939     default:
5940       if (x86_maybe_negate_const_int (&operands[2], SImode))
5941         return "sub{l}\t{%2, %k0|%k0, %2}";
5942
5943       return "add{l}\t{%2, %k0|%k0, %2}";
5944     }
5945 }
5946   [(set (attr "type")
5947      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5948         (const_string "incdec")
5949         (const_string "alu")))
5950    (set (attr "length_immediate")
5951       (if_then_else
5952         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5953         (const_string "1")
5954         (const_string "*")))
5955    (set_attr "mode" "SI")])
5956
5957 (define_insn "*add<mode>_3"
5958   [(set (reg FLAGS_REG)
5959         (compare
5960           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5961           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5962    (clobber (match_scratch:SWI 0 "=<r>"))]
5963   "ix86_match_ccmode (insn, CCZmode)
5964    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5965 {
5966   switch (get_attr_type (insn))
5967     {
5968     case TYPE_INCDEC:
5969       if (operands[2] == const1_rtx)
5970         return "inc{<imodesuffix>}\t%0";
5971       else
5972         {
5973           gcc_assert (operands[2] == constm1_rtx);
5974           return "dec{<imodesuffix>}\t%0";
5975         }
5976
5977     default:
5978       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5979         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5980
5981       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5982     }
5983 }
5984   [(set (attr "type")
5985      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5986         (const_string "incdec")
5987         (const_string "alu")))
5988    (set (attr "length_immediate")
5989       (if_then_else
5990         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5991         (const_string "1")
5992         (const_string "*")))
5993    (set_attr "mode" "<MODE>")])
5994
5995 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5996 (define_insn "*addsi_3_zext"
5997   [(set (reg FLAGS_REG)
5998         (compare
5999           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6000           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6001    (set (match_operand:DI 0 "register_operand" "=r")
6002         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6003   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6004    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6005 {
6006   switch (get_attr_type (insn))
6007     {
6008     case TYPE_INCDEC:
6009       if (operands[2] == const1_rtx)
6010         return "inc{l}\t%k0";
6011       else
6012         {
6013           gcc_assert (operands[2] == constm1_rtx);
6014           return "dec{l}\t%k0";
6015         }
6016
6017     default:
6018       if (x86_maybe_negate_const_int (&operands[2], SImode))
6019         return "sub{l}\t{%2, %k0|%k0, %2}";
6020
6021       return "add{l}\t{%2, %k0|%k0, %2}";
6022     }
6023 }
6024   [(set (attr "type")
6025      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6026         (const_string "incdec")
6027         (const_string "alu")))
6028    (set (attr "length_immediate")
6029       (if_then_else
6030         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6031         (const_string "1")
6032         (const_string "*")))
6033    (set_attr "mode" "SI")])
6034
6035 ; For comparisons against 1, -1 and 128, we may generate better code
6036 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6037 ; is matched then.  We can't accept general immediate, because for
6038 ; case of overflows,  the result is messed up.
6039 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6040 ; only for comparisons not depending on it.
6041
6042 (define_insn "*adddi_4"
6043   [(set (reg FLAGS_REG)
6044         (compare
6045           (match_operand:DI 1 "nonimmediate_operand" "0")
6046           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6047    (clobber (match_scratch:DI 0 "=rm"))]
6048   "TARGET_64BIT
6049    && ix86_match_ccmode (insn, CCGCmode)"
6050 {
6051   switch (get_attr_type (insn))
6052     {
6053     case TYPE_INCDEC:
6054       if (operands[2] == constm1_rtx)
6055         return "inc{q}\t%0";
6056       else
6057         {
6058           gcc_assert (operands[2] == const1_rtx);
6059           return "dec{q}\t%0";
6060         }
6061
6062     default:
6063       if (x86_maybe_negate_const_int (&operands[2], DImode))
6064         return "add{q}\t{%2, %0|%0, %2}";
6065
6066       return "sub{q}\t{%2, %0|%0, %2}";
6067     }
6068 }
6069   [(set (attr "type")
6070      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6071         (const_string "incdec")
6072         (const_string "alu")))
6073    (set (attr "length_immediate")
6074       (if_then_else
6075         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6076         (const_string "1")
6077         (const_string "*")))
6078    (set_attr "mode" "DI")])
6079
6080 ; For comparisons against 1, -1 and 128, we may generate better code
6081 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6082 ; is matched then.  We can't accept general immediate, because for
6083 ; case of overflows,  the result is messed up.
6084 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6085 ; only for comparisons not depending on it.
6086
6087 (define_insn "*add<mode>_4"
6088   [(set (reg FLAGS_REG)
6089         (compare
6090           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6091           (match_operand:SWI124 2 "const_int_operand" "n")))
6092    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6093   "ix86_match_ccmode (insn, CCGCmode)"
6094 {
6095   switch (get_attr_type (insn))
6096     {
6097     case TYPE_INCDEC:
6098       if (operands[2] == constm1_rtx)
6099         return "inc{<imodesuffix>}\t%0";
6100       else
6101         {
6102           gcc_assert (operands[2] == const1_rtx);
6103           return "dec{<imodesuffix>}\t%0";
6104         }
6105
6106     default:
6107       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6108         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6109
6110       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6111     }
6112 }
6113   [(set (attr "type")
6114      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6115         (const_string "incdec")
6116         (const_string "alu")))
6117    (set (attr "length_immediate")
6118       (if_then_else
6119         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6120         (const_string "1")
6121         (const_string "*")))
6122    (set_attr "mode" "<MODE>")])
6123
6124 (define_insn "*add<mode>_5"
6125   [(set (reg FLAGS_REG)
6126         (compare
6127           (plus:SWI
6128             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6129             (match_operand:SWI 2 "<general_operand>" "<g>"))
6130           (const_int 0)))
6131    (clobber (match_scratch:SWI 0 "=<r>"))]
6132   "ix86_match_ccmode (insn, CCGOCmode)
6133    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6134 {
6135   switch (get_attr_type (insn))
6136     {
6137     case TYPE_INCDEC:
6138       if (operands[2] == const1_rtx)
6139         return "inc{<imodesuffix>}\t%0";
6140       else
6141         {
6142           gcc_assert (operands[2] == constm1_rtx);
6143           return "dec{<imodesuffix>}\t%0";
6144         }
6145
6146     default:
6147       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6148         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6149
6150       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6151     }
6152 }
6153   [(set (attr "type")
6154      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6155         (const_string "incdec")
6156         (const_string "alu")))
6157    (set (attr "length_immediate")
6158       (if_then_else
6159         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6160         (const_string "1")
6161         (const_string "*")))
6162    (set_attr "mode" "<MODE>")])
6163
6164 (define_insn "*addqi_ext_1_rex64"
6165   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6166                          (const_int 8)
6167                          (const_int 8))
6168         (plus:SI
6169           (zero_extract:SI
6170             (match_operand 1 "ext_register_operand" "0")
6171             (const_int 8)
6172             (const_int 8))
6173           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6174    (clobber (reg:CC FLAGS_REG))]
6175   "TARGET_64BIT"
6176 {
6177   switch (get_attr_type (insn))
6178     {
6179     case TYPE_INCDEC:
6180       if (operands[2] == const1_rtx)
6181         return "inc{b}\t%h0";
6182       else
6183         {
6184           gcc_assert (operands[2] == constm1_rtx);
6185           return "dec{b}\t%h0";
6186         }
6187
6188     default:
6189       return "add{b}\t{%2, %h0|%h0, %2}";
6190     }
6191 }
6192   [(set (attr "type")
6193      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6194         (const_string "incdec")
6195         (const_string "alu")))
6196    (set_attr "modrm" "1")
6197    (set_attr "mode" "QI")])
6198
6199 (define_insn "addqi_ext_1"
6200   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6201                          (const_int 8)
6202                          (const_int 8))
6203         (plus:SI
6204           (zero_extract:SI
6205             (match_operand 1 "ext_register_operand" "0")
6206             (const_int 8)
6207             (const_int 8))
6208           (match_operand:QI 2 "general_operand" "Qmn")))
6209    (clobber (reg:CC FLAGS_REG))]
6210   "!TARGET_64BIT"
6211 {
6212   switch (get_attr_type (insn))
6213     {
6214     case TYPE_INCDEC:
6215       if (operands[2] == const1_rtx)
6216         return "inc{b}\t%h0";
6217       else
6218         {
6219           gcc_assert (operands[2] == constm1_rtx);
6220           return "dec{b}\t%h0";
6221         }
6222
6223     default:
6224       return "add{b}\t{%2, %h0|%h0, %2}";
6225     }
6226 }
6227   [(set (attr "type")
6228      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6229         (const_string "incdec")
6230         (const_string "alu")))
6231    (set_attr "modrm" "1")
6232    (set_attr "mode" "QI")])
6233
6234 (define_insn "*addqi_ext_2"
6235   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6236                          (const_int 8)
6237                          (const_int 8))
6238         (plus:SI
6239           (zero_extract:SI
6240             (match_operand 1 "ext_register_operand" "%0")
6241             (const_int 8)
6242             (const_int 8))
6243           (zero_extract:SI
6244             (match_operand 2 "ext_register_operand" "Q")
6245             (const_int 8)
6246             (const_int 8))))
6247    (clobber (reg:CC FLAGS_REG))]
6248   ""
6249   "add{b}\t{%h2, %h0|%h0, %h2}"
6250   [(set_attr "type" "alu")
6251    (set_attr "mode" "QI")])
6252
6253 ;; The lea patterns for non-Pmodes needs to be matched by
6254 ;; several insns converted to real lea by splitters.
6255
6256 (define_insn_and_split "*lea_general_1"
6257   [(set (match_operand 0 "register_operand" "=r")
6258         (plus (plus (match_operand 1 "index_register_operand" "l")
6259                     (match_operand 2 "register_operand" "r"))
6260               (match_operand 3 "immediate_operand" "i")))]
6261   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6262     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6263    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6264    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6265    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6266    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6267        || GET_MODE (operands[3]) == VOIDmode)"
6268   "#"
6269   "&& reload_completed"
6270   [(const_int 0)]
6271 {
6272   rtx pat;
6273   operands[0] = gen_lowpart (SImode, operands[0]);
6274   operands[1] = gen_lowpart (Pmode, operands[1]);
6275   operands[2] = gen_lowpart (Pmode, operands[2]);
6276   operands[3] = gen_lowpart (Pmode, operands[3]);
6277   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6278                       operands[3]);
6279   if (Pmode != SImode)
6280     pat = gen_rtx_SUBREG (SImode, pat, 0);
6281   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6282   DONE;
6283 }
6284   [(set_attr "type" "lea")
6285    (set_attr "mode" "SI")])
6286
6287 (define_insn_and_split "*lea_general_1_zext"
6288   [(set (match_operand:DI 0 "register_operand" "=r")
6289         (zero_extend:DI
6290           (plus:SI (plus:SI
6291                      (match_operand:SI 1 "index_register_operand" "l")
6292                      (match_operand:SI 2 "register_operand" "r"))
6293                    (match_operand:SI 3 "immediate_operand" "i"))))]
6294   "TARGET_64BIT"
6295   "#"
6296   "&& reload_completed"
6297   [(set (match_dup 0)
6298         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6299                                                      (match_dup 2))
6300                                             (match_dup 3)) 0)))]
6301 {
6302   operands[1] = gen_lowpart (Pmode, operands[1]);
6303   operands[2] = gen_lowpart (Pmode, operands[2]);
6304   operands[3] = gen_lowpart (Pmode, operands[3]);
6305 }
6306   [(set_attr "type" "lea")
6307    (set_attr "mode" "SI")])
6308
6309 (define_insn_and_split "*lea_general_2"
6310   [(set (match_operand 0 "register_operand" "=r")
6311         (plus (mult (match_operand 1 "index_register_operand" "l")
6312                     (match_operand 2 "const248_operand" "i"))
6313               (match_operand 3 "nonmemory_operand" "ri")))]
6314   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6315     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6316    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6317    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6318    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6319        || GET_MODE (operands[3]) == VOIDmode)"
6320   "#"
6321   "&& reload_completed"
6322   [(const_int 0)]
6323 {
6324   rtx pat;
6325   operands[0] = gen_lowpart (SImode, operands[0]);
6326   operands[1] = gen_lowpart (Pmode, operands[1]);
6327   operands[3] = gen_lowpart (Pmode, operands[3]);
6328   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6329                       operands[3]);
6330   if (Pmode != SImode)
6331     pat = gen_rtx_SUBREG (SImode, pat, 0);
6332   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6333   DONE;
6334 }
6335   [(set_attr "type" "lea")
6336    (set_attr "mode" "SI")])
6337
6338 (define_insn_and_split "*lea_general_2_zext"
6339   [(set (match_operand:DI 0 "register_operand" "=r")
6340         (zero_extend:DI
6341           (plus:SI (mult:SI
6342                      (match_operand:SI 1 "index_register_operand" "l")
6343                      (match_operand:SI 2 "const248_operand" "n"))
6344                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6345   "TARGET_64BIT"
6346   "#"
6347   "&& reload_completed"
6348   [(set (match_dup 0)
6349         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6350                                                      (match_dup 2))
6351                                             (match_dup 3)) 0)))]
6352 {
6353   operands[1] = gen_lowpart (Pmode, operands[1]);
6354   operands[3] = gen_lowpart (Pmode, operands[3]);
6355 }
6356   [(set_attr "type" "lea")
6357    (set_attr "mode" "SI")])
6358
6359 (define_insn_and_split "*lea_general_3"
6360   [(set (match_operand 0 "register_operand" "=r")
6361         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6362                           (match_operand 2 "const248_operand" "i"))
6363                     (match_operand 3 "register_operand" "r"))
6364               (match_operand 4 "immediate_operand" "i")))]
6365   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6366     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6367    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6368    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6369    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6370   "#"
6371   "&& reload_completed"
6372   [(const_int 0)]
6373 {
6374   rtx pat;
6375   operands[0] = gen_lowpart (SImode, operands[0]);
6376   operands[1] = gen_lowpart (Pmode, operands[1]);
6377   operands[3] = gen_lowpart (Pmode, operands[3]);
6378   operands[4] = gen_lowpart (Pmode, operands[4]);
6379   pat = gen_rtx_PLUS (Pmode,
6380                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6381                                                          operands[2]),
6382                                     operands[3]),
6383                       operands[4]);
6384   if (Pmode != SImode)
6385     pat = gen_rtx_SUBREG (SImode, pat, 0);
6386   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6387   DONE;
6388 }
6389   [(set_attr "type" "lea")
6390    (set_attr "mode" "SI")])
6391
6392 (define_insn_and_split "*lea_general_3_zext"
6393   [(set (match_operand:DI 0 "register_operand" "=r")
6394         (zero_extend:DI
6395           (plus:SI (plus:SI
6396                      (mult:SI
6397                        (match_operand:SI 1 "index_register_operand" "l")
6398                        (match_operand:SI 2 "const248_operand" "n"))
6399                      (match_operand:SI 3 "register_operand" "r"))
6400                    (match_operand:SI 4 "immediate_operand" "i"))))]
6401   "TARGET_64BIT"
6402   "#"
6403   "&& reload_completed"
6404   [(set (match_dup 0)
6405         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6406                                                               (match_dup 2))
6407                                                      (match_dup 3))
6408                                             (match_dup 4)) 0)))]
6409 {
6410   operands[1] = gen_lowpart (Pmode, operands[1]);
6411   operands[3] = gen_lowpart (Pmode, operands[3]);
6412   operands[4] = gen_lowpart (Pmode, operands[4]);
6413 }
6414   [(set_attr "type" "lea")
6415    (set_attr "mode" "SI")])
6416 \f
6417 ;; Subtract instructions
6418
6419 (define_expand "sub<mode>3"
6420   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6421         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6422                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6423   ""
6424   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6425
6426 (define_insn_and_split "*sub<dwi>3_doubleword"
6427   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6428         (minus:<DWI>
6429           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6430           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6431    (clobber (reg:CC FLAGS_REG))]
6432   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6433   "#"
6434   "reload_completed"
6435   [(parallel [(set (reg:CC FLAGS_REG)
6436                    (compare:CC (match_dup 1) (match_dup 2)))
6437               (set (match_dup 0)
6438                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6439    (parallel [(set (match_dup 3)
6440                    (minus:DWIH
6441                      (match_dup 4)
6442                      (plus:DWIH
6443                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6444                        (match_dup 5))))
6445               (clobber (reg:CC FLAGS_REG))])]
6446   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6447
6448 (define_insn "*sub<mode>_1"
6449   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6450         (minus:SWI
6451           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6452           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6453    (clobber (reg:CC FLAGS_REG))]
6454   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6455   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6456   [(set_attr "type" "alu")
6457    (set_attr "mode" "<MODE>")])
6458
6459 (define_insn "*subsi_1_zext"
6460   [(set (match_operand:DI 0 "register_operand" "=r")
6461         (zero_extend:DI
6462           (minus:SI (match_operand:SI 1 "register_operand" "0")
6463                     (match_operand:SI 2 "general_operand" "g"))))
6464    (clobber (reg:CC FLAGS_REG))]
6465   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6466   "sub{l}\t{%2, %k0|%k0, %2}"
6467   [(set_attr "type" "alu")
6468    (set_attr "mode" "SI")])
6469
6470 (define_insn "*subqi_1_slp"
6471   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6472         (minus:QI (match_dup 0)
6473                   (match_operand:QI 1 "general_operand" "qn,qm")))
6474    (clobber (reg:CC FLAGS_REG))]
6475   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6476    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6477   "sub{b}\t{%1, %0|%0, %1}"
6478   [(set_attr "type" "alu1")
6479    (set_attr "mode" "QI")])
6480
6481 (define_insn "*sub<mode>_2"
6482   [(set (reg FLAGS_REG)
6483         (compare
6484           (minus:SWI
6485             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6486             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6487           (const_int 0)))
6488    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6489         (minus:SWI (match_dup 1) (match_dup 2)))]
6490   "ix86_match_ccmode (insn, CCGOCmode)
6491    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6492   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6493   [(set_attr "type" "alu")
6494    (set_attr "mode" "<MODE>")])
6495
6496 (define_insn "*subsi_2_zext"
6497   [(set (reg FLAGS_REG)
6498         (compare
6499           (minus:SI (match_operand:SI 1 "register_operand" "0")
6500                     (match_operand:SI 2 "general_operand" "g"))
6501           (const_int 0)))
6502    (set (match_operand:DI 0 "register_operand" "=r")
6503         (zero_extend:DI
6504           (minus:SI (match_dup 1)
6505                     (match_dup 2))))]
6506   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6507    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6508   "sub{l}\t{%2, %k0|%k0, %2}"
6509   [(set_attr "type" "alu")
6510    (set_attr "mode" "SI")])
6511
6512 (define_insn "*sub<mode>_3"
6513   [(set (reg FLAGS_REG)
6514         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6515                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6516    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6517         (minus:SWI (match_dup 1) (match_dup 2)))]
6518   "ix86_match_ccmode (insn, CCmode)
6519    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6520   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6521   [(set_attr "type" "alu")
6522    (set_attr "mode" "<MODE>")])
6523
6524 (define_insn "*subsi_3_zext"
6525   [(set (reg FLAGS_REG)
6526         (compare (match_operand:SI 1 "register_operand" "0")
6527                  (match_operand:SI 2 "general_operand" "g")))
6528    (set (match_operand:DI 0 "register_operand" "=r")
6529         (zero_extend:DI
6530           (minus:SI (match_dup 1)
6531                     (match_dup 2))))]
6532   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6533    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6534   "sub{l}\t{%2, %1|%1, %2}"
6535   [(set_attr "type" "alu")
6536    (set_attr "mode" "SI")])
6537 \f
6538 ;; Add with carry and subtract with borrow
6539
6540 (define_expand "<plusminus_insn><mode>3_carry"
6541   [(parallel
6542     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6543           (plusminus:SWI
6544             (match_operand:SWI 1 "nonimmediate_operand" "")
6545             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6546                        [(match_operand 3 "flags_reg_operand" "")
6547                         (const_int 0)])
6548                       (match_operand:SWI 2 "<general_operand>" ""))))
6549      (clobber (reg:CC FLAGS_REG))])]
6550   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6551
6552 (define_insn "*<plusminus_insn><mode>3_carry"
6553   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6554         (plusminus:SWI
6555           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6556           (plus:SWI
6557             (match_operator 3 "ix86_carry_flag_operator"
6558              [(reg FLAGS_REG) (const_int 0)])
6559             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6560    (clobber (reg:CC FLAGS_REG))]
6561   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6562   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6563   [(set_attr "type" "alu")
6564    (set_attr "use_carry" "1")
6565    (set_attr "pent_pair" "pu")
6566    (set_attr "mode" "<MODE>")])
6567
6568 (define_insn "*addsi3_carry_zext"
6569   [(set (match_operand:DI 0 "register_operand" "=r")
6570         (zero_extend:DI
6571           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6572                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6573                              [(reg FLAGS_REG) (const_int 0)])
6574                             (match_operand:SI 2 "general_operand" "g")))))
6575    (clobber (reg:CC FLAGS_REG))]
6576   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6577   "adc{l}\t{%2, %k0|%k0, %2}"
6578   [(set_attr "type" "alu")
6579    (set_attr "use_carry" "1")
6580    (set_attr "pent_pair" "pu")
6581    (set_attr "mode" "SI")])
6582
6583 (define_insn "*subsi3_carry_zext"
6584   [(set (match_operand:DI 0 "register_operand" "=r")
6585         (zero_extend:DI
6586           (minus:SI (match_operand:SI 1 "register_operand" "0")
6587                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6588                               [(reg FLAGS_REG) (const_int 0)])
6589                              (match_operand:SI 2 "general_operand" "g")))))
6590    (clobber (reg:CC FLAGS_REG))]
6591   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6592   "sbb{l}\t{%2, %k0|%k0, %2}"
6593   [(set_attr "type" "alu")
6594    (set_attr "pent_pair" "pu")
6595    (set_attr "mode" "SI")])
6596 \f
6597 ;; Overflow setting add and subtract instructions
6598
6599 (define_insn "*add<mode>3_cconly_overflow"
6600   [(set (reg:CCC FLAGS_REG)
6601         (compare:CCC
6602           (plus:SWI
6603             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6604             (match_operand:SWI 2 "<general_operand>" "<g>"))
6605           (match_dup 1)))
6606    (clobber (match_scratch:SWI 0 "=<r>"))]
6607   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6608   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6609   [(set_attr "type" "alu")
6610    (set_attr "mode" "<MODE>")])
6611
6612 (define_insn "*sub<mode>3_cconly_overflow"
6613   [(set (reg:CCC FLAGS_REG)
6614         (compare:CCC
6615           (minus:SWI
6616             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6617             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6618           (match_dup 0)))]
6619   ""
6620   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6621   [(set_attr "type" "icmp")
6622    (set_attr "mode" "<MODE>")])
6623
6624 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6625   [(set (reg:CCC FLAGS_REG)
6626         (compare:CCC
6627             (plusminus:SWI
6628                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6629                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6630             (match_dup 1)))
6631    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6632         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6633   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6634   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6635   [(set_attr "type" "alu")
6636    (set_attr "mode" "<MODE>")])
6637
6638 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6639   [(set (reg:CCC FLAGS_REG)
6640         (compare:CCC
6641           (plusminus:SI
6642             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6643             (match_operand:SI 2 "general_operand" "g"))
6644           (match_dup 1)))
6645    (set (match_operand:DI 0 "register_operand" "=r")
6646         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6647   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6648   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6649   [(set_attr "type" "alu")
6650    (set_attr "mode" "SI")])
6651
6652 ;; The patterns that match these are at the end of this file.
6653
6654 (define_expand "<plusminus_insn>xf3"
6655   [(set (match_operand:XF 0 "register_operand" "")
6656         (plusminus:XF
6657           (match_operand:XF 1 "register_operand" "")
6658           (match_operand:XF 2 "register_operand" "")))]
6659   "TARGET_80387")
6660
6661 (define_expand "<plusminus_insn><mode>3"
6662   [(set (match_operand:MODEF 0 "register_operand" "")
6663         (plusminus:MODEF
6664           (match_operand:MODEF 1 "register_operand" "")
6665           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6666   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6667     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6668 \f
6669 ;; Multiply instructions
6670
6671 (define_expand "mul<mode>3"
6672   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6673                    (mult:SWIM248
6674                      (match_operand:SWIM248 1 "register_operand" "")
6675                      (match_operand:SWIM248 2 "<general_operand>" "")))
6676               (clobber (reg:CC FLAGS_REG))])])
6677
6678 (define_expand "mulqi3"
6679   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6680                    (mult:QI
6681                      (match_operand:QI 1 "register_operand" "")
6682                      (match_operand:QI 2 "nonimmediate_operand" "")))
6683               (clobber (reg:CC FLAGS_REG))])]
6684   "TARGET_QIMODE_MATH")
6685
6686 ;; On AMDFAM10
6687 ;; IMUL reg32/64, reg32/64, imm8        Direct
6688 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6689 ;; IMUL reg32/64, reg32/64, imm32       Direct
6690 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6691 ;; IMUL reg32/64, reg32/64              Direct
6692 ;; IMUL reg32/64, mem32/64              Direct
6693 ;;
6694 ;; On BDVER1, all above IMULs use DirectPath
6695
6696 (define_insn "*mul<mode>3_1"
6697   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6698         (mult:SWI48
6699           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6700           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6701    (clobber (reg:CC FLAGS_REG))]
6702   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6703   "@
6704    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6705    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6706    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6707   [(set_attr "type" "imul")
6708    (set_attr "prefix_0f" "0,0,1")
6709    (set (attr "athlon_decode")
6710         (cond [(eq_attr "cpu" "athlon")
6711                   (const_string "vector")
6712                (eq_attr "alternative" "1")
6713                   (const_string "vector")
6714                (and (eq_attr "alternative" "2")
6715                     (match_operand 1 "memory_operand" ""))
6716                   (const_string "vector")]
6717               (const_string "direct")))
6718    (set (attr "amdfam10_decode")
6719         (cond [(and (eq_attr "alternative" "0,1")
6720                     (match_operand 1 "memory_operand" ""))
6721                   (const_string "vector")]
6722               (const_string "direct")))
6723    (set_attr "bdver1_decode" "direct")
6724    (set_attr "mode" "<MODE>")])
6725
6726 (define_insn "*mulsi3_1_zext"
6727   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6728         (zero_extend:DI
6729           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6730                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6731    (clobber (reg:CC FLAGS_REG))]
6732   "TARGET_64BIT
6733    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6734   "@
6735    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6736    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6737    imul{l}\t{%2, %k0|%k0, %2}"
6738   [(set_attr "type" "imul")
6739    (set_attr "prefix_0f" "0,0,1")
6740    (set (attr "athlon_decode")
6741         (cond [(eq_attr "cpu" "athlon")
6742                   (const_string "vector")
6743                (eq_attr "alternative" "1")
6744                   (const_string "vector")
6745                (and (eq_attr "alternative" "2")
6746                     (match_operand 1 "memory_operand" ""))
6747                   (const_string "vector")]
6748               (const_string "direct")))
6749    (set (attr "amdfam10_decode")
6750         (cond [(and (eq_attr "alternative" "0,1")
6751                     (match_operand 1 "memory_operand" ""))
6752                   (const_string "vector")]
6753               (const_string "direct")))
6754    (set_attr "bdver1_decode" "direct")
6755    (set_attr "mode" "SI")])
6756
6757 ;; On AMDFAM10
6758 ;; IMUL reg16, reg16, imm8      VectorPath
6759 ;; IMUL reg16, mem16, imm8      VectorPath
6760 ;; IMUL reg16, reg16, imm16     VectorPath
6761 ;; IMUL reg16, mem16, imm16     VectorPath
6762 ;; IMUL reg16, reg16            Direct
6763 ;; IMUL reg16, mem16            Direct
6764 ;;
6765 ;; On BDVER1, all HI MULs use DoublePath
6766
6767 (define_insn "*mulhi3_1"
6768   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6769         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6770                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6771    (clobber (reg:CC FLAGS_REG))]
6772   "TARGET_HIMODE_MATH
6773    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6774   "@
6775    imul{w}\t{%2, %1, %0|%0, %1, %2}
6776    imul{w}\t{%2, %1, %0|%0, %1, %2}
6777    imul{w}\t{%2, %0|%0, %2}"
6778   [(set_attr "type" "imul")
6779    (set_attr "prefix_0f" "0,0,1")
6780    (set (attr "athlon_decode")
6781         (cond [(eq_attr "cpu" "athlon")
6782                   (const_string "vector")
6783                (eq_attr "alternative" "1,2")
6784                   (const_string "vector")]
6785               (const_string "direct")))
6786    (set (attr "amdfam10_decode")
6787         (cond [(eq_attr "alternative" "0,1")
6788                   (const_string "vector")]
6789               (const_string "direct")))
6790    (set_attr "bdver1_decode" "double")
6791    (set_attr "mode" "HI")])
6792
6793 ;;On AMDFAM10 and BDVER1
6794 ;; MUL reg8     Direct
6795 ;; MUL mem8     Direct
6796
6797 (define_insn "*mulqi3_1"
6798   [(set (match_operand:QI 0 "register_operand" "=a")
6799         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6800                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6801    (clobber (reg:CC FLAGS_REG))]
6802   "TARGET_QIMODE_MATH
6803    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6804   "mul{b}\t%2"
6805   [(set_attr "type" "imul")
6806    (set_attr "length_immediate" "0")
6807    (set (attr "athlon_decode")
6808      (if_then_else (eq_attr "cpu" "athlon")
6809         (const_string "vector")
6810         (const_string "direct")))
6811    (set_attr "amdfam10_decode" "direct")
6812    (set_attr "bdver1_decode" "direct")
6813    (set_attr "mode" "QI")])
6814
6815 (define_expand "<u>mul<mode><dwi>3"
6816   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6817                    (mult:<DWI>
6818                      (any_extend:<DWI>
6819                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6820                      (any_extend:<DWI>
6821                        (match_operand:DWIH 2 "register_operand" ""))))
6822               (clobber (reg:CC FLAGS_REG))])])
6823
6824 (define_expand "<u>mulqihi3"
6825   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6826                    (mult:HI
6827                      (any_extend:HI
6828                        (match_operand:QI 1 "nonimmediate_operand" ""))
6829                      (any_extend:HI
6830                        (match_operand:QI 2 "register_operand" ""))))
6831               (clobber (reg:CC FLAGS_REG))])]
6832   "TARGET_QIMODE_MATH")
6833
6834 (define_insn "*<u>mul<mode><dwi>3_1"
6835   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6836         (mult:<DWI>
6837           (any_extend:<DWI>
6838             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6839           (any_extend:<DWI>
6840             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6841    (clobber (reg:CC FLAGS_REG))]
6842   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6843   "<sgnprefix>mul{<imodesuffix>}\t%2"
6844   [(set_attr "type" "imul")
6845    (set_attr "length_immediate" "0")
6846    (set (attr "athlon_decode")
6847      (if_then_else (eq_attr "cpu" "athlon")
6848         (const_string "vector")
6849         (const_string "double")))
6850    (set_attr "amdfam10_decode" "double")
6851    (set_attr "bdver1_decode" "direct")
6852    (set_attr "mode" "<MODE>")])
6853
6854 (define_insn "*<u>mulqihi3_1"
6855   [(set (match_operand:HI 0 "register_operand" "=a")
6856         (mult:HI
6857           (any_extend:HI
6858             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6859           (any_extend:HI
6860             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6861    (clobber (reg:CC FLAGS_REG))]
6862   "TARGET_QIMODE_MATH
6863    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6864   "<sgnprefix>mul{b}\t%2"
6865   [(set_attr "type" "imul")
6866    (set_attr "length_immediate" "0")
6867    (set (attr "athlon_decode")
6868      (if_then_else (eq_attr "cpu" "athlon")
6869         (const_string "vector")
6870         (const_string "direct")))
6871    (set_attr "amdfam10_decode" "direct")
6872    (set_attr "bdver1_decode" "direct")
6873    (set_attr "mode" "QI")])
6874
6875 (define_expand "<s>mul<mode>3_highpart"
6876   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6877                    (truncate:SWI48
6878                      (lshiftrt:<DWI>
6879                        (mult:<DWI>
6880                          (any_extend:<DWI>
6881                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6882                          (any_extend:<DWI>
6883                            (match_operand:SWI48 2 "register_operand" "")))
6884                        (match_dup 4))))
6885               (clobber (match_scratch:SWI48 3 ""))
6886               (clobber (reg:CC FLAGS_REG))])]
6887   ""
6888   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6889
6890 (define_insn "*<s>muldi3_highpart_1"
6891   [(set (match_operand:DI 0 "register_operand" "=d")
6892         (truncate:DI
6893           (lshiftrt:TI
6894             (mult:TI
6895               (any_extend:TI
6896                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6897               (any_extend:TI
6898                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6899             (const_int 64))))
6900    (clobber (match_scratch:DI 3 "=1"))
6901    (clobber (reg:CC FLAGS_REG))]
6902   "TARGET_64BIT
6903    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6904   "<sgnprefix>mul{q}\t%2"
6905   [(set_attr "type" "imul")
6906    (set_attr "length_immediate" "0")
6907    (set (attr "athlon_decode")
6908      (if_then_else (eq_attr "cpu" "athlon")
6909         (const_string "vector")
6910         (const_string "double")))
6911    (set_attr "amdfam10_decode" "double")
6912    (set_attr "bdver1_decode" "direct")
6913    (set_attr "mode" "DI")])
6914
6915 (define_insn "*<s>mulsi3_highpart_1"
6916   [(set (match_operand:SI 0 "register_operand" "=d")
6917         (truncate:SI
6918           (lshiftrt:DI
6919             (mult:DI
6920               (any_extend:DI
6921                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6922               (any_extend:DI
6923                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6924             (const_int 32))))
6925    (clobber (match_scratch:SI 3 "=1"))
6926    (clobber (reg:CC FLAGS_REG))]
6927   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6928   "<sgnprefix>mul{l}\t%2"
6929   [(set_attr "type" "imul")
6930    (set_attr "length_immediate" "0")
6931    (set (attr "athlon_decode")
6932      (if_then_else (eq_attr "cpu" "athlon")
6933         (const_string "vector")
6934         (const_string "double")))
6935    (set_attr "amdfam10_decode" "double")
6936    (set_attr "bdver1_decode" "direct")
6937    (set_attr "mode" "SI")])
6938
6939 (define_insn "*<s>mulsi3_highpart_zext"
6940   [(set (match_operand:DI 0 "register_operand" "=d")
6941         (zero_extend:DI (truncate:SI
6942           (lshiftrt:DI
6943             (mult:DI (any_extend:DI
6944                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6945                      (any_extend:DI
6946                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6947             (const_int 32)))))
6948    (clobber (match_scratch:SI 3 "=1"))
6949    (clobber (reg:CC FLAGS_REG))]
6950   "TARGET_64BIT
6951    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6952   "<sgnprefix>mul{l}\t%2"
6953   [(set_attr "type" "imul")
6954    (set_attr "length_immediate" "0")
6955    (set (attr "athlon_decode")
6956      (if_then_else (eq_attr "cpu" "athlon")
6957         (const_string "vector")
6958         (const_string "double")))
6959    (set_attr "amdfam10_decode" "double")
6960    (set_attr "bdver1_decode" "direct")
6961    (set_attr "mode" "SI")])
6962
6963 ;; The patterns that match these are at the end of this file.
6964
6965 (define_expand "mulxf3"
6966   [(set (match_operand:XF 0 "register_operand" "")
6967         (mult:XF (match_operand:XF 1 "register_operand" "")
6968                  (match_operand:XF 2 "register_operand" "")))]
6969   "TARGET_80387")
6970
6971 (define_expand "mul<mode>3"
6972   [(set (match_operand:MODEF 0 "register_operand" "")
6973         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6974                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6975   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6976     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6977 \f
6978 ;; Divide instructions
6979
6980 ;; The patterns that match these are at the end of this file.
6981
6982 (define_expand "divxf3"
6983   [(set (match_operand:XF 0 "register_operand" "")
6984         (div:XF (match_operand:XF 1 "register_operand" "")
6985                 (match_operand:XF 2 "register_operand" "")))]
6986   "TARGET_80387")
6987
6988 (define_expand "divdf3"
6989   [(set (match_operand:DF 0 "register_operand" "")
6990         (div:DF (match_operand:DF 1 "register_operand" "")
6991                 (match_operand:DF 2 "nonimmediate_operand" "")))]
6992    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6993     || (TARGET_SSE2 && TARGET_SSE_MATH)")
6994
6995 (define_expand "divsf3"
6996   [(set (match_operand:SF 0 "register_operand" "")
6997         (div:SF (match_operand:SF 1 "register_operand" "")
6998                 (match_operand:SF 2 "nonimmediate_operand" "")))]
6999   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7000     || TARGET_SSE_MATH"
7001 {
7002   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7003       && flag_finite_math_only && !flag_trapping_math
7004       && flag_unsafe_math_optimizations)
7005     {
7006       ix86_emit_swdivsf (operands[0], operands[1],
7007                          operands[2], SFmode);
7008       DONE;
7009     }
7010 })
7011 \f
7012 ;; Divmod instructions.
7013
7014 (define_expand "divmod<mode>4"
7015   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7016                    (div:SWIM248
7017                      (match_operand:SWIM248 1 "register_operand" "")
7018                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7019               (set (match_operand:SWIM248 3 "register_operand" "")
7020                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7021               (clobber (reg:CC FLAGS_REG))])])
7022
7023 ;; Split with 8bit unsigned divide:
7024 ;;      if (dividend an divisor are in [0-255])
7025 ;;         use 8bit unsigned integer divide
7026 ;;       else
7027 ;;         use original integer divide
7028 (define_split
7029   [(set (match_operand:SWI48 0 "register_operand" "")
7030         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7031                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7032    (set (match_operand:SWI48 1 "register_operand" "")
7033         (mod:SWI48 (match_dup 2) (match_dup 3)))
7034    (clobber (reg:CC FLAGS_REG))]
7035   "TARGET_USE_8BIT_IDIV
7036    && TARGET_QIMODE_MATH
7037    && can_create_pseudo_p ()
7038    && !optimize_insn_for_size_p ()"
7039   [(const_int 0)]
7040   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7041
7042 (define_insn_and_split "divmod<mode>4_1"
7043   [(set (match_operand:SWI48 0 "register_operand" "=a")
7044         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7045                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7046    (set (match_operand:SWI48 1 "register_operand" "=&d")
7047         (mod:SWI48 (match_dup 2) (match_dup 3)))
7048    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7049    (clobber (reg:CC FLAGS_REG))]
7050   ""
7051   "#"
7052   "reload_completed"
7053   [(parallel [(set (match_dup 1)
7054                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7055               (clobber (reg:CC FLAGS_REG))])
7056    (parallel [(set (match_dup 0)
7057                    (div:SWI48 (match_dup 2) (match_dup 3)))
7058               (set (match_dup 1)
7059                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7060               (use (match_dup 1))
7061               (clobber (reg:CC FLAGS_REG))])]
7062 {
7063   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7064
7065   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7066     operands[4] = operands[2];
7067   else
7068     {
7069       /* Avoid use of cltd in favor of a mov+shift.  */
7070       emit_move_insn (operands[1], operands[2]);
7071       operands[4] = operands[1];
7072     }
7073 }
7074   [(set_attr "type" "multi")
7075    (set_attr "mode" "<MODE>")])
7076
7077 (define_insn_and_split "*divmod<mode>4"
7078   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7079         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7080                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7081    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7082         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7083    (clobber (reg:CC FLAGS_REG))]
7084   ""
7085   "#"
7086   "reload_completed"
7087   [(parallel [(set (match_dup 1)
7088                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7089               (clobber (reg:CC FLAGS_REG))])
7090    (parallel [(set (match_dup 0)
7091                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7092               (set (match_dup 1)
7093                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7094               (use (match_dup 1))
7095               (clobber (reg:CC FLAGS_REG))])]
7096 {
7097   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7098
7099   if (<MODE>mode != HImode
7100       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7101     operands[4] = operands[2];
7102   else
7103     {
7104       /* Avoid use of cltd in favor of a mov+shift.  */
7105       emit_move_insn (operands[1], operands[2]);
7106       operands[4] = operands[1];
7107     }
7108 }
7109   [(set_attr "type" "multi")
7110    (set_attr "mode" "<MODE>")])
7111
7112 (define_insn "*divmod<mode>4_noext"
7113   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7114         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7115                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7116    (set (match_operand:SWIM248 1 "register_operand" "=d")
7117         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7118    (use (match_operand:SWIM248 4 "register_operand" "1"))
7119    (clobber (reg:CC FLAGS_REG))]
7120   ""
7121   "idiv{<imodesuffix>}\t%3"
7122   [(set_attr "type" "idiv")
7123    (set_attr "mode" "<MODE>")])
7124
7125 (define_expand "divmodqi4"
7126   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7127                    (div:QI
7128                      (match_operand:QI 1 "register_operand" "")
7129                      (match_operand:QI 2 "nonimmediate_operand" "")))
7130               (set (match_operand:QI 3 "register_operand" "")
7131                    (mod:QI (match_dup 1) (match_dup 2)))
7132               (clobber (reg:CC FLAGS_REG))])]
7133   "TARGET_QIMODE_MATH"
7134 {
7135   rtx div, mod, insn;
7136   rtx tmp0, tmp1;
7137   
7138   tmp0 = gen_reg_rtx (HImode);
7139   tmp1 = gen_reg_rtx (HImode);
7140
7141   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7142      in AX.  */
7143   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7144   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7145
7146   /* Extract remainder from AH.  */
7147   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7148   insn = emit_move_insn (operands[3], tmp1);
7149
7150   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7151   set_unique_reg_note (insn, REG_EQUAL, mod);
7152
7153   /* Extract quotient from AL.  */
7154   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7155
7156   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7157   set_unique_reg_note (insn, REG_EQUAL, div);
7158
7159   DONE;
7160 })
7161
7162 ;; Divide AX by r/m8, with result stored in
7163 ;; AL <- Quotient
7164 ;; AH <- Remainder
7165 ;; Change div/mod to HImode and extend the second argument to HImode
7166 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7167 ;; combine may fail.
7168 (define_insn "divmodhiqi3"
7169   [(set (match_operand:HI 0 "register_operand" "=a")
7170         (ior:HI
7171           (ashift:HI
7172             (zero_extend:HI
7173               (truncate:QI
7174                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7175                         (sign_extend:HI
7176                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7177             (const_int 8))
7178           (zero_extend:HI
7179             (truncate:QI
7180               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7181    (clobber (reg:CC FLAGS_REG))]
7182   "TARGET_QIMODE_MATH"
7183   "idiv{b}\t%2"
7184   [(set_attr "type" "idiv")
7185    (set_attr "mode" "QI")])
7186
7187 (define_expand "udivmod<mode>4"
7188   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7189                    (udiv:SWIM248
7190                      (match_operand:SWIM248 1 "register_operand" "")
7191                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7192               (set (match_operand:SWIM248 3 "register_operand" "")
7193                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7194               (clobber (reg:CC FLAGS_REG))])])
7195
7196 ;; Split with 8bit unsigned divide:
7197 ;;      if (dividend an divisor are in [0-255])
7198 ;;         use 8bit unsigned integer divide
7199 ;;       else
7200 ;;         use original integer divide
7201 (define_split
7202   [(set (match_operand:SWI48 0 "register_operand" "")
7203         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7204                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7205    (set (match_operand:SWI48 1 "register_operand" "")
7206         (umod:SWI48 (match_dup 2) (match_dup 3)))
7207    (clobber (reg:CC FLAGS_REG))]
7208   "TARGET_USE_8BIT_IDIV
7209    && TARGET_QIMODE_MATH
7210    && can_create_pseudo_p ()
7211    && !optimize_insn_for_size_p ()"
7212   [(const_int 0)]
7213   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7214
7215 (define_insn_and_split "udivmod<mode>4_1"
7216   [(set (match_operand:SWI48 0 "register_operand" "=a")
7217         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7218                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7219    (set (match_operand:SWI48 1 "register_operand" "=&d")
7220         (umod:SWI48 (match_dup 2) (match_dup 3)))
7221    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7222    (clobber (reg:CC FLAGS_REG))]
7223   ""
7224   "#"
7225   "reload_completed"
7226   [(set (match_dup 1) (const_int 0))
7227    (parallel [(set (match_dup 0)
7228                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7229               (set (match_dup 1)
7230                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7231               (use (match_dup 1))
7232               (clobber (reg:CC FLAGS_REG))])]
7233   ""
7234   [(set_attr "type" "multi")
7235    (set_attr "mode" "<MODE>")])
7236
7237 (define_insn_and_split "*udivmod<mode>4"
7238   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7239         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7240                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7241    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7242         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7243    (clobber (reg:CC FLAGS_REG))]
7244   ""
7245   "#"
7246   "reload_completed"
7247   [(set (match_dup 1) (const_int 0))
7248    (parallel [(set (match_dup 0)
7249                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7250               (set (match_dup 1)
7251                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7252               (use (match_dup 1))
7253               (clobber (reg:CC FLAGS_REG))])]
7254   ""
7255   [(set_attr "type" "multi")
7256    (set_attr "mode" "<MODE>")])
7257
7258 (define_insn "*udivmod<mode>4_noext"
7259   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7260         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7261                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7262    (set (match_operand:SWIM248 1 "register_operand" "=d")
7263         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7264    (use (match_operand:SWIM248 4 "register_operand" "1"))
7265    (clobber (reg:CC FLAGS_REG))]
7266   ""
7267   "div{<imodesuffix>}\t%3"
7268   [(set_attr "type" "idiv")
7269    (set_attr "mode" "<MODE>")])
7270
7271 (define_expand "udivmodqi4"
7272   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7273                    (udiv:QI
7274                      (match_operand:QI 1 "register_operand" "")
7275                      (match_operand:QI 2 "nonimmediate_operand" "")))
7276               (set (match_operand:QI 3 "register_operand" "")
7277                    (umod:QI (match_dup 1) (match_dup 2)))
7278               (clobber (reg:CC FLAGS_REG))])]
7279   "TARGET_QIMODE_MATH"
7280 {
7281   rtx div, mod, insn;
7282   rtx tmp0, tmp1;
7283   
7284   tmp0 = gen_reg_rtx (HImode);
7285   tmp1 = gen_reg_rtx (HImode);
7286
7287   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7288      in AX.  */
7289   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7290   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7291
7292   /* Extract remainder from AH.  */
7293   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7294   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7295   insn = emit_move_insn (operands[3], tmp1);
7296
7297   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7298   set_unique_reg_note (insn, REG_EQUAL, mod);
7299
7300   /* Extract quotient from AL.  */
7301   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7302
7303   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7304   set_unique_reg_note (insn, REG_EQUAL, div);
7305
7306   DONE;
7307 })
7308
7309 (define_insn "udivmodhiqi3"
7310   [(set (match_operand:HI 0 "register_operand" "=a")
7311         (ior:HI
7312           (ashift:HI
7313             (zero_extend:HI
7314               (truncate:QI
7315                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7316                         (zero_extend:HI
7317                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7318             (const_int 8))
7319           (zero_extend:HI
7320             (truncate:QI
7321               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7322    (clobber (reg:CC FLAGS_REG))]
7323   "TARGET_QIMODE_MATH"
7324   "div{b}\t%2"
7325   [(set_attr "type" "idiv")
7326    (set_attr "mode" "QI")])
7327
7328 ;; We cannot use div/idiv for double division, because it causes
7329 ;; "division by zero" on the overflow and that's not what we expect
7330 ;; from truncate.  Because true (non truncating) double division is
7331 ;; never generated, we can't create this insn anyway.
7332 ;
7333 ;(define_insn ""
7334 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7335 ;       (truncate:SI
7336 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7337 ;                  (zero_extend:DI
7338 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7339 ;   (set (match_operand:SI 3 "register_operand" "=d")
7340 ;       (truncate:SI
7341 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7342 ;   (clobber (reg:CC FLAGS_REG))]
7343 ;  ""
7344 ;  "div{l}\t{%2, %0|%0, %2}"
7345 ;  [(set_attr "type" "idiv")])
7346 \f
7347 ;;- Logical AND instructions
7348
7349 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7350 ;; Note that this excludes ah.
7351
7352 (define_expand "testsi_ccno_1"
7353   [(set (reg:CCNO FLAGS_REG)
7354         (compare:CCNO
7355           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7356                   (match_operand:SI 1 "nonmemory_operand" ""))
7357           (const_int 0)))])
7358
7359 (define_expand "testqi_ccz_1"
7360   [(set (reg:CCZ FLAGS_REG)
7361         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7362                              (match_operand:QI 1 "nonmemory_operand" ""))
7363                  (const_int 0)))])
7364
7365 (define_expand "testdi_ccno_1"
7366   [(set (reg:CCNO FLAGS_REG)
7367         (compare:CCNO
7368           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7369                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7370           (const_int 0)))]
7371   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7372
7373 (define_insn "*testdi_1"
7374   [(set (reg FLAGS_REG)
7375         (compare
7376          (and:DI
7377           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7378           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7379          (const_int 0)))]
7380   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7381    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7382   "@
7383    test{l}\t{%k1, %k0|%k0, %k1}
7384    test{l}\t{%k1, %k0|%k0, %k1}
7385    test{q}\t{%1, %0|%0, %1}
7386    test{q}\t{%1, %0|%0, %1}
7387    test{q}\t{%1, %0|%0, %1}"
7388   [(set_attr "type" "test")
7389    (set_attr "modrm" "0,1,0,1,1")
7390    (set_attr "mode" "SI,SI,DI,DI,DI")])
7391
7392 (define_insn "*testqi_1_maybe_si"
7393   [(set (reg FLAGS_REG)
7394         (compare
7395           (and:QI
7396             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7397             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7398           (const_int 0)))]
7399    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7400     && ix86_match_ccmode (insn,
7401                          CONST_INT_P (operands[1])
7402                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7403 {
7404   if (which_alternative == 3)
7405     {
7406       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7407         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7408       return "test{l}\t{%1, %k0|%k0, %1}";
7409     }
7410   return "test{b}\t{%1, %0|%0, %1}";
7411 }
7412   [(set_attr "type" "test")
7413    (set_attr "modrm" "0,1,1,1")
7414    (set_attr "mode" "QI,QI,QI,SI")
7415    (set_attr "pent_pair" "uv,np,uv,np")])
7416
7417 (define_insn "*test<mode>_1"
7418   [(set (reg FLAGS_REG)
7419         (compare
7420          (and:SWI124
7421           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7422           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7423          (const_int 0)))]
7424   "ix86_match_ccmode (insn, CCNOmode)
7425    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7426   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7427   [(set_attr "type" "test")
7428    (set_attr "modrm" "0,1,1")
7429    (set_attr "mode" "<MODE>")
7430    (set_attr "pent_pair" "uv,np,uv")])
7431
7432 (define_expand "testqi_ext_ccno_0"
7433   [(set (reg:CCNO FLAGS_REG)
7434         (compare:CCNO
7435           (and:SI
7436             (zero_extract:SI
7437               (match_operand 0 "ext_register_operand" "")
7438               (const_int 8)
7439               (const_int 8))
7440             (match_operand 1 "const_int_operand" ""))
7441           (const_int 0)))])
7442
7443 (define_insn "*testqi_ext_0"
7444   [(set (reg FLAGS_REG)
7445         (compare
7446           (and:SI
7447             (zero_extract:SI
7448               (match_operand 0 "ext_register_operand" "Q")
7449               (const_int 8)
7450               (const_int 8))
7451             (match_operand 1 "const_int_operand" "n"))
7452           (const_int 0)))]
7453   "ix86_match_ccmode (insn, CCNOmode)"
7454   "test{b}\t{%1, %h0|%h0, %1}"
7455   [(set_attr "type" "test")
7456    (set_attr "mode" "QI")
7457    (set_attr "length_immediate" "1")
7458    (set_attr "modrm" "1")
7459    (set_attr "pent_pair" "np")])
7460
7461 (define_insn "*testqi_ext_1_rex64"
7462   [(set (reg FLAGS_REG)
7463         (compare
7464           (and:SI
7465             (zero_extract:SI
7466               (match_operand 0 "ext_register_operand" "Q")
7467               (const_int 8)
7468               (const_int 8))
7469             (zero_extend:SI
7470               (match_operand:QI 1 "register_operand" "Q")))
7471           (const_int 0)))]
7472   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7473   "test{b}\t{%1, %h0|%h0, %1}"
7474   [(set_attr "type" "test")
7475    (set_attr "mode" "QI")])
7476
7477 (define_insn "*testqi_ext_1"
7478   [(set (reg FLAGS_REG)
7479         (compare
7480           (and:SI
7481             (zero_extract:SI
7482               (match_operand 0 "ext_register_operand" "Q")
7483               (const_int 8)
7484               (const_int 8))
7485             (zero_extend:SI
7486               (match_operand:QI 1 "general_operand" "Qm")))
7487           (const_int 0)))]
7488   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7489   "test{b}\t{%1, %h0|%h0, %1}"
7490   [(set_attr "type" "test")
7491    (set_attr "mode" "QI")])
7492
7493 (define_insn "*testqi_ext_2"
7494   [(set (reg FLAGS_REG)
7495         (compare
7496           (and:SI
7497             (zero_extract:SI
7498               (match_operand 0 "ext_register_operand" "Q")
7499               (const_int 8)
7500               (const_int 8))
7501             (zero_extract:SI
7502               (match_operand 1 "ext_register_operand" "Q")
7503               (const_int 8)
7504               (const_int 8)))
7505           (const_int 0)))]
7506   "ix86_match_ccmode (insn, CCNOmode)"
7507   "test{b}\t{%h1, %h0|%h0, %h1}"
7508   [(set_attr "type" "test")
7509    (set_attr "mode" "QI")])
7510
7511 (define_insn "*testqi_ext_3_rex64"
7512   [(set (reg FLAGS_REG)
7513         (compare (zero_extract:DI
7514                    (match_operand 0 "nonimmediate_operand" "rm")
7515                    (match_operand:DI 1 "const_int_operand" "")
7516                    (match_operand:DI 2 "const_int_operand" ""))
7517                  (const_int 0)))]
7518   "TARGET_64BIT
7519    && ix86_match_ccmode (insn, CCNOmode)
7520    && INTVAL (operands[1]) > 0
7521    && INTVAL (operands[2]) >= 0
7522    /* Ensure that resulting mask is zero or sign extended operand.  */
7523    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7524        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7525            && INTVAL (operands[1]) > 32))
7526    && (GET_MODE (operands[0]) == SImode
7527        || GET_MODE (operands[0]) == DImode
7528        || GET_MODE (operands[0]) == HImode
7529        || GET_MODE (operands[0]) == QImode)"
7530   "#")
7531
7532 ;; Combine likes to form bit extractions for some tests.  Humor it.
7533 (define_insn "*testqi_ext_3"
7534   [(set (reg FLAGS_REG)
7535         (compare (zero_extract:SI
7536                    (match_operand 0 "nonimmediate_operand" "rm")
7537                    (match_operand:SI 1 "const_int_operand" "")
7538                    (match_operand:SI 2 "const_int_operand" ""))
7539                  (const_int 0)))]
7540   "ix86_match_ccmode (insn, CCNOmode)
7541    && INTVAL (operands[1]) > 0
7542    && INTVAL (operands[2]) >= 0
7543    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7544    && (GET_MODE (operands[0]) == SImode
7545        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7546        || GET_MODE (operands[0]) == HImode
7547        || GET_MODE (operands[0]) == QImode)"
7548   "#")
7549
7550 (define_split
7551   [(set (match_operand 0 "flags_reg_operand" "")
7552         (match_operator 1 "compare_operator"
7553           [(zero_extract
7554              (match_operand 2 "nonimmediate_operand" "")
7555              (match_operand 3 "const_int_operand" "")
7556              (match_operand 4 "const_int_operand" ""))
7557            (const_int 0)]))]
7558   "ix86_match_ccmode (insn, CCNOmode)"
7559   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7560 {
7561   rtx val = operands[2];
7562   HOST_WIDE_INT len = INTVAL (operands[3]);
7563   HOST_WIDE_INT pos = INTVAL (operands[4]);
7564   HOST_WIDE_INT mask;
7565   enum machine_mode mode, submode;
7566
7567   mode = GET_MODE (val);
7568   if (MEM_P (val))
7569     {
7570       /* ??? Combine likes to put non-volatile mem extractions in QImode
7571          no matter the size of the test.  So find a mode that works.  */
7572       if (! MEM_VOLATILE_P (val))
7573         {
7574           mode = smallest_mode_for_size (pos + len, MODE_INT);
7575           val = adjust_address (val, mode, 0);
7576         }
7577     }
7578   else if (GET_CODE (val) == SUBREG
7579            && (submode = GET_MODE (SUBREG_REG (val)),
7580                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7581            && pos + len <= GET_MODE_BITSIZE (submode)
7582            && GET_MODE_CLASS (submode) == MODE_INT)
7583     {
7584       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7585       mode = submode;
7586       val = SUBREG_REG (val);
7587     }
7588   else if (mode == HImode && pos + len <= 8)
7589     {
7590       /* Small HImode tests can be converted to QImode.  */
7591       mode = QImode;
7592       val = gen_lowpart (QImode, val);
7593     }
7594
7595   if (len == HOST_BITS_PER_WIDE_INT)
7596     mask = -1;
7597   else
7598     mask = ((HOST_WIDE_INT)1 << len) - 1;
7599   mask <<= pos;
7600
7601   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7602 })
7603
7604 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7605 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7606 ;; this is relatively important trick.
7607 ;; Do the conversion only post-reload to avoid limiting of the register class
7608 ;; to QI regs.
7609 (define_split
7610   [(set (match_operand 0 "flags_reg_operand" "")
7611         (match_operator 1 "compare_operator"
7612           [(and (match_operand 2 "register_operand" "")
7613                 (match_operand 3 "const_int_operand" ""))
7614            (const_int 0)]))]
7615    "reload_completed
7616     && QI_REG_P (operands[2])
7617     && GET_MODE (operands[2]) != QImode
7618     && ((ix86_match_ccmode (insn, CCZmode)
7619          && !(INTVAL (operands[3]) & ~(255 << 8)))
7620         || (ix86_match_ccmode (insn, CCNOmode)
7621             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7622   [(set (match_dup 0)
7623         (match_op_dup 1
7624           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7625                    (match_dup 3))
7626            (const_int 0)]))]
7627   "operands[2] = gen_lowpart (SImode, operands[2]);
7628    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7629
7630 (define_split
7631   [(set (match_operand 0 "flags_reg_operand" "")
7632         (match_operator 1 "compare_operator"
7633           [(and (match_operand 2 "nonimmediate_operand" "")
7634                 (match_operand 3 "const_int_operand" ""))
7635            (const_int 0)]))]
7636    "reload_completed
7637     && GET_MODE (operands[2]) != QImode
7638     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7639     && ((ix86_match_ccmode (insn, CCZmode)
7640          && !(INTVAL (operands[3]) & ~255))
7641         || (ix86_match_ccmode (insn, CCNOmode)
7642             && !(INTVAL (operands[3]) & ~127)))"
7643   [(set (match_dup 0)
7644         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7645                          (const_int 0)]))]
7646   "operands[2] = gen_lowpart (QImode, operands[2]);
7647    operands[3] = gen_lowpart (QImode, operands[3]);")
7648
7649 ;; %%% This used to optimize known byte-wide and operations to memory,
7650 ;; and sometimes to QImode registers.  If this is considered useful,
7651 ;; it should be done with splitters.
7652
7653 (define_expand "and<mode>3"
7654   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7655         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7656                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7657   ""
7658   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7659
7660 (define_insn "*anddi_1"
7661   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7662         (and:DI
7663          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7664          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7665    (clobber (reg:CC FLAGS_REG))]
7666   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7667 {
7668   switch (get_attr_type (insn))
7669     {
7670     case TYPE_IMOVX:
7671       {
7672         enum machine_mode mode;
7673
7674         gcc_assert (CONST_INT_P (operands[2]));
7675         if (INTVAL (operands[2]) == 0xff)
7676           mode = QImode;
7677         else
7678           {
7679             gcc_assert (INTVAL (operands[2]) == 0xffff);
7680             mode = HImode;
7681           }
7682
7683         operands[1] = gen_lowpart (mode, operands[1]);
7684         if (mode == QImode)
7685           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7686         else
7687           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7688       }
7689
7690     default:
7691       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7692       if (get_attr_mode (insn) == MODE_SI)
7693         return "and{l}\t{%k2, %k0|%k0, %k2}";
7694       else
7695         return "and{q}\t{%2, %0|%0, %2}";
7696     }
7697 }
7698   [(set_attr "type" "alu,alu,alu,imovx")
7699    (set_attr "length_immediate" "*,*,*,0")
7700    (set (attr "prefix_rex")
7701      (if_then_else
7702        (and (eq_attr "type" "imovx")
7703             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7704                  (match_operand 1 "ext_QIreg_operand" "")))
7705        (const_string "1")
7706        (const_string "*")))
7707    (set_attr "mode" "SI,DI,DI,SI")])
7708
7709 (define_insn "*andsi_1"
7710   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7711         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7712                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7713    (clobber (reg:CC FLAGS_REG))]
7714   "ix86_binary_operator_ok (AND, SImode, operands)"
7715 {
7716   switch (get_attr_type (insn))
7717     {
7718     case TYPE_IMOVX:
7719       {
7720         enum machine_mode mode;
7721
7722         gcc_assert (CONST_INT_P (operands[2]));
7723         if (INTVAL (operands[2]) == 0xff)
7724           mode = QImode;
7725         else
7726           {
7727             gcc_assert (INTVAL (operands[2]) == 0xffff);
7728             mode = HImode;
7729           }
7730
7731         operands[1] = gen_lowpart (mode, operands[1]);
7732         if (mode == QImode)
7733           return "movz{bl|x}\t{%1, %0|%0, %1}";
7734         else
7735           return "movz{wl|x}\t{%1, %0|%0, %1}";
7736       }
7737
7738     default:
7739       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7740       return "and{l}\t{%2, %0|%0, %2}";
7741     }
7742 }
7743   [(set_attr "type" "alu,alu,imovx")
7744    (set (attr "prefix_rex")
7745      (if_then_else
7746        (and (eq_attr "type" "imovx")
7747             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7748                  (match_operand 1 "ext_QIreg_operand" "")))
7749        (const_string "1")
7750        (const_string "*")))
7751    (set_attr "length_immediate" "*,*,0")
7752    (set_attr "mode" "SI")])
7753
7754 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7755 (define_insn "*andsi_1_zext"
7756   [(set (match_operand:DI 0 "register_operand" "=r")
7757         (zero_extend:DI
7758           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7759                   (match_operand:SI 2 "general_operand" "g"))))
7760    (clobber (reg:CC FLAGS_REG))]
7761   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7762   "and{l}\t{%2, %k0|%k0, %2}"
7763   [(set_attr "type" "alu")
7764    (set_attr "mode" "SI")])
7765
7766 (define_insn "*andhi_1"
7767   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7768         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7769                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7770    (clobber (reg:CC FLAGS_REG))]
7771   "ix86_binary_operator_ok (AND, HImode, operands)"
7772 {
7773   switch (get_attr_type (insn))
7774     {
7775     case TYPE_IMOVX:
7776       gcc_assert (CONST_INT_P (operands[2]));
7777       gcc_assert (INTVAL (operands[2]) == 0xff);
7778       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7779
7780     default:
7781       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7782
7783       return "and{w}\t{%2, %0|%0, %2}";
7784     }
7785 }
7786   [(set_attr "type" "alu,alu,imovx")
7787    (set_attr "length_immediate" "*,*,0")
7788    (set (attr "prefix_rex")
7789      (if_then_else
7790        (and (eq_attr "type" "imovx")
7791             (match_operand 1 "ext_QIreg_operand" ""))
7792        (const_string "1")
7793        (const_string "*")))
7794    (set_attr "mode" "HI,HI,SI")])
7795
7796 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7797 (define_insn "*andqi_1"
7798   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7799         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7800                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7801    (clobber (reg:CC FLAGS_REG))]
7802   "ix86_binary_operator_ok (AND, QImode, operands)"
7803   "@
7804    and{b}\t{%2, %0|%0, %2}
7805    and{b}\t{%2, %0|%0, %2}
7806    and{l}\t{%k2, %k0|%k0, %k2}"
7807   [(set_attr "type" "alu")
7808    (set_attr "mode" "QI,QI,SI")])
7809
7810 (define_insn "*andqi_1_slp"
7811   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7812         (and:QI (match_dup 0)
7813                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7814    (clobber (reg:CC FLAGS_REG))]
7815   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7816    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7817   "and{b}\t{%1, %0|%0, %1}"
7818   [(set_attr "type" "alu1")
7819    (set_attr "mode" "QI")])
7820
7821 (define_split
7822   [(set (match_operand 0 "register_operand" "")
7823         (and (match_dup 0)
7824              (const_int -65536)))
7825    (clobber (reg:CC FLAGS_REG))]
7826   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7827     || optimize_function_for_size_p (cfun)"
7828   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7829   "operands[1] = gen_lowpart (HImode, operands[0]);")
7830
7831 (define_split
7832   [(set (match_operand 0 "ext_register_operand" "")
7833         (and (match_dup 0)
7834              (const_int -256)))
7835    (clobber (reg:CC FLAGS_REG))]
7836   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7837    && reload_completed"
7838   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7839   "operands[1] = gen_lowpart (QImode, operands[0]);")
7840
7841 (define_split
7842   [(set (match_operand 0 "ext_register_operand" "")
7843         (and (match_dup 0)
7844              (const_int -65281)))
7845    (clobber (reg:CC FLAGS_REG))]
7846   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7847    && reload_completed"
7848   [(parallel [(set (zero_extract:SI (match_dup 0)
7849                                     (const_int 8)
7850                                     (const_int 8))
7851                    (xor:SI
7852                      (zero_extract:SI (match_dup 0)
7853                                       (const_int 8)
7854                                       (const_int 8))
7855                      (zero_extract:SI (match_dup 0)
7856                                       (const_int 8)
7857                                       (const_int 8))))
7858               (clobber (reg:CC FLAGS_REG))])]
7859   "operands[0] = gen_lowpart (SImode, operands[0]);")
7860
7861 (define_insn "*anddi_2"
7862   [(set (reg FLAGS_REG)
7863         (compare
7864          (and:DI
7865           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7866           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7867          (const_int 0)))
7868    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7869         (and:DI (match_dup 1) (match_dup 2)))]
7870   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7871    && ix86_binary_operator_ok (AND, DImode, operands)"
7872   "@
7873    and{l}\t{%k2, %k0|%k0, %k2}
7874    and{q}\t{%2, %0|%0, %2}
7875    and{q}\t{%2, %0|%0, %2}"
7876   [(set_attr "type" "alu")
7877    (set_attr "mode" "SI,DI,DI")])
7878
7879 (define_insn "*andqi_2_maybe_si"
7880   [(set (reg FLAGS_REG)
7881         (compare (and:QI
7882                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7883                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7884                  (const_int 0)))
7885    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7886         (and:QI (match_dup 1) (match_dup 2)))]
7887   "ix86_binary_operator_ok (AND, QImode, operands)
7888    && ix86_match_ccmode (insn,
7889                          CONST_INT_P (operands[2])
7890                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7891 {
7892   if (which_alternative == 2)
7893     {
7894       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7895         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7896       return "and{l}\t{%2, %k0|%k0, %2}";
7897     }
7898   return "and{b}\t{%2, %0|%0, %2}";
7899 }
7900   [(set_attr "type" "alu")
7901    (set_attr "mode" "QI,QI,SI")])
7902
7903 (define_insn "*and<mode>_2"
7904   [(set (reg FLAGS_REG)
7905         (compare (and:SWI124
7906                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7907                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7908                  (const_int 0)))
7909    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7910         (and:SWI124 (match_dup 1) (match_dup 2)))]
7911   "ix86_match_ccmode (insn, CCNOmode)
7912    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7913   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7914   [(set_attr "type" "alu")
7915    (set_attr "mode" "<MODE>")])
7916
7917 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7918 (define_insn "*andsi_2_zext"
7919   [(set (reg FLAGS_REG)
7920         (compare (and:SI
7921                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7922                   (match_operand:SI 2 "general_operand" "g"))
7923                  (const_int 0)))
7924    (set (match_operand:DI 0 "register_operand" "=r")
7925         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7926   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7927    && ix86_binary_operator_ok (AND, SImode, operands)"
7928   "and{l}\t{%2, %k0|%k0, %2}"
7929   [(set_attr "type" "alu")
7930    (set_attr "mode" "SI")])
7931
7932 (define_insn "*andqi_2_slp"
7933   [(set (reg FLAGS_REG)
7934         (compare (and:QI
7935                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7936                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7937                  (const_int 0)))
7938    (set (strict_low_part (match_dup 0))
7939         (and:QI (match_dup 0) (match_dup 1)))]
7940   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7941    && ix86_match_ccmode (insn, CCNOmode)
7942    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7943   "and{b}\t{%1, %0|%0, %1}"
7944   [(set_attr "type" "alu1")
7945    (set_attr "mode" "QI")])
7946
7947 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7948 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7949 ;; for a QImode operand, which of course failed.
7950 (define_insn "andqi_ext_0"
7951   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7952                          (const_int 8)
7953                          (const_int 8))
7954         (and:SI
7955           (zero_extract:SI
7956             (match_operand 1 "ext_register_operand" "0")
7957             (const_int 8)
7958             (const_int 8))
7959           (match_operand 2 "const_int_operand" "n")))
7960    (clobber (reg:CC FLAGS_REG))]
7961   ""
7962   "and{b}\t{%2, %h0|%h0, %2}"
7963   [(set_attr "type" "alu")
7964    (set_attr "length_immediate" "1")
7965    (set_attr "modrm" "1")
7966    (set_attr "mode" "QI")])
7967
7968 ;; Generated by peephole translating test to and.  This shows up
7969 ;; often in fp comparisons.
7970 (define_insn "*andqi_ext_0_cc"
7971   [(set (reg FLAGS_REG)
7972         (compare
7973           (and:SI
7974             (zero_extract:SI
7975               (match_operand 1 "ext_register_operand" "0")
7976               (const_int 8)
7977               (const_int 8))
7978             (match_operand 2 "const_int_operand" "n"))
7979           (const_int 0)))
7980    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7981                          (const_int 8)
7982                          (const_int 8))
7983         (and:SI
7984           (zero_extract:SI
7985             (match_dup 1)
7986             (const_int 8)
7987             (const_int 8))
7988           (match_dup 2)))]
7989   "ix86_match_ccmode (insn, CCNOmode)"
7990   "and{b}\t{%2, %h0|%h0, %2}"
7991   [(set_attr "type" "alu")
7992    (set_attr "length_immediate" "1")
7993    (set_attr "modrm" "1")
7994    (set_attr "mode" "QI")])
7995
7996 (define_insn "*andqi_ext_1_rex64"
7997   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7998                          (const_int 8)
7999                          (const_int 8))
8000         (and:SI
8001           (zero_extract:SI
8002             (match_operand 1 "ext_register_operand" "0")
8003             (const_int 8)
8004             (const_int 8))
8005           (zero_extend:SI
8006             (match_operand 2 "ext_register_operand" "Q"))))
8007    (clobber (reg:CC FLAGS_REG))]
8008   "TARGET_64BIT"
8009   "and{b}\t{%2, %h0|%h0, %2}"
8010   [(set_attr "type" "alu")
8011    (set_attr "length_immediate" "0")
8012    (set_attr "mode" "QI")])
8013
8014 (define_insn "*andqi_ext_1"
8015   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8016                          (const_int 8)
8017                          (const_int 8))
8018         (and:SI
8019           (zero_extract:SI
8020             (match_operand 1 "ext_register_operand" "0")
8021             (const_int 8)
8022             (const_int 8))
8023           (zero_extend:SI
8024             (match_operand:QI 2 "general_operand" "Qm"))))
8025    (clobber (reg:CC FLAGS_REG))]
8026   "!TARGET_64BIT"
8027   "and{b}\t{%2, %h0|%h0, %2}"
8028   [(set_attr "type" "alu")
8029    (set_attr "length_immediate" "0")
8030    (set_attr "mode" "QI")])
8031
8032 (define_insn "*andqi_ext_2"
8033   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8034                          (const_int 8)
8035                          (const_int 8))
8036         (and:SI
8037           (zero_extract:SI
8038             (match_operand 1 "ext_register_operand" "%0")
8039             (const_int 8)
8040             (const_int 8))
8041           (zero_extract:SI
8042             (match_operand 2 "ext_register_operand" "Q")
8043             (const_int 8)
8044             (const_int 8))))
8045    (clobber (reg:CC FLAGS_REG))]
8046   ""
8047   "and{b}\t{%h2, %h0|%h0, %h2}"
8048   [(set_attr "type" "alu")
8049    (set_attr "length_immediate" "0")
8050    (set_attr "mode" "QI")])
8051
8052 ;; Convert wide AND instructions with immediate operand to shorter QImode
8053 ;; equivalents when possible.
8054 ;; Don't do the splitting with memory operands, since it introduces risk
8055 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8056 ;; for size, but that can (should?) be handled by generic code instead.
8057 (define_split
8058   [(set (match_operand 0 "register_operand" "")
8059         (and (match_operand 1 "register_operand" "")
8060              (match_operand 2 "const_int_operand" "")))
8061    (clobber (reg:CC FLAGS_REG))]
8062    "reload_completed
8063     && QI_REG_P (operands[0])
8064     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8065     && !(~INTVAL (operands[2]) & ~(255 << 8))
8066     && GET_MODE (operands[0]) != QImode"
8067   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8068                    (and:SI (zero_extract:SI (match_dup 1)
8069                                             (const_int 8) (const_int 8))
8070                            (match_dup 2)))
8071               (clobber (reg:CC FLAGS_REG))])]
8072   "operands[0] = gen_lowpart (SImode, operands[0]);
8073    operands[1] = gen_lowpart (SImode, operands[1]);
8074    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8075
8076 ;; Since AND can be encoded with sign extended immediate, this is only
8077 ;; profitable when 7th bit is not set.
8078 (define_split
8079   [(set (match_operand 0 "register_operand" "")
8080         (and (match_operand 1 "general_operand" "")
8081              (match_operand 2 "const_int_operand" "")))
8082    (clobber (reg:CC FLAGS_REG))]
8083    "reload_completed
8084     && ANY_QI_REG_P (operands[0])
8085     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8086     && !(~INTVAL (operands[2]) & ~255)
8087     && !(INTVAL (operands[2]) & 128)
8088     && GET_MODE (operands[0]) != QImode"
8089   [(parallel [(set (strict_low_part (match_dup 0))
8090                    (and:QI (match_dup 1)
8091                            (match_dup 2)))
8092               (clobber (reg:CC FLAGS_REG))])]
8093   "operands[0] = gen_lowpart (QImode, operands[0]);
8094    operands[1] = gen_lowpart (QImode, operands[1]);
8095    operands[2] = gen_lowpart (QImode, operands[2]);")
8096 \f
8097 ;; Logical inclusive and exclusive OR instructions
8098
8099 ;; %%% This used to optimize known byte-wide and operations to memory.
8100 ;; If this is considered useful, it should be done with splitters.
8101
8102 (define_expand "<code><mode>3"
8103   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8104         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8105                      (match_operand:SWIM 2 "<general_operand>" "")))]
8106   ""
8107   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8108
8109 (define_insn "*<code><mode>_1"
8110   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8111         (any_or:SWI248
8112          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8113          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8114    (clobber (reg:CC FLAGS_REG))]
8115   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8116   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8117   [(set_attr "type" "alu")
8118    (set_attr "mode" "<MODE>")])
8119
8120 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8121 (define_insn "*<code>qi_1"
8122   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8123         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8124                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8125    (clobber (reg:CC FLAGS_REG))]
8126   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8127   "@
8128    <logic>{b}\t{%2, %0|%0, %2}
8129    <logic>{b}\t{%2, %0|%0, %2}
8130    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8131   [(set_attr "type" "alu")
8132    (set_attr "mode" "QI,QI,SI")])
8133
8134 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8135 (define_insn "*<code>si_1_zext"
8136   [(set (match_operand:DI 0 "register_operand" "=r")
8137         (zero_extend:DI
8138          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8139                     (match_operand:SI 2 "general_operand" "g"))))
8140    (clobber (reg:CC FLAGS_REG))]
8141   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8142   "<logic>{l}\t{%2, %k0|%k0, %2}"
8143   [(set_attr "type" "alu")
8144    (set_attr "mode" "SI")])
8145
8146 (define_insn "*<code>si_1_zext_imm"
8147   [(set (match_operand:DI 0 "register_operand" "=r")
8148         (any_or:DI
8149          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8150          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8151    (clobber (reg:CC FLAGS_REG))]
8152   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8153   "<logic>{l}\t{%2, %k0|%k0, %2}"
8154   [(set_attr "type" "alu")
8155    (set_attr "mode" "SI")])
8156
8157 (define_insn "*<code>qi_1_slp"
8158   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8159         (any_or:QI (match_dup 0)
8160                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8161    (clobber (reg:CC FLAGS_REG))]
8162   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8163    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8164   "<logic>{b}\t{%1, %0|%0, %1}"
8165   [(set_attr "type" "alu1")
8166    (set_attr "mode" "QI")])
8167
8168 (define_insn "*<code><mode>_2"
8169   [(set (reg FLAGS_REG)
8170         (compare (any_or:SWI
8171                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8172                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8173                  (const_int 0)))
8174    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8175         (any_or:SWI (match_dup 1) (match_dup 2)))]
8176   "ix86_match_ccmode (insn, CCNOmode)
8177    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8178   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8179   [(set_attr "type" "alu")
8180    (set_attr "mode" "<MODE>")])
8181
8182 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8183 ;; ??? Special case for immediate operand is missing - it is tricky.
8184 (define_insn "*<code>si_2_zext"
8185   [(set (reg FLAGS_REG)
8186         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8187                             (match_operand:SI 2 "general_operand" "g"))
8188                  (const_int 0)))
8189    (set (match_operand:DI 0 "register_operand" "=r")
8190         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8191   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8192    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8193   "<logic>{l}\t{%2, %k0|%k0, %2}"
8194   [(set_attr "type" "alu")
8195    (set_attr "mode" "SI")])
8196
8197 (define_insn "*<code>si_2_zext_imm"
8198   [(set (reg FLAGS_REG)
8199         (compare (any_or:SI
8200                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8201                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8202                  (const_int 0)))
8203    (set (match_operand:DI 0 "register_operand" "=r")
8204         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8205   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8206    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8207   "<logic>{l}\t{%2, %k0|%k0, %2}"
8208   [(set_attr "type" "alu")
8209    (set_attr "mode" "SI")])
8210
8211 (define_insn "*<code>qi_2_slp"
8212   [(set (reg FLAGS_REG)
8213         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8214                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8215                  (const_int 0)))
8216    (set (strict_low_part (match_dup 0))
8217         (any_or:QI (match_dup 0) (match_dup 1)))]
8218   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8219    && ix86_match_ccmode (insn, CCNOmode)
8220    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8221   "<logic>{b}\t{%1, %0|%0, %1}"
8222   [(set_attr "type" "alu1")
8223    (set_attr "mode" "QI")])
8224
8225 (define_insn "*<code><mode>_3"
8226   [(set (reg FLAGS_REG)
8227         (compare (any_or:SWI
8228                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8229                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8230                  (const_int 0)))
8231    (clobber (match_scratch:SWI 0 "=<r>"))]
8232   "ix86_match_ccmode (insn, CCNOmode)
8233    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8234   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8235   [(set_attr "type" "alu")
8236    (set_attr "mode" "<MODE>")])
8237
8238 (define_insn "*<code>qi_ext_0"
8239   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8240                          (const_int 8)
8241                          (const_int 8))
8242         (any_or:SI
8243           (zero_extract:SI
8244             (match_operand 1 "ext_register_operand" "0")
8245             (const_int 8)
8246             (const_int 8))
8247           (match_operand 2 "const_int_operand" "n")))
8248    (clobber (reg:CC FLAGS_REG))]
8249   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8250   "<logic>{b}\t{%2, %h0|%h0, %2}"
8251   [(set_attr "type" "alu")
8252    (set_attr "length_immediate" "1")
8253    (set_attr "modrm" "1")
8254    (set_attr "mode" "QI")])
8255
8256 (define_insn "*<code>qi_ext_1_rex64"
8257   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8258                          (const_int 8)
8259                          (const_int 8))
8260         (any_or:SI
8261           (zero_extract:SI
8262             (match_operand 1 "ext_register_operand" "0")
8263             (const_int 8)
8264             (const_int 8))
8265           (zero_extend:SI
8266             (match_operand 2 "ext_register_operand" "Q"))))
8267    (clobber (reg:CC FLAGS_REG))]
8268   "TARGET_64BIT
8269    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8270   "<logic>{b}\t{%2, %h0|%h0, %2}"
8271   [(set_attr "type" "alu")
8272    (set_attr "length_immediate" "0")
8273    (set_attr "mode" "QI")])
8274
8275 (define_insn "*<code>qi_ext_1"
8276   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8277                          (const_int 8)
8278                          (const_int 8))
8279         (any_or:SI
8280           (zero_extract:SI
8281             (match_operand 1 "ext_register_operand" "0")
8282             (const_int 8)
8283             (const_int 8))
8284           (zero_extend:SI
8285             (match_operand:QI 2 "general_operand" "Qm"))))
8286    (clobber (reg:CC FLAGS_REG))]
8287   "!TARGET_64BIT
8288    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8289   "<logic>{b}\t{%2, %h0|%h0, %2}"
8290   [(set_attr "type" "alu")
8291    (set_attr "length_immediate" "0")
8292    (set_attr "mode" "QI")])
8293
8294 (define_insn "*<code>qi_ext_2"
8295   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8296                          (const_int 8)
8297                          (const_int 8))
8298         (any_or:SI
8299           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8300                            (const_int 8)
8301                            (const_int 8))
8302           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8303                            (const_int 8)
8304                            (const_int 8))))
8305    (clobber (reg:CC FLAGS_REG))]
8306   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8307   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8308   [(set_attr "type" "alu")
8309    (set_attr "length_immediate" "0")
8310    (set_attr "mode" "QI")])
8311
8312 (define_split
8313   [(set (match_operand 0 "register_operand" "")
8314         (any_or (match_operand 1 "register_operand" "")
8315                 (match_operand 2 "const_int_operand" "")))
8316    (clobber (reg:CC FLAGS_REG))]
8317    "reload_completed
8318     && QI_REG_P (operands[0])
8319     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8320     && !(INTVAL (operands[2]) & ~(255 << 8))
8321     && GET_MODE (operands[0]) != QImode"
8322   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8323                    (any_or:SI (zero_extract:SI (match_dup 1)
8324                                                (const_int 8) (const_int 8))
8325                               (match_dup 2)))
8326               (clobber (reg:CC FLAGS_REG))])]
8327   "operands[0] = gen_lowpart (SImode, operands[0]);
8328    operands[1] = gen_lowpart (SImode, operands[1]);
8329    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8330
8331 ;; Since OR can be encoded with sign extended immediate, this is only
8332 ;; profitable when 7th bit is set.
8333 (define_split
8334   [(set (match_operand 0 "register_operand" "")
8335         (any_or (match_operand 1 "general_operand" "")
8336                 (match_operand 2 "const_int_operand" "")))
8337    (clobber (reg:CC FLAGS_REG))]
8338    "reload_completed
8339     && ANY_QI_REG_P (operands[0])
8340     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8341     && !(INTVAL (operands[2]) & ~255)
8342     && (INTVAL (operands[2]) & 128)
8343     && GET_MODE (operands[0]) != QImode"
8344   [(parallel [(set (strict_low_part (match_dup 0))
8345                    (any_or:QI (match_dup 1)
8346                               (match_dup 2)))
8347               (clobber (reg:CC FLAGS_REG))])]
8348   "operands[0] = gen_lowpart (QImode, operands[0]);
8349    operands[1] = gen_lowpart (QImode, operands[1]);
8350    operands[2] = gen_lowpart (QImode, operands[2]);")
8351
8352 (define_expand "xorqi_cc_ext_1"
8353   [(parallel [
8354      (set (reg:CCNO FLAGS_REG)
8355           (compare:CCNO
8356             (xor:SI
8357               (zero_extract:SI
8358                 (match_operand 1 "ext_register_operand" "")
8359                 (const_int 8)
8360                 (const_int 8))
8361               (match_operand:QI 2 "general_operand" ""))
8362             (const_int 0)))
8363      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8364                            (const_int 8)
8365                            (const_int 8))
8366           (xor:SI
8367             (zero_extract:SI
8368              (match_dup 1)
8369              (const_int 8)
8370              (const_int 8))
8371             (match_dup 2)))])])
8372
8373 (define_insn "*xorqi_cc_ext_1_rex64"
8374   [(set (reg FLAGS_REG)
8375         (compare
8376           (xor:SI
8377             (zero_extract:SI
8378               (match_operand 1 "ext_register_operand" "0")
8379               (const_int 8)
8380               (const_int 8))
8381             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8382           (const_int 0)))
8383    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8384                          (const_int 8)
8385                          (const_int 8))
8386         (xor:SI
8387           (zero_extract:SI
8388            (match_dup 1)
8389            (const_int 8)
8390            (const_int 8))
8391           (match_dup 2)))]
8392   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8393   "xor{b}\t{%2, %h0|%h0, %2}"
8394   [(set_attr "type" "alu")
8395    (set_attr "modrm" "1")
8396    (set_attr "mode" "QI")])
8397
8398 (define_insn "*xorqi_cc_ext_1"
8399   [(set (reg FLAGS_REG)
8400         (compare
8401           (xor:SI
8402             (zero_extract:SI
8403               (match_operand 1 "ext_register_operand" "0")
8404               (const_int 8)
8405               (const_int 8))
8406             (match_operand:QI 2 "general_operand" "qmn"))
8407           (const_int 0)))
8408    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8409                          (const_int 8)
8410                          (const_int 8))
8411         (xor:SI
8412           (zero_extract:SI
8413            (match_dup 1)
8414            (const_int 8)
8415            (const_int 8))
8416           (match_dup 2)))]
8417   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8418   "xor{b}\t{%2, %h0|%h0, %2}"
8419   [(set_attr "type" "alu")
8420    (set_attr "modrm" "1")
8421    (set_attr "mode" "QI")])
8422 \f
8423 ;; Negation instructions
8424
8425 (define_expand "neg<mode>2"
8426   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8427         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8428   ""
8429   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8430
8431 (define_insn_and_split "*neg<dwi>2_doubleword"
8432   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8433         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8434    (clobber (reg:CC FLAGS_REG))]
8435   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8436   "#"
8437   "reload_completed"
8438   [(parallel
8439     [(set (reg:CCZ FLAGS_REG)
8440           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8441      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8442    (parallel
8443     [(set (match_dup 2)
8444           (plus:DWIH (match_dup 3)
8445                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8446                                 (const_int 0))))
8447      (clobber (reg:CC FLAGS_REG))])
8448    (parallel
8449     [(set (match_dup 2)
8450           (neg:DWIH (match_dup 2)))
8451      (clobber (reg:CC FLAGS_REG))])]
8452   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8453
8454 (define_insn "*neg<mode>2_1"
8455   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8456         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8457    (clobber (reg:CC FLAGS_REG))]
8458   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8459   "neg{<imodesuffix>}\t%0"
8460   [(set_attr "type" "negnot")
8461    (set_attr "mode" "<MODE>")])
8462
8463 ;; Combine is quite creative about this pattern.
8464 (define_insn "*negsi2_1_zext"
8465   [(set (match_operand:DI 0 "register_operand" "=r")
8466         (lshiftrt:DI
8467           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8468                              (const_int 32)))
8469         (const_int 32)))
8470    (clobber (reg:CC FLAGS_REG))]
8471   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8472   "neg{l}\t%k0"
8473   [(set_attr "type" "negnot")
8474    (set_attr "mode" "SI")])
8475
8476 ;; The problem with neg is that it does not perform (compare x 0),
8477 ;; it really performs (compare 0 x), which leaves us with the zero
8478 ;; flag being the only useful item.
8479
8480 (define_insn "*neg<mode>2_cmpz"
8481   [(set (reg:CCZ FLAGS_REG)
8482         (compare:CCZ
8483           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8484                    (const_int 0)))
8485    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8486         (neg:SWI (match_dup 1)))]
8487   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8488   "neg{<imodesuffix>}\t%0"
8489   [(set_attr "type" "negnot")
8490    (set_attr "mode" "<MODE>")])
8491
8492 (define_insn "*negsi2_cmpz_zext"
8493   [(set (reg:CCZ FLAGS_REG)
8494         (compare:CCZ
8495           (lshiftrt:DI
8496             (neg:DI (ashift:DI
8497                       (match_operand:DI 1 "register_operand" "0")
8498                       (const_int 32)))
8499             (const_int 32))
8500           (const_int 0)))
8501    (set (match_operand:DI 0 "register_operand" "=r")
8502         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8503                                         (const_int 32)))
8504                      (const_int 32)))]
8505   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8506   "neg{l}\t%k0"
8507   [(set_attr "type" "negnot")
8508    (set_attr "mode" "SI")])
8509
8510 ;; Changing of sign for FP values is doable using integer unit too.
8511
8512 (define_expand "<code><mode>2"
8513   [(set (match_operand:X87MODEF 0 "register_operand" "")
8514         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8515   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8516   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8517
8518 (define_insn "*absneg<mode>2_mixed"
8519   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8520         (match_operator:MODEF 3 "absneg_operator"
8521           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8522    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8523    (clobber (reg:CC FLAGS_REG))]
8524   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8525   "#")
8526
8527 (define_insn "*absneg<mode>2_sse"
8528   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8529         (match_operator:MODEF 3 "absneg_operator"
8530           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8531    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8532    (clobber (reg:CC FLAGS_REG))]
8533   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8534   "#")
8535
8536 (define_insn "*absneg<mode>2_i387"
8537   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8538         (match_operator:X87MODEF 3 "absneg_operator"
8539           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8540    (use (match_operand 2 "" ""))
8541    (clobber (reg:CC FLAGS_REG))]
8542   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8543   "#")
8544
8545 (define_expand "<code>tf2"
8546   [(set (match_operand:TF 0 "register_operand" "")
8547         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8548   "TARGET_SSE2"
8549   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8550
8551 (define_insn "*absnegtf2_sse"
8552   [(set (match_operand:TF 0 "register_operand" "=x,x")
8553         (match_operator:TF 3 "absneg_operator"
8554           [(match_operand:TF 1 "register_operand" "0,x")]))
8555    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8556    (clobber (reg:CC FLAGS_REG))]
8557   "TARGET_SSE2"
8558   "#")
8559
8560 ;; Splitters for fp abs and neg.
8561
8562 (define_split
8563   [(set (match_operand 0 "fp_register_operand" "")
8564         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8565    (use (match_operand 2 "" ""))
8566    (clobber (reg:CC FLAGS_REG))]
8567   "reload_completed"
8568   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8569
8570 (define_split
8571   [(set (match_operand 0 "register_operand" "")
8572         (match_operator 3 "absneg_operator"
8573           [(match_operand 1 "register_operand" "")]))
8574    (use (match_operand 2 "nonimmediate_operand" ""))
8575    (clobber (reg:CC FLAGS_REG))]
8576   "reload_completed && SSE_REG_P (operands[0])"
8577   [(set (match_dup 0) (match_dup 3))]
8578 {
8579   enum machine_mode mode = GET_MODE (operands[0]);
8580   enum machine_mode vmode = GET_MODE (operands[2]);
8581   rtx tmp;
8582
8583   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8584   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8585   if (operands_match_p (operands[0], operands[2]))
8586     {
8587       tmp = operands[1];
8588       operands[1] = operands[2];
8589       operands[2] = tmp;
8590     }
8591   if (GET_CODE (operands[3]) == ABS)
8592     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8593   else
8594     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8595   operands[3] = tmp;
8596 })
8597
8598 (define_split
8599   [(set (match_operand:SF 0 "register_operand" "")
8600         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8601    (use (match_operand:V4SF 2 "" ""))
8602    (clobber (reg:CC FLAGS_REG))]
8603   "reload_completed"
8604   [(parallel [(set (match_dup 0) (match_dup 1))
8605               (clobber (reg:CC FLAGS_REG))])]
8606 {
8607   rtx tmp;
8608   operands[0] = gen_lowpart (SImode, operands[0]);
8609   if (GET_CODE (operands[1]) == ABS)
8610     {
8611       tmp = gen_int_mode (0x7fffffff, SImode);
8612       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8613     }
8614   else
8615     {
8616       tmp = gen_int_mode (0x80000000, SImode);
8617       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8618     }
8619   operands[1] = tmp;
8620 })
8621
8622 (define_split
8623   [(set (match_operand:DF 0 "register_operand" "")
8624         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8625    (use (match_operand 2 "" ""))
8626    (clobber (reg:CC FLAGS_REG))]
8627   "reload_completed"
8628   [(parallel [(set (match_dup 0) (match_dup 1))
8629               (clobber (reg:CC FLAGS_REG))])]
8630 {
8631   rtx tmp;
8632   if (TARGET_64BIT)
8633     {
8634       tmp = gen_lowpart (DImode, operands[0]);
8635       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8636       operands[0] = tmp;
8637
8638       if (GET_CODE (operands[1]) == ABS)
8639         tmp = const0_rtx;
8640       else
8641         tmp = gen_rtx_NOT (DImode, tmp);
8642     }
8643   else
8644     {
8645       operands[0] = gen_highpart (SImode, operands[0]);
8646       if (GET_CODE (operands[1]) == ABS)
8647         {
8648           tmp = gen_int_mode (0x7fffffff, SImode);
8649           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8650         }
8651       else
8652         {
8653           tmp = gen_int_mode (0x80000000, SImode);
8654           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8655         }
8656     }
8657   operands[1] = tmp;
8658 })
8659
8660 (define_split
8661   [(set (match_operand:XF 0 "register_operand" "")
8662         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8663    (use (match_operand 2 "" ""))
8664    (clobber (reg:CC FLAGS_REG))]
8665   "reload_completed"
8666   [(parallel [(set (match_dup 0) (match_dup 1))
8667               (clobber (reg:CC FLAGS_REG))])]
8668 {
8669   rtx tmp;
8670   operands[0] = gen_rtx_REG (SImode,
8671                              true_regnum (operands[0])
8672                              + (TARGET_64BIT ? 1 : 2));
8673   if (GET_CODE (operands[1]) == ABS)
8674     {
8675       tmp = GEN_INT (0x7fff);
8676       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8677     }
8678   else
8679     {
8680       tmp = GEN_INT (0x8000);
8681       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8682     }
8683   operands[1] = tmp;
8684 })
8685
8686 ;; Conditionalize these after reload. If they match before reload, we
8687 ;; lose the clobber and ability to use integer instructions.
8688
8689 (define_insn "*<code><mode>2_1"
8690   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8691         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8692   "TARGET_80387
8693    && (reload_completed
8694        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8695   "f<absneg_mnemonic>"
8696   [(set_attr "type" "fsgn")
8697    (set_attr "mode" "<MODE>")])
8698
8699 (define_insn "*<code>extendsfdf2"
8700   [(set (match_operand:DF 0 "register_operand" "=f")
8701         (absneg:DF (float_extend:DF
8702                      (match_operand:SF 1 "register_operand" "0"))))]
8703   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8704   "f<absneg_mnemonic>"
8705   [(set_attr "type" "fsgn")
8706    (set_attr "mode" "DF")])
8707
8708 (define_insn "*<code>extendsfxf2"
8709   [(set (match_operand:XF 0 "register_operand" "=f")
8710         (absneg:XF (float_extend:XF
8711                      (match_operand:SF 1 "register_operand" "0"))))]
8712   "TARGET_80387"
8713   "f<absneg_mnemonic>"
8714   [(set_attr "type" "fsgn")
8715    (set_attr "mode" "XF")])
8716
8717 (define_insn "*<code>extenddfxf2"
8718   [(set (match_operand:XF 0 "register_operand" "=f")
8719         (absneg:XF (float_extend:XF
8720                      (match_operand:DF 1 "register_operand" "0"))))]
8721   "TARGET_80387"
8722   "f<absneg_mnemonic>"
8723   [(set_attr "type" "fsgn")
8724    (set_attr "mode" "XF")])
8725
8726 ;; Copysign instructions
8727
8728 (define_mode_iterator CSGNMODE [SF DF TF])
8729 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8730
8731 (define_expand "copysign<mode>3"
8732   [(match_operand:CSGNMODE 0 "register_operand" "")
8733    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8734    (match_operand:CSGNMODE 2 "register_operand" "")]
8735   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8736    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8737   "ix86_expand_copysign (operands); DONE;")
8738
8739 (define_insn_and_split "copysign<mode>3_const"
8740   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8741         (unspec:CSGNMODE
8742           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8743            (match_operand:CSGNMODE 2 "register_operand" "0")
8744            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8745           UNSPEC_COPYSIGN))]
8746   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8747    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8748   "#"
8749   "&& reload_completed"
8750   [(const_int 0)]
8751   "ix86_split_copysign_const (operands); DONE;")
8752
8753 (define_insn "copysign<mode>3_var"
8754   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8755         (unspec:CSGNMODE
8756           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8757            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8758            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8759            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8760           UNSPEC_COPYSIGN))
8761    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8762   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8763    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8764   "#")
8765
8766 (define_split
8767   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8768         (unspec:CSGNMODE
8769           [(match_operand:CSGNMODE 2 "register_operand" "")
8770            (match_operand:CSGNMODE 3 "register_operand" "")
8771            (match_operand:<CSGNVMODE> 4 "" "")
8772            (match_operand:<CSGNVMODE> 5 "" "")]
8773           UNSPEC_COPYSIGN))
8774    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8775   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8776     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8777    && reload_completed"
8778   [(const_int 0)]
8779   "ix86_split_copysign_var (operands); DONE;")
8780 \f
8781 ;; One complement instructions
8782
8783 (define_expand "one_cmpl<mode>2"
8784   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8785         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8786   ""
8787   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8788
8789 (define_insn "*one_cmpl<mode>2_1"
8790   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8791         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8792   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8793   "not{<imodesuffix>}\t%0"
8794   [(set_attr "type" "negnot")
8795    (set_attr "mode" "<MODE>")])
8796
8797 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8798 (define_insn "*one_cmplqi2_1"
8799   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8800         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8801   "ix86_unary_operator_ok (NOT, QImode, operands)"
8802   "@
8803    not{b}\t%0
8804    not{l}\t%k0"
8805   [(set_attr "type" "negnot")
8806    (set_attr "mode" "QI,SI")])
8807
8808 ;; ??? Currently never generated - xor is used instead.
8809 (define_insn "*one_cmplsi2_1_zext"
8810   [(set (match_operand:DI 0 "register_operand" "=r")
8811         (zero_extend:DI
8812           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8813   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8814   "not{l}\t%k0"
8815   [(set_attr "type" "negnot")
8816    (set_attr "mode" "SI")])
8817
8818 (define_insn "*one_cmpl<mode>2_2"
8819   [(set (reg FLAGS_REG)
8820         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8821                  (const_int 0)))
8822    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8823         (not:SWI (match_dup 1)))]
8824   "ix86_match_ccmode (insn, CCNOmode)
8825    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8826   "#"
8827   [(set_attr "type" "alu1")
8828    (set_attr "mode" "<MODE>")])
8829
8830 (define_split
8831   [(set (match_operand 0 "flags_reg_operand" "")
8832         (match_operator 2 "compare_operator"
8833           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8834            (const_int 0)]))
8835    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8836         (not:SWI (match_dup 3)))]
8837   "ix86_match_ccmode (insn, CCNOmode)"
8838   [(parallel [(set (match_dup 0)
8839                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8840                                     (const_int 0)]))
8841               (set (match_dup 1)
8842                    (xor:SWI (match_dup 3) (const_int -1)))])])
8843
8844 ;; ??? Currently never generated - xor is used instead.
8845 (define_insn "*one_cmplsi2_2_zext"
8846   [(set (reg FLAGS_REG)
8847         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8848                  (const_int 0)))
8849    (set (match_operand:DI 0 "register_operand" "=r")
8850         (zero_extend:DI (not:SI (match_dup 1))))]
8851   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8852    && ix86_unary_operator_ok (NOT, SImode, operands)"
8853   "#"
8854   [(set_attr "type" "alu1")
8855    (set_attr "mode" "SI")])
8856
8857 (define_split
8858   [(set (match_operand 0 "flags_reg_operand" "")
8859         (match_operator 2 "compare_operator"
8860           [(not:SI (match_operand:SI 3 "register_operand" ""))
8861            (const_int 0)]))
8862    (set (match_operand:DI 1 "register_operand" "")
8863         (zero_extend:DI (not:SI (match_dup 3))))]
8864   "ix86_match_ccmode (insn, CCNOmode)"
8865   [(parallel [(set (match_dup 0)
8866                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8867                                     (const_int 0)]))
8868               (set (match_dup 1)
8869                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8870 \f
8871 ;; Shift instructions
8872
8873 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8874 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8875 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8876 ;; from the assembler input.
8877 ;;
8878 ;; This instruction shifts the target reg/mem as usual, but instead of
8879 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8880 ;; is a left shift double, bits are taken from the high order bits of
8881 ;; reg, else if the insn is a shift right double, bits are taken from the
8882 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8883 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8884 ;;
8885 ;; Since sh[lr]d does not change the `reg' operand, that is done
8886 ;; separately, making all shifts emit pairs of shift double and normal
8887 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8888 ;; support a 63 bit shift, each shift where the count is in a reg expands
8889 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8890 ;;
8891 ;; If the shift count is a constant, we need never emit more than one
8892 ;; shift pair, instead using moves and sign extension for counts greater
8893 ;; than 31.
8894
8895 (define_expand "ashl<mode>3"
8896   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8897         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8898                       (match_operand:QI 2 "nonmemory_operand" "")))]
8899   ""
8900   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8901
8902 (define_insn "*ashl<mode>3_doubleword"
8903   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8904         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8905                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8906    (clobber (reg:CC FLAGS_REG))]
8907   ""
8908   "#"
8909   [(set_attr "type" "multi")])
8910
8911 (define_split
8912   [(set (match_operand:DWI 0 "register_operand" "")
8913         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8914                     (match_operand:QI 2 "nonmemory_operand" "")))
8915    (clobber (reg:CC FLAGS_REG))]
8916   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8917   [(const_int 0)]
8918   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8919
8920 ;; By default we don't ask for a scratch register, because when DWImode
8921 ;; values are manipulated, registers are already at a premium.  But if
8922 ;; we have one handy, we won't turn it away.
8923
8924 (define_peephole2
8925   [(match_scratch:DWIH 3 "r")
8926    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8927                    (ashift:<DWI>
8928                      (match_operand:<DWI> 1 "nonmemory_operand" "")
8929                      (match_operand:QI 2 "nonmemory_operand" "")))
8930               (clobber (reg:CC FLAGS_REG))])
8931    (match_dup 3)]
8932   "TARGET_CMOVE"
8933   [(const_int 0)]
8934   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8935
8936 (define_insn "x86_64_shld"
8937   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8938         (ior:DI (ashift:DI (match_dup 0)
8939                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
8940                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8941                   (minus:QI (const_int 64) (match_dup 2)))))
8942    (clobber (reg:CC FLAGS_REG))]
8943   "TARGET_64BIT"
8944   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8945   [(set_attr "type" "ishift")
8946    (set_attr "prefix_0f" "1")
8947    (set_attr "mode" "DI")
8948    (set_attr "athlon_decode" "vector")
8949    (set_attr "amdfam10_decode" "vector")
8950    (set_attr "bdver1_decode" "vector")])
8951
8952 (define_insn "x86_shld"
8953   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8954         (ior:SI (ashift:SI (match_dup 0)
8955                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
8956                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8957                   (minus:QI (const_int 32) (match_dup 2)))))
8958    (clobber (reg:CC FLAGS_REG))]
8959   ""
8960   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8961   [(set_attr "type" "ishift")
8962    (set_attr "prefix_0f" "1")
8963    (set_attr "mode" "SI")
8964    (set_attr "pent_pair" "np")
8965    (set_attr "athlon_decode" "vector")
8966    (set_attr "amdfam10_decode" "vector")
8967    (set_attr "bdver1_decode" "vector")])
8968
8969 (define_expand "x86_shift<mode>_adj_1"
8970   [(set (reg:CCZ FLAGS_REG)
8971         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8972                              (match_dup 4))
8973                      (const_int 0)))
8974    (set (match_operand:SWI48 0 "register_operand" "")
8975         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8976                             (match_operand:SWI48 1 "register_operand" "")
8977                             (match_dup 0)))
8978    (set (match_dup 1)
8979         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8980                             (match_operand:SWI48 3 "register_operand" "r")
8981                             (match_dup 1)))]
8982   "TARGET_CMOVE"
8983   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8984
8985 (define_expand "x86_shift<mode>_adj_2"
8986   [(use (match_operand:SWI48 0 "register_operand" ""))
8987    (use (match_operand:SWI48 1 "register_operand" ""))
8988    (use (match_operand:QI 2 "register_operand" ""))]
8989   ""
8990 {
8991   rtx label = gen_label_rtx ();
8992   rtx tmp;
8993
8994   emit_insn (gen_testqi_ccz_1 (operands[2],
8995                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8996
8997   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8998   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8999   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9000                               gen_rtx_LABEL_REF (VOIDmode, label),
9001                               pc_rtx);
9002   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9003   JUMP_LABEL (tmp) = label;
9004
9005   emit_move_insn (operands[0], operands[1]);
9006   ix86_expand_clear (operands[1]);
9007
9008   emit_label (label);
9009   LABEL_NUSES (label) = 1;
9010
9011   DONE;
9012 })
9013
9014 ;; Avoid useless masking of count operand.
9015 (define_insn_and_split "*ashl<mode>3_mask"
9016   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9017         (ashift:SWI48
9018           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9019           (subreg:QI
9020             (and:SI
9021               (match_operand:SI 2 "nonimmediate_operand" "c")
9022               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9023    (clobber (reg:CC FLAGS_REG))]
9024   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9025    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9026       == GET_MODE_BITSIZE (<MODE>mode)-1"
9027   "#"
9028   "&& 1"
9029   [(parallel [(set (match_dup 0)
9030                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9031               (clobber (reg:CC FLAGS_REG))])]
9032 {
9033   if (can_create_pseudo_p ())
9034     operands [2] = force_reg (SImode, operands[2]);
9035
9036   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9037 }
9038   [(set_attr "type" "ishift")
9039    (set_attr "mode" "<MODE>")])
9040
9041 (define_insn "*ashl<mode>3_1"
9042   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9043         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9044                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9045    (clobber (reg:CC FLAGS_REG))]
9046   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9047 {
9048   switch (get_attr_type (insn))
9049     {
9050     case TYPE_LEA:
9051       return "#";
9052
9053     case TYPE_ALU:
9054       gcc_assert (operands[2] == const1_rtx);
9055       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9056       return "add{<imodesuffix>}\t%0, %0";
9057
9058     default:
9059       if (operands[2] == const1_rtx
9060           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9061         return "sal{<imodesuffix>}\t%0";
9062       else
9063         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9064     }
9065 }
9066   [(set (attr "type")
9067      (cond [(eq_attr "alternative" "1")
9068               (const_string "lea")
9069             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9070                           (const_int 0))
9071                       (match_operand 0 "register_operand" ""))
9072                  (match_operand 2 "const1_operand" ""))
9073               (const_string "alu")
9074            ]
9075            (const_string "ishift")))
9076    (set (attr "length_immediate")
9077      (if_then_else
9078        (ior (eq_attr "type" "alu")
9079             (and (eq_attr "type" "ishift")
9080                  (and (match_operand 2 "const1_operand" "")
9081                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9082                           (const_int 0)))))
9083        (const_string "0")
9084        (const_string "*")))
9085    (set_attr "mode" "<MODE>")])
9086
9087 (define_insn "*ashlsi3_1_zext"
9088   [(set (match_operand:DI 0 "register_operand" "=r,r")
9089         (zero_extend:DI
9090           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9091                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9092    (clobber (reg:CC FLAGS_REG))]
9093   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9094 {
9095   switch (get_attr_type (insn))
9096     {
9097     case TYPE_LEA:
9098       return "#";
9099
9100     case TYPE_ALU:
9101       gcc_assert (operands[2] == const1_rtx);
9102       return "add{l}\t%k0, %k0";
9103
9104     default:
9105       if (operands[2] == const1_rtx
9106           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9107         return "sal{l}\t%k0";
9108       else
9109         return "sal{l}\t{%2, %k0|%k0, %2}";
9110     }
9111 }
9112   [(set (attr "type")
9113      (cond [(eq_attr "alternative" "1")
9114               (const_string "lea")
9115             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9116                      (const_int 0))
9117                  (match_operand 2 "const1_operand" ""))
9118               (const_string "alu")
9119            ]
9120            (const_string "ishift")))
9121    (set (attr "length_immediate")
9122      (if_then_else
9123        (ior (eq_attr "type" "alu")
9124             (and (eq_attr "type" "ishift")
9125                  (and (match_operand 2 "const1_operand" "")
9126                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9127                           (const_int 0)))))
9128        (const_string "0")
9129        (const_string "*")))
9130    (set_attr "mode" "SI")])
9131
9132 (define_insn "*ashlhi3_1"
9133   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9134         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9135                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9136    (clobber (reg:CC FLAGS_REG))]
9137   "TARGET_PARTIAL_REG_STALL
9138    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9139 {
9140   switch (get_attr_type (insn))
9141     {
9142     case TYPE_ALU:
9143       gcc_assert (operands[2] == const1_rtx);
9144       return "add{w}\t%0, %0";
9145
9146     default:
9147       if (operands[2] == const1_rtx
9148           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9149         return "sal{w}\t%0";
9150       else
9151         return "sal{w}\t{%2, %0|%0, %2}";
9152     }
9153 }
9154   [(set (attr "type")
9155      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9156                           (const_int 0))
9157                       (match_operand 0 "register_operand" ""))
9158                  (match_operand 2 "const1_operand" ""))
9159               (const_string "alu")
9160            ]
9161            (const_string "ishift")))
9162    (set (attr "length_immediate")
9163      (if_then_else
9164        (ior (eq_attr "type" "alu")
9165             (and (eq_attr "type" "ishift")
9166                  (and (match_operand 2 "const1_operand" "")
9167                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9168                           (const_int 0)))))
9169        (const_string "0")
9170        (const_string "*")))
9171    (set_attr "mode" "HI")])
9172
9173 (define_insn "*ashlhi3_1_lea"
9174   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9175         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9176                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9177    (clobber (reg:CC FLAGS_REG))]
9178   "!TARGET_PARTIAL_REG_STALL
9179    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9180 {
9181   switch (get_attr_type (insn))
9182     {
9183     case TYPE_LEA:
9184       return "#";
9185
9186     case TYPE_ALU:
9187       gcc_assert (operands[2] == const1_rtx);
9188       return "add{w}\t%0, %0";
9189
9190     default:
9191       if (operands[2] == const1_rtx
9192           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9193         return "sal{w}\t%0";
9194       else
9195         return "sal{w}\t{%2, %0|%0, %2}";
9196     }
9197 }
9198   [(set (attr "type")
9199      (cond [(eq_attr "alternative" "1")
9200               (const_string "lea")
9201             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9202                           (const_int 0))
9203                       (match_operand 0 "register_operand" ""))
9204                  (match_operand 2 "const1_operand" ""))
9205               (const_string "alu")
9206            ]
9207            (const_string "ishift")))
9208    (set (attr "length_immediate")
9209      (if_then_else
9210        (ior (eq_attr "type" "alu")
9211             (and (eq_attr "type" "ishift")
9212                  (and (match_operand 2 "const1_operand" "")
9213                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9214                           (const_int 0)))))
9215        (const_string "0")
9216        (const_string "*")))
9217    (set_attr "mode" "HI,SI")])
9218
9219 (define_insn "*ashlqi3_1"
9220   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9221         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9222                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9223    (clobber (reg:CC FLAGS_REG))]
9224   "TARGET_PARTIAL_REG_STALL
9225    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9226 {
9227   switch (get_attr_type (insn))
9228     {
9229     case TYPE_ALU:
9230       gcc_assert (operands[2] == const1_rtx);
9231       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9232         return "add{l}\t%k0, %k0";
9233       else
9234         return "add{b}\t%0, %0";
9235
9236     default:
9237       if (operands[2] == const1_rtx
9238           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9239         {
9240           if (get_attr_mode (insn) == MODE_SI)
9241             return "sal{l}\t%k0";
9242           else
9243             return "sal{b}\t%0";
9244         }
9245       else
9246         {
9247           if (get_attr_mode (insn) == MODE_SI)
9248             return "sal{l}\t{%2, %k0|%k0, %2}";
9249           else
9250             return "sal{b}\t{%2, %0|%0, %2}";
9251         }
9252     }
9253 }
9254   [(set (attr "type")
9255      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9256                           (const_int 0))
9257                       (match_operand 0 "register_operand" ""))
9258                  (match_operand 2 "const1_operand" ""))
9259               (const_string "alu")
9260            ]
9261            (const_string "ishift")))
9262    (set (attr "length_immediate")
9263      (if_then_else
9264        (ior (eq_attr "type" "alu")
9265             (and (eq_attr "type" "ishift")
9266                  (and (match_operand 2 "const1_operand" "")
9267                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9268                           (const_int 0)))))
9269        (const_string "0")
9270        (const_string "*")))
9271    (set_attr "mode" "QI,SI")])
9272
9273 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9274 (define_insn "*ashlqi3_1_lea"
9275   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9276         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9277                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9278    (clobber (reg:CC FLAGS_REG))]
9279   "!TARGET_PARTIAL_REG_STALL
9280    && ix86_binary_operator_ok (ASHIFT, QImode, 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       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9290         return "add{l}\t%k0, %k0";
9291       else
9292         return "add{b}\t%0, %0";
9293
9294     default:
9295       if (operands[2] == const1_rtx
9296           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9297         {
9298           if (get_attr_mode (insn) == MODE_SI)
9299             return "sal{l}\t%k0";
9300           else
9301             return "sal{b}\t%0";
9302         }
9303       else
9304         {
9305           if (get_attr_mode (insn) == MODE_SI)
9306             return "sal{l}\t{%2, %k0|%k0, %2}";
9307           else
9308             return "sal{b}\t{%2, %0|%0, %2}";
9309         }
9310     }
9311 }
9312   [(set (attr "type")
9313      (cond [(eq_attr "alternative" "2")
9314               (const_string "lea")
9315             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9316                           (const_int 0))
9317                       (match_operand 0 "register_operand" ""))
9318                  (match_operand 2 "const1_operand" ""))
9319               (const_string "alu")
9320            ]
9321            (const_string "ishift")))
9322    (set (attr "length_immediate")
9323      (if_then_else
9324        (ior (eq_attr "type" "alu")
9325             (and (eq_attr "type" "ishift")
9326                  (and (match_operand 2 "const1_operand" "")
9327                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9328                           (const_int 0)))))
9329        (const_string "0")
9330        (const_string "*")))
9331    (set_attr "mode" "QI,SI,SI")])
9332
9333 (define_insn "*ashlqi3_1_slp"
9334   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9335         (ashift:QI (match_dup 0)
9336                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9337    (clobber (reg:CC FLAGS_REG))]
9338   "(optimize_function_for_size_p (cfun)
9339     || !TARGET_PARTIAL_FLAG_REG_STALL
9340     || (operands[1] == const1_rtx
9341         && (TARGET_SHIFT1
9342             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9343 {
9344   switch (get_attr_type (insn))
9345     {
9346     case TYPE_ALU:
9347       gcc_assert (operands[1] == const1_rtx);
9348       return "add{b}\t%0, %0";
9349
9350     default:
9351       if (operands[1] == const1_rtx
9352           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9353         return "sal{b}\t%0";
9354       else
9355         return "sal{b}\t{%1, %0|%0, %1}";
9356     }
9357 }
9358   [(set (attr "type")
9359      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9360                           (const_int 0))
9361                       (match_operand 0 "register_operand" ""))
9362                  (match_operand 1 "const1_operand" ""))
9363               (const_string "alu")
9364            ]
9365            (const_string "ishift1")))
9366    (set (attr "length_immediate")
9367      (if_then_else
9368        (ior (eq_attr "type" "alu")
9369             (and (eq_attr "type" "ishift1")
9370                  (and (match_operand 1 "const1_operand" "")
9371                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9372                           (const_int 0)))))
9373        (const_string "0")
9374        (const_string "*")))
9375    (set_attr "mode" "QI")])
9376
9377 ;; Convert lea to the lea pattern to avoid flags dependency.
9378 (define_split
9379   [(set (match_operand 0 "register_operand" "")
9380         (ashift (match_operand 1 "index_register_operand" "")
9381                 (match_operand:QI 2 "const_int_operand" "")))
9382    (clobber (reg:CC FLAGS_REG))]
9383   "reload_completed
9384    && true_regnum (operands[0]) != true_regnum (operands[1])"
9385   [(const_int 0)]
9386 {
9387   rtx pat;
9388   enum machine_mode mode = GET_MODE (operands[0]);
9389
9390   if (mode != Pmode)
9391     operands[1] = gen_lowpart (Pmode, operands[1]);
9392   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9393
9394   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9395
9396   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9397     operands[0] = gen_lowpart (SImode, operands[0]);
9398
9399   if (TARGET_64BIT && mode != Pmode)
9400     pat = gen_rtx_SUBREG (SImode, pat, 0);
9401
9402   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9403   DONE;
9404 })
9405
9406 ;; Convert lea to the lea pattern to avoid flags dependency.
9407 (define_split
9408   [(set (match_operand:DI 0 "register_operand" "")
9409         (zero_extend:DI
9410           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9411                      (match_operand:QI 2 "const_int_operand" ""))))
9412    (clobber (reg:CC FLAGS_REG))]
9413   "TARGET_64BIT && reload_completed
9414    && true_regnum (operands[0]) != true_regnum (operands[1])"
9415   [(set (match_dup 0)
9416         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9417 {
9418   operands[1] = gen_lowpart (DImode, operands[1]);
9419   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9420 })
9421
9422 ;; This pattern can't accept a variable shift count, since shifts by
9423 ;; zero don't affect the flags.  We assume that shifts by constant
9424 ;; zero are optimized away.
9425 (define_insn "*ashl<mode>3_cmp"
9426   [(set (reg FLAGS_REG)
9427         (compare
9428           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9429                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9430           (const_int 0)))
9431    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9432         (ashift:SWI (match_dup 1) (match_dup 2)))]
9433   "(optimize_function_for_size_p (cfun)
9434     || !TARGET_PARTIAL_FLAG_REG_STALL
9435     || (operands[2] == const1_rtx
9436         && (TARGET_SHIFT1
9437             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9438    && ix86_match_ccmode (insn, CCGOCmode)
9439    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9440 {
9441   switch (get_attr_type (insn))
9442     {
9443     case TYPE_ALU:
9444       gcc_assert (operands[2] == const1_rtx);
9445       return "add{<imodesuffix>}\t%0, %0";
9446
9447     default:
9448       if (operands[2] == const1_rtx
9449           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9450         return "sal{<imodesuffix>}\t%0";
9451       else
9452         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9453     }
9454 }
9455   [(set (attr "type")
9456      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9457                           (const_int 0))
9458                       (match_operand 0 "register_operand" ""))
9459                  (match_operand 2 "const1_operand" ""))
9460               (const_string "alu")
9461            ]
9462            (const_string "ishift")))
9463    (set (attr "length_immediate")
9464      (if_then_else
9465        (ior (eq_attr "type" "alu")
9466             (and (eq_attr "type" "ishift")
9467                  (and (match_operand 2 "const1_operand" "")
9468                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9469                           (const_int 0)))))
9470        (const_string "0")
9471        (const_string "*")))
9472    (set_attr "mode" "<MODE>")])
9473
9474 (define_insn "*ashlsi3_cmp_zext"
9475   [(set (reg FLAGS_REG)
9476         (compare
9477           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9478                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9479           (const_int 0)))
9480    (set (match_operand:DI 0 "register_operand" "=r")
9481         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9482   "TARGET_64BIT
9483    && (optimize_function_for_size_p (cfun)
9484        || !TARGET_PARTIAL_FLAG_REG_STALL
9485        || (operands[2] == const1_rtx
9486            && (TARGET_SHIFT1
9487                || TARGET_DOUBLE_WITH_ADD)))
9488    && ix86_match_ccmode (insn, CCGOCmode)
9489    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9490 {
9491   switch (get_attr_type (insn))
9492     {
9493     case TYPE_ALU:
9494       gcc_assert (operands[2] == const1_rtx);
9495       return "add{l}\t%k0, %k0";
9496
9497     default:
9498       if (operands[2] == const1_rtx
9499           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9500         return "sal{l}\t%k0";
9501       else
9502         return "sal{l}\t{%2, %k0|%k0, %2}";
9503     }
9504 }
9505   [(set (attr "type")
9506      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9507                      (const_int 0))
9508                  (match_operand 2 "const1_operand" ""))
9509               (const_string "alu")
9510            ]
9511            (const_string "ishift")))
9512    (set (attr "length_immediate")
9513      (if_then_else
9514        (ior (eq_attr "type" "alu")
9515             (and (eq_attr "type" "ishift")
9516                  (and (match_operand 2 "const1_operand" "")
9517                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9518                           (const_int 0)))))
9519        (const_string "0")
9520        (const_string "*")))
9521    (set_attr "mode" "SI")])
9522
9523 (define_insn "*ashl<mode>3_cconly"
9524   [(set (reg FLAGS_REG)
9525         (compare
9526           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9527                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9528           (const_int 0)))
9529    (clobber (match_scratch:SWI 0 "=<r>"))]
9530   "(optimize_function_for_size_p (cfun)
9531     || !TARGET_PARTIAL_FLAG_REG_STALL
9532     || (operands[2] == const1_rtx
9533         && (TARGET_SHIFT1
9534             || TARGET_DOUBLE_WITH_ADD)))
9535    && ix86_match_ccmode (insn, CCGOCmode)"
9536 {
9537   switch (get_attr_type (insn))
9538     {
9539     case TYPE_ALU:
9540       gcc_assert (operands[2] == const1_rtx);
9541       return "add{<imodesuffix>}\t%0, %0";
9542
9543     default:
9544       if (operands[2] == const1_rtx
9545           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9546         return "sal{<imodesuffix>}\t%0";
9547       else
9548         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9549     }
9550 }
9551   [(set (attr "type")
9552      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9553                           (const_int 0))
9554                       (match_operand 0 "register_operand" ""))
9555                  (match_operand 2 "const1_operand" ""))
9556               (const_string "alu")
9557            ]
9558            (const_string "ishift")))
9559    (set (attr "length_immediate")
9560      (if_then_else
9561        (ior (eq_attr "type" "alu")
9562             (and (eq_attr "type" "ishift")
9563                  (and (match_operand 2 "const1_operand" "")
9564                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9565                           (const_int 0)))))
9566        (const_string "0")
9567        (const_string "*")))
9568    (set_attr "mode" "<MODE>")])
9569
9570 ;; See comment above `ashl<mode>3' about how this works.
9571
9572 (define_expand "<shiftrt_insn><mode>3"
9573   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9574         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9575                            (match_operand:QI 2 "nonmemory_operand" "")))]
9576   ""
9577   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9578
9579 ;; Avoid useless masking of count operand.
9580 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9581   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9582         (any_shiftrt:SWI48
9583           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9584           (subreg:QI
9585             (and:SI
9586               (match_operand:SI 2 "nonimmediate_operand" "c")
9587               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9588    (clobber (reg:CC FLAGS_REG))]
9589   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9590    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9591       == GET_MODE_BITSIZE (<MODE>mode)-1"
9592   "#"
9593   "&& 1"
9594   [(parallel [(set (match_dup 0)
9595                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9596               (clobber (reg:CC FLAGS_REG))])]
9597 {
9598   if (can_create_pseudo_p ())
9599     operands [2] = force_reg (SImode, operands[2]);
9600
9601   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9602 }
9603   [(set_attr "type" "ishift")
9604    (set_attr "mode" "<MODE>")])
9605
9606 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9607   [(set (match_operand:DWI 0 "register_operand" "=r")
9608         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9609                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9610    (clobber (reg:CC FLAGS_REG))]
9611   ""
9612   "#"
9613   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9614   [(const_int 0)]
9615   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9616   [(set_attr "type" "multi")])
9617
9618 ;; By default we don't ask for a scratch register, because when DWImode
9619 ;; values are manipulated, registers are already at a premium.  But if
9620 ;; we have one handy, we won't turn it away.
9621
9622 (define_peephole2
9623   [(match_scratch:DWIH 3 "r")
9624    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9625                    (any_shiftrt:<DWI>
9626                      (match_operand:<DWI> 1 "register_operand" "")
9627                      (match_operand:QI 2 "nonmemory_operand" "")))
9628               (clobber (reg:CC FLAGS_REG))])
9629    (match_dup 3)]
9630   "TARGET_CMOVE"
9631   [(const_int 0)]
9632   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9633
9634 (define_insn "x86_64_shrd"
9635   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9636         (ior:DI (ashiftrt:DI (match_dup 0)
9637                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9638                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9639                   (minus:QI (const_int 64) (match_dup 2)))))
9640    (clobber (reg:CC FLAGS_REG))]
9641   "TARGET_64BIT"
9642   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9643   [(set_attr "type" "ishift")
9644    (set_attr "prefix_0f" "1")
9645    (set_attr "mode" "DI")
9646    (set_attr "athlon_decode" "vector")
9647    (set_attr "amdfam10_decode" "vector")
9648    (set_attr "bdver1_decode" "vector")])
9649
9650 (define_insn "x86_shrd"
9651   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9652         (ior:SI (ashiftrt:SI (match_dup 0)
9653                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9654                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9655                   (minus:QI (const_int 32) (match_dup 2)))))
9656    (clobber (reg:CC FLAGS_REG))]
9657   ""
9658   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9659   [(set_attr "type" "ishift")
9660    (set_attr "prefix_0f" "1")
9661    (set_attr "mode" "SI")
9662    (set_attr "pent_pair" "np")
9663    (set_attr "athlon_decode" "vector")
9664    (set_attr "amdfam10_decode" "vector")
9665    (set_attr "bdver1_decode" "vector")])
9666
9667 (define_insn "ashrdi3_cvt"
9668   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9669         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9670                      (match_operand:QI 2 "const_int_operand" "")))
9671    (clobber (reg:CC FLAGS_REG))]
9672   "TARGET_64BIT && INTVAL (operands[2]) == 63
9673    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9674    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9675   "@
9676    {cqto|cqo}
9677    sar{q}\t{%2, %0|%0, %2}"
9678   [(set_attr "type" "imovx,ishift")
9679    (set_attr "prefix_0f" "0,*")
9680    (set_attr "length_immediate" "0,*")
9681    (set_attr "modrm" "0,1")
9682    (set_attr "mode" "DI")])
9683
9684 (define_insn "ashrsi3_cvt"
9685   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9686         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9687                      (match_operand:QI 2 "const_int_operand" "")))
9688    (clobber (reg:CC FLAGS_REG))]
9689   "INTVAL (operands[2]) == 31
9690    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9691    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9692   "@
9693    {cltd|cdq}
9694    sar{l}\t{%2, %0|%0, %2}"
9695   [(set_attr "type" "imovx,ishift")
9696    (set_attr "prefix_0f" "0,*")
9697    (set_attr "length_immediate" "0,*")
9698    (set_attr "modrm" "0,1")
9699    (set_attr "mode" "SI")])
9700
9701 (define_insn "*ashrsi3_cvt_zext"
9702   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9703         (zero_extend:DI
9704           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9705                        (match_operand:QI 2 "const_int_operand" ""))))
9706    (clobber (reg:CC FLAGS_REG))]
9707   "TARGET_64BIT && INTVAL (operands[2]) == 31
9708    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9709    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9710   "@
9711    {cltd|cdq}
9712    sar{l}\t{%2, %k0|%k0, %2}"
9713   [(set_attr "type" "imovx,ishift")
9714    (set_attr "prefix_0f" "0,*")
9715    (set_attr "length_immediate" "0,*")
9716    (set_attr "modrm" "0,1")
9717    (set_attr "mode" "SI")])
9718
9719 (define_expand "x86_shift<mode>_adj_3"
9720   [(use (match_operand:SWI48 0 "register_operand" ""))
9721    (use (match_operand:SWI48 1 "register_operand" ""))
9722    (use (match_operand:QI 2 "register_operand" ""))]
9723   ""
9724 {
9725   rtx label = gen_label_rtx ();
9726   rtx tmp;
9727
9728   emit_insn (gen_testqi_ccz_1 (operands[2],
9729                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9730
9731   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9732   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9733   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9734                               gen_rtx_LABEL_REF (VOIDmode, label),
9735                               pc_rtx);
9736   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9737   JUMP_LABEL (tmp) = label;
9738
9739   emit_move_insn (operands[0], operands[1]);
9740   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9741                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9742   emit_label (label);
9743   LABEL_NUSES (label) = 1;
9744
9745   DONE;
9746 })
9747
9748 (define_insn "*<shiftrt_insn><mode>3_1"
9749   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9750         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9751                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9752    (clobber (reg:CC FLAGS_REG))]
9753   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9754 {
9755   if (operands[2] == const1_rtx
9756       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9757     return "<shiftrt>{<imodesuffix>}\t%0";
9758   else
9759     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9760 }
9761   [(set_attr "type" "ishift")
9762    (set (attr "length_immediate")
9763      (if_then_else
9764        (and (match_operand 2 "const1_operand" "")
9765             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9766                 (const_int 0)))
9767        (const_string "0")
9768        (const_string "*")))
9769    (set_attr "mode" "<MODE>")])
9770
9771 (define_insn "*<shiftrt_insn>si3_1_zext"
9772   [(set (match_operand:DI 0 "register_operand" "=r")
9773         (zero_extend:DI
9774           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9775                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9776    (clobber (reg:CC FLAGS_REG))]
9777   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9778 {
9779   if (operands[2] == const1_rtx
9780       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9781     return "<shiftrt>{l}\t%k0";
9782   else
9783     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9784 }
9785   [(set_attr "type" "ishift")
9786    (set (attr "length_immediate")
9787      (if_then_else
9788        (and (match_operand 2 "const1_operand" "")
9789             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9790                 (const_int 0)))
9791        (const_string "0")
9792        (const_string "*")))
9793    (set_attr "mode" "SI")])
9794
9795 (define_insn "*<shiftrt_insn>qi3_1_slp"
9796   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9797         (any_shiftrt:QI (match_dup 0)
9798                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9799    (clobber (reg:CC FLAGS_REG))]
9800   "(optimize_function_for_size_p (cfun)
9801     || !TARGET_PARTIAL_REG_STALL
9802     || (operands[1] == const1_rtx
9803         && TARGET_SHIFT1))"
9804 {
9805   if (operands[1] == const1_rtx
9806       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9807     return "<shiftrt>{b}\t%0";
9808   else
9809     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9810 }
9811   [(set_attr "type" "ishift1")
9812    (set (attr "length_immediate")
9813      (if_then_else
9814        (and (match_operand 1 "const1_operand" "")
9815             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9816                 (const_int 0)))
9817        (const_string "0")
9818        (const_string "*")))
9819    (set_attr "mode" "QI")])
9820
9821 ;; This pattern can't accept a variable shift count, since shifts by
9822 ;; zero don't affect the flags.  We assume that shifts by constant
9823 ;; zero are optimized away.
9824 (define_insn "*<shiftrt_insn><mode>3_cmp"
9825   [(set (reg FLAGS_REG)
9826         (compare
9827           (any_shiftrt:SWI
9828             (match_operand:SWI 1 "nonimmediate_operand" "0")
9829             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9830           (const_int 0)))
9831    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9832         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9833   "(optimize_function_for_size_p (cfun)
9834     || !TARGET_PARTIAL_FLAG_REG_STALL
9835     || (operands[2] == const1_rtx
9836         && TARGET_SHIFT1))
9837    && ix86_match_ccmode (insn, CCGOCmode)
9838    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9839 {
9840   if (operands[2] == const1_rtx
9841       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9842     return "<shiftrt>{<imodesuffix>}\t%0";
9843   else
9844     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9845 }
9846   [(set_attr "type" "ishift")
9847    (set (attr "length_immediate")
9848      (if_then_else
9849        (and (match_operand 2 "const1_operand" "")
9850             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9851                 (const_int 0)))
9852        (const_string "0")
9853        (const_string "*")))
9854    (set_attr "mode" "<MODE>")])
9855
9856 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9857   [(set (reg FLAGS_REG)
9858         (compare
9859           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9860                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9861           (const_int 0)))
9862    (set (match_operand:DI 0 "register_operand" "=r")
9863         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9864   "TARGET_64BIT
9865    && (optimize_function_for_size_p (cfun)
9866        || !TARGET_PARTIAL_FLAG_REG_STALL
9867        || (operands[2] == const1_rtx
9868            && TARGET_SHIFT1))
9869    && ix86_match_ccmode (insn, CCGOCmode)
9870    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9871 {
9872   if (operands[2] == const1_rtx
9873       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9874     return "<shiftrt>{l}\t%k0";
9875   else
9876     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9877 }
9878   [(set_attr "type" "ishift")
9879    (set (attr "length_immediate")
9880      (if_then_else
9881        (and (match_operand 2 "const1_operand" "")
9882             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9883                 (const_int 0)))
9884        (const_string "0")
9885        (const_string "*")))
9886    (set_attr "mode" "SI")])
9887
9888 (define_insn "*<shiftrt_insn><mode>3_cconly"
9889   [(set (reg FLAGS_REG)
9890         (compare
9891           (any_shiftrt:SWI
9892             (match_operand:SWI 1 "register_operand" "0")
9893             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9894           (const_int 0)))
9895    (clobber (match_scratch:SWI 0 "=<r>"))]
9896   "(optimize_function_for_size_p (cfun)
9897     || !TARGET_PARTIAL_FLAG_REG_STALL
9898     || (operands[2] == const1_rtx
9899         && TARGET_SHIFT1))
9900    && ix86_match_ccmode (insn, CCGOCmode)"
9901 {
9902   if (operands[2] == const1_rtx
9903       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9904     return "<shiftrt>{<imodesuffix>}\t%0";
9905   else
9906     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9907 }
9908   [(set_attr "type" "ishift")
9909    (set (attr "length_immediate")
9910      (if_then_else
9911        (and (match_operand 2 "const1_operand" "")
9912             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9913                 (const_int 0)))
9914        (const_string "0")
9915        (const_string "*")))
9916    (set_attr "mode" "<MODE>")])
9917 \f
9918 ;; Rotate instructions
9919
9920 (define_expand "<rotate_insn>ti3"
9921   [(set (match_operand:TI 0 "register_operand" "")
9922         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9923                        (match_operand:QI 2 "nonmemory_operand" "")))]
9924   "TARGET_64BIT"
9925 {
9926   if (const_1_to_63_operand (operands[2], VOIDmode))
9927     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9928                 (operands[0], operands[1], operands[2]));
9929   else
9930     FAIL;
9931
9932   DONE;
9933 })
9934
9935 (define_expand "<rotate_insn>di3"
9936   [(set (match_operand:DI 0 "shiftdi_operand" "")
9937         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9938                        (match_operand:QI 2 "nonmemory_operand" "")))]
9939  ""
9940 {
9941   if (TARGET_64BIT)
9942     ix86_expand_binary_operator (<CODE>, DImode, operands);
9943   else if (const_1_to_31_operand (operands[2], VOIDmode))
9944     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9945                 (operands[0], operands[1], operands[2]));
9946   else
9947     FAIL;
9948
9949   DONE;
9950 })
9951
9952 (define_expand "<rotate_insn><mode>3"
9953   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9954         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9955                             (match_operand:QI 2 "nonmemory_operand" "")))]
9956   ""
9957   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9958
9959 ;; Avoid useless masking of count operand.
9960 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9961   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9962         (any_rotate:SWI48
9963           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9964           (subreg:QI
9965             (and:SI
9966               (match_operand:SI 2 "nonimmediate_operand" "c")
9967               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9968    (clobber (reg:CC FLAGS_REG))]
9969   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9970    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9971       == GET_MODE_BITSIZE (<MODE>mode)-1"
9972   "#"
9973   "&& 1"
9974   [(parallel [(set (match_dup 0)
9975                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9976               (clobber (reg:CC FLAGS_REG))])]
9977 {
9978   if (can_create_pseudo_p ())
9979     operands [2] = force_reg (SImode, operands[2]);
9980
9981   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9982 }
9983   [(set_attr "type" "rotate")
9984    (set_attr "mode" "<MODE>")])
9985
9986 ;; Implement rotation using two double-precision
9987 ;; shift instructions and a scratch register.
9988
9989 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9990  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9991        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9992                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9993   (clobber (reg:CC FLAGS_REG))
9994   (clobber (match_scratch:DWIH 3 "=&r"))]
9995  ""
9996  "#"
9997  "reload_completed"
9998  [(set (match_dup 3) (match_dup 4))
9999   (parallel
10000    [(set (match_dup 4)
10001          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10002                    (lshiftrt:DWIH (match_dup 5)
10003                                   (minus:QI (match_dup 6) (match_dup 2)))))
10004     (clobber (reg:CC FLAGS_REG))])
10005   (parallel
10006    [(set (match_dup 5)
10007          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10008                    (lshiftrt:DWIH (match_dup 3)
10009                                   (minus:QI (match_dup 6) (match_dup 2)))))
10010     (clobber (reg:CC FLAGS_REG))])]
10011 {
10012   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10013
10014   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10015 })
10016
10017 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10018  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10019        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10020                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10021   (clobber (reg:CC FLAGS_REG))
10022   (clobber (match_scratch:DWIH 3 "=&r"))]
10023  ""
10024  "#"
10025  "reload_completed"
10026  [(set (match_dup 3) (match_dup 4))
10027   (parallel
10028    [(set (match_dup 4)
10029          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10030                    (ashift:DWIH (match_dup 5)
10031                                 (minus:QI (match_dup 6) (match_dup 2)))))
10032     (clobber (reg:CC FLAGS_REG))])
10033   (parallel
10034    [(set (match_dup 5)
10035          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10036                    (ashift:DWIH (match_dup 3)
10037                                 (minus:QI (match_dup 6) (match_dup 2)))))
10038     (clobber (reg:CC FLAGS_REG))])]
10039 {
10040   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10041
10042   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10043 })
10044
10045 (define_insn "*<rotate_insn><mode>3_1"
10046   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10047         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10048                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10049    (clobber (reg:CC FLAGS_REG))]
10050   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10051 {
10052   if (operands[2] == const1_rtx
10053       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10054     return "<rotate>{<imodesuffix>}\t%0";
10055   else
10056     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10057 }
10058   [(set_attr "type" "rotate")
10059    (set (attr "length_immediate")
10060      (if_then_else
10061        (and (match_operand 2 "const1_operand" "")
10062             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10063                 (const_int 0)))
10064        (const_string "0")
10065        (const_string "*")))
10066    (set_attr "mode" "<MODE>")])
10067
10068 (define_insn "*<rotate_insn>si3_1_zext"
10069   [(set (match_operand:DI 0 "register_operand" "=r")
10070         (zero_extend:DI
10071           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10072                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10073    (clobber (reg:CC FLAGS_REG))]
10074   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10075 {
10076     if (operands[2] == const1_rtx
10077         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10078     return "<rotate>{l}\t%k0";
10079   else
10080     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10081 }
10082   [(set_attr "type" "rotate")
10083    (set (attr "length_immediate")
10084      (if_then_else
10085        (and (match_operand 2 "const1_operand" "")
10086             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10087                 (const_int 0)))
10088        (const_string "0")
10089        (const_string "*")))
10090    (set_attr "mode" "SI")])
10091
10092 (define_insn "*<rotate_insn>qi3_1_slp"
10093   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10094         (any_rotate:QI (match_dup 0)
10095                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10096    (clobber (reg:CC FLAGS_REG))]
10097   "(optimize_function_for_size_p (cfun)
10098     || !TARGET_PARTIAL_REG_STALL
10099     || (operands[1] == const1_rtx
10100         && TARGET_SHIFT1))"
10101 {
10102   if (operands[1] == const1_rtx
10103       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10104     return "<rotate>{b}\t%0";
10105   else
10106     return "<rotate>{b}\t{%1, %0|%0, %1}";
10107 }
10108   [(set_attr "type" "rotate1")
10109    (set (attr "length_immediate")
10110      (if_then_else
10111        (and (match_operand 1 "const1_operand" "")
10112             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10113                 (const_int 0)))
10114        (const_string "0")
10115        (const_string "*")))
10116    (set_attr "mode" "QI")])
10117
10118 (define_split
10119  [(set (match_operand:HI 0 "register_operand" "")
10120        (any_rotate:HI (match_dup 0) (const_int 8)))
10121   (clobber (reg:CC FLAGS_REG))]
10122  "reload_completed
10123   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10124  [(parallel [(set (strict_low_part (match_dup 0))
10125                   (bswap:HI (match_dup 0)))
10126              (clobber (reg:CC FLAGS_REG))])])
10127 \f
10128 ;; Bit set / bit test instructions
10129
10130 (define_expand "extv"
10131   [(set (match_operand:SI 0 "register_operand" "")
10132         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10133                          (match_operand:SI 2 "const8_operand" "")
10134                          (match_operand:SI 3 "const8_operand" "")))]
10135   ""
10136 {
10137   /* Handle extractions from %ah et al.  */
10138   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10139     FAIL;
10140
10141   /* From mips.md: extract_bit_field doesn't verify that our source
10142      matches the predicate, so check it again here.  */
10143   if (! ext_register_operand (operands[1], VOIDmode))
10144     FAIL;
10145 })
10146
10147 (define_expand "extzv"
10148   [(set (match_operand:SI 0 "register_operand" "")
10149         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10150                          (match_operand:SI 2 "const8_operand" "")
10151                          (match_operand:SI 3 "const8_operand" "")))]
10152   ""
10153 {
10154   /* Handle extractions from %ah et al.  */
10155   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10156     FAIL;
10157
10158   /* From mips.md: extract_bit_field doesn't verify that our source
10159      matches the predicate, so check it again here.  */
10160   if (! ext_register_operand (operands[1], VOIDmode))
10161     FAIL;
10162 })
10163
10164 (define_expand "insv"
10165   [(set (zero_extract (match_operand 0 "register_operand" "")
10166                       (match_operand 1 "const_int_operand" "")
10167                       (match_operand 2 "const_int_operand" ""))
10168         (match_operand 3 "register_operand" ""))]
10169   ""
10170 {
10171   rtx (*gen_mov_insv_1) (rtx, rtx);
10172
10173   if (ix86_expand_pinsr (operands))
10174     DONE;
10175
10176   /* Handle insertions to %ah et al.  */
10177   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10178     FAIL;
10179
10180   /* From mips.md: insert_bit_field doesn't verify that our source
10181      matches the predicate, so check it again here.  */
10182   if (! ext_register_operand (operands[0], VOIDmode))
10183     FAIL;
10184
10185   gen_mov_insv_1 = (TARGET_64BIT
10186                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10187
10188   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10189   DONE;
10190 })
10191
10192 ;; %%% bts, btr, btc, bt.
10193 ;; In general these instructions are *slow* when applied to memory,
10194 ;; since they enforce atomic operation.  When applied to registers,
10195 ;; it depends on the cpu implementation.  They're never faster than
10196 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10197 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10198 ;; within the instruction itself, so operating on bits in the high
10199 ;; 32-bits of a register becomes easier.
10200 ;;
10201 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10202 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10203 ;; negdf respectively, so they can never be disabled entirely.
10204
10205 (define_insn "*btsq"
10206   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10207                          (const_int 1)
10208                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10209         (const_int 1))
10210    (clobber (reg:CC FLAGS_REG))]
10211   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10212   "bts{q}\t{%1, %0|%0, %1}"
10213   [(set_attr "type" "alu1")
10214    (set_attr "prefix_0f" "1")
10215    (set_attr "mode" "DI")])
10216
10217 (define_insn "*btrq"
10218   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10219                          (const_int 1)
10220                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10221         (const_int 0))
10222    (clobber (reg:CC FLAGS_REG))]
10223   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10224   "btr{q}\t{%1, %0|%0, %1}"
10225   [(set_attr "type" "alu1")
10226    (set_attr "prefix_0f" "1")
10227    (set_attr "mode" "DI")])
10228
10229 (define_insn "*btcq"
10230   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10231                          (const_int 1)
10232                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10233         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10234    (clobber (reg:CC FLAGS_REG))]
10235   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10236   "btc{q}\t{%1, %0|%0, %1}"
10237   [(set_attr "type" "alu1")
10238    (set_attr "prefix_0f" "1")
10239    (set_attr "mode" "DI")])
10240
10241 ;; Allow Nocona to avoid these instructions if a register is available.
10242
10243 (define_peephole2
10244   [(match_scratch:DI 2 "r")
10245    (parallel [(set (zero_extract:DI
10246                      (match_operand:DI 0 "register_operand" "")
10247                      (const_int 1)
10248                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10249                    (const_int 1))
10250               (clobber (reg:CC FLAGS_REG))])]
10251   "TARGET_64BIT && !TARGET_USE_BT"
10252   [(const_int 0)]
10253 {
10254   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10255   rtx op1;
10256
10257   if (HOST_BITS_PER_WIDE_INT >= 64)
10258     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10259   else if (i < HOST_BITS_PER_WIDE_INT)
10260     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10261   else
10262     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10263
10264   op1 = immed_double_const (lo, hi, DImode);
10265   if (i >= 31)
10266     {
10267       emit_move_insn (operands[2], op1);
10268       op1 = operands[2];
10269     }
10270
10271   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10272   DONE;
10273 })
10274
10275 (define_peephole2
10276   [(match_scratch:DI 2 "r")
10277    (parallel [(set (zero_extract:DI
10278                      (match_operand:DI 0 "register_operand" "")
10279                      (const_int 1)
10280                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10281                    (const_int 0))
10282               (clobber (reg:CC FLAGS_REG))])]
10283   "TARGET_64BIT && !TARGET_USE_BT"
10284   [(const_int 0)]
10285 {
10286   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10287   rtx op1;
10288
10289   if (HOST_BITS_PER_WIDE_INT >= 64)
10290     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10291   else if (i < HOST_BITS_PER_WIDE_INT)
10292     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10293   else
10294     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10295
10296   op1 = immed_double_const (~lo, ~hi, DImode);
10297   if (i >= 32)
10298     {
10299       emit_move_insn (operands[2], op1);
10300       op1 = operands[2];
10301     }
10302
10303   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10304   DONE;
10305 })
10306
10307 (define_peephole2
10308   [(match_scratch:DI 2 "r")
10309    (parallel [(set (zero_extract:DI
10310                      (match_operand:DI 0 "register_operand" "")
10311                      (const_int 1)
10312                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10313               (not:DI (zero_extract:DI
10314                         (match_dup 0) (const_int 1) (match_dup 1))))
10315               (clobber (reg:CC FLAGS_REG))])]
10316   "TARGET_64BIT && !TARGET_USE_BT"
10317   [(const_int 0)]
10318 {
10319   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10320   rtx op1;
10321
10322   if (HOST_BITS_PER_WIDE_INT >= 64)
10323     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10324   else if (i < HOST_BITS_PER_WIDE_INT)
10325     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10326   else
10327     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10328
10329   op1 = immed_double_const (lo, hi, DImode);
10330   if (i >= 31)
10331     {
10332       emit_move_insn (operands[2], op1);
10333       op1 = operands[2];
10334     }
10335
10336   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10337   DONE;
10338 })
10339
10340 (define_insn "*bt<mode>"
10341   [(set (reg:CCC FLAGS_REG)
10342         (compare:CCC
10343           (zero_extract:SWI48
10344             (match_operand:SWI48 0 "register_operand" "r")
10345             (const_int 1)
10346             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10347           (const_int 0)))]
10348   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10349   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10350   [(set_attr "type" "alu1")
10351    (set_attr "prefix_0f" "1")
10352    (set_attr "mode" "<MODE>")])
10353 \f
10354 ;; Store-flag instructions.
10355
10356 ;; For all sCOND expanders, also expand the compare or test insn that
10357 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10358
10359 (define_insn_and_split "*setcc_di_1"
10360   [(set (match_operand:DI 0 "register_operand" "=q")
10361         (match_operator:DI 1 "ix86_comparison_operator"
10362           [(reg FLAGS_REG) (const_int 0)]))]
10363   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10364   "#"
10365   "&& reload_completed"
10366   [(set (match_dup 2) (match_dup 1))
10367    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10368 {
10369   PUT_MODE (operands[1], QImode);
10370   operands[2] = gen_lowpart (QImode, operands[0]);
10371 })
10372
10373 (define_insn_and_split "*setcc_si_1_and"
10374   [(set (match_operand:SI 0 "register_operand" "=q")
10375         (match_operator:SI 1 "ix86_comparison_operator"
10376           [(reg FLAGS_REG) (const_int 0)]))
10377    (clobber (reg:CC FLAGS_REG))]
10378   "!TARGET_PARTIAL_REG_STALL
10379    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10380   "#"
10381   "&& reload_completed"
10382   [(set (match_dup 2) (match_dup 1))
10383    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10384               (clobber (reg:CC FLAGS_REG))])]
10385 {
10386   PUT_MODE (operands[1], QImode);
10387   operands[2] = gen_lowpart (QImode, operands[0]);
10388 })
10389
10390 (define_insn_and_split "*setcc_si_1_movzbl"
10391   [(set (match_operand:SI 0 "register_operand" "=q")
10392         (match_operator:SI 1 "ix86_comparison_operator"
10393           [(reg FLAGS_REG) (const_int 0)]))]
10394   "!TARGET_PARTIAL_REG_STALL
10395    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10396   "#"
10397   "&& reload_completed"
10398   [(set (match_dup 2) (match_dup 1))
10399    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10400 {
10401   PUT_MODE (operands[1], QImode);
10402   operands[2] = gen_lowpart (QImode, operands[0]);
10403 })
10404
10405 (define_insn "*setcc_qi"
10406   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10407         (match_operator:QI 1 "ix86_comparison_operator"
10408           [(reg FLAGS_REG) (const_int 0)]))]
10409   ""
10410   "set%C1\t%0"
10411   [(set_attr "type" "setcc")
10412    (set_attr "mode" "QI")])
10413
10414 (define_insn "*setcc_qi_slp"
10415   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10416         (match_operator:QI 1 "ix86_comparison_operator"
10417           [(reg FLAGS_REG) (const_int 0)]))]
10418   ""
10419   "set%C1\t%0"
10420   [(set_attr "type" "setcc")
10421    (set_attr "mode" "QI")])
10422
10423 ;; In general it is not safe to assume too much about CCmode registers,
10424 ;; so simplify-rtx stops when it sees a second one.  Under certain
10425 ;; conditions this is safe on x86, so help combine not create
10426 ;;
10427 ;;      seta    %al
10428 ;;      testb   %al, %al
10429 ;;      sete    %al
10430
10431 (define_split
10432   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10433         (ne:QI (match_operator 1 "ix86_comparison_operator"
10434                  [(reg FLAGS_REG) (const_int 0)])
10435             (const_int 0)))]
10436   ""
10437   [(set (match_dup 0) (match_dup 1))]
10438   "PUT_MODE (operands[1], QImode);")
10439
10440 (define_split
10441   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10442         (ne:QI (match_operator 1 "ix86_comparison_operator"
10443                  [(reg FLAGS_REG) (const_int 0)])
10444             (const_int 0)))]
10445   ""
10446   [(set (match_dup 0) (match_dup 1))]
10447   "PUT_MODE (operands[1], QImode);")
10448
10449 (define_split
10450   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10451         (eq:QI (match_operator 1 "ix86_comparison_operator"
10452                  [(reg FLAGS_REG) (const_int 0)])
10453             (const_int 0)))]
10454   ""
10455   [(set (match_dup 0) (match_dup 1))]
10456 {
10457   rtx new_op1 = copy_rtx (operands[1]);
10458   operands[1] = new_op1;
10459   PUT_MODE (new_op1, QImode);
10460   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10461                                              GET_MODE (XEXP (new_op1, 0))));
10462
10463   /* Make sure that (a) the CCmode we have for the flags is strong
10464      enough for the reversed compare or (b) we have a valid FP compare.  */
10465   if (! ix86_comparison_operator (new_op1, VOIDmode))
10466     FAIL;
10467 })
10468
10469 (define_split
10470   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10471         (eq:QI (match_operator 1 "ix86_comparison_operator"
10472                  [(reg FLAGS_REG) (const_int 0)])
10473             (const_int 0)))]
10474   ""
10475   [(set (match_dup 0) (match_dup 1))]
10476 {
10477   rtx new_op1 = copy_rtx (operands[1]);
10478   operands[1] = new_op1;
10479   PUT_MODE (new_op1, QImode);
10480   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10481                                              GET_MODE (XEXP (new_op1, 0))));
10482
10483   /* Make sure that (a) the CCmode we have for the flags is strong
10484      enough for the reversed compare or (b) we have a valid FP compare.  */
10485   if (! ix86_comparison_operator (new_op1, VOIDmode))
10486     FAIL;
10487 })
10488
10489 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10490 ;; subsequent logical operations are used to imitate conditional moves.
10491 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10492 ;; it directly.
10493
10494 (define_insn "setcc_<mode>_sse"
10495   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10496         (match_operator:MODEF 3 "sse_comparison_operator"
10497           [(match_operand:MODEF 1 "register_operand" "0,x")
10498            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10499   "SSE_FLOAT_MODE_P (<MODE>mode)"
10500   "@
10501    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10502    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10503   [(set_attr "isa" "noavx,avx")
10504    (set_attr "type" "ssecmp")
10505    (set_attr "length_immediate" "1")
10506    (set_attr "prefix" "orig,vex")
10507    (set_attr "mode" "<MODE>")])
10508 \f
10509 ;; Basic conditional jump instructions.
10510 ;; We ignore the overflow flag for signed branch instructions.
10511
10512 (define_insn "*jcc_1"
10513   [(set (pc)
10514         (if_then_else (match_operator 1 "ix86_comparison_operator"
10515                                       [(reg FLAGS_REG) (const_int 0)])
10516                       (label_ref (match_operand 0 "" ""))
10517                       (pc)))]
10518   ""
10519   "%+j%C1\t%l0"
10520   [(set_attr "type" "ibr")
10521    (set_attr "modrm" "0")
10522    (set (attr "length")
10523            (if_then_else (and (ge (minus (match_dup 0) (pc))
10524                                   (const_int -126))
10525                               (lt (minus (match_dup 0) (pc))
10526                                   (const_int 128)))
10527              (const_int 2)
10528              (const_int 6)))])
10529
10530 (define_insn "*jcc_2"
10531   [(set (pc)
10532         (if_then_else (match_operator 1 "ix86_comparison_operator"
10533                                       [(reg FLAGS_REG) (const_int 0)])
10534                       (pc)
10535                       (label_ref (match_operand 0 "" ""))))]
10536   ""
10537   "%+j%c1\t%l0"
10538   [(set_attr "type" "ibr")
10539    (set_attr "modrm" "0")
10540    (set (attr "length")
10541            (if_then_else (and (ge (minus (match_dup 0) (pc))
10542                                   (const_int -126))
10543                               (lt (minus (match_dup 0) (pc))
10544                                   (const_int 128)))
10545              (const_int 2)
10546              (const_int 6)))])
10547
10548 ;; In general it is not safe to assume too much about CCmode registers,
10549 ;; so simplify-rtx stops when it sees a second one.  Under certain
10550 ;; conditions this is safe on x86, so help combine not create
10551 ;;
10552 ;;      seta    %al
10553 ;;      testb   %al, %al
10554 ;;      je      Lfoo
10555
10556 (define_split
10557   [(set (pc)
10558         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10559                                       [(reg FLAGS_REG) (const_int 0)])
10560                           (const_int 0))
10561                       (label_ref (match_operand 1 "" ""))
10562                       (pc)))]
10563   ""
10564   [(set (pc)
10565         (if_then_else (match_dup 0)
10566                       (label_ref (match_dup 1))
10567                       (pc)))]
10568   "PUT_MODE (operands[0], VOIDmode);")
10569
10570 (define_split
10571   [(set (pc)
10572         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10573                                       [(reg FLAGS_REG) (const_int 0)])
10574                           (const_int 0))
10575                       (label_ref (match_operand 1 "" ""))
10576                       (pc)))]
10577   ""
10578   [(set (pc)
10579         (if_then_else (match_dup 0)
10580                       (label_ref (match_dup 1))
10581                       (pc)))]
10582 {
10583   rtx new_op0 = copy_rtx (operands[0]);
10584   operands[0] = new_op0;
10585   PUT_MODE (new_op0, VOIDmode);
10586   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10587                                              GET_MODE (XEXP (new_op0, 0))));
10588
10589   /* Make sure that (a) the CCmode we have for the flags is strong
10590      enough for the reversed compare or (b) we have a valid FP compare.  */
10591   if (! ix86_comparison_operator (new_op0, VOIDmode))
10592     FAIL;
10593 })
10594
10595 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10596 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10597 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10598 ;; appropriate modulo of the bit offset value.
10599
10600 (define_insn_and_split "*jcc_bt<mode>"
10601   [(set (pc)
10602         (if_then_else (match_operator 0 "bt_comparison_operator"
10603                         [(zero_extract:SWI48
10604                            (match_operand:SWI48 1 "register_operand" "r")
10605                            (const_int 1)
10606                            (zero_extend:SI
10607                              (match_operand:QI 2 "register_operand" "r")))
10608                          (const_int 0)])
10609                       (label_ref (match_operand 3 "" ""))
10610                       (pc)))
10611    (clobber (reg:CC FLAGS_REG))]
10612   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10613   "#"
10614   "&& 1"
10615   [(set (reg:CCC FLAGS_REG)
10616         (compare:CCC
10617           (zero_extract:SWI48
10618             (match_dup 1)
10619             (const_int 1)
10620             (match_dup 2))
10621           (const_int 0)))
10622    (set (pc)
10623         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10624                       (label_ref (match_dup 3))
10625                       (pc)))]
10626 {
10627   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10628
10629   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10630 })
10631
10632 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10633 ;; also for DImode, this is what combine produces.
10634 (define_insn_and_split "*jcc_bt<mode>_mask"
10635   [(set (pc)
10636         (if_then_else (match_operator 0 "bt_comparison_operator"
10637                         [(zero_extract:SWI48
10638                            (match_operand:SWI48 1 "register_operand" "r")
10639                            (const_int 1)
10640                            (and:SI
10641                              (match_operand:SI 2 "register_operand" "r")
10642                              (match_operand:SI 3 "const_int_operand" "n")))])
10643                       (label_ref (match_operand 4 "" ""))
10644                       (pc)))
10645    (clobber (reg:CC FLAGS_REG))]
10646   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10647    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10648       == GET_MODE_BITSIZE (<MODE>mode)-1"
10649   "#"
10650   "&& 1"
10651   [(set (reg:CCC FLAGS_REG)
10652         (compare:CCC
10653           (zero_extract:SWI48
10654             (match_dup 1)
10655             (const_int 1)
10656             (match_dup 2))
10657           (const_int 0)))
10658    (set (pc)
10659         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10660                       (label_ref (match_dup 4))
10661                       (pc)))]
10662 {
10663   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10664
10665   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10666 })
10667
10668 (define_insn_and_split "*jcc_btsi_1"
10669   [(set (pc)
10670         (if_then_else (match_operator 0 "bt_comparison_operator"
10671                         [(and:SI
10672                            (lshiftrt:SI
10673                              (match_operand:SI 1 "register_operand" "r")
10674                              (match_operand:QI 2 "register_operand" "r"))
10675                            (const_int 1))
10676                          (const_int 0)])
10677                       (label_ref (match_operand 3 "" ""))
10678                       (pc)))
10679    (clobber (reg:CC FLAGS_REG))]
10680   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10681   "#"
10682   "&& 1"
10683   [(set (reg:CCC FLAGS_REG)
10684         (compare:CCC
10685           (zero_extract:SI
10686             (match_dup 1)
10687             (const_int 1)
10688             (match_dup 2))
10689           (const_int 0)))
10690    (set (pc)
10691         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10692                       (label_ref (match_dup 3))
10693                       (pc)))]
10694 {
10695   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10696
10697   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10698 })
10699
10700 ;; avoid useless masking of bit offset operand
10701 (define_insn_and_split "*jcc_btsi_mask_1"
10702   [(set (pc)
10703         (if_then_else
10704           (match_operator 0 "bt_comparison_operator"
10705             [(and:SI
10706                (lshiftrt:SI
10707                  (match_operand:SI 1 "register_operand" "r")
10708                  (subreg:QI
10709                    (and:SI
10710                      (match_operand:SI 2 "register_operand" "r")
10711                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10712                (const_int 1))
10713              (const_int 0)])
10714           (label_ref (match_operand 4 "" ""))
10715           (pc)))
10716    (clobber (reg:CC FLAGS_REG))]
10717   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10718    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10719   "#"
10720   "&& 1"
10721   [(set (reg:CCC FLAGS_REG)
10722         (compare:CCC
10723           (zero_extract:SI
10724             (match_dup 1)
10725             (const_int 1)
10726             (match_dup 2))
10727           (const_int 0)))
10728    (set (pc)
10729         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10730                       (label_ref (match_dup 4))
10731                       (pc)))]
10732   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10733
10734 ;; Define combination compare-and-branch fp compare instructions to help
10735 ;; combine.
10736
10737 (define_insn "*fp_jcc_1_387"
10738   [(set (pc)
10739         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10740                         [(match_operand 1 "register_operand" "f")
10741                          (match_operand 2 "nonimmediate_operand" "fm")])
10742           (label_ref (match_operand 3 "" ""))
10743           (pc)))
10744    (clobber (reg:CCFP FPSR_REG))
10745    (clobber (reg:CCFP FLAGS_REG))
10746    (clobber (match_scratch:HI 4 "=a"))]
10747   "TARGET_80387
10748    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10749    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10750    && SELECT_CC_MODE (GET_CODE (operands[0]),
10751                       operands[1], operands[2]) == CCFPmode
10752    && !TARGET_CMOVE"
10753   "#")
10754
10755 (define_insn "*fp_jcc_1r_387"
10756   [(set (pc)
10757         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10758                         [(match_operand 1 "register_operand" "f")
10759                          (match_operand 2 "nonimmediate_operand" "fm")])
10760           (pc)
10761           (label_ref (match_operand 3 "" ""))))
10762    (clobber (reg:CCFP FPSR_REG))
10763    (clobber (reg:CCFP FLAGS_REG))
10764    (clobber (match_scratch:HI 4 "=a"))]
10765   "TARGET_80387
10766    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10767    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10768    && SELECT_CC_MODE (GET_CODE (operands[0]),
10769                       operands[1], operands[2]) == CCFPmode
10770    && !TARGET_CMOVE"
10771   "#")
10772
10773 (define_insn "*fp_jcc_2_387"
10774   [(set (pc)
10775         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10776                         [(match_operand 1 "register_operand" "f")
10777                          (match_operand 2 "register_operand" "f")])
10778           (label_ref (match_operand 3 "" ""))
10779           (pc)))
10780    (clobber (reg:CCFP FPSR_REG))
10781    (clobber (reg:CCFP FLAGS_REG))
10782    (clobber (match_scratch:HI 4 "=a"))]
10783   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10784    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10785    && !TARGET_CMOVE"
10786   "#")
10787
10788 (define_insn "*fp_jcc_2r_387"
10789   [(set (pc)
10790         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10791                         [(match_operand 1 "register_operand" "f")
10792                          (match_operand 2 "register_operand" "f")])
10793           (pc)
10794           (label_ref (match_operand 3 "" ""))))
10795    (clobber (reg:CCFP FPSR_REG))
10796    (clobber (reg:CCFP FLAGS_REG))
10797    (clobber (match_scratch:HI 4 "=a"))]
10798   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10799    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10800    && !TARGET_CMOVE"
10801   "#")
10802
10803 (define_insn "*fp_jcc_3_387"
10804   [(set (pc)
10805         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10806                         [(match_operand 1 "register_operand" "f")
10807                          (match_operand 2 "const0_operand" "")])
10808           (label_ref (match_operand 3 "" ""))
10809           (pc)))
10810    (clobber (reg:CCFP FPSR_REG))
10811    (clobber (reg:CCFP FLAGS_REG))
10812    (clobber (match_scratch:HI 4 "=a"))]
10813   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10814    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10815    && SELECT_CC_MODE (GET_CODE (operands[0]),
10816                       operands[1], operands[2]) == CCFPmode
10817    && !TARGET_CMOVE"
10818   "#")
10819
10820 (define_split
10821   [(set (pc)
10822         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10823                         [(match_operand 1 "register_operand" "")
10824                          (match_operand 2 "nonimmediate_operand" "")])
10825           (match_operand 3 "" "")
10826           (match_operand 4 "" "")))
10827    (clobber (reg:CCFP FPSR_REG))
10828    (clobber (reg:CCFP FLAGS_REG))]
10829   "reload_completed"
10830   [(const_int 0)]
10831 {
10832   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10833                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10834   DONE;
10835 })
10836
10837 (define_split
10838   [(set (pc)
10839         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10840                         [(match_operand 1 "register_operand" "")
10841                          (match_operand 2 "general_operand" "")])
10842           (match_operand 3 "" "")
10843           (match_operand 4 "" "")))
10844    (clobber (reg:CCFP FPSR_REG))
10845    (clobber (reg:CCFP FLAGS_REG))
10846    (clobber (match_scratch:HI 5 "=a"))]
10847   "reload_completed"
10848   [(const_int 0)]
10849 {
10850   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10851                         operands[3], operands[4], operands[5], NULL_RTX);
10852   DONE;
10853 })
10854
10855 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10856 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10857 ;; with a precedence over other operators and is always put in the first
10858 ;; place. Swap condition and operands to match ficom instruction.
10859
10860 (define_insn "*fp_jcc_4_<mode>_387"
10861   [(set (pc)
10862         (if_then_else
10863           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10864             [(match_operator 1 "float_operator"
10865               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10866              (match_operand 3 "register_operand" "f,f")])
10867           (label_ref (match_operand 4 "" ""))
10868           (pc)))
10869    (clobber (reg:CCFP FPSR_REG))
10870    (clobber (reg:CCFP FLAGS_REG))
10871    (clobber (match_scratch:HI 5 "=a,a"))]
10872   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10873    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10874    && GET_MODE (operands[1]) == GET_MODE (operands[3])
10875    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10876    && !TARGET_CMOVE"
10877   "#")
10878
10879 (define_split
10880   [(set (pc)
10881         (if_then_else
10882           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10883             [(match_operator 1 "float_operator"
10884               [(match_operand:SWI24 2 "memory_operand" "")])
10885              (match_operand 3 "register_operand" "")])
10886           (match_operand 4 "" "")
10887           (match_operand 5 "" "")))
10888    (clobber (reg:CCFP FPSR_REG))
10889    (clobber (reg:CCFP FLAGS_REG))
10890    (clobber (match_scratch:HI 6 "=a"))]
10891   "reload_completed"
10892   [(const_int 0)]
10893 {
10894   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10895
10896   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10897                         operands[3], operands[7],
10898                         operands[4], operands[5], operands[6], NULL_RTX);
10899   DONE;
10900 })
10901
10902 ;; %%% Kill this when reload knows how to do it.
10903 (define_split
10904   [(set (pc)
10905         (if_then_else
10906           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10907             [(match_operator 1 "float_operator"
10908               [(match_operand:SWI24 2 "register_operand" "")])
10909              (match_operand 3 "register_operand" "")])
10910           (match_operand 4 "" "")
10911           (match_operand 5 "" "")))
10912    (clobber (reg:CCFP FPSR_REG))
10913    (clobber (reg:CCFP FLAGS_REG))
10914    (clobber (match_scratch:HI 6 "=a"))]
10915   "reload_completed"
10916   [(const_int 0)]
10917 {
10918   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10919   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10920
10921   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10922                         operands[3], operands[7],
10923                         operands[4], operands[5], operands[6], operands[2]);
10924   DONE;
10925 })
10926 \f
10927 ;; Unconditional and other jump instructions
10928
10929 (define_insn "jump"
10930   [(set (pc)
10931         (label_ref (match_operand 0 "" "")))]
10932   ""
10933   "jmp\t%l0"
10934   [(set_attr "type" "ibr")
10935    (set (attr "length")
10936            (if_then_else (and (ge (minus (match_dup 0) (pc))
10937                                   (const_int -126))
10938                               (lt (minus (match_dup 0) (pc))
10939                                   (const_int 128)))
10940              (const_int 2)
10941              (const_int 5)))
10942    (set_attr "modrm" "0")])
10943
10944 (define_expand "indirect_jump"
10945   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10946   ""
10947   "")
10948
10949 (define_insn "*indirect_jump"
10950   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10951   ""
10952   "jmp\t%A0"
10953   [(set_attr "type" "ibr")
10954    (set_attr "length_immediate" "0")])
10955
10956 (define_expand "tablejump"
10957   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10958               (use (label_ref (match_operand 1 "" "")))])]
10959   ""
10960 {
10961   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10962      relative.  Convert the relative address to an absolute address.  */
10963   if (flag_pic)
10964     {
10965       rtx op0, op1;
10966       enum rtx_code code;
10967
10968       /* We can't use @GOTOFF for text labels on VxWorks;
10969          see gotoff_operand.  */
10970       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10971         {
10972           code = PLUS;
10973           op0 = operands[0];
10974           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10975         }
10976       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10977         {
10978           code = PLUS;
10979           op0 = operands[0];
10980           op1 = pic_offset_table_rtx;
10981         }
10982       else
10983         {
10984           code = MINUS;
10985           op0 = pic_offset_table_rtx;
10986           op1 = operands[0];
10987         }
10988
10989       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10990                                          OPTAB_DIRECT);
10991     }
10992 })
10993
10994 (define_insn "*tablejump_1"
10995   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
10996    (use (label_ref (match_operand 1 "" "")))]
10997   ""
10998   "jmp\t%A0"
10999   [(set_attr "type" "ibr")
11000    (set_attr "length_immediate" "0")])
11001 \f
11002 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11003
11004 (define_peephole2
11005   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11006    (set (match_operand:QI 1 "register_operand" "")
11007         (match_operator:QI 2 "ix86_comparison_operator"
11008           [(reg FLAGS_REG) (const_int 0)]))
11009    (set (match_operand 3 "q_regs_operand" "")
11010         (zero_extend (match_dup 1)))]
11011   "(peep2_reg_dead_p (3, operands[1])
11012     || operands_match_p (operands[1], operands[3]))
11013    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11014   [(set (match_dup 4) (match_dup 0))
11015    (set (strict_low_part (match_dup 5))
11016         (match_dup 2))]
11017 {
11018   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11019   operands[5] = gen_lowpart (QImode, operands[3]);
11020   ix86_expand_clear (operands[3]);
11021 })
11022
11023 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11024
11025 (define_peephole2
11026   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11027    (set (match_operand:QI 1 "register_operand" "")
11028         (match_operator:QI 2 "ix86_comparison_operator"
11029           [(reg FLAGS_REG) (const_int 0)]))
11030    (parallel [(set (match_operand 3 "q_regs_operand" "")
11031                    (zero_extend (match_dup 1)))
11032               (clobber (reg:CC FLAGS_REG))])]
11033   "(peep2_reg_dead_p (3, operands[1])
11034     || operands_match_p (operands[1], operands[3]))
11035    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11036   [(set (match_dup 4) (match_dup 0))
11037    (set (strict_low_part (match_dup 5))
11038         (match_dup 2))]
11039 {
11040   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11041   operands[5] = gen_lowpart (QImode, operands[3]);
11042   ix86_expand_clear (operands[3]);
11043 })
11044 \f
11045 ;; Call instructions.
11046
11047 ;; The predicates normally associated with named expanders are not properly
11048 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11049 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11050
11051 ;; P6 processors will jump to the address after the decrement when %esp
11052 ;; is used as a call operand, so they will execute return address as a code.
11053 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11054
11055 ;; Register constraint for call instruction.
11056 (define_mode_attr c [(SI "l") (DI "r")])
11057
11058 ;; Call subroutine returning no value.
11059
11060 (define_expand "call"
11061   [(call (match_operand:QI 0 "" "")
11062          (match_operand 1 "" ""))
11063    (use (match_operand 2 "" ""))]
11064   ""
11065 {
11066   ix86_expand_call (NULL, operands[0], operands[1],
11067                     operands[2], NULL, false);
11068   DONE;
11069 })
11070
11071 (define_expand "sibcall"
11072   [(call (match_operand:QI 0 "" "")
11073          (match_operand 1 "" ""))
11074    (use (match_operand 2 "" ""))]
11075   ""
11076 {
11077   ix86_expand_call (NULL, operands[0], operands[1],
11078                     operands[2], NULL, true);
11079   DONE;
11080 })
11081
11082 (define_insn_and_split "*call_vzeroupper"
11083   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11084          (match_operand 1 "" ""))
11085    (unspec [(match_operand 2 "const_int_operand" "")]
11086            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11087   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11088   "#"
11089   "&& reload_completed"
11090   [(const_int 0)]
11091   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11092   [(set_attr "type" "call")])
11093
11094 (define_insn "*call"
11095   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
11096          (match_operand 1 "" ""))]
11097   "!SIBLING_CALL_P (insn)"
11098   "* return ix86_output_call_insn (insn, operands[0]);"
11099   [(set_attr "type" "call")])
11100
11101 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11102   [(parallel
11103     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11104            (match_operand 1 "" ""))
11105      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11106      (clobber (reg:TI XMM6_REG))
11107      (clobber (reg:TI XMM7_REG))
11108      (clobber (reg:TI XMM8_REG))
11109      (clobber (reg:TI XMM9_REG))
11110      (clobber (reg:TI XMM10_REG))
11111      (clobber (reg:TI XMM11_REG))
11112      (clobber (reg:TI XMM12_REG))
11113      (clobber (reg:TI XMM13_REG))
11114      (clobber (reg:TI XMM14_REG))
11115      (clobber (reg:TI XMM15_REG))
11116      (clobber (reg:DI SI_REG))
11117      (clobber (reg:DI DI_REG))])
11118    (unspec [(match_operand 2 "const_int_operand" "")]
11119            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11120   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11121   "#"
11122   "&& reload_completed"
11123   [(const_int 0)]
11124   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11125   [(set_attr "type" "call")])
11126
11127 (define_insn "*call_rex64_ms_sysv"
11128   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
11129          (match_operand 1 "" ""))
11130    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11131    (clobber (reg:TI XMM6_REG))
11132    (clobber (reg:TI XMM7_REG))
11133    (clobber (reg:TI XMM8_REG))
11134    (clobber (reg:TI XMM9_REG))
11135    (clobber (reg:TI XMM10_REG))
11136    (clobber (reg:TI XMM11_REG))
11137    (clobber (reg:TI XMM12_REG))
11138    (clobber (reg:TI XMM13_REG))
11139    (clobber (reg:TI XMM14_REG))
11140    (clobber (reg:TI XMM15_REG))
11141    (clobber (reg:DI SI_REG))
11142    (clobber (reg:DI DI_REG))]
11143   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11144   "* return ix86_output_call_insn (insn, operands[0]);"
11145   [(set_attr "type" "call")])
11146
11147 (define_insn_and_split "*sibcall_vzeroupper"
11148   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11149          (match_operand 1 "" ""))
11150    (unspec [(match_operand 2 "const_int_operand" "")]
11151            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11152   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11153   "#"
11154   "&& reload_completed"
11155   [(const_int 0)]
11156   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11157   [(set_attr "type" "call")])
11158
11159 (define_insn "*sibcall"
11160   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11161          (match_operand 1 "" ""))]
11162   "SIBLING_CALL_P (insn)"
11163   "* return ix86_output_call_insn (insn, operands[0]);"
11164   [(set_attr "type" "call")])
11165
11166 (define_expand "call_pop"
11167   [(parallel [(call (match_operand:QI 0 "" "")
11168                     (match_operand:SI 1 "" ""))
11169               (set (reg:SI SP_REG)
11170                    (plus:SI (reg:SI SP_REG)
11171                             (match_operand:SI 3 "" "")))])]
11172   "!TARGET_64BIT"
11173 {
11174   ix86_expand_call (NULL, operands[0], operands[1],
11175                     operands[2], operands[3], false);
11176   DONE;
11177 })
11178
11179 (define_insn_and_split "*call_pop_vzeroupper"
11180   [(parallel
11181     [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11182            (match_operand:SI 1 "" ""))
11183      (set (reg:SI SP_REG)
11184           (plus:SI (reg:SI SP_REG)
11185                    (match_operand:SI 2 "immediate_operand" "i")))])
11186    (unspec [(match_operand 3 "const_int_operand" "")]
11187            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11188   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11189   "#"
11190   "&& reload_completed"
11191   [(const_int 0)]
11192   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11193   [(set_attr "type" "call")])
11194
11195 (define_insn "*call_pop"
11196   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11197          (match_operand 1 "" ""))
11198    (set (reg:SI SP_REG)
11199         (plus:SI (reg:SI SP_REG)
11200                  (match_operand:SI 2 "immediate_operand" "i")))]
11201   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11202   "* return ix86_output_call_insn (insn, operands[0]);"
11203   [(set_attr "type" "call")])
11204
11205 (define_insn_and_split "*sibcall_pop_vzeroupper"
11206  [(parallel
11207    [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11208           (match_operand 1 "" ""))
11209      (set (reg:SI SP_REG)
11210           (plus:SI (reg:SI SP_REG)
11211                    (match_operand:SI 2 "immediate_operand" "i")))])
11212    (unspec [(match_operand 3 "const_int_operand" "")]
11213            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11214   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11215   "#"
11216   "&& reload_completed"
11217   [(const_int 0)]
11218   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11219   [(set_attr "type" "call")])
11220
11221 (define_insn "*sibcall_pop"
11222   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11223          (match_operand 1 "" ""))
11224    (set (reg:SI SP_REG)
11225         (plus:SI (reg:SI SP_REG)
11226                  (match_operand:SI 2 "immediate_operand" "i")))]
11227   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11228   "* return ix86_output_call_insn (insn, operands[0]);"
11229   [(set_attr "type" "call")])
11230
11231 ;; Call subroutine, returning value in operand 0
11232
11233 (define_expand "call_value"
11234   [(set (match_operand 0 "" "")
11235         (call (match_operand:QI 1 "" "")
11236               (match_operand 2 "" "")))
11237    (use (match_operand 3 "" ""))]
11238   ""
11239 {
11240   ix86_expand_call (operands[0], operands[1], operands[2],
11241                     operands[3], NULL, false);
11242   DONE;
11243 })
11244
11245 (define_expand "sibcall_value"
11246   [(set (match_operand 0 "" "")
11247         (call (match_operand:QI 1 "" "")
11248               (match_operand 2 "" "")))
11249    (use (match_operand 3 "" ""))]
11250   ""
11251 {
11252   ix86_expand_call (operands[0], operands[1], operands[2],
11253                     operands[3], NULL, true);
11254   DONE;
11255 })
11256
11257 (define_insn_and_split "*call_value_vzeroupper"
11258   [(set (match_operand 0 "" "")
11259         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11260               (match_operand 2 "" "")))
11261    (unspec [(match_operand 3 "const_int_operand" "")]
11262            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11263   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11264   "#"
11265   "&& reload_completed"
11266   [(const_int 0)]
11267   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11268   [(set_attr "type" "callv")])
11269
11270 (define_insn "*call_value"
11271   [(set (match_operand 0 "" "")
11272         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
11273               (match_operand 2 "" "")))]
11274   "!SIBLING_CALL_P (insn)"
11275   "* return ix86_output_call_insn (insn, operands[1]);"
11276   [(set_attr "type" "callv")])
11277
11278 (define_insn_and_split "*sibcall_value_vzeroupper"
11279   [(set (match_operand 0 "" "")
11280         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11281               (match_operand 2 "" "")))
11282    (unspec [(match_operand 3 "const_int_operand" "")]
11283            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11284   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11285   "#"
11286   "&& reload_completed"
11287   [(const_int 0)]
11288   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11289   [(set_attr "type" "callv")])
11290
11291 (define_insn "*sibcall_value"
11292   [(set (match_operand 0 "" "")
11293         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11294               (match_operand 2 "" "")))]
11295   "SIBLING_CALL_P (insn)"
11296   "* return ix86_output_call_insn (insn, operands[1]);"
11297   [(set_attr "type" "callv")])
11298
11299 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11300   [(parallel
11301     [(set (match_operand 0 "" "")
11302           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11303                 (match_operand 2 "" "")))
11304      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11305      (clobber (reg:TI XMM6_REG))
11306      (clobber (reg:TI XMM7_REG))
11307      (clobber (reg:TI XMM8_REG))
11308      (clobber (reg:TI XMM9_REG))
11309      (clobber (reg:TI XMM10_REG))
11310      (clobber (reg:TI XMM11_REG))
11311      (clobber (reg:TI XMM12_REG))
11312      (clobber (reg:TI XMM13_REG))
11313      (clobber (reg:TI XMM14_REG))
11314      (clobber (reg:TI XMM15_REG))
11315      (clobber (reg:DI SI_REG))
11316      (clobber (reg:DI DI_REG))])
11317    (unspec [(match_operand 3 "const_int_operand" "")]
11318            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11319   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11320   "#"
11321   "&& reload_completed"
11322   [(const_int 0)]
11323   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11324   [(set_attr "type" "callv")])
11325
11326 (define_insn "*call_value_rex64_ms_sysv"
11327   [(set (match_operand 0 "" "")
11328         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
11329               (match_operand 2 "" "")))
11330    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11331    (clobber (reg:TI XMM6_REG))
11332    (clobber (reg:TI XMM7_REG))
11333    (clobber (reg:TI XMM8_REG))
11334    (clobber (reg:TI XMM9_REG))
11335    (clobber (reg:TI XMM10_REG))
11336    (clobber (reg:TI XMM11_REG))
11337    (clobber (reg:TI XMM12_REG))
11338    (clobber (reg:TI XMM13_REG))
11339    (clobber (reg:TI XMM14_REG))
11340    (clobber (reg:TI XMM15_REG))
11341    (clobber (reg:DI SI_REG))
11342    (clobber (reg:DI DI_REG))]
11343   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11344   "* return ix86_output_call_insn (insn, operands[1]);"
11345   [(set_attr "type" "callv")])
11346
11347 (define_expand "call_value_pop"
11348   [(parallel [(set (match_operand 0 "" "")
11349                    (call (match_operand:QI 1 "" "")
11350                          (match_operand:SI 2 "" "")))
11351               (set (reg:SI SP_REG)
11352                    (plus:SI (reg:SI SP_REG)
11353                             (match_operand:SI 4 "" "")))])]
11354   "!TARGET_64BIT"
11355 {
11356   ix86_expand_call (operands[0], operands[1], operands[2],
11357                     operands[3], operands[4], false);
11358   DONE;
11359 })
11360
11361 (define_insn_and_split "*call_value_pop_vzeroupper"
11362   [(parallel
11363     [(set (match_operand 0 "" "")
11364           (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11365                 (match_operand 2 "" "")))
11366      (set (reg:SI SP_REG)
11367           (plus:SI (reg:SI SP_REG)
11368                    (match_operand:SI 3 "immediate_operand" "i")))])
11369    (unspec [(match_operand 4 "const_int_operand" "")]
11370            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11371   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11372   "#"
11373   "&& reload_completed"
11374   [(const_int 0)]
11375   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11376   [(set_attr "type" "callv")])
11377
11378 (define_insn "*call_value_pop"
11379   [(set (match_operand 0 "" "")
11380         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11381               (match_operand 2 "" "")))
11382    (set (reg:SI SP_REG)
11383         (plus:SI (reg:SI SP_REG)
11384                  (match_operand:SI 3 "immediate_operand" "i")))]
11385   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11386   "* return ix86_output_call_insn (insn, operands[1]);"
11387   [(set_attr "type" "callv")])
11388
11389 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11390  [(parallel
11391    [(set (match_operand 0 "" "")
11392           (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11393                 (match_operand 2 "" "")))
11394      (set (reg:SI SP_REG)
11395           (plus:SI (reg:SI SP_REG)
11396                    (match_operand:SI 3 "immediate_operand" "i")))])
11397    (unspec [(match_operand 4 "const_int_operand" "")]
11398            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11399   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11400   "#"
11401   "&& reload_completed"
11402   [(const_int 0)]
11403   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11404   [(set_attr "type" "callv")])
11405
11406 (define_insn "*sibcall_value_pop"
11407   [(set (match_operand 0 "" "")
11408         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11409               (match_operand 2 "" "")))
11410    (set (reg:SI SP_REG)
11411         (plus:SI (reg:SI SP_REG)
11412                  (match_operand:SI 3 "immediate_operand" "i")))]
11413   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11414   "* return ix86_output_call_insn (insn, operands[1]);"
11415   [(set_attr "type" "callv")])
11416
11417 ;; Call subroutine returning any type.
11418
11419 (define_expand "untyped_call"
11420   [(parallel [(call (match_operand 0 "" "")
11421                     (const_int 0))
11422               (match_operand 1 "" "")
11423               (match_operand 2 "" "")])]
11424   ""
11425 {
11426   int i;
11427
11428   /* In order to give reg-stack an easier job in validating two
11429      coprocessor registers as containing a possible return value,
11430      simply pretend the untyped call returns a complex long double
11431      value. 
11432
11433      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11434      and should have the default ABI.  */
11435
11436   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11437                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11438                     operands[0], const0_rtx,
11439                     GEN_INT ((TARGET_64BIT
11440                               ? (ix86_abi == SYSV_ABI
11441                                  ? X86_64_SSE_REGPARM_MAX
11442                                  : X86_64_MS_SSE_REGPARM_MAX)
11443                               : X86_32_SSE_REGPARM_MAX)
11444                              - 1),
11445                     NULL, false);
11446
11447   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11448     {
11449       rtx set = XVECEXP (operands[2], 0, i);
11450       emit_move_insn (SET_DEST (set), SET_SRC (set));
11451     }
11452
11453   /* The optimizer does not know that the call sets the function value
11454      registers we stored in the result block.  We avoid problems by
11455      claiming that all hard registers are used and clobbered at this
11456      point.  */
11457   emit_insn (gen_blockage ());
11458
11459   DONE;
11460 })
11461 \f
11462 ;; Prologue and epilogue instructions
11463
11464 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11465 ;; all of memory.  This blocks insns from being moved across this point.
11466
11467 (define_insn "blockage"
11468   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11469   ""
11470   ""
11471   [(set_attr "length" "0")])
11472
11473 ;; Do not schedule instructions accessing memory across this point.
11474
11475 (define_expand "memory_blockage"
11476   [(set (match_dup 0)
11477         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11478   ""
11479 {
11480   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11481   MEM_VOLATILE_P (operands[0]) = 1;
11482 })
11483
11484 (define_insn "*memory_blockage"
11485   [(set (match_operand:BLK 0 "" "")
11486         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11487   ""
11488   ""
11489   [(set_attr "length" "0")])
11490
11491 ;; As USE insns aren't meaningful after reload, this is used instead
11492 ;; to prevent deleting instructions setting registers for PIC code
11493 (define_insn "prologue_use"
11494   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11495   ""
11496   ""
11497   [(set_attr "length" "0")])
11498
11499 ;; Insn emitted into the body of a function to return from a function.
11500 ;; This is only done if the function's epilogue is known to be simple.
11501 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11502
11503 (define_expand "return"
11504   [(return)]
11505   "ix86_can_use_return_insn_p ()"
11506 {
11507   if (crtl->args.pops_args)
11508     {
11509       rtx popc = GEN_INT (crtl->args.pops_args);
11510       emit_jump_insn (gen_return_pop_internal (popc));
11511       DONE;
11512     }
11513 })
11514
11515 (define_insn "return_internal"
11516   [(return)]
11517   "reload_completed"
11518   "ret"
11519   [(set_attr "length" "1")
11520    (set_attr "atom_unit" "jeu")
11521    (set_attr "length_immediate" "0")
11522    (set_attr "modrm" "0")])
11523
11524 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11525 ;; instruction Athlon and K8 have.
11526
11527 (define_insn "return_internal_long"
11528   [(return)
11529    (unspec [(const_int 0)] UNSPEC_REP)]
11530   "reload_completed"
11531   "rep\;ret"
11532   [(set_attr "length" "2")
11533    (set_attr "atom_unit" "jeu")
11534    (set_attr "length_immediate" "0")
11535    (set_attr "prefix_rep" "1")
11536    (set_attr "modrm" "0")])
11537
11538 (define_insn "return_pop_internal"
11539   [(return)
11540    (use (match_operand:SI 0 "const_int_operand" ""))]
11541   "reload_completed"
11542   "ret\t%0"
11543   [(set_attr "length" "3")
11544    (set_attr "atom_unit" "jeu")
11545    (set_attr "length_immediate" "2")
11546    (set_attr "modrm" "0")])
11547
11548 (define_insn "return_indirect_internal"
11549   [(return)
11550    (use (match_operand:SI 0 "register_operand" "r"))]
11551   "reload_completed"
11552   "jmp\t%A0"
11553   [(set_attr "type" "ibr")
11554    (set_attr "length_immediate" "0")])
11555
11556 (define_insn "nop"
11557   [(const_int 0)]
11558   ""
11559   "nop"
11560   [(set_attr "length" "1")
11561    (set_attr "length_immediate" "0")
11562    (set_attr "modrm" "0")])
11563
11564 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11565 (define_insn "nops"
11566   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11567                     UNSPECV_NOPS)]
11568   "reload_completed"
11569 {
11570   int num = INTVAL (operands[0]);
11571
11572   gcc_assert (num >= 1 && num <= 8);
11573
11574   while (num--)
11575     fputs ("\tnop\n", asm_out_file);
11576
11577   return "";
11578 }
11579   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11580    (set_attr "length_immediate" "0")
11581    (set_attr "modrm" "0")])
11582
11583 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11584 ;; branch prediction penalty for the third jump in a 16-byte
11585 ;; block on K8.
11586
11587 (define_insn "pad"
11588   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11589   ""
11590 {
11591 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11592   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11593 #else
11594   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11595      The align insn is used to avoid 3 jump instructions in the row to improve
11596      branch prediction and the benefits hardly outweigh the cost of extra 8
11597      nops on the average inserted by full alignment pseudo operation.  */
11598 #endif
11599   return "";
11600 }
11601   [(set_attr "length" "16")])
11602
11603 (define_expand "prologue"
11604   [(const_int 0)]
11605   ""
11606   "ix86_expand_prologue (); DONE;")
11607
11608 (define_insn "set_got"
11609   [(set (match_operand:SI 0 "register_operand" "=r")
11610         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11611    (clobber (reg:CC FLAGS_REG))]
11612   "!TARGET_64BIT"
11613   "* return output_set_got (operands[0], NULL_RTX);"
11614   [(set_attr "type" "multi")
11615    (set_attr "length" "12")])
11616
11617 (define_insn "set_got_labelled"
11618   [(set (match_operand:SI 0 "register_operand" "=r")
11619         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11620          UNSPEC_SET_GOT))
11621    (clobber (reg:CC FLAGS_REG))]
11622   "!TARGET_64BIT"
11623   "* return output_set_got (operands[0], operands[1]);"
11624   [(set_attr "type" "multi")
11625    (set_attr "length" "12")])
11626
11627 (define_insn "set_got_rex64"
11628   [(set (match_operand:DI 0 "register_operand" "=r")
11629         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11630   "TARGET_64BIT"
11631   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11632   [(set_attr "type" "lea")
11633    (set_attr "length_address" "4")
11634    (set_attr "mode" "DI")])
11635
11636 (define_insn "set_rip_rex64"
11637   [(set (match_operand:DI 0 "register_operand" "=r")
11638         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11639   "TARGET_64BIT"
11640   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11641   [(set_attr "type" "lea")
11642    (set_attr "length_address" "4")
11643    (set_attr "mode" "DI")])
11644
11645 (define_insn "set_got_offset_rex64"
11646   [(set (match_operand:DI 0 "register_operand" "=r")
11647         (unspec:DI
11648           [(label_ref (match_operand 1 "" ""))]
11649           UNSPEC_SET_GOT_OFFSET))]
11650   "TARGET_64BIT"
11651   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11652   [(set_attr "type" "imov")
11653    (set_attr "length_immediate" "0")
11654    (set_attr "length_address" "8")
11655    (set_attr "mode" "DI")])
11656
11657 (define_expand "epilogue"
11658   [(const_int 0)]
11659   ""
11660   "ix86_expand_epilogue (1); DONE;")
11661
11662 (define_expand "sibcall_epilogue"
11663   [(const_int 0)]
11664   ""
11665   "ix86_expand_epilogue (0); DONE;")
11666
11667 (define_expand "eh_return"
11668   [(use (match_operand 0 "register_operand" ""))]
11669   ""
11670 {
11671   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11672
11673   /* Tricky bit: we write the address of the handler to which we will
11674      be returning into someone else's stack frame, one word below the
11675      stack address we wish to restore.  */
11676   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11677   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11678   tmp = gen_rtx_MEM (Pmode, tmp);
11679   emit_move_insn (tmp, ra);
11680
11681   emit_jump_insn (gen_eh_return_internal ());
11682   emit_barrier ();
11683   DONE;
11684 })
11685
11686 (define_insn_and_split "eh_return_internal"
11687   [(eh_return)]
11688   ""
11689   "#"
11690   "epilogue_completed"
11691   [(const_int 0)]
11692   "ix86_expand_epilogue (2); DONE;")
11693
11694 (define_insn "leave"
11695   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11696    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11697    (clobber (mem:BLK (scratch)))]
11698   "!TARGET_64BIT"
11699   "leave"
11700   [(set_attr "type" "leave")])
11701
11702 (define_insn "leave_rex64"
11703   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11704    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11705    (clobber (mem:BLK (scratch)))]
11706   "TARGET_64BIT"
11707   "leave"
11708   [(set_attr "type" "leave")])
11709 \f
11710 ;; Handle -fsplit-stack.
11711
11712 (define_expand "split_stack_prologue"
11713   [(const_int 0)]
11714   ""
11715 {
11716   ix86_expand_split_stack_prologue ();
11717   DONE;
11718 })
11719
11720 ;; In order to support the call/return predictor, we use a return
11721 ;; instruction which the middle-end doesn't see.
11722 (define_insn "split_stack_return"
11723   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11724                      UNSPECV_SPLIT_STACK_RETURN)]
11725   ""
11726 {
11727   if (operands[0] == const0_rtx)
11728     return "ret";
11729   else
11730     return "ret\t%0";
11731 }
11732   [(set_attr "atom_unit" "jeu")
11733    (set_attr "modrm" "0")
11734    (set (attr "length")
11735         (if_then_else (match_operand:SI 0 "const0_operand" "")
11736                       (const_int 1)
11737                       (const_int 3)))
11738    (set (attr "length_immediate")
11739         (if_then_else (match_operand:SI 0 "const0_operand" "")
11740                       (const_int 0)
11741                       (const_int 2)))])
11742
11743 ;; If there are operand 0 bytes available on the stack, jump to
11744 ;; operand 1.
11745
11746 (define_expand "split_stack_space_check"
11747   [(set (pc) (if_then_else
11748               (ltu (minus (reg SP_REG)
11749                           (match_operand 0 "register_operand" ""))
11750                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11751               (label_ref (match_operand 1 "" ""))
11752               (pc)))]
11753   ""
11754 {
11755   rtx reg, size, limit;
11756
11757   reg = gen_reg_rtx (Pmode);
11758   size = force_reg (Pmode, operands[0]);
11759   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11760   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11761                           UNSPEC_STACK_CHECK);
11762   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11763   ix86_expand_branch (GEU, reg, limit, operands[1]);
11764
11765   DONE;
11766 })
11767 \f
11768 ;; Bit manipulation instructions.
11769
11770 (define_expand "ffs<mode>2"
11771   [(set (match_dup 2) (const_int -1))
11772    (parallel [(set (reg:CCZ FLAGS_REG)
11773                    (compare:CCZ
11774                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11775                      (const_int 0)))
11776               (set (match_operand:SWI48 0 "register_operand" "")
11777                    (ctz:SWI48 (match_dup 1)))])
11778    (set (match_dup 0) (if_then_else:SWI48
11779                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11780                         (match_dup 2)
11781                         (match_dup 0)))
11782    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11783               (clobber (reg:CC FLAGS_REG))])]
11784   ""
11785 {
11786   if (<MODE>mode == SImode && !TARGET_CMOVE)
11787     {
11788       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11789       DONE;
11790     }
11791   operands[2] = gen_reg_rtx (<MODE>mode);
11792 })
11793
11794 (define_insn_and_split "ffssi2_no_cmove"
11795   [(set (match_operand:SI 0 "register_operand" "=r")
11796         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11797    (clobber (match_scratch:SI 2 "=&q"))
11798    (clobber (reg:CC FLAGS_REG))]
11799   "!TARGET_CMOVE"
11800   "#"
11801   "&& reload_completed"
11802   [(parallel [(set (reg:CCZ FLAGS_REG)
11803                    (compare:CCZ (match_dup 1) (const_int 0)))
11804               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11805    (set (strict_low_part (match_dup 3))
11806         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11807    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11808               (clobber (reg:CC FLAGS_REG))])
11809    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11810               (clobber (reg:CC FLAGS_REG))])
11811    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11812               (clobber (reg:CC FLAGS_REG))])]
11813 {
11814   operands[3] = gen_lowpart (QImode, operands[2]);
11815   ix86_expand_clear (operands[2]);
11816 })
11817
11818 (define_insn "*ffs<mode>_1"
11819   [(set (reg:CCZ FLAGS_REG)
11820         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11821                      (const_int 0)))
11822    (set (match_operand:SWI48 0 "register_operand" "=r")
11823         (ctz:SWI48 (match_dup 1)))]
11824   ""
11825   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11826   [(set_attr "type" "alu1")
11827    (set_attr "prefix_0f" "1")
11828    (set_attr "mode" "<MODE>")])
11829
11830 (define_insn "ctz<mode>2"
11831   [(set (match_operand:SWI248 0 "register_operand" "=r")
11832         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11833    (clobber (reg:CC FLAGS_REG))]
11834   ""
11835 {
11836   if (TARGET_BMI)
11837     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11838   else
11839     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11840 }
11841   [(set_attr "type" "alu1")
11842    (set_attr "prefix_0f" "1")
11843    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11844    (set_attr "mode" "<MODE>")])
11845
11846 (define_expand "clz<mode>2"
11847   [(parallel
11848      [(set (match_operand:SWI248 0 "register_operand" "")
11849            (minus:SWI248
11850              (match_dup 2)
11851              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11852       (clobber (reg:CC FLAGS_REG))])
11853    (parallel
11854      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11855       (clobber (reg:CC FLAGS_REG))])]
11856   ""
11857 {
11858   if (TARGET_ABM)
11859     {
11860       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11861       DONE;
11862     }
11863   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11864 })
11865
11866 (define_insn "clz<mode>2_abm"
11867   [(set (match_operand:SWI248 0 "register_operand" "=r")
11868         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11869    (clobber (reg:CC FLAGS_REG))]
11870   "TARGET_ABM || TARGET_BMI"
11871   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11872   [(set_attr "prefix_rep" "1")
11873    (set_attr "type" "bitmanip")
11874    (set_attr "mode" "<MODE>")])
11875
11876 ;; BMI instructions.
11877 (define_insn "*bmi_andn_<mode>"
11878   [(set (match_operand:SWI48 0 "register_operand" "=r")
11879         (and:SWI48
11880           (not:SWI48
11881             (match_operand:SWI48 1 "register_operand" "r"))
11882             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11883    (clobber (reg:CC FLAGS_REG))]
11884   "TARGET_BMI"
11885   "andn\t{%2, %1, %0|%0, %1, %2}"
11886   [(set_attr "type" "bitmanip")
11887    (set_attr "mode" "<MODE>")])
11888
11889 (define_insn "bmi_bextr_<mode>"
11890   [(set (match_operand:SWI48 0 "register_operand" "=r")
11891         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11892                        (match_operand:SWI48 2 "register_operand" "r")]
11893                        UNSPEC_BEXTR))
11894    (clobber (reg:CC FLAGS_REG))]
11895   "TARGET_BMI"
11896   "bextr\t{%2, %1, %0|%0, %1, %2}"
11897   [(set_attr "type" "bitmanip")
11898    (set_attr "mode" "<MODE>")])
11899
11900 (define_insn "*bmi_blsi_<mode>"
11901   [(set (match_operand:SWI48 0 "register_operand" "=r")
11902         (and:SWI48
11903           (neg:SWI48
11904             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11905           (match_dup 1)))
11906    (clobber (reg:CC FLAGS_REG))]
11907   "TARGET_BMI"
11908   "blsi\t{%1, %0|%0, %1}"
11909   [(set_attr "type" "bitmanip")
11910    (set_attr "mode" "<MODE>")])
11911
11912 (define_insn "*bmi_blsmsk_<mode>"
11913   [(set (match_operand:SWI48 0 "register_operand" "=r")
11914         (xor:SWI48
11915           (plus:SWI48
11916             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11917             (const_int -1))
11918           (match_dup 1)))
11919    (clobber (reg:CC FLAGS_REG))]
11920   "TARGET_BMI"
11921   "blsmsk\t{%1, %0|%0, %1}"
11922   [(set_attr "type" "bitmanip")
11923    (set_attr "mode" "<MODE>")])
11924
11925 (define_insn "*bmi_blsr_<mode>"
11926   [(set (match_operand:SWI48 0 "register_operand" "=r")
11927         (and:SWI48
11928           (plus:SWI48
11929             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11930             (const_int -1))
11931           (match_dup 1)))
11932    (clobber (reg:CC FLAGS_REG))]
11933    "TARGET_BMI"
11934    "blsr\t{%1, %0|%0, %1}"
11935   [(set_attr "type" "bitmanip")
11936    (set_attr "mode" "<MODE>")])
11937
11938 ;; TBM instructions.
11939 (define_insn "tbm_bextri_<mode>"
11940   [(set (match_operand:SWI48 0 "register_operand" "=r")
11941         (zero_extract:SWI48
11942           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11943           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11944           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11945    (clobber (reg:CC FLAGS_REG))]
11946    "TARGET_TBM"
11947 {
11948   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11949   return "bextr\t{%2, %1, %0|%0, %1, %2}";
11950 }
11951   [(set_attr "type" "bitmanip")
11952    (set_attr "mode" "<MODE>")])
11953
11954 (define_insn "*tbm_blcfill_<mode>"
11955   [(set (match_operand:SWI48 0 "register_operand" "=r")
11956         (and:SWI48
11957           (plus:SWI48
11958             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11959             (const_int 1))
11960           (match_dup 1)))
11961    (clobber (reg:CC FLAGS_REG))]
11962    "TARGET_TBM"
11963    "blcfill\t{%1, %0|%0, %1}"
11964   [(set_attr "type" "bitmanip")
11965    (set_attr "mode" "<MODE>")])
11966
11967 (define_insn "*tbm_blci_<mode>"
11968   [(set (match_operand:SWI48 0 "register_operand" "=r")
11969         (ior:SWI48
11970           (not:SWI48
11971             (plus:SWI48
11972               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11973               (const_int 1)))
11974           (match_dup 1)))
11975    (clobber (reg:CC FLAGS_REG))]
11976    "TARGET_TBM"
11977    "blci\t{%1, %0|%0, %1}"
11978   [(set_attr "type" "bitmanip")
11979    (set_attr "mode" "<MODE>")])
11980
11981 (define_insn "*tbm_blcic_<mode>"
11982   [(set (match_operand:SWI48 0 "register_operand" "=r")
11983         (and:SWI48
11984           (plus:SWI48
11985             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11986             (const_int 1))
11987           (not:SWI48
11988             (match_dup 1))))
11989    (clobber (reg:CC FLAGS_REG))]
11990    "TARGET_TBM"
11991    "blcic\t{%1, %0|%0, %1}"
11992   [(set_attr "type" "bitmanip")
11993    (set_attr "mode" "<MODE>")])
11994
11995 (define_insn "*tbm_blcmsk_<mode>"
11996   [(set (match_operand:SWI48 0 "register_operand" "=r")
11997         (xor:SWI48
11998           (plus:SWI48
11999             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12000             (const_int 1))
12001           (match_dup 1)))
12002    (clobber (reg:CC FLAGS_REG))]
12003    "TARGET_TBM"
12004    "blcmsk\t{%1, %0|%0, %1}"
12005   [(set_attr "type" "bitmanip")
12006    (set_attr "mode" "<MODE>")])
12007
12008 (define_insn "*tbm_blcs_<mode>"
12009   [(set (match_operand:SWI48 0 "register_operand" "=r")
12010         (ior:SWI48
12011           (plus:SWI48
12012             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12013             (const_int 1))
12014           (match_dup 1)))
12015    (clobber (reg:CC FLAGS_REG))]
12016    "TARGET_TBM"
12017    "blcs\t{%1, %0|%0, %1}"
12018   [(set_attr "type" "bitmanip")
12019    (set_attr "mode" "<MODE>")])
12020
12021 (define_insn "*tbm_blsfill_<mode>"
12022   [(set (match_operand:SWI48 0 "register_operand" "=r")
12023         (ior:SWI48
12024           (plus:SWI48
12025             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12026             (const_int -1))
12027           (match_dup 1)))
12028    (clobber (reg:CC FLAGS_REG))]
12029    "TARGET_TBM"
12030    "blsfill\t{%1, %0|%0, %1}"
12031   [(set_attr "type" "bitmanip")
12032    (set_attr "mode" "<MODE>")])
12033
12034 (define_insn "*tbm_blsic_<mode>"
12035   [(set (match_operand:SWI48 0 "register_operand" "=r")
12036         (ior:SWI48
12037           (plus:SWI48
12038             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12039             (const_int -1))
12040           (not:SWI48
12041             (match_dup 1))))
12042    (clobber (reg:CC FLAGS_REG))]
12043    "TARGET_TBM"
12044    "blsic\t{%1, %0|%0, %1}"
12045   [(set_attr "type" "bitmanip")
12046    (set_attr "mode" "<MODE>")])
12047
12048 (define_insn "*tbm_t1mskc_<mode>"
12049   [(set (match_operand:SWI48 0 "register_operand" "=r")
12050         (ior:SWI48
12051           (plus:SWI48
12052             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12053             (const_int 1))
12054           (not:SWI48
12055             (match_dup 1))))
12056    (clobber (reg:CC FLAGS_REG))]
12057    "TARGET_TBM"
12058    "t1mskc\t{%1, %0|%0, %1}"
12059   [(set_attr "type" "bitmanip")
12060    (set_attr "mode" "<MODE>")])
12061
12062 (define_insn "*tbm_tzmsk_<mode>"
12063   [(set (match_operand:SWI48 0 "register_operand" "=r")
12064         (and:SWI48
12065           (plus:SWI48
12066             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12067             (const_int -1))
12068           (not:SWI48
12069             (match_dup 1))))
12070    (clobber (reg:CC FLAGS_REG))]
12071    "TARGET_TBM"
12072    "tzmsk\t{%1, %0|%0, %1}"
12073   [(set_attr "type" "bitmanip")
12074    (set_attr "mode" "<MODE>")])
12075
12076 (define_insn "bsr_rex64"
12077   [(set (match_operand:DI 0 "register_operand" "=r")
12078         (minus:DI (const_int 63)
12079                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12080    (clobber (reg:CC FLAGS_REG))]
12081   "TARGET_64BIT"
12082   "bsr{q}\t{%1, %0|%0, %1}"
12083   [(set_attr "type" "alu1")
12084    (set_attr "prefix_0f" "1")
12085    (set_attr "mode" "DI")])
12086
12087 (define_insn "bsr"
12088   [(set (match_operand:SI 0 "register_operand" "=r")
12089         (minus:SI (const_int 31)
12090                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12091    (clobber (reg:CC FLAGS_REG))]
12092   ""
12093   "bsr{l}\t{%1, %0|%0, %1}"
12094   [(set_attr "type" "alu1")
12095    (set_attr "prefix_0f" "1")
12096    (set_attr "mode" "SI")])
12097
12098 (define_insn "*bsrhi"
12099   [(set (match_operand:HI 0 "register_operand" "=r")
12100         (minus:HI (const_int 15)
12101                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12102    (clobber (reg:CC FLAGS_REG))]
12103   ""
12104   "bsr{w}\t{%1, %0|%0, %1}"
12105   [(set_attr "type" "alu1")
12106    (set_attr "prefix_0f" "1")
12107    (set_attr "mode" "HI")])
12108
12109 (define_insn "popcount<mode>2"
12110   [(set (match_operand:SWI248 0 "register_operand" "=r")
12111         (popcount:SWI248
12112           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12113    (clobber (reg:CC FLAGS_REG))]
12114   "TARGET_POPCNT"
12115 {
12116 #if TARGET_MACHO
12117   return "popcnt\t{%1, %0|%0, %1}";
12118 #else
12119   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12120 #endif
12121 }
12122   [(set_attr "prefix_rep" "1")
12123    (set_attr "type" "bitmanip")
12124    (set_attr "mode" "<MODE>")])
12125
12126 (define_insn "*popcount<mode>2_cmp"
12127   [(set (reg FLAGS_REG)
12128         (compare
12129           (popcount:SWI248
12130             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12131           (const_int 0)))
12132    (set (match_operand:SWI248 0 "register_operand" "=r")
12133         (popcount:SWI248 (match_dup 1)))]
12134   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12135 {
12136 #if TARGET_MACHO
12137   return "popcnt\t{%1, %0|%0, %1}";
12138 #else
12139   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12140 #endif
12141 }
12142   [(set_attr "prefix_rep" "1")
12143    (set_attr "type" "bitmanip")
12144    (set_attr "mode" "<MODE>")])
12145
12146 (define_insn "*popcountsi2_cmp_zext"
12147   [(set (reg FLAGS_REG)
12148         (compare
12149           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12150           (const_int 0)))
12151    (set (match_operand:DI 0 "register_operand" "=r")
12152         (zero_extend:DI(popcount:SI (match_dup 1))))]
12153   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12154 {
12155 #if TARGET_MACHO
12156   return "popcnt\t{%1, %0|%0, %1}";
12157 #else
12158   return "popcnt{l}\t{%1, %0|%0, %1}";
12159 #endif
12160 }
12161   [(set_attr "prefix_rep" "1")
12162    (set_attr "type" "bitmanip")
12163    (set_attr "mode" "SI")])
12164
12165 (define_expand "bswap<mode>2"
12166   [(set (match_operand:SWI48 0 "register_operand" "")
12167         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12168   ""
12169 {
12170   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12171     {
12172       rtx x = operands[0];
12173
12174       emit_move_insn (x, operands[1]);
12175       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12176       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12177       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12178       DONE;
12179     }
12180 })
12181
12182 (define_insn "*bswap<mode>2_movbe"
12183   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12184         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12185   "TARGET_MOVBE
12186    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12187   "@
12188     bswap\t%0
12189     movbe\t{%1, %0|%0, %1}
12190     movbe\t{%1, %0|%0, %1}"
12191   [(set_attr "type" "bitmanip,imov,imov")
12192    (set_attr "modrm" "0,1,1")
12193    (set_attr "prefix_0f" "*,1,1")
12194    (set_attr "prefix_extra" "*,1,1")
12195    (set_attr "mode" "<MODE>")])
12196
12197 (define_insn "*bswap<mode>2_1"
12198   [(set (match_operand:SWI48 0 "register_operand" "=r")
12199         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12200   "TARGET_BSWAP"
12201   "bswap\t%0"
12202   [(set_attr "type" "bitmanip")
12203    (set_attr "modrm" "0")
12204    (set_attr "mode" "<MODE>")])
12205
12206 (define_insn "*bswaphi_lowpart_1"
12207   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12208         (bswap:HI (match_dup 0)))
12209    (clobber (reg:CC FLAGS_REG))]
12210   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12211   "@
12212     xchg{b}\t{%h0, %b0|%b0, %h0}
12213     rol{w}\t{$8, %0|%0, 8}"
12214   [(set_attr "length" "2,4")
12215    (set_attr "mode" "QI,HI")])
12216
12217 (define_insn "bswaphi_lowpart"
12218   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12219         (bswap:HI (match_dup 0)))
12220    (clobber (reg:CC FLAGS_REG))]
12221   ""
12222   "rol{w}\t{$8, %0|%0, 8}"
12223   [(set_attr "length" "4")
12224    (set_attr "mode" "HI")])
12225
12226 (define_expand "paritydi2"
12227   [(set (match_operand:DI 0 "register_operand" "")
12228         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12229   "! TARGET_POPCNT"
12230 {
12231   rtx scratch = gen_reg_rtx (QImode);
12232   rtx cond;
12233
12234   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12235                                 NULL_RTX, operands[1]));
12236
12237   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12238                          gen_rtx_REG (CCmode, FLAGS_REG),
12239                          const0_rtx);
12240   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12241
12242   if (TARGET_64BIT)
12243     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12244   else
12245     {
12246       rtx tmp = gen_reg_rtx (SImode);
12247
12248       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12249       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12250     }
12251   DONE;
12252 })
12253
12254 (define_expand "paritysi2"
12255   [(set (match_operand:SI 0 "register_operand" "")
12256         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12257   "! TARGET_POPCNT"
12258 {
12259   rtx scratch = gen_reg_rtx (QImode);
12260   rtx cond;
12261
12262   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12263
12264   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12265                          gen_rtx_REG (CCmode, FLAGS_REG),
12266                          const0_rtx);
12267   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12268
12269   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12270   DONE;
12271 })
12272
12273 (define_insn_and_split "paritydi2_cmp"
12274   [(set (reg:CC FLAGS_REG)
12275         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12276                    UNSPEC_PARITY))
12277    (clobber (match_scratch:DI 0 "=r"))
12278    (clobber (match_scratch:SI 1 "=&r"))
12279    (clobber (match_scratch:HI 2 "=Q"))]
12280   "! TARGET_POPCNT"
12281   "#"
12282   "&& reload_completed"
12283   [(parallel
12284      [(set (match_dup 1)
12285            (xor:SI (match_dup 1) (match_dup 4)))
12286       (clobber (reg:CC FLAGS_REG))])
12287    (parallel
12288      [(set (reg:CC FLAGS_REG)
12289            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12290       (clobber (match_dup 1))
12291       (clobber (match_dup 2))])]
12292 {
12293   operands[4] = gen_lowpart (SImode, operands[3]);
12294
12295   if (TARGET_64BIT)
12296     {
12297       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12298       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12299     }
12300   else
12301     operands[1] = gen_highpart (SImode, operands[3]);
12302 })
12303
12304 (define_insn_and_split "paritysi2_cmp"
12305   [(set (reg:CC FLAGS_REG)
12306         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12307                    UNSPEC_PARITY))
12308    (clobber (match_scratch:SI 0 "=r"))
12309    (clobber (match_scratch:HI 1 "=&Q"))]
12310   "! TARGET_POPCNT"
12311   "#"
12312   "&& reload_completed"
12313   [(parallel
12314      [(set (match_dup 1)
12315            (xor:HI (match_dup 1) (match_dup 3)))
12316       (clobber (reg:CC FLAGS_REG))])
12317    (parallel
12318      [(set (reg:CC FLAGS_REG)
12319            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12320       (clobber (match_dup 1))])]
12321 {
12322   operands[3] = gen_lowpart (HImode, operands[2]);
12323
12324   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12325   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12326 })
12327
12328 (define_insn "*parityhi2_cmp"
12329   [(set (reg:CC FLAGS_REG)
12330         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12331                    UNSPEC_PARITY))
12332    (clobber (match_scratch:HI 0 "=Q"))]
12333   "! TARGET_POPCNT"
12334   "xor{b}\t{%h0, %b0|%b0, %h0}"
12335   [(set_attr "length" "2")
12336    (set_attr "mode" "HI")])
12337 \f
12338 ;; Thread-local storage patterns for ELF.
12339 ;;
12340 ;; Note that these code sequences must appear exactly as shown
12341 ;; in order to allow linker relaxation.
12342
12343 (define_insn "*tls_global_dynamic_32_gnu"
12344   [(set (match_operand:SI 0 "register_operand" "=a")
12345         (unspec:SI
12346          [(match_operand:SI 1 "register_operand" "b")
12347           (match_operand:SI 2 "tls_symbolic_operand" "")
12348           (match_operand:SI 3 "constant_call_address_operand" "z")]
12349          UNSPEC_TLS_GD))
12350    (clobber (match_scratch:SI 4 "=d"))
12351    (clobber (match_scratch:SI 5 "=c"))
12352    (clobber (reg:CC FLAGS_REG))]
12353   "!TARGET_64BIT && TARGET_GNU_TLS"
12354 {
12355   output_asm_insn
12356     ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12357   if (TARGET_SUN_TLS)
12358 #ifdef HAVE_AS_IX86_TLSGDPLT
12359     return "call\t%a2@tlsgdplt";
12360 #else
12361     return "call\t%p3@plt";
12362 #endif
12363   return "call\t%P3";
12364 }
12365   [(set_attr "type" "multi")
12366    (set_attr "length" "12")])
12367
12368 (define_expand "tls_global_dynamic_32"
12369   [(parallel
12370     [(set (match_operand:SI 0 "register_operand" "")
12371           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12372                       (match_operand:SI 1 "tls_symbolic_operand" "")
12373                       (match_operand:SI 3 "constant_call_address_operand" "")]
12374                      UNSPEC_TLS_GD))
12375      (clobber (match_scratch:SI 4 ""))
12376      (clobber (match_scratch:SI 5 ""))
12377      (clobber (reg:CC FLAGS_REG))])])
12378
12379 (define_insn "*tls_global_dynamic_64"
12380   [(set (match_operand:DI 0 "register_operand" "=a")
12381         (call:DI
12382          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12383          (match_operand:DI 3 "" "")))
12384    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12385               UNSPEC_TLS_GD)]
12386   "TARGET_64BIT"
12387 {
12388   fputs (ASM_BYTE "0x66\n", asm_out_file);
12389   output_asm_insn
12390     ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12391   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12392   fputs ("\trex64\n", asm_out_file);
12393   if (TARGET_SUN_TLS)
12394     return "call\t%p2@plt";
12395   return "call\t%P2";
12396 }
12397   [(set_attr "type" "multi")
12398    (set_attr "length" "16")])
12399
12400 (define_expand "tls_global_dynamic_64"
12401   [(parallel
12402     [(set (match_operand:DI 0 "register_operand" "")
12403           (call:DI
12404            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12405            (const_int 0)))
12406      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12407                 UNSPEC_TLS_GD)])])
12408
12409 (define_insn "*tls_local_dynamic_base_32_gnu"
12410   [(set (match_operand:SI 0 "register_operand" "=a")
12411         (unspec:SI
12412          [(match_operand:SI 1 "register_operand" "b")
12413           (match_operand:SI 2 "constant_call_address_operand" "z")]
12414          UNSPEC_TLS_LD_BASE))
12415    (clobber (match_scratch:SI 3 "=d"))
12416    (clobber (match_scratch:SI 4 "=c"))
12417    (clobber (reg:CC FLAGS_REG))]
12418   "!TARGET_64BIT && TARGET_GNU_TLS"
12419 {
12420   output_asm_insn
12421     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12422   if (TARGET_SUN_TLS)
12423 #ifdef HAVE_AS_IX86_TLSLDMPLT
12424     return "call\t%&@tlsldmplt";
12425 #else
12426     return "call\t%p2@plt";
12427 #endif
12428   return "call\t%P2";
12429 }
12430   [(set_attr "type" "multi")
12431    (set_attr "length" "11")])
12432
12433 (define_expand "tls_local_dynamic_base_32"
12434   [(parallel
12435      [(set (match_operand:SI 0 "register_operand" "")
12436            (unspec:SI
12437             [(match_operand:SI 1 "register_operand" "")
12438              (match_operand:SI 2 "constant_call_address_operand" "")]
12439             UNSPEC_TLS_LD_BASE))
12440       (clobber (match_scratch:SI 3 ""))
12441       (clobber (match_scratch:SI 4 ""))
12442       (clobber (reg:CC FLAGS_REG))])])
12443
12444 (define_insn "*tls_local_dynamic_base_64"
12445   [(set (match_operand:DI 0 "register_operand" "=a")
12446         (call:DI
12447          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12448          (match_operand:DI 2 "" "")))
12449    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12450   "TARGET_64BIT"
12451 {
12452   output_asm_insn
12453     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12454   if (TARGET_SUN_TLS)
12455     return "call\t%p1@plt";
12456   return "call\t%P1";
12457 }
12458   [(set_attr "type" "multi")
12459    (set_attr "length" "12")])
12460
12461 (define_expand "tls_local_dynamic_base_64"
12462   [(parallel
12463      [(set (match_operand:DI 0 "register_operand" "")
12464            (call:DI
12465             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12466             (const_int 0)))
12467       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12468
12469 ;; Local dynamic of a single variable is a lose.  Show combine how
12470 ;; to convert that back to global dynamic.
12471
12472 (define_insn_and_split "*tls_local_dynamic_32_once"
12473   [(set (match_operand:SI 0 "register_operand" "=a")
12474         (plus:SI
12475          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12476                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12477                     UNSPEC_TLS_LD_BASE)
12478          (const:SI (unspec:SI
12479                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12480                     UNSPEC_DTPOFF))))
12481    (clobber (match_scratch:SI 4 "=d"))
12482    (clobber (match_scratch:SI 5 "=c"))
12483    (clobber (reg:CC FLAGS_REG))]
12484   ""
12485   "#"
12486   ""
12487   [(parallel
12488      [(set (match_dup 0)
12489            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12490                       UNSPEC_TLS_GD))
12491       (clobber (match_dup 4))
12492       (clobber (match_dup 5))
12493       (clobber (reg:CC FLAGS_REG))])])
12494
12495 ;; Segment register for the thread base ptr load
12496 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12497
12498 ;; Load and add the thread base pointer from %<tp_seg>:0.
12499 (define_insn "*load_tp_<mode>"
12500   [(set (match_operand:P 0 "register_operand" "=r")
12501         (unspec:P [(const_int 0)] UNSPEC_TP))]
12502   ""
12503   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12504   [(set_attr "type" "imov")
12505    (set_attr "modrm" "0")
12506    (set_attr "length" "7")
12507    (set_attr "memory" "load")
12508    (set_attr "imm_disp" "false")])
12509
12510 (define_insn "*add_tp_<mode>"
12511   [(set (match_operand:P 0 "register_operand" "=r")
12512         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12513                 (match_operand:P 1 "register_operand" "0")))
12514    (clobber (reg:CC FLAGS_REG))]
12515   ""
12516   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12517   [(set_attr "type" "alu")
12518    (set_attr "modrm" "0")
12519    (set_attr "length" "7")
12520    (set_attr "memory" "load")
12521    (set_attr "imm_disp" "false")])
12522
12523 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12524 ;; %rax as destination of the initial executable code sequence.
12525 (define_insn "tls_initial_exec_64_sun"
12526   [(set (match_operand:DI 0 "register_operand" "=a")
12527         (unspec:DI
12528          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12529          UNSPEC_TLS_IE_SUN))
12530    (clobber (reg:CC FLAGS_REG))]
12531   "TARGET_64BIT && TARGET_SUN_TLS"
12532 {
12533   output_asm_insn
12534     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12535   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12536 }
12537   [(set_attr "type" "multi")])
12538
12539 ;; GNU2 TLS patterns can be split.
12540
12541 (define_expand "tls_dynamic_gnu2_32"
12542   [(set (match_dup 3)
12543         (plus:SI (match_operand:SI 2 "register_operand" "")
12544                  (const:SI
12545                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12546                              UNSPEC_TLSDESC))))
12547    (parallel
12548     [(set (match_operand:SI 0 "register_operand" "")
12549           (unspec:SI [(match_dup 1) (match_dup 3)
12550                       (match_dup 2) (reg:SI SP_REG)]
12551                       UNSPEC_TLSDESC))
12552      (clobber (reg:CC FLAGS_REG))])]
12553   "!TARGET_64BIT && TARGET_GNU2_TLS"
12554 {
12555   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12556   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12557 })
12558
12559 (define_insn "*tls_dynamic_lea_32"
12560   [(set (match_operand:SI 0 "register_operand" "=r")
12561         (plus:SI (match_operand:SI 1 "register_operand" "b")
12562                  (const:SI
12563                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12564                               UNSPEC_TLSDESC))))]
12565   "!TARGET_64BIT && TARGET_GNU2_TLS"
12566   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12567   [(set_attr "type" "lea")
12568    (set_attr "mode" "SI")
12569    (set_attr "length" "6")
12570    (set_attr "length_address" "4")])
12571
12572 (define_insn "*tls_dynamic_call_32"
12573   [(set (match_operand:SI 0 "register_operand" "=a")
12574         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12575                     (match_operand:SI 2 "register_operand" "0")
12576                     ;; we have to make sure %ebx still points to the GOT
12577                     (match_operand:SI 3 "register_operand" "b")
12578                     (reg:SI SP_REG)]
12579                    UNSPEC_TLSDESC))
12580    (clobber (reg:CC FLAGS_REG))]
12581   "!TARGET_64BIT && TARGET_GNU2_TLS"
12582   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12583   [(set_attr "type" "call")
12584    (set_attr "length" "2")
12585    (set_attr "length_address" "0")])
12586
12587 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12588   [(set (match_operand:SI 0 "register_operand" "=&a")
12589         (plus:SI
12590          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12591                      (match_operand:SI 4 "" "")
12592                      (match_operand:SI 2 "register_operand" "b")
12593                      (reg:SI SP_REG)]
12594                     UNSPEC_TLSDESC)
12595          (const:SI (unspec:SI
12596                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12597                     UNSPEC_DTPOFF))))
12598    (clobber (reg:CC FLAGS_REG))]
12599   "!TARGET_64BIT && TARGET_GNU2_TLS"
12600   "#"
12601   ""
12602   [(set (match_dup 0) (match_dup 5))]
12603 {
12604   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12605   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12606 })
12607
12608 (define_expand "tls_dynamic_gnu2_64"
12609   [(set (match_dup 2)
12610         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12611                    UNSPEC_TLSDESC))
12612    (parallel
12613     [(set (match_operand:DI 0 "register_operand" "")
12614           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12615                      UNSPEC_TLSDESC))
12616      (clobber (reg:CC FLAGS_REG))])]
12617   "TARGET_64BIT && TARGET_GNU2_TLS"
12618 {
12619   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12620   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12621 })
12622
12623 (define_insn "*tls_dynamic_lea_64"
12624   [(set (match_operand:DI 0 "register_operand" "=r")
12625         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12626                    UNSPEC_TLSDESC))]
12627   "TARGET_64BIT && TARGET_GNU2_TLS"
12628   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12629   [(set_attr "type" "lea")
12630    (set_attr "mode" "DI")
12631    (set_attr "length" "7")
12632    (set_attr "length_address" "4")])
12633
12634 (define_insn "*tls_dynamic_call_64"
12635   [(set (match_operand:DI 0 "register_operand" "=a")
12636         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12637                     (match_operand:DI 2 "register_operand" "0")
12638                     (reg:DI SP_REG)]
12639                    UNSPEC_TLSDESC))
12640    (clobber (reg:CC FLAGS_REG))]
12641   "TARGET_64BIT && TARGET_GNU2_TLS"
12642   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12643   [(set_attr "type" "call")
12644    (set_attr "length" "2")
12645    (set_attr "length_address" "0")])
12646
12647 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12648   [(set (match_operand:DI 0 "register_operand" "=&a")
12649         (plus:DI
12650          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12651                      (match_operand:DI 3 "" "")
12652                      (reg:DI SP_REG)]
12653                     UNSPEC_TLSDESC)
12654          (const:DI (unspec:DI
12655                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12656                     UNSPEC_DTPOFF))))
12657    (clobber (reg:CC FLAGS_REG))]
12658   "TARGET_64BIT && TARGET_GNU2_TLS"
12659   "#"
12660   ""
12661   [(set (match_dup 0) (match_dup 4))]
12662 {
12663   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12664   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12665 })
12666 \f
12667 ;; These patterns match the binary 387 instructions for addM3, subM3,
12668 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12669 ;; SFmode.  The first is the normal insn, the second the same insn but
12670 ;; with one operand a conversion, and the third the same insn but with
12671 ;; the other operand a conversion.  The conversion may be SFmode or
12672 ;; SImode if the target mode DFmode, but only SImode if the target mode
12673 ;; is SFmode.
12674
12675 ;; Gcc is slightly more smart about handling normal two address instructions
12676 ;; so use special patterns for add and mull.
12677
12678 (define_insn "*fop_<mode>_comm_mixed"
12679   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12680         (match_operator:MODEF 3 "binary_fp_operator"
12681           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12682            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12683   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12684    && COMMUTATIVE_ARITH_P (operands[3])
12685    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12686   "* return output_387_binary_op (insn, operands);"
12687   [(set (attr "type")
12688         (if_then_else (eq_attr "alternative" "1,2")
12689            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12690               (const_string "ssemul")
12691               (const_string "sseadd"))
12692            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12693               (const_string "fmul")
12694               (const_string "fop"))))
12695    (set_attr "isa" "base,noavx,avx")
12696    (set_attr "prefix" "orig,orig,vex")
12697    (set_attr "mode" "<MODE>")])
12698
12699 (define_insn "*fop_<mode>_comm_sse"
12700   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12701         (match_operator:MODEF 3 "binary_fp_operator"
12702           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12703            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12704   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12705    && COMMUTATIVE_ARITH_P (operands[3])
12706    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12707   "* return output_387_binary_op (insn, operands);"
12708   [(set (attr "type")
12709         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12710            (const_string "ssemul")
12711            (const_string "sseadd")))
12712    (set_attr "isa" "noavx,avx")
12713    (set_attr "prefix" "orig,vex")
12714    (set_attr "mode" "<MODE>")])
12715
12716 (define_insn "*fop_<mode>_comm_i387"
12717   [(set (match_operand:MODEF 0 "register_operand" "=f")
12718         (match_operator:MODEF 3 "binary_fp_operator"
12719           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12720            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12721   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12722    && COMMUTATIVE_ARITH_P (operands[3])
12723    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12724   "* return output_387_binary_op (insn, operands);"
12725   [(set (attr "type")
12726         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12727            (const_string "fmul")
12728            (const_string "fop")))
12729    (set_attr "mode" "<MODE>")])
12730
12731 (define_insn "*fop_<mode>_1_mixed"
12732   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12733         (match_operator:MODEF 3 "binary_fp_operator"
12734           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12735            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12736   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12737    && !COMMUTATIVE_ARITH_P (operands[3])
12738    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12739   "* return output_387_binary_op (insn, operands);"
12740   [(set (attr "type")
12741         (cond [(and (eq_attr "alternative" "2,3")
12742                     (match_operand:MODEF 3 "mult_operator" ""))
12743                  (const_string "ssemul")
12744                (and (eq_attr "alternative" "2,3")
12745                     (match_operand:MODEF 3 "div_operator" ""))
12746                  (const_string "ssediv")
12747                (eq_attr "alternative" "2,3")
12748                  (const_string "sseadd")
12749                (match_operand:MODEF 3 "mult_operator" "")
12750                  (const_string "fmul")
12751                (match_operand:MODEF 3 "div_operator" "")
12752                  (const_string "fdiv")
12753               ]
12754               (const_string "fop")))
12755    (set_attr "isa" "base,base,noavx,avx")
12756    (set_attr "prefix" "orig,orig,orig,vex")
12757    (set_attr "mode" "<MODE>")])
12758
12759 (define_insn "*rcpsf2_sse"
12760   [(set (match_operand:SF 0 "register_operand" "=x")
12761         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12762                    UNSPEC_RCP))]
12763   "TARGET_SSE_MATH"
12764   "%vrcpss\t{%1, %d0|%d0, %1}"
12765   [(set_attr "type" "sse")
12766    (set_attr "atom_sse_attr" "rcp")
12767    (set_attr "prefix" "maybe_vex")
12768    (set_attr "mode" "SF")])
12769
12770 (define_insn "*fop_<mode>_1_sse"
12771   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12772         (match_operator:MODEF 3 "binary_fp_operator"
12773           [(match_operand:MODEF 1 "register_operand" "0,x")
12774            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12775   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12776    && !COMMUTATIVE_ARITH_P (operands[3])"
12777   "* return output_387_binary_op (insn, operands);"
12778   [(set (attr "type")
12779         (cond [(match_operand:MODEF 3 "mult_operator" "")
12780                  (const_string "ssemul")
12781                (match_operand:MODEF 3 "div_operator" "")
12782                  (const_string "ssediv")
12783               ]
12784               (const_string "sseadd")))
12785    (set_attr "isa" "noavx,avx")
12786    (set_attr "prefix" "orig,vex")
12787    (set_attr "mode" "<MODE>")])
12788
12789 ;; This pattern is not fully shadowed by the pattern above.
12790 (define_insn "*fop_<mode>_1_i387"
12791   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12792         (match_operator:MODEF 3 "binary_fp_operator"
12793           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12794            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12795   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12796    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12797    && !COMMUTATIVE_ARITH_P (operands[3])
12798    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12799   "* return output_387_binary_op (insn, operands);"
12800   [(set (attr "type")
12801         (cond [(match_operand:MODEF 3 "mult_operator" "")
12802                  (const_string "fmul")
12803                (match_operand:MODEF 3 "div_operator" "")
12804                  (const_string "fdiv")
12805               ]
12806               (const_string "fop")))
12807    (set_attr "mode" "<MODE>")])
12808
12809 ;; ??? Add SSE splitters for these!
12810 (define_insn "*fop_<MODEF:mode>_2_i387"
12811   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12812         (match_operator:MODEF 3 "binary_fp_operator"
12813           [(float:MODEF
12814              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12815            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12816   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12817    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12818    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12819   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12820   [(set (attr "type")
12821         (cond [(match_operand:MODEF 3 "mult_operator" "")
12822                  (const_string "fmul")
12823                (match_operand:MODEF 3 "div_operator" "")
12824                  (const_string "fdiv")
12825               ]
12826               (const_string "fop")))
12827    (set_attr "fp_int_src" "true")
12828    (set_attr "mode" "<SWI24:MODE>")])
12829
12830 (define_insn "*fop_<MODEF:mode>_3_i387"
12831   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12832         (match_operator:MODEF 3 "binary_fp_operator"
12833           [(match_operand:MODEF 1 "register_operand" "0,0")
12834            (float:MODEF
12835              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12836   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12837    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12838    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12839   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12840   [(set (attr "type")
12841         (cond [(match_operand:MODEF 3 "mult_operator" "")
12842                  (const_string "fmul")
12843                (match_operand:MODEF 3 "div_operator" "")
12844                  (const_string "fdiv")
12845               ]
12846               (const_string "fop")))
12847    (set_attr "fp_int_src" "true")
12848    (set_attr "mode" "<MODE>")])
12849
12850 (define_insn "*fop_df_4_i387"
12851   [(set (match_operand:DF 0 "register_operand" "=f,f")
12852         (match_operator:DF 3 "binary_fp_operator"
12853            [(float_extend:DF
12854              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12855             (match_operand:DF 2 "register_operand" "0,f")]))]
12856   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12857    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12858    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12859   "* return output_387_binary_op (insn, operands);"
12860   [(set (attr "type")
12861         (cond [(match_operand:DF 3 "mult_operator" "")
12862                  (const_string "fmul")
12863                (match_operand:DF 3 "div_operator" "")
12864                  (const_string "fdiv")
12865               ]
12866               (const_string "fop")))
12867    (set_attr "mode" "SF")])
12868
12869 (define_insn "*fop_df_5_i387"
12870   [(set (match_operand:DF 0 "register_operand" "=f,f")
12871         (match_operator:DF 3 "binary_fp_operator"
12872           [(match_operand:DF 1 "register_operand" "0,f")
12873            (float_extend:DF
12874             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12875   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12876    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12877   "* return output_387_binary_op (insn, operands);"
12878   [(set (attr "type")
12879         (cond [(match_operand:DF 3 "mult_operator" "")
12880                  (const_string "fmul")
12881                (match_operand:DF 3 "div_operator" "")
12882                  (const_string "fdiv")
12883               ]
12884               (const_string "fop")))
12885    (set_attr "mode" "SF")])
12886
12887 (define_insn "*fop_df_6_i387"
12888   [(set (match_operand:DF 0 "register_operand" "=f,f")
12889         (match_operator:DF 3 "binary_fp_operator"
12890           [(float_extend:DF
12891             (match_operand:SF 1 "register_operand" "0,f"))
12892            (float_extend:DF
12893             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12894   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12895    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12896   "* return output_387_binary_op (insn, operands);"
12897   [(set (attr "type")
12898         (cond [(match_operand:DF 3 "mult_operator" "")
12899                  (const_string "fmul")
12900                (match_operand:DF 3 "div_operator" "")
12901                  (const_string "fdiv")
12902               ]
12903               (const_string "fop")))
12904    (set_attr "mode" "SF")])
12905
12906 (define_insn "*fop_xf_comm_i387"
12907   [(set (match_operand:XF 0 "register_operand" "=f")
12908         (match_operator:XF 3 "binary_fp_operator"
12909                         [(match_operand:XF 1 "register_operand" "%0")
12910                          (match_operand:XF 2 "register_operand" "f")]))]
12911   "TARGET_80387
12912    && COMMUTATIVE_ARITH_P (operands[3])"
12913   "* return output_387_binary_op (insn, operands);"
12914   [(set (attr "type")
12915         (if_then_else (match_operand:XF 3 "mult_operator" "")
12916            (const_string "fmul")
12917            (const_string "fop")))
12918    (set_attr "mode" "XF")])
12919
12920 (define_insn "*fop_xf_1_i387"
12921   [(set (match_operand:XF 0 "register_operand" "=f,f")
12922         (match_operator:XF 3 "binary_fp_operator"
12923                         [(match_operand:XF 1 "register_operand" "0,f")
12924                          (match_operand:XF 2 "register_operand" "f,0")]))]
12925   "TARGET_80387
12926    && !COMMUTATIVE_ARITH_P (operands[3])"
12927   "* return output_387_binary_op (insn, operands);"
12928   [(set (attr "type")
12929         (cond [(match_operand:XF 3 "mult_operator" "")
12930                  (const_string "fmul")
12931                (match_operand:XF 3 "div_operator" "")
12932                  (const_string "fdiv")
12933               ]
12934               (const_string "fop")))
12935    (set_attr "mode" "XF")])
12936
12937 (define_insn "*fop_xf_2_i387"
12938   [(set (match_operand:XF 0 "register_operand" "=f,f")
12939         (match_operator:XF 3 "binary_fp_operator"
12940           [(float:XF
12941              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12942            (match_operand:XF 2 "register_operand" "0,0")]))]
12943   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12944   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12945   [(set (attr "type")
12946         (cond [(match_operand:XF 3 "mult_operator" "")
12947                  (const_string "fmul")
12948                (match_operand:XF 3 "div_operator" "")
12949                  (const_string "fdiv")
12950               ]
12951               (const_string "fop")))
12952    (set_attr "fp_int_src" "true")
12953    (set_attr "mode" "<MODE>")])
12954
12955 (define_insn "*fop_xf_3_i387"
12956   [(set (match_operand:XF 0 "register_operand" "=f,f")
12957         (match_operator:XF 3 "binary_fp_operator"
12958           [(match_operand:XF 1 "register_operand" "0,0")
12959            (float:XF
12960              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12961   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12962   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12963   [(set (attr "type")
12964         (cond [(match_operand:XF 3 "mult_operator" "")
12965                  (const_string "fmul")
12966                (match_operand:XF 3 "div_operator" "")
12967                  (const_string "fdiv")
12968               ]
12969               (const_string "fop")))
12970    (set_attr "fp_int_src" "true")
12971    (set_attr "mode" "<MODE>")])
12972
12973 (define_insn "*fop_xf_4_i387"
12974   [(set (match_operand:XF 0 "register_operand" "=f,f")
12975         (match_operator:XF 3 "binary_fp_operator"
12976            [(float_extend:XF
12977               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12978             (match_operand:XF 2 "register_operand" "0,f")]))]
12979   "TARGET_80387"
12980   "* return output_387_binary_op (insn, operands);"
12981   [(set (attr "type")
12982         (cond [(match_operand:XF 3 "mult_operator" "")
12983                  (const_string "fmul")
12984                (match_operand:XF 3 "div_operator" "")
12985                  (const_string "fdiv")
12986               ]
12987               (const_string "fop")))
12988    (set_attr "mode" "<MODE>")])
12989
12990 (define_insn "*fop_xf_5_i387"
12991   [(set (match_operand:XF 0 "register_operand" "=f,f")
12992         (match_operator:XF 3 "binary_fp_operator"
12993           [(match_operand:XF 1 "register_operand" "0,f")
12994            (float_extend:XF
12995              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12996   "TARGET_80387"
12997   "* return output_387_binary_op (insn, operands);"
12998   [(set (attr "type")
12999         (cond [(match_operand:XF 3 "mult_operator" "")
13000                  (const_string "fmul")
13001                (match_operand:XF 3 "div_operator" "")
13002                  (const_string "fdiv")
13003               ]
13004               (const_string "fop")))
13005    (set_attr "mode" "<MODE>")])
13006
13007 (define_insn "*fop_xf_6_i387"
13008   [(set (match_operand:XF 0 "register_operand" "=f,f")
13009         (match_operator:XF 3 "binary_fp_operator"
13010           [(float_extend:XF
13011              (match_operand:MODEF 1 "register_operand" "0,f"))
13012            (float_extend:XF
13013              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13014   "TARGET_80387"
13015   "* return output_387_binary_op (insn, operands);"
13016   [(set (attr "type")
13017         (cond [(match_operand:XF 3 "mult_operator" "")
13018                  (const_string "fmul")
13019                (match_operand:XF 3 "div_operator" "")
13020                  (const_string "fdiv")
13021               ]
13022               (const_string "fop")))
13023    (set_attr "mode" "<MODE>")])
13024
13025 (define_split
13026   [(set (match_operand 0 "register_operand" "")
13027         (match_operator 3 "binary_fp_operator"
13028            [(float (match_operand:SWI24 1 "register_operand" ""))
13029             (match_operand 2 "register_operand" "")]))]
13030   "reload_completed
13031    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13032    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13033   [(const_int 0)]
13034 {
13035   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13036   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13037   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13038                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13039                                           GET_MODE (operands[3]),
13040                                           operands[4],
13041                                           operands[2])));
13042   ix86_free_from_memory (GET_MODE (operands[1]));
13043   DONE;
13044 })
13045
13046 (define_split
13047   [(set (match_operand 0 "register_operand" "")
13048         (match_operator 3 "binary_fp_operator"
13049            [(match_operand 1 "register_operand" "")
13050             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13051   "reload_completed
13052    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13053    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13054   [(const_int 0)]
13055 {
13056   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13057   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13058   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13059                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13060                                           GET_MODE (operands[3]),
13061                                           operands[1],
13062                                           operands[4])));
13063   ix86_free_from_memory (GET_MODE (operands[2]));
13064   DONE;
13065 })
13066 \f
13067 ;; FPU special functions.
13068
13069 ;; This pattern implements a no-op XFmode truncation for
13070 ;; all fancy i386 XFmode math functions.
13071
13072 (define_insn "truncxf<mode>2_i387_noop_unspec"
13073   [(set (match_operand:MODEF 0 "register_operand" "=f")
13074         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13075         UNSPEC_TRUNC_NOOP))]
13076   "TARGET_USE_FANCY_MATH_387"
13077   "* return output_387_reg_move (insn, operands);"
13078   [(set_attr "type" "fmov")
13079    (set_attr "mode" "<MODE>")])
13080
13081 (define_insn "sqrtxf2"
13082   [(set (match_operand:XF 0 "register_operand" "=f")
13083         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13084   "TARGET_USE_FANCY_MATH_387"
13085   "fsqrt"
13086   [(set_attr "type" "fpspc")
13087    (set_attr "mode" "XF")
13088    (set_attr "athlon_decode" "direct")
13089    (set_attr "amdfam10_decode" "direct")
13090    (set_attr "bdver1_decode" "direct")])
13091
13092 (define_insn "sqrt_extend<mode>xf2_i387"
13093   [(set (match_operand:XF 0 "register_operand" "=f")
13094         (sqrt:XF
13095           (float_extend:XF
13096             (match_operand:MODEF 1 "register_operand" "0"))))]
13097   "TARGET_USE_FANCY_MATH_387"
13098   "fsqrt"
13099   [(set_attr "type" "fpspc")
13100    (set_attr "mode" "XF")
13101    (set_attr "athlon_decode" "direct")
13102    (set_attr "amdfam10_decode" "direct")
13103    (set_attr "bdver1_decode" "direct")])
13104
13105 (define_insn "*rsqrtsf2_sse"
13106   [(set (match_operand:SF 0 "register_operand" "=x")
13107         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13108                    UNSPEC_RSQRT))]
13109   "TARGET_SSE_MATH"
13110   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13111   [(set_attr "type" "sse")
13112    (set_attr "atom_sse_attr" "rcp")
13113    (set_attr "prefix" "maybe_vex")
13114    (set_attr "mode" "SF")])
13115
13116 (define_expand "rsqrtsf2"
13117   [(set (match_operand:SF 0 "register_operand" "")
13118         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13119                    UNSPEC_RSQRT))]
13120   "TARGET_SSE_MATH"
13121 {
13122   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13123   DONE;
13124 })
13125
13126 (define_insn "*sqrt<mode>2_sse"
13127   [(set (match_operand:MODEF 0 "register_operand" "=x")
13128         (sqrt:MODEF
13129           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13130   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13131   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13132   [(set_attr "type" "sse")
13133    (set_attr "atom_sse_attr" "sqrt")
13134    (set_attr "prefix" "maybe_vex")
13135    (set_attr "mode" "<MODE>")
13136    (set_attr "athlon_decode" "*")
13137    (set_attr "amdfam10_decode" "*")
13138    (set_attr "bdver1_decode" "*")])
13139
13140 (define_expand "sqrt<mode>2"
13141   [(set (match_operand:MODEF 0 "register_operand" "")
13142         (sqrt:MODEF
13143           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13144   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13145    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13146 {
13147   if (<MODE>mode == SFmode
13148       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13149       && flag_finite_math_only && !flag_trapping_math
13150       && flag_unsafe_math_optimizations)
13151     {
13152       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13153       DONE;
13154     }
13155
13156   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13157     {
13158       rtx op0 = gen_reg_rtx (XFmode);
13159       rtx op1 = force_reg (<MODE>mode, operands[1]);
13160
13161       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13162       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13163       DONE;
13164    }
13165 })
13166
13167 (define_insn "fpremxf4_i387"
13168   [(set (match_operand:XF 0 "register_operand" "=f")
13169         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13170                     (match_operand:XF 3 "register_operand" "1")]
13171                    UNSPEC_FPREM_F))
13172    (set (match_operand:XF 1 "register_operand" "=u")
13173         (unspec:XF [(match_dup 2) (match_dup 3)]
13174                    UNSPEC_FPREM_U))
13175    (set (reg:CCFP FPSR_REG)
13176         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13177                      UNSPEC_C2_FLAG))]
13178   "TARGET_USE_FANCY_MATH_387"
13179   "fprem"
13180   [(set_attr "type" "fpspc")
13181    (set_attr "mode" "XF")])
13182
13183 (define_expand "fmodxf3"
13184   [(use (match_operand:XF 0 "register_operand" ""))
13185    (use (match_operand:XF 1 "general_operand" ""))
13186    (use (match_operand:XF 2 "general_operand" ""))]
13187   "TARGET_USE_FANCY_MATH_387"
13188 {
13189   rtx label = gen_label_rtx ();
13190
13191   rtx op1 = gen_reg_rtx (XFmode);
13192   rtx op2 = gen_reg_rtx (XFmode);
13193
13194   emit_move_insn (op2, operands[2]);
13195   emit_move_insn (op1, operands[1]);
13196
13197   emit_label (label);
13198   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13199   ix86_emit_fp_unordered_jump (label);
13200   LABEL_NUSES (label) = 1;
13201
13202   emit_move_insn (operands[0], op1);
13203   DONE;
13204 })
13205
13206 (define_expand "fmod<mode>3"
13207   [(use (match_operand:MODEF 0 "register_operand" ""))
13208    (use (match_operand:MODEF 1 "general_operand" ""))
13209    (use (match_operand:MODEF 2 "general_operand" ""))]
13210   "TARGET_USE_FANCY_MATH_387"
13211 {
13212   rtx (*gen_truncxf) (rtx, rtx);
13213
13214   rtx label = gen_label_rtx ();
13215
13216   rtx op1 = gen_reg_rtx (XFmode);
13217   rtx op2 = gen_reg_rtx (XFmode);
13218
13219   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13220   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13221
13222   emit_label (label);
13223   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13224   ix86_emit_fp_unordered_jump (label);
13225   LABEL_NUSES (label) = 1;
13226
13227   /* Truncate the result properly for strict SSE math.  */
13228   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13229       && !TARGET_MIX_SSE_I387)
13230     gen_truncxf = gen_truncxf<mode>2;
13231   else
13232     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13233
13234   emit_insn (gen_truncxf (operands[0], op1));
13235   DONE;
13236 })
13237
13238 (define_insn "fprem1xf4_i387"
13239   [(set (match_operand:XF 0 "register_operand" "=f")
13240         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13241                     (match_operand:XF 3 "register_operand" "1")]
13242                    UNSPEC_FPREM1_F))
13243    (set (match_operand:XF 1 "register_operand" "=u")
13244         (unspec:XF [(match_dup 2) (match_dup 3)]
13245                    UNSPEC_FPREM1_U))
13246    (set (reg:CCFP FPSR_REG)
13247         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13248                      UNSPEC_C2_FLAG))]
13249   "TARGET_USE_FANCY_MATH_387"
13250   "fprem1"
13251   [(set_attr "type" "fpspc")
13252    (set_attr "mode" "XF")])
13253
13254 (define_expand "remainderxf3"
13255   [(use (match_operand:XF 0 "register_operand" ""))
13256    (use (match_operand:XF 1 "general_operand" ""))
13257    (use (match_operand:XF 2 "general_operand" ""))]
13258   "TARGET_USE_FANCY_MATH_387"
13259 {
13260   rtx label = gen_label_rtx ();
13261
13262   rtx op1 = gen_reg_rtx (XFmode);
13263   rtx op2 = gen_reg_rtx (XFmode);
13264
13265   emit_move_insn (op2, operands[2]);
13266   emit_move_insn (op1, operands[1]);
13267
13268   emit_label (label);
13269   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13270   ix86_emit_fp_unordered_jump (label);
13271   LABEL_NUSES (label) = 1;
13272
13273   emit_move_insn (operands[0], op1);
13274   DONE;
13275 })
13276
13277 (define_expand "remainder<mode>3"
13278   [(use (match_operand:MODEF 0 "register_operand" ""))
13279    (use (match_operand:MODEF 1 "general_operand" ""))
13280    (use (match_operand:MODEF 2 "general_operand" ""))]
13281   "TARGET_USE_FANCY_MATH_387"
13282 {
13283   rtx (*gen_truncxf) (rtx, rtx);
13284
13285   rtx label = gen_label_rtx ();
13286
13287   rtx op1 = gen_reg_rtx (XFmode);
13288   rtx op2 = gen_reg_rtx (XFmode);
13289
13290   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13291   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13292
13293   emit_label (label);
13294
13295   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13296   ix86_emit_fp_unordered_jump (label);
13297   LABEL_NUSES (label) = 1;
13298
13299   /* Truncate the result properly for strict SSE math.  */
13300   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13301       && !TARGET_MIX_SSE_I387)
13302     gen_truncxf = gen_truncxf<mode>2;
13303   else
13304     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13305
13306   emit_insn (gen_truncxf (operands[0], op1));
13307   DONE;
13308 })
13309
13310 (define_insn "*sinxf2_i387"
13311   [(set (match_operand:XF 0 "register_operand" "=f")
13312         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13313   "TARGET_USE_FANCY_MATH_387
13314    && flag_unsafe_math_optimizations"
13315   "fsin"
13316   [(set_attr "type" "fpspc")
13317    (set_attr "mode" "XF")])
13318
13319 (define_insn "*sin_extend<mode>xf2_i387"
13320   [(set (match_operand:XF 0 "register_operand" "=f")
13321         (unspec:XF [(float_extend:XF
13322                       (match_operand:MODEF 1 "register_operand" "0"))]
13323                    UNSPEC_SIN))]
13324   "TARGET_USE_FANCY_MATH_387
13325    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13326        || TARGET_MIX_SSE_I387)
13327    && flag_unsafe_math_optimizations"
13328   "fsin"
13329   [(set_attr "type" "fpspc")
13330    (set_attr "mode" "XF")])
13331
13332 (define_insn "*cosxf2_i387"
13333   [(set (match_operand:XF 0 "register_operand" "=f")
13334         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13335   "TARGET_USE_FANCY_MATH_387
13336    && flag_unsafe_math_optimizations"
13337   "fcos"
13338   [(set_attr "type" "fpspc")
13339    (set_attr "mode" "XF")])
13340
13341 (define_insn "*cos_extend<mode>xf2_i387"
13342   [(set (match_operand:XF 0 "register_operand" "=f")
13343         (unspec:XF [(float_extend:XF
13344                       (match_operand:MODEF 1 "register_operand" "0"))]
13345                    UNSPEC_COS))]
13346   "TARGET_USE_FANCY_MATH_387
13347    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13348        || TARGET_MIX_SSE_I387)
13349    && flag_unsafe_math_optimizations"
13350   "fcos"
13351   [(set_attr "type" "fpspc")
13352    (set_attr "mode" "XF")])
13353
13354 ;; When sincos pattern is defined, sin and cos builtin functions will be
13355 ;; expanded to sincos pattern with one of its outputs left unused.
13356 ;; CSE pass will figure out if two sincos patterns can be combined,
13357 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13358 ;; depending on the unused output.
13359
13360 (define_insn "sincosxf3"
13361   [(set (match_operand:XF 0 "register_operand" "=f")
13362         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13363                    UNSPEC_SINCOS_COS))
13364    (set (match_operand:XF 1 "register_operand" "=u")
13365         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13366   "TARGET_USE_FANCY_MATH_387
13367    && flag_unsafe_math_optimizations"
13368   "fsincos"
13369   [(set_attr "type" "fpspc")
13370    (set_attr "mode" "XF")])
13371
13372 (define_split
13373   [(set (match_operand:XF 0 "register_operand" "")
13374         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13375                    UNSPEC_SINCOS_COS))
13376    (set (match_operand:XF 1 "register_operand" "")
13377         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13378   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13379    && can_create_pseudo_p ()"
13380   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13381
13382 (define_split
13383   [(set (match_operand:XF 0 "register_operand" "")
13384         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13385                    UNSPEC_SINCOS_COS))
13386    (set (match_operand:XF 1 "register_operand" "")
13387         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13388   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13389    && can_create_pseudo_p ()"
13390   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13391
13392 (define_insn "sincos_extend<mode>xf3_i387"
13393   [(set (match_operand:XF 0 "register_operand" "=f")
13394         (unspec:XF [(float_extend:XF
13395                       (match_operand:MODEF 2 "register_operand" "0"))]
13396                    UNSPEC_SINCOS_COS))
13397    (set (match_operand:XF 1 "register_operand" "=u")
13398         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13399   "TARGET_USE_FANCY_MATH_387
13400    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13401        || TARGET_MIX_SSE_I387)
13402    && flag_unsafe_math_optimizations"
13403   "fsincos"
13404   [(set_attr "type" "fpspc")
13405    (set_attr "mode" "XF")])
13406
13407 (define_split
13408   [(set (match_operand:XF 0 "register_operand" "")
13409         (unspec:XF [(float_extend:XF
13410                       (match_operand:MODEF 2 "register_operand" ""))]
13411                    UNSPEC_SINCOS_COS))
13412    (set (match_operand:XF 1 "register_operand" "")
13413         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13414   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13415    && can_create_pseudo_p ()"
13416   [(set (match_dup 1)
13417         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13418
13419 (define_split
13420   [(set (match_operand:XF 0 "register_operand" "")
13421         (unspec:XF [(float_extend:XF
13422                       (match_operand:MODEF 2 "register_operand" ""))]
13423                    UNSPEC_SINCOS_COS))
13424    (set (match_operand:XF 1 "register_operand" "")
13425         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13426   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13427    && can_create_pseudo_p ()"
13428   [(set (match_dup 0)
13429         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13430
13431 (define_expand "sincos<mode>3"
13432   [(use (match_operand:MODEF 0 "register_operand" ""))
13433    (use (match_operand:MODEF 1 "register_operand" ""))
13434    (use (match_operand:MODEF 2 "register_operand" ""))]
13435   "TARGET_USE_FANCY_MATH_387
13436    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13437        || TARGET_MIX_SSE_I387)
13438    && flag_unsafe_math_optimizations"
13439 {
13440   rtx op0 = gen_reg_rtx (XFmode);
13441   rtx op1 = gen_reg_rtx (XFmode);
13442
13443   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13444   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13445   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13446   DONE;
13447 })
13448
13449 (define_insn "fptanxf4_i387"
13450   [(set (match_operand:XF 0 "register_operand" "=f")
13451         (match_operand:XF 3 "const_double_operand" "F"))
13452    (set (match_operand:XF 1 "register_operand" "=u")
13453         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13454                    UNSPEC_TAN))]
13455   "TARGET_USE_FANCY_MATH_387
13456    && flag_unsafe_math_optimizations
13457    && standard_80387_constant_p (operands[3]) == 2"
13458   "fptan"
13459   [(set_attr "type" "fpspc")
13460    (set_attr "mode" "XF")])
13461
13462 (define_insn "fptan_extend<mode>xf4_i387"
13463   [(set (match_operand:MODEF 0 "register_operand" "=f")
13464         (match_operand:MODEF 3 "const_double_operand" "F"))
13465    (set (match_operand:XF 1 "register_operand" "=u")
13466         (unspec:XF [(float_extend:XF
13467                       (match_operand:MODEF 2 "register_operand" "0"))]
13468                    UNSPEC_TAN))]
13469   "TARGET_USE_FANCY_MATH_387
13470    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13471        || TARGET_MIX_SSE_I387)
13472    && flag_unsafe_math_optimizations
13473    && standard_80387_constant_p (operands[3]) == 2"
13474   "fptan"
13475   [(set_attr "type" "fpspc")
13476    (set_attr "mode" "XF")])
13477
13478 (define_expand "tanxf2"
13479   [(use (match_operand:XF 0 "register_operand" ""))
13480    (use (match_operand:XF 1 "register_operand" ""))]
13481   "TARGET_USE_FANCY_MATH_387
13482    && flag_unsafe_math_optimizations"
13483 {
13484   rtx one = gen_reg_rtx (XFmode);
13485   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13486
13487   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13488   DONE;
13489 })
13490
13491 (define_expand "tan<mode>2"
13492   [(use (match_operand:MODEF 0 "register_operand" ""))
13493    (use (match_operand:MODEF 1 "register_operand" ""))]
13494   "TARGET_USE_FANCY_MATH_387
13495    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13496        || TARGET_MIX_SSE_I387)
13497    && flag_unsafe_math_optimizations"
13498 {
13499   rtx op0 = gen_reg_rtx (XFmode);
13500
13501   rtx one = gen_reg_rtx (<MODE>mode);
13502   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13503
13504   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13505                                              operands[1], op2));
13506   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13507   DONE;
13508 })
13509
13510 (define_insn "*fpatanxf3_i387"
13511   [(set (match_operand:XF 0 "register_operand" "=f")
13512         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13513                     (match_operand:XF 2 "register_operand" "u")]
13514                    UNSPEC_FPATAN))
13515    (clobber (match_scratch:XF 3 "=2"))]
13516   "TARGET_USE_FANCY_MATH_387
13517    && flag_unsafe_math_optimizations"
13518   "fpatan"
13519   [(set_attr "type" "fpspc")
13520    (set_attr "mode" "XF")])
13521
13522 (define_insn "fpatan_extend<mode>xf3_i387"
13523   [(set (match_operand:XF 0 "register_operand" "=f")
13524         (unspec:XF [(float_extend:XF
13525                       (match_operand:MODEF 1 "register_operand" "0"))
13526                     (float_extend:XF
13527                       (match_operand:MODEF 2 "register_operand" "u"))]
13528                    UNSPEC_FPATAN))
13529    (clobber (match_scratch:XF 3 "=2"))]
13530   "TARGET_USE_FANCY_MATH_387
13531    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13532        || TARGET_MIX_SSE_I387)
13533    && flag_unsafe_math_optimizations"
13534   "fpatan"
13535   [(set_attr "type" "fpspc")
13536    (set_attr "mode" "XF")])
13537
13538 (define_expand "atan2xf3"
13539   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13540                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13541                                (match_operand:XF 1 "register_operand" "")]
13542                               UNSPEC_FPATAN))
13543               (clobber (match_scratch:XF 3 ""))])]
13544   "TARGET_USE_FANCY_MATH_387
13545    && flag_unsafe_math_optimizations")
13546
13547 (define_expand "atan2<mode>3"
13548   [(use (match_operand:MODEF 0 "register_operand" ""))
13549    (use (match_operand:MODEF 1 "register_operand" ""))
13550    (use (match_operand:MODEF 2 "register_operand" ""))]
13551   "TARGET_USE_FANCY_MATH_387
13552    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13553        || TARGET_MIX_SSE_I387)
13554    && flag_unsafe_math_optimizations"
13555 {
13556   rtx op0 = gen_reg_rtx (XFmode);
13557
13558   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13559   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13560   DONE;
13561 })
13562
13563 (define_expand "atanxf2"
13564   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13565                    (unspec:XF [(match_dup 2)
13566                                (match_operand:XF 1 "register_operand" "")]
13567                               UNSPEC_FPATAN))
13568               (clobber (match_scratch:XF 3 ""))])]
13569   "TARGET_USE_FANCY_MATH_387
13570    && flag_unsafe_math_optimizations"
13571 {
13572   operands[2] = gen_reg_rtx (XFmode);
13573   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13574 })
13575
13576 (define_expand "atan<mode>2"
13577   [(use (match_operand:MODEF 0 "register_operand" ""))
13578    (use (match_operand:MODEF 1 "register_operand" ""))]
13579   "TARGET_USE_FANCY_MATH_387
13580    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13581        || TARGET_MIX_SSE_I387)
13582    && flag_unsafe_math_optimizations"
13583 {
13584   rtx op0 = gen_reg_rtx (XFmode);
13585
13586   rtx op2 = gen_reg_rtx (<MODE>mode);
13587   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13588
13589   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13590   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13591   DONE;
13592 })
13593
13594 (define_expand "asinxf2"
13595   [(set (match_dup 2)
13596         (mult:XF (match_operand:XF 1 "register_operand" "")
13597                  (match_dup 1)))
13598    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13599    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13600    (parallel [(set (match_operand:XF 0 "register_operand" "")
13601                    (unspec:XF [(match_dup 5) (match_dup 1)]
13602                               UNSPEC_FPATAN))
13603               (clobber (match_scratch:XF 6 ""))])]
13604   "TARGET_USE_FANCY_MATH_387
13605    && flag_unsafe_math_optimizations"
13606 {
13607   int i;
13608
13609   if (optimize_insn_for_size_p ())
13610     FAIL;
13611
13612   for (i = 2; i < 6; i++)
13613     operands[i] = gen_reg_rtx (XFmode);
13614
13615   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13616 })
13617
13618 (define_expand "asin<mode>2"
13619   [(use (match_operand:MODEF 0 "register_operand" ""))
13620    (use (match_operand:MODEF 1 "general_operand" ""))]
13621  "TARGET_USE_FANCY_MATH_387
13622    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13623        || TARGET_MIX_SSE_I387)
13624    && flag_unsafe_math_optimizations"
13625 {
13626   rtx op0 = gen_reg_rtx (XFmode);
13627   rtx op1 = gen_reg_rtx (XFmode);
13628
13629   if (optimize_insn_for_size_p ())
13630     FAIL;
13631
13632   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13633   emit_insn (gen_asinxf2 (op0, op1));
13634   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13635   DONE;
13636 })
13637
13638 (define_expand "acosxf2"
13639   [(set (match_dup 2)
13640         (mult:XF (match_operand:XF 1 "register_operand" "")
13641                  (match_dup 1)))
13642    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13643    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13644    (parallel [(set (match_operand:XF 0 "register_operand" "")
13645                    (unspec:XF [(match_dup 1) (match_dup 5)]
13646                               UNSPEC_FPATAN))
13647               (clobber (match_scratch:XF 6 ""))])]
13648   "TARGET_USE_FANCY_MATH_387
13649    && flag_unsafe_math_optimizations"
13650 {
13651   int i;
13652
13653   if (optimize_insn_for_size_p ())
13654     FAIL;
13655
13656   for (i = 2; i < 6; i++)
13657     operands[i] = gen_reg_rtx (XFmode);
13658
13659   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13660 })
13661
13662 (define_expand "acos<mode>2"
13663   [(use (match_operand:MODEF 0 "register_operand" ""))
13664    (use (match_operand:MODEF 1 "general_operand" ""))]
13665  "TARGET_USE_FANCY_MATH_387
13666    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13667        || TARGET_MIX_SSE_I387)
13668    && flag_unsafe_math_optimizations"
13669 {
13670   rtx op0 = gen_reg_rtx (XFmode);
13671   rtx op1 = gen_reg_rtx (XFmode);
13672
13673   if (optimize_insn_for_size_p ())
13674     FAIL;
13675
13676   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13677   emit_insn (gen_acosxf2 (op0, op1));
13678   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13679   DONE;
13680 })
13681
13682 (define_insn "fyl2xxf3_i387"
13683   [(set (match_operand:XF 0 "register_operand" "=f")
13684         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13685                     (match_operand:XF 2 "register_operand" "u")]
13686                    UNSPEC_FYL2X))
13687    (clobber (match_scratch:XF 3 "=2"))]
13688   "TARGET_USE_FANCY_MATH_387
13689    && flag_unsafe_math_optimizations"
13690   "fyl2x"
13691   [(set_attr "type" "fpspc")
13692    (set_attr "mode" "XF")])
13693
13694 (define_insn "fyl2x_extend<mode>xf3_i387"
13695   [(set (match_operand:XF 0 "register_operand" "=f")
13696         (unspec:XF [(float_extend:XF
13697                       (match_operand:MODEF 1 "register_operand" "0"))
13698                     (match_operand:XF 2 "register_operand" "u")]
13699                    UNSPEC_FYL2X))
13700    (clobber (match_scratch:XF 3 "=2"))]
13701   "TARGET_USE_FANCY_MATH_387
13702    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13703        || TARGET_MIX_SSE_I387)
13704    && flag_unsafe_math_optimizations"
13705   "fyl2x"
13706   [(set_attr "type" "fpspc")
13707    (set_attr "mode" "XF")])
13708
13709 (define_expand "logxf2"
13710   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13711                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13712                                (match_dup 2)] UNSPEC_FYL2X))
13713               (clobber (match_scratch:XF 3 ""))])]
13714   "TARGET_USE_FANCY_MATH_387
13715    && flag_unsafe_math_optimizations"
13716 {
13717   operands[2] = gen_reg_rtx (XFmode);
13718   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13719 })
13720
13721 (define_expand "log<mode>2"
13722   [(use (match_operand:MODEF 0 "register_operand" ""))
13723    (use (match_operand:MODEF 1 "register_operand" ""))]
13724   "TARGET_USE_FANCY_MATH_387
13725    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13726        || TARGET_MIX_SSE_I387)
13727    && flag_unsafe_math_optimizations"
13728 {
13729   rtx op0 = gen_reg_rtx (XFmode);
13730
13731   rtx op2 = gen_reg_rtx (XFmode);
13732   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13733
13734   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13735   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13736   DONE;
13737 })
13738
13739 (define_expand "log10xf2"
13740   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13741                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13742                                (match_dup 2)] UNSPEC_FYL2X))
13743               (clobber (match_scratch:XF 3 ""))])]
13744   "TARGET_USE_FANCY_MATH_387
13745    && flag_unsafe_math_optimizations"
13746 {
13747   operands[2] = gen_reg_rtx (XFmode);
13748   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13749 })
13750
13751 (define_expand "log10<mode>2"
13752   [(use (match_operand:MODEF 0 "register_operand" ""))
13753    (use (match_operand:MODEF 1 "register_operand" ""))]
13754   "TARGET_USE_FANCY_MATH_387
13755    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13756        || TARGET_MIX_SSE_I387)
13757    && flag_unsafe_math_optimizations"
13758 {
13759   rtx op0 = gen_reg_rtx (XFmode);
13760
13761   rtx op2 = gen_reg_rtx (XFmode);
13762   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13763
13764   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13765   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13766   DONE;
13767 })
13768
13769 (define_expand "log2xf2"
13770   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13771                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13772                                (match_dup 2)] UNSPEC_FYL2X))
13773               (clobber (match_scratch:XF 3 ""))])]
13774   "TARGET_USE_FANCY_MATH_387
13775    && flag_unsafe_math_optimizations"
13776 {
13777   operands[2] = gen_reg_rtx (XFmode);
13778   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13779 })
13780
13781 (define_expand "log2<mode>2"
13782   [(use (match_operand:MODEF 0 "register_operand" ""))
13783    (use (match_operand:MODEF 1 "register_operand" ""))]
13784   "TARGET_USE_FANCY_MATH_387
13785    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13786        || TARGET_MIX_SSE_I387)
13787    && flag_unsafe_math_optimizations"
13788 {
13789   rtx op0 = gen_reg_rtx (XFmode);
13790
13791   rtx op2 = gen_reg_rtx (XFmode);
13792   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13793
13794   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13795   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13796   DONE;
13797 })
13798
13799 (define_insn "fyl2xp1xf3_i387"
13800   [(set (match_operand:XF 0 "register_operand" "=f")
13801         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13802                     (match_operand:XF 2 "register_operand" "u")]
13803                    UNSPEC_FYL2XP1))
13804    (clobber (match_scratch:XF 3 "=2"))]
13805   "TARGET_USE_FANCY_MATH_387
13806    && flag_unsafe_math_optimizations"
13807   "fyl2xp1"
13808   [(set_attr "type" "fpspc")
13809    (set_attr "mode" "XF")])
13810
13811 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13812   [(set (match_operand:XF 0 "register_operand" "=f")
13813         (unspec:XF [(float_extend:XF
13814                       (match_operand:MODEF 1 "register_operand" "0"))
13815                     (match_operand:XF 2 "register_operand" "u")]
13816                    UNSPEC_FYL2XP1))
13817    (clobber (match_scratch:XF 3 "=2"))]
13818   "TARGET_USE_FANCY_MATH_387
13819    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13820        || TARGET_MIX_SSE_I387)
13821    && flag_unsafe_math_optimizations"
13822   "fyl2xp1"
13823   [(set_attr "type" "fpspc")
13824    (set_attr "mode" "XF")])
13825
13826 (define_expand "log1pxf2"
13827   [(use (match_operand:XF 0 "register_operand" ""))
13828    (use (match_operand:XF 1 "register_operand" ""))]
13829   "TARGET_USE_FANCY_MATH_387
13830    && flag_unsafe_math_optimizations"
13831 {
13832   if (optimize_insn_for_size_p ())
13833     FAIL;
13834
13835   ix86_emit_i387_log1p (operands[0], operands[1]);
13836   DONE;
13837 })
13838
13839 (define_expand "log1p<mode>2"
13840   [(use (match_operand:MODEF 0 "register_operand" ""))
13841    (use (match_operand:MODEF 1 "register_operand" ""))]
13842   "TARGET_USE_FANCY_MATH_387
13843    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13844        || TARGET_MIX_SSE_I387)
13845    && flag_unsafe_math_optimizations"
13846 {
13847   rtx op0;
13848
13849   if (optimize_insn_for_size_p ())
13850     FAIL;
13851
13852   op0 = gen_reg_rtx (XFmode);
13853
13854   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13855
13856   ix86_emit_i387_log1p (op0, operands[1]);
13857   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13858   DONE;
13859 })
13860
13861 (define_insn "fxtractxf3_i387"
13862   [(set (match_operand:XF 0 "register_operand" "=f")
13863         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13864                    UNSPEC_XTRACT_FRACT))
13865    (set (match_operand:XF 1 "register_operand" "=u")
13866         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13867   "TARGET_USE_FANCY_MATH_387
13868    && flag_unsafe_math_optimizations"
13869   "fxtract"
13870   [(set_attr "type" "fpspc")
13871    (set_attr "mode" "XF")])
13872
13873 (define_insn "fxtract_extend<mode>xf3_i387"
13874   [(set (match_operand:XF 0 "register_operand" "=f")
13875         (unspec:XF [(float_extend:XF
13876                       (match_operand:MODEF 2 "register_operand" "0"))]
13877                    UNSPEC_XTRACT_FRACT))
13878    (set (match_operand:XF 1 "register_operand" "=u")
13879         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13880   "TARGET_USE_FANCY_MATH_387
13881    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13882        || TARGET_MIX_SSE_I387)
13883    && flag_unsafe_math_optimizations"
13884   "fxtract"
13885   [(set_attr "type" "fpspc")
13886    (set_attr "mode" "XF")])
13887
13888 (define_expand "logbxf2"
13889   [(parallel [(set (match_dup 2)
13890                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13891                               UNSPEC_XTRACT_FRACT))
13892               (set (match_operand:XF 0 "register_operand" "")
13893                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13894   "TARGET_USE_FANCY_MATH_387
13895    && flag_unsafe_math_optimizations"
13896   "operands[2] = gen_reg_rtx (XFmode);")
13897
13898 (define_expand "logb<mode>2"
13899   [(use (match_operand:MODEF 0 "register_operand" ""))
13900    (use (match_operand:MODEF 1 "register_operand" ""))]
13901   "TARGET_USE_FANCY_MATH_387
13902    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13903        || TARGET_MIX_SSE_I387)
13904    && flag_unsafe_math_optimizations"
13905 {
13906   rtx op0 = gen_reg_rtx (XFmode);
13907   rtx op1 = gen_reg_rtx (XFmode);
13908
13909   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13910   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13911   DONE;
13912 })
13913
13914 (define_expand "ilogbxf2"
13915   [(use (match_operand:SI 0 "register_operand" ""))
13916    (use (match_operand:XF 1 "register_operand" ""))]
13917   "TARGET_USE_FANCY_MATH_387
13918    && flag_unsafe_math_optimizations"
13919 {
13920   rtx op0, op1;
13921
13922   if (optimize_insn_for_size_p ())
13923     FAIL;
13924
13925   op0 = gen_reg_rtx (XFmode);
13926   op1 = gen_reg_rtx (XFmode);
13927
13928   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13929   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13930   DONE;
13931 })
13932
13933 (define_expand "ilogb<mode>2"
13934   [(use (match_operand:SI 0 "register_operand" ""))
13935    (use (match_operand:MODEF 1 "register_operand" ""))]
13936   "TARGET_USE_FANCY_MATH_387
13937    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13938        || TARGET_MIX_SSE_I387)
13939    && flag_unsafe_math_optimizations"
13940 {
13941   rtx op0, op1;
13942
13943   if (optimize_insn_for_size_p ())
13944     FAIL;
13945
13946   op0 = gen_reg_rtx (XFmode);
13947   op1 = gen_reg_rtx (XFmode);
13948
13949   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13950   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13951   DONE;
13952 })
13953
13954 (define_insn "*f2xm1xf2_i387"
13955   [(set (match_operand:XF 0 "register_operand" "=f")
13956         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13957                    UNSPEC_F2XM1))]
13958   "TARGET_USE_FANCY_MATH_387
13959    && flag_unsafe_math_optimizations"
13960   "f2xm1"
13961   [(set_attr "type" "fpspc")
13962    (set_attr "mode" "XF")])
13963
13964 (define_insn "*fscalexf4_i387"
13965   [(set (match_operand:XF 0 "register_operand" "=f")
13966         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13967                     (match_operand:XF 3 "register_operand" "1")]
13968                    UNSPEC_FSCALE_FRACT))
13969    (set (match_operand:XF 1 "register_operand" "=u")
13970         (unspec:XF [(match_dup 2) (match_dup 3)]
13971                    UNSPEC_FSCALE_EXP))]
13972   "TARGET_USE_FANCY_MATH_387
13973    && flag_unsafe_math_optimizations"
13974   "fscale"
13975   [(set_attr "type" "fpspc")
13976    (set_attr "mode" "XF")])
13977
13978 (define_expand "expNcorexf3"
13979   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13980                                (match_operand:XF 2 "register_operand" "")))
13981    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13982    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13983    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13984    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13985    (parallel [(set (match_operand:XF 0 "register_operand" "")
13986                    (unspec:XF [(match_dup 8) (match_dup 4)]
13987                               UNSPEC_FSCALE_FRACT))
13988               (set (match_dup 9)
13989                    (unspec:XF [(match_dup 8) (match_dup 4)]
13990                               UNSPEC_FSCALE_EXP))])]
13991   "TARGET_USE_FANCY_MATH_387
13992    && flag_unsafe_math_optimizations"
13993 {
13994   int i;
13995
13996   if (optimize_insn_for_size_p ())
13997     FAIL;
13998
13999   for (i = 3; i < 10; i++)
14000     operands[i] = gen_reg_rtx (XFmode);
14001
14002   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14003 })
14004
14005 (define_expand "expxf2"
14006   [(use (match_operand:XF 0 "register_operand" ""))
14007    (use (match_operand:XF 1 "register_operand" ""))]
14008   "TARGET_USE_FANCY_MATH_387
14009    && flag_unsafe_math_optimizations"
14010 {
14011   rtx op2;
14012
14013   if (optimize_insn_for_size_p ())
14014     FAIL;
14015
14016   op2 = gen_reg_rtx (XFmode);
14017   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14018
14019   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14020   DONE;
14021 })
14022
14023 (define_expand "exp<mode>2"
14024   [(use (match_operand:MODEF 0 "register_operand" ""))
14025    (use (match_operand:MODEF 1 "general_operand" ""))]
14026  "TARGET_USE_FANCY_MATH_387
14027    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14028        || TARGET_MIX_SSE_I387)
14029    && flag_unsafe_math_optimizations"
14030 {
14031   rtx op0, op1;
14032
14033   if (optimize_insn_for_size_p ())
14034     FAIL;
14035
14036   op0 = gen_reg_rtx (XFmode);
14037   op1 = gen_reg_rtx (XFmode);
14038
14039   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14040   emit_insn (gen_expxf2 (op0, op1));
14041   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14042   DONE;
14043 })
14044
14045 (define_expand "exp10xf2"
14046   [(use (match_operand:XF 0 "register_operand" ""))
14047    (use (match_operand:XF 1 "register_operand" ""))]
14048   "TARGET_USE_FANCY_MATH_387
14049    && flag_unsafe_math_optimizations"
14050 {
14051   rtx op2;
14052
14053   if (optimize_insn_for_size_p ())
14054     FAIL;
14055
14056   op2 = gen_reg_rtx (XFmode);
14057   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14058
14059   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14060   DONE;
14061 })
14062
14063 (define_expand "exp10<mode>2"
14064   [(use (match_operand:MODEF 0 "register_operand" ""))
14065    (use (match_operand:MODEF 1 "general_operand" ""))]
14066  "TARGET_USE_FANCY_MATH_387
14067    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14068        || TARGET_MIX_SSE_I387)
14069    && flag_unsafe_math_optimizations"
14070 {
14071   rtx op0, op1;
14072
14073   if (optimize_insn_for_size_p ())
14074     FAIL;
14075
14076   op0 = gen_reg_rtx (XFmode);
14077   op1 = gen_reg_rtx (XFmode);
14078
14079   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14080   emit_insn (gen_exp10xf2 (op0, op1));
14081   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14082   DONE;
14083 })
14084
14085 (define_expand "exp2xf2"
14086   [(use (match_operand:XF 0 "register_operand" ""))
14087    (use (match_operand:XF 1 "register_operand" ""))]
14088   "TARGET_USE_FANCY_MATH_387
14089    && flag_unsafe_math_optimizations"
14090 {
14091   rtx op2;
14092
14093   if (optimize_insn_for_size_p ())
14094     FAIL;
14095
14096   op2 = gen_reg_rtx (XFmode);
14097   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14098
14099   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14100   DONE;
14101 })
14102
14103 (define_expand "exp2<mode>2"
14104   [(use (match_operand:MODEF 0 "register_operand" ""))
14105    (use (match_operand:MODEF 1 "general_operand" ""))]
14106  "TARGET_USE_FANCY_MATH_387
14107    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14108        || TARGET_MIX_SSE_I387)
14109    && flag_unsafe_math_optimizations"
14110 {
14111   rtx op0, op1;
14112
14113   if (optimize_insn_for_size_p ())
14114     FAIL;
14115
14116   op0 = gen_reg_rtx (XFmode);
14117   op1 = gen_reg_rtx (XFmode);
14118
14119   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14120   emit_insn (gen_exp2xf2 (op0, op1));
14121   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14122   DONE;
14123 })
14124
14125 (define_expand "expm1xf2"
14126   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14127                                (match_dup 2)))
14128    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14129    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14130    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14131    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14132    (parallel [(set (match_dup 7)
14133                    (unspec:XF [(match_dup 6) (match_dup 4)]
14134                               UNSPEC_FSCALE_FRACT))
14135               (set (match_dup 8)
14136                    (unspec:XF [(match_dup 6) (match_dup 4)]
14137                               UNSPEC_FSCALE_EXP))])
14138    (parallel [(set (match_dup 10)
14139                    (unspec:XF [(match_dup 9) (match_dup 8)]
14140                               UNSPEC_FSCALE_FRACT))
14141               (set (match_dup 11)
14142                    (unspec:XF [(match_dup 9) (match_dup 8)]
14143                               UNSPEC_FSCALE_EXP))])
14144    (set (match_dup 12) (minus:XF (match_dup 10)
14145                                  (float_extend:XF (match_dup 13))))
14146    (set (match_operand:XF 0 "register_operand" "")
14147         (plus:XF (match_dup 12) (match_dup 7)))]
14148   "TARGET_USE_FANCY_MATH_387
14149    && flag_unsafe_math_optimizations"
14150 {
14151   int i;
14152
14153   if (optimize_insn_for_size_p ())
14154     FAIL;
14155
14156   for (i = 2; i < 13; i++)
14157     operands[i] = gen_reg_rtx (XFmode);
14158
14159   operands[13]
14160     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14161
14162   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14163 })
14164
14165 (define_expand "expm1<mode>2"
14166   [(use (match_operand:MODEF 0 "register_operand" ""))
14167    (use (match_operand:MODEF 1 "general_operand" ""))]
14168  "TARGET_USE_FANCY_MATH_387
14169    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14170        || TARGET_MIX_SSE_I387)
14171    && flag_unsafe_math_optimizations"
14172 {
14173   rtx op0, op1;
14174
14175   if (optimize_insn_for_size_p ())
14176     FAIL;
14177
14178   op0 = gen_reg_rtx (XFmode);
14179   op1 = gen_reg_rtx (XFmode);
14180
14181   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14182   emit_insn (gen_expm1xf2 (op0, op1));
14183   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14184   DONE;
14185 })
14186
14187 (define_expand "ldexpxf3"
14188   [(set (match_dup 3)
14189         (float:XF (match_operand:SI 2 "register_operand" "")))
14190    (parallel [(set (match_operand:XF 0 " register_operand" "")
14191                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14192                                (match_dup 3)]
14193                               UNSPEC_FSCALE_FRACT))
14194               (set (match_dup 4)
14195                    (unspec:XF [(match_dup 1) (match_dup 3)]
14196                               UNSPEC_FSCALE_EXP))])]
14197   "TARGET_USE_FANCY_MATH_387
14198    && flag_unsafe_math_optimizations"
14199 {
14200   if (optimize_insn_for_size_p ())
14201     FAIL;
14202
14203   operands[3] = gen_reg_rtx (XFmode);
14204   operands[4] = gen_reg_rtx (XFmode);
14205 })
14206
14207 (define_expand "ldexp<mode>3"
14208   [(use (match_operand:MODEF 0 "register_operand" ""))
14209    (use (match_operand:MODEF 1 "general_operand" ""))
14210    (use (match_operand:SI 2 "register_operand" ""))]
14211  "TARGET_USE_FANCY_MATH_387
14212    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14213        || TARGET_MIX_SSE_I387)
14214    && flag_unsafe_math_optimizations"
14215 {
14216   rtx op0, op1;
14217
14218   if (optimize_insn_for_size_p ())
14219     FAIL;
14220
14221   op0 = gen_reg_rtx (XFmode);
14222   op1 = gen_reg_rtx (XFmode);
14223
14224   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14225   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14226   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14227   DONE;
14228 })
14229
14230 (define_expand "scalbxf3"
14231   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14232                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14233                                (match_operand:XF 2 "register_operand" "")]
14234                               UNSPEC_FSCALE_FRACT))
14235               (set (match_dup 3)
14236                    (unspec:XF [(match_dup 1) (match_dup 2)]
14237                               UNSPEC_FSCALE_EXP))])]
14238   "TARGET_USE_FANCY_MATH_387
14239    && flag_unsafe_math_optimizations"
14240 {
14241   if (optimize_insn_for_size_p ())
14242     FAIL;
14243
14244   operands[3] = gen_reg_rtx (XFmode);
14245 })
14246
14247 (define_expand "scalb<mode>3"
14248   [(use (match_operand:MODEF 0 "register_operand" ""))
14249    (use (match_operand:MODEF 1 "general_operand" ""))
14250    (use (match_operand:MODEF 2 "general_operand" ""))]
14251  "TARGET_USE_FANCY_MATH_387
14252    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14253        || TARGET_MIX_SSE_I387)
14254    && flag_unsafe_math_optimizations"
14255 {
14256   rtx op0, op1, op2;
14257
14258   if (optimize_insn_for_size_p ())
14259     FAIL;
14260
14261   op0 = gen_reg_rtx (XFmode);
14262   op1 = gen_reg_rtx (XFmode);
14263   op2 = gen_reg_rtx (XFmode);
14264
14265   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14266   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14267   emit_insn (gen_scalbxf3 (op0, op1, op2));
14268   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14269   DONE;
14270 })
14271
14272 (define_expand "significandxf2"
14273   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14274                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14275                               UNSPEC_XTRACT_FRACT))
14276               (set (match_dup 2)
14277                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14278   "TARGET_USE_FANCY_MATH_387
14279    && flag_unsafe_math_optimizations"
14280   "operands[2] = gen_reg_rtx (XFmode);")
14281
14282 (define_expand "significand<mode>2"
14283   [(use (match_operand:MODEF 0 "register_operand" ""))
14284    (use (match_operand:MODEF 1 "register_operand" ""))]
14285   "TARGET_USE_FANCY_MATH_387
14286    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14287        || TARGET_MIX_SSE_I387)
14288    && flag_unsafe_math_optimizations"
14289 {
14290   rtx op0 = gen_reg_rtx (XFmode);
14291   rtx op1 = gen_reg_rtx (XFmode);
14292
14293   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14294   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14295   DONE;
14296 })
14297 \f
14298
14299 (define_insn "sse4_1_round<mode>2"
14300   [(set (match_operand:MODEF 0 "register_operand" "=x")
14301         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14302                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14303                       UNSPEC_ROUND))]
14304   "TARGET_ROUND"
14305   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14306   [(set_attr "type" "ssecvt")
14307    (set_attr "prefix_extra" "1")
14308    (set_attr "prefix" "maybe_vex")
14309    (set_attr "mode" "<MODE>")])
14310
14311 (define_insn "rintxf2"
14312   [(set (match_operand:XF 0 "register_operand" "=f")
14313         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14314                    UNSPEC_FRNDINT))]
14315   "TARGET_USE_FANCY_MATH_387
14316    && flag_unsafe_math_optimizations"
14317   "frndint"
14318   [(set_attr "type" "fpspc")
14319    (set_attr "mode" "XF")])
14320
14321 (define_expand "rint<mode>2"
14322   [(use (match_operand:MODEF 0 "register_operand" ""))
14323    (use (match_operand:MODEF 1 "register_operand" ""))]
14324   "(TARGET_USE_FANCY_MATH_387
14325     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14326         || TARGET_MIX_SSE_I387)
14327     && flag_unsafe_math_optimizations)
14328    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14329        && !flag_trapping_math)"
14330 {
14331   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14332       && !flag_trapping_math)
14333     {
14334       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14335         FAIL;
14336       if (TARGET_ROUND)
14337         emit_insn (gen_sse4_1_round<mode>2
14338                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14339       else
14340         ix86_expand_rint (operand0, operand1);
14341     }
14342   else
14343     {
14344       rtx op0 = gen_reg_rtx (XFmode);
14345       rtx op1 = gen_reg_rtx (XFmode);
14346
14347       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14348       emit_insn (gen_rintxf2 (op0, op1));
14349
14350       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14351     }
14352   DONE;
14353 })
14354
14355 (define_expand "round<mode>2"
14356   [(match_operand:MODEF 0 "register_operand" "")
14357    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14358   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14359    && !flag_trapping_math && !flag_rounding_math"
14360 {
14361   if (optimize_insn_for_size_p ())
14362     FAIL;
14363   if (TARGET_64BIT || (<MODE>mode != DFmode))
14364     ix86_expand_round (operand0, operand1);
14365   else
14366     ix86_expand_rounddf_32 (operand0, operand1);
14367   DONE;
14368 })
14369
14370 (define_insn_and_split "*fistdi2_1"
14371   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14372         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14373                    UNSPEC_FIST))]
14374   "TARGET_USE_FANCY_MATH_387
14375    && can_create_pseudo_p ()"
14376   "#"
14377   "&& 1"
14378   [(const_int 0)]
14379 {
14380   if (memory_operand (operands[0], VOIDmode))
14381     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14382   else
14383     {
14384       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14385       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14386                                          operands[2]));
14387     }
14388   DONE;
14389 }
14390   [(set_attr "type" "fpspc")
14391    (set_attr "mode" "DI")])
14392
14393 (define_insn "fistdi2"
14394   [(set (match_operand:DI 0 "memory_operand" "=m")
14395         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14396                    UNSPEC_FIST))
14397    (clobber (match_scratch:XF 2 "=&1f"))]
14398   "TARGET_USE_FANCY_MATH_387"
14399   "* return output_fix_trunc (insn, operands, false);"
14400   [(set_attr "type" "fpspc")
14401    (set_attr "mode" "DI")])
14402
14403 (define_insn "fistdi2_with_temp"
14404   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14405         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14406                    UNSPEC_FIST))
14407    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14408    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14409   "TARGET_USE_FANCY_MATH_387"
14410   "#"
14411   [(set_attr "type" "fpspc")
14412    (set_attr "mode" "DI")])
14413
14414 (define_split
14415   [(set (match_operand:DI 0 "register_operand" "")
14416         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14417                    UNSPEC_FIST))
14418    (clobber (match_operand:DI 2 "memory_operand" ""))
14419    (clobber (match_scratch 3 ""))]
14420   "reload_completed"
14421   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14422               (clobber (match_dup 3))])
14423    (set (match_dup 0) (match_dup 2))])
14424
14425 (define_split
14426   [(set (match_operand:DI 0 "memory_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 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14433               (clobber (match_dup 3))])])
14434
14435 (define_insn_and_split "*fist<mode>2_1"
14436   [(set (match_operand:SWI24 0 "register_operand" "")
14437         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14438                       UNSPEC_FIST))]
14439   "TARGET_USE_FANCY_MATH_387
14440    && can_create_pseudo_p ()"
14441   "#"
14442   "&& 1"
14443   [(const_int 0)]
14444 {
14445   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14446   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14447                                         operands[2]));
14448   DONE;
14449 }
14450   [(set_attr "type" "fpspc")
14451    (set_attr "mode" "<MODE>")])
14452
14453 (define_insn "fist<mode>2"
14454   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14455         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14456                       UNSPEC_FIST))]
14457   "TARGET_USE_FANCY_MATH_387"
14458   "* return output_fix_trunc (insn, operands, false);"
14459   [(set_attr "type" "fpspc")
14460    (set_attr "mode" "<MODE>")])
14461
14462 (define_insn "fist<mode>2_with_temp"
14463   [(set (match_operand:SWI24 0 "register_operand" "=r")
14464         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14465                       UNSPEC_FIST))
14466    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14467   "TARGET_USE_FANCY_MATH_387"
14468   "#"
14469   [(set_attr "type" "fpspc")
14470    (set_attr "mode" "<MODE>")])
14471
14472 (define_split
14473   [(set (match_operand:SWI24 0 "register_operand" "")
14474         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14475                       UNSPEC_FIST))
14476    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14477   "reload_completed"
14478   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14479    (set (match_dup 0) (match_dup 2))])
14480
14481 (define_split
14482   [(set (match_operand:SWI24 0 "memory_operand" "")
14483         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14484                       UNSPEC_FIST))
14485    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14486   "reload_completed"
14487   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14488
14489 (define_expand "lrintxf<mode>2"
14490   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14491      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14492                      UNSPEC_FIST))]
14493   "TARGET_USE_FANCY_MATH_387")
14494
14495 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14496   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14497      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14498                         UNSPEC_FIX_NOTRUNC))]
14499   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14500    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14501
14502 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14503   [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14504    (match_operand:MODEF 1 "register_operand" "")]
14505   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14506    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14507    && !flag_trapping_math && !flag_rounding_math"
14508 {
14509   if (optimize_insn_for_size_p ())
14510     FAIL;
14511   ix86_expand_lround (operand0, operand1);
14512   DONE;
14513 })
14514
14515 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14516 (define_insn_and_split "frndintxf2_floor"
14517   [(set (match_operand:XF 0 "register_operand" "")
14518         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14519          UNSPEC_FRNDINT_FLOOR))
14520    (clobber (reg:CC FLAGS_REG))]
14521   "TARGET_USE_FANCY_MATH_387
14522    && flag_unsafe_math_optimizations
14523    && can_create_pseudo_p ()"
14524   "#"
14525   "&& 1"
14526   [(const_int 0)]
14527 {
14528   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14529
14530   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14531   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14532
14533   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14534                                         operands[2], operands[3]));
14535   DONE;
14536 }
14537   [(set_attr "type" "frndint")
14538    (set_attr "i387_cw" "floor")
14539    (set_attr "mode" "XF")])
14540
14541 (define_insn "frndintxf2_floor_i387"
14542   [(set (match_operand:XF 0 "register_operand" "=f")
14543         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14544          UNSPEC_FRNDINT_FLOOR))
14545    (use (match_operand:HI 2 "memory_operand" "m"))
14546    (use (match_operand:HI 3 "memory_operand" "m"))]
14547   "TARGET_USE_FANCY_MATH_387
14548    && flag_unsafe_math_optimizations"
14549   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14550   [(set_attr "type" "frndint")
14551    (set_attr "i387_cw" "floor")
14552    (set_attr "mode" "XF")])
14553
14554 (define_expand "floorxf2"
14555   [(use (match_operand:XF 0 "register_operand" ""))
14556    (use (match_operand:XF 1 "register_operand" ""))]
14557   "TARGET_USE_FANCY_MATH_387
14558    && flag_unsafe_math_optimizations"
14559 {
14560   if (optimize_insn_for_size_p ())
14561     FAIL;
14562   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14563   DONE;
14564 })
14565
14566 (define_expand "floor<mode>2"
14567   [(use (match_operand:MODEF 0 "register_operand" ""))
14568    (use (match_operand:MODEF 1 "register_operand" ""))]
14569   "(TARGET_USE_FANCY_MATH_387
14570     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14571         || TARGET_MIX_SSE_I387)
14572     && flag_unsafe_math_optimizations)
14573    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14574        && !flag_trapping_math)"
14575 {
14576   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14577       && !flag_trapping_math
14578       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14579     {
14580       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14581         FAIL;
14582       if (TARGET_ROUND)
14583         emit_insn (gen_sse4_1_round<mode>2
14584                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14585       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14586         ix86_expand_floorceil (operand0, operand1, true);
14587       else
14588         ix86_expand_floorceildf_32 (operand0, operand1, true);
14589     }
14590   else
14591     {
14592       rtx op0, op1;
14593
14594       if (optimize_insn_for_size_p ())
14595         FAIL;
14596
14597       op0 = gen_reg_rtx (XFmode);
14598       op1 = gen_reg_rtx (XFmode);
14599       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14600       emit_insn (gen_frndintxf2_floor (op0, op1));
14601
14602       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14603     }
14604   DONE;
14605 })
14606
14607 (define_insn_and_split "*fist<mode>2_floor_1"
14608   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14609         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14610                         UNSPEC_FIST_FLOOR))
14611    (clobber (reg:CC FLAGS_REG))]
14612   "TARGET_USE_FANCY_MATH_387
14613    && flag_unsafe_math_optimizations
14614    && can_create_pseudo_p ()"
14615   "#"
14616   "&& 1"
14617   [(const_int 0)]
14618 {
14619   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14620
14621   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14622   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14623   if (memory_operand (operands[0], VOIDmode))
14624     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14625                                       operands[2], operands[3]));
14626   else
14627     {
14628       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14629       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14630                                                   operands[2], operands[3],
14631                                                   operands[4]));
14632     }
14633   DONE;
14634 }
14635   [(set_attr "type" "fistp")
14636    (set_attr "i387_cw" "floor")
14637    (set_attr "mode" "<MODE>")])
14638
14639 (define_insn "fistdi2_floor"
14640   [(set (match_operand:DI 0 "memory_operand" "=m")
14641         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14642                    UNSPEC_FIST_FLOOR))
14643    (use (match_operand:HI 2 "memory_operand" "m"))
14644    (use (match_operand:HI 3 "memory_operand" "m"))
14645    (clobber (match_scratch:XF 4 "=&1f"))]
14646   "TARGET_USE_FANCY_MATH_387
14647    && flag_unsafe_math_optimizations"
14648   "* return output_fix_trunc (insn, operands, false);"
14649   [(set_attr "type" "fistp")
14650    (set_attr "i387_cw" "floor")
14651    (set_attr "mode" "DI")])
14652
14653 (define_insn "fistdi2_floor_with_temp"
14654   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14655         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14656                    UNSPEC_FIST_FLOOR))
14657    (use (match_operand:HI 2 "memory_operand" "m,m"))
14658    (use (match_operand:HI 3 "memory_operand" "m,m"))
14659    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14660    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14661   "TARGET_USE_FANCY_MATH_387
14662    && flag_unsafe_math_optimizations"
14663   "#"
14664   [(set_attr "type" "fistp")
14665    (set_attr "i387_cw" "floor")
14666    (set_attr "mode" "DI")])
14667
14668 (define_split
14669   [(set (match_operand:DI 0 "register_operand" "")
14670         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14671                    UNSPEC_FIST_FLOOR))
14672    (use (match_operand:HI 2 "memory_operand" ""))
14673    (use (match_operand:HI 3 "memory_operand" ""))
14674    (clobber (match_operand:DI 4 "memory_operand" ""))
14675    (clobber (match_scratch 5 ""))]
14676   "reload_completed"
14677   [(parallel [(set (match_dup 4)
14678                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14679               (use (match_dup 2))
14680               (use (match_dup 3))
14681               (clobber (match_dup 5))])
14682    (set (match_dup 0) (match_dup 4))])
14683
14684 (define_split
14685   [(set (match_operand:DI 0 "memory_operand" "")
14686         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14687                    UNSPEC_FIST_FLOOR))
14688    (use (match_operand:HI 2 "memory_operand" ""))
14689    (use (match_operand:HI 3 "memory_operand" ""))
14690    (clobber (match_operand:DI 4 "memory_operand" ""))
14691    (clobber (match_scratch 5 ""))]
14692   "reload_completed"
14693   [(parallel [(set (match_dup 0)
14694                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14695               (use (match_dup 2))
14696               (use (match_dup 3))
14697               (clobber (match_dup 5))])])
14698
14699 (define_insn "fist<mode>2_floor"
14700   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14701         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14702                       UNSPEC_FIST_FLOOR))
14703    (use (match_operand:HI 2 "memory_operand" "m"))
14704    (use (match_operand:HI 3 "memory_operand" "m"))]
14705   "TARGET_USE_FANCY_MATH_387
14706    && flag_unsafe_math_optimizations"
14707   "* return output_fix_trunc (insn, operands, false);"
14708   [(set_attr "type" "fistp")
14709    (set_attr "i387_cw" "floor")
14710    (set_attr "mode" "<MODE>")])
14711
14712 (define_insn "fist<mode>2_floor_with_temp"
14713   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14714         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14715                       UNSPEC_FIST_FLOOR))
14716    (use (match_operand:HI 2 "memory_operand" "m,m"))
14717    (use (match_operand:HI 3 "memory_operand" "m,m"))
14718    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14719   "TARGET_USE_FANCY_MATH_387
14720    && flag_unsafe_math_optimizations"
14721   "#"
14722   [(set_attr "type" "fistp")
14723    (set_attr "i387_cw" "floor")
14724    (set_attr "mode" "<MODE>")])
14725
14726 (define_split
14727   [(set (match_operand:SWI24 0 "register_operand" "")
14728         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14729                       UNSPEC_FIST_FLOOR))
14730    (use (match_operand:HI 2 "memory_operand" ""))
14731    (use (match_operand:HI 3 "memory_operand" ""))
14732    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14733   "reload_completed"
14734   [(parallel [(set (match_dup 4)
14735                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14736               (use (match_dup 2))
14737               (use (match_dup 3))])
14738    (set (match_dup 0) (match_dup 4))])
14739
14740 (define_split
14741   [(set (match_operand:SWI24 0 "memory_operand" "")
14742         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14743                       UNSPEC_FIST_FLOOR))
14744    (use (match_operand:HI 2 "memory_operand" ""))
14745    (use (match_operand:HI 3 "memory_operand" ""))
14746    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14747   "reload_completed"
14748   [(parallel [(set (match_dup 0)
14749                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14750               (use (match_dup 2))
14751               (use (match_dup 3))])])
14752
14753 (define_expand "lfloorxf<mode>2"
14754   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14755                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14756                                    UNSPEC_FIST_FLOOR))
14757               (clobber (reg:CC FLAGS_REG))])]
14758   "TARGET_USE_FANCY_MATH_387
14759    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14760    && flag_unsafe_math_optimizations")
14761
14762 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14763   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14764    (match_operand:MODEF 1 "register_operand" "")]
14765   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14766    && !flag_trapping_math"
14767 {
14768   if (TARGET_64BIT && optimize_insn_for_size_p ())
14769     FAIL;
14770   ix86_expand_lfloorceil (operand0, operand1, true);
14771   DONE;
14772 })
14773
14774 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14775 (define_insn_and_split "frndintxf2_ceil"
14776   [(set (match_operand:XF 0 "register_operand" "")
14777         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14778          UNSPEC_FRNDINT_CEIL))
14779    (clobber (reg:CC FLAGS_REG))]
14780   "TARGET_USE_FANCY_MATH_387
14781    && flag_unsafe_math_optimizations
14782    && can_create_pseudo_p ()"
14783   "#"
14784   "&& 1"
14785   [(const_int 0)]
14786 {
14787   ix86_optimize_mode_switching[I387_CEIL] = 1;
14788
14789   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14790   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14791
14792   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14793                                        operands[2], operands[3]));
14794   DONE;
14795 }
14796   [(set_attr "type" "frndint")
14797    (set_attr "i387_cw" "ceil")
14798    (set_attr "mode" "XF")])
14799
14800 (define_insn "frndintxf2_ceil_i387"
14801   [(set (match_operand:XF 0 "register_operand" "=f")
14802         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14803          UNSPEC_FRNDINT_CEIL))
14804    (use (match_operand:HI 2 "memory_operand" "m"))
14805    (use (match_operand:HI 3 "memory_operand" "m"))]
14806   "TARGET_USE_FANCY_MATH_387
14807    && flag_unsafe_math_optimizations"
14808   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14809   [(set_attr "type" "frndint")
14810    (set_attr "i387_cw" "ceil")
14811    (set_attr "mode" "XF")])
14812
14813 (define_expand "ceilxf2"
14814   [(use (match_operand:XF 0 "register_operand" ""))
14815    (use (match_operand:XF 1 "register_operand" ""))]
14816   "TARGET_USE_FANCY_MATH_387
14817    && flag_unsafe_math_optimizations"
14818 {
14819   if (optimize_insn_for_size_p ())
14820     FAIL;
14821   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14822   DONE;
14823 })
14824
14825 (define_expand "ceil<mode>2"
14826   [(use (match_operand:MODEF 0 "register_operand" ""))
14827    (use (match_operand:MODEF 1 "register_operand" ""))]
14828   "(TARGET_USE_FANCY_MATH_387
14829     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14830         || TARGET_MIX_SSE_I387)
14831     && flag_unsafe_math_optimizations)
14832    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14833        && !flag_trapping_math)"
14834 {
14835   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14836       && !flag_trapping_math
14837       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14838     {
14839       if (TARGET_ROUND)
14840         emit_insn (gen_sse4_1_round<mode>2
14841                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14842       else if (optimize_insn_for_size_p ())
14843         FAIL;
14844       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14845         ix86_expand_floorceil (operand0, operand1, false);
14846       else
14847         ix86_expand_floorceildf_32 (operand0, operand1, false);
14848     }
14849   else
14850     {
14851       rtx op0, op1;
14852
14853       if (optimize_insn_for_size_p ())
14854         FAIL;
14855
14856       op0 = gen_reg_rtx (XFmode);
14857       op1 = gen_reg_rtx (XFmode);
14858       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14859       emit_insn (gen_frndintxf2_ceil (op0, op1));
14860
14861       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14862     }
14863   DONE;
14864 })
14865
14866 (define_insn_and_split "*fist<mode>2_ceil_1"
14867   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14868         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14869                         UNSPEC_FIST_CEIL))
14870    (clobber (reg:CC FLAGS_REG))]
14871   "TARGET_USE_FANCY_MATH_387
14872    && flag_unsafe_math_optimizations
14873    && can_create_pseudo_p ()"
14874   "#"
14875   "&& 1"
14876   [(const_int 0)]
14877 {
14878   ix86_optimize_mode_switching[I387_CEIL] = 1;
14879
14880   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14881   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14882   if (memory_operand (operands[0], VOIDmode))
14883     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14884                                      operands[2], operands[3]));
14885   else
14886     {
14887       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14888       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14889                                                  operands[2], operands[3],
14890                                                  operands[4]));
14891     }
14892   DONE;
14893 }
14894   [(set_attr "type" "fistp")
14895    (set_attr "i387_cw" "ceil")
14896    (set_attr "mode" "<MODE>")])
14897
14898 (define_insn "fistdi2_ceil"
14899   [(set (match_operand:DI 0 "memory_operand" "=m")
14900         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14901                    UNSPEC_FIST_CEIL))
14902    (use (match_operand:HI 2 "memory_operand" "m"))
14903    (use (match_operand:HI 3 "memory_operand" "m"))
14904    (clobber (match_scratch:XF 4 "=&1f"))]
14905   "TARGET_USE_FANCY_MATH_387
14906    && flag_unsafe_math_optimizations"
14907   "* return output_fix_trunc (insn, operands, false);"
14908   [(set_attr "type" "fistp")
14909    (set_attr "i387_cw" "ceil")
14910    (set_attr "mode" "DI")])
14911
14912 (define_insn "fistdi2_ceil_with_temp"
14913   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14914         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14915                    UNSPEC_FIST_CEIL))
14916    (use (match_operand:HI 2 "memory_operand" "m,m"))
14917    (use (match_operand:HI 3 "memory_operand" "m,m"))
14918    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14919    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14920   "TARGET_USE_FANCY_MATH_387
14921    && flag_unsafe_math_optimizations"
14922   "#"
14923   [(set_attr "type" "fistp")
14924    (set_attr "i387_cw" "ceil")
14925    (set_attr "mode" "DI")])
14926
14927 (define_split
14928   [(set (match_operand:DI 0 "register_operand" "")
14929         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14930                    UNSPEC_FIST_CEIL))
14931    (use (match_operand:HI 2 "memory_operand" ""))
14932    (use (match_operand:HI 3 "memory_operand" ""))
14933    (clobber (match_operand:DI 4 "memory_operand" ""))
14934    (clobber (match_scratch 5 ""))]
14935   "reload_completed"
14936   [(parallel [(set (match_dup 4)
14937                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14938               (use (match_dup 2))
14939               (use (match_dup 3))
14940               (clobber (match_dup 5))])
14941    (set (match_dup 0) (match_dup 4))])
14942
14943 (define_split
14944   [(set (match_operand:DI 0 "memory_operand" "")
14945         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14946                    UNSPEC_FIST_CEIL))
14947    (use (match_operand:HI 2 "memory_operand" ""))
14948    (use (match_operand:HI 3 "memory_operand" ""))
14949    (clobber (match_operand:DI 4 "memory_operand" ""))
14950    (clobber (match_scratch 5 ""))]
14951   "reload_completed"
14952   [(parallel [(set (match_dup 0)
14953                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14954               (use (match_dup 2))
14955               (use (match_dup 3))
14956               (clobber (match_dup 5))])])
14957
14958 (define_insn "fist<mode>2_ceil"
14959   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14960         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14961                       UNSPEC_FIST_CEIL))
14962    (use (match_operand:HI 2 "memory_operand" "m"))
14963    (use (match_operand:HI 3 "memory_operand" "m"))]
14964   "TARGET_USE_FANCY_MATH_387
14965    && flag_unsafe_math_optimizations"
14966   "* return output_fix_trunc (insn, operands, false);"
14967   [(set_attr "type" "fistp")
14968    (set_attr "i387_cw" "ceil")
14969    (set_attr "mode" "<MODE>")])
14970
14971 (define_insn "fist<mode>2_ceil_with_temp"
14972   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14973         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14974                       UNSPEC_FIST_CEIL))
14975    (use (match_operand:HI 2 "memory_operand" "m,m"))
14976    (use (match_operand:HI 3 "memory_operand" "m,m"))
14977    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14978   "TARGET_USE_FANCY_MATH_387
14979    && flag_unsafe_math_optimizations"
14980   "#"
14981   [(set_attr "type" "fistp")
14982    (set_attr "i387_cw" "ceil")
14983    (set_attr "mode" "<MODE>")])
14984
14985 (define_split
14986   [(set (match_operand:SWI24 0 "register_operand" "")
14987         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14988                       UNSPEC_FIST_CEIL))
14989    (use (match_operand:HI 2 "memory_operand" ""))
14990    (use (match_operand:HI 3 "memory_operand" ""))
14991    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14992   "reload_completed"
14993   [(parallel [(set (match_dup 4)
14994                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
14995               (use (match_dup 2))
14996               (use (match_dup 3))])
14997    (set (match_dup 0) (match_dup 4))])
14998
14999 (define_split
15000   [(set (match_operand:SWI24 0 "memory_operand" "")
15001         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15002                       UNSPEC_FIST_CEIL))
15003    (use (match_operand:HI 2 "memory_operand" ""))
15004    (use (match_operand:HI 3 "memory_operand" ""))
15005    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15006   "reload_completed"
15007   [(parallel [(set (match_dup 0)
15008                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15009               (use (match_dup 2))
15010               (use (match_dup 3))])])
15011
15012 (define_expand "lceilxf<mode>2"
15013   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15014                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15015                                    UNSPEC_FIST_CEIL))
15016               (clobber (reg:CC FLAGS_REG))])]
15017   "TARGET_USE_FANCY_MATH_387
15018    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15019    && flag_unsafe_math_optimizations")
15020
15021 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15022   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15023    (match_operand:MODEF 1 "register_operand" "")]
15024   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15025    && !flag_trapping_math"
15026 {
15027   ix86_expand_lfloorceil (operand0, operand1, false);
15028   DONE;
15029 })
15030
15031 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15032 (define_insn_and_split "frndintxf2_trunc"
15033   [(set (match_operand:XF 0 "register_operand" "")
15034         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15035          UNSPEC_FRNDINT_TRUNC))
15036    (clobber (reg:CC FLAGS_REG))]
15037   "TARGET_USE_FANCY_MATH_387
15038    && flag_unsafe_math_optimizations
15039    && can_create_pseudo_p ()"
15040   "#"
15041   "&& 1"
15042   [(const_int 0)]
15043 {
15044   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15045
15046   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15047   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15048
15049   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15050                                         operands[2], operands[3]));
15051   DONE;
15052 }
15053   [(set_attr "type" "frndint")
15054    (set_attr "i387_cw" "trunc")
15055    (set_attr "mode" "XF")])
15056
15057 (define_insn "frndintxf2_trunc_i387"
15058   [(set (match_operand:XF 0 "register_operand" "=f")
15059         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15060          UNSPEC_FRNDINT_TRUNC))
15061    (use (match_operand:HI 2 "memory_operand" "m"))
15062    (use (match_operand:HI 3 "memory_operand" "m"))]
15063   "TARGET_USE_FANCY_MATH_387
15064    && flag_unsafe_math_optimizations"
15065   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15066   [(set_attr "type" "frndint")
15067    (set_attr "i387_cw" "trunc")
15068    (set_attr "mode" "XF")])
15069
15070 (define_expand "btruncxf2"
15071   [(use (match_operand:XF 0 "register_operand" ""))
15072    (use (match_operand:XF 1 "register_operand" ""))]
15073   "TARGET_USE_FANCY_MATH_387
15074    && flag_unsafe_math_optimizations"
15075 {
15076   if (optimize_insn_for_size_p ())
15077     FAIL;
15078   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15079   DONE;
15080 })
15081
15082 (define_expand "btrunc<mode>2"
15083   [(use (match_operand:MODEF 0 "register_operand" ""))
15084    (use (match_operand:MODEF 1 "register_operand" ""))]
15085   "(TARGET_USE_FANCY_MATH_387
15086     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15087         || TARGET_MIX_SSE_I387)
15088     && flag_unsafe_math_optimizations)
15089    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15090        && !flag_trapping_math)"
15091 {
15092   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15093       && !flag_trapping_math
15094       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15095     {
15096       if (TARGET_ROUND)
15097         emit_insn (gen_sse4_1_round<mode>2
15098                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15099       else if (optimize_insn_for_size_p ())
15100         FAIL;
15101       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15102         ix86_expand_trunc (operand0, operand1);
15103       else
15104         ix86_expand_truncdf_32 (operand0, operand1);
15105     }
15106   else
15107     {
15108       rtx op0, op1;
15109
15110       if (optimize_insn_for_size_p ())
15111         FAIL;
15112
15113       op0 = gen_reg_rtx (XFmode);
15114       op1 = gen_reg_rtx (XFmode);
15115       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15116       emit_insn (gen_frndintxf2_trunc (op0, op1));
15117
15118       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15119     }
15120   DONE;
15121 })
15122
15123 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15124 (define_insn_and_split "frndintxf2_mask_pm"
15125   [(set (match_operand:XF 0 "register_operand" "")
15126         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15127          UNSPEC_FRNDINT_MASK_PM))
15128    (clobber (reg:CC FLAGS_REG))]
15129   "TARGET_USE_FANCY_MATH_387
15130    && flag_unsafe_math_optimizations
15131    && can_create_pseudo_p ()"
15132   "#"
15133   "&& 1"
15134   [(const_int 0)]
15135 {
15136   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15137
15138   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15139   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15140
15141   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15142                                           operands[2], operands[3]));
15143   DONE;
15144 }
15145   [(set_attr "type" "frndint")
15146    (set_attr "i387_cw" "mask_pm")
15147    (set_attr "mode" "XF")])
15148
15149 (define_insn "frndintxf2_mask_pm_i387"
15150   [(set (match_operand:XF 0 "register_operand" "=f")
15151         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15152          UNSPEC_FRNDINT_MASK_PM))
15153    (use (match_operand:HI 2 "memory_operand" "m"))
15154    (use (match_operand:HI 3 "memory_operand" "m"))]
15155   "TARGET_USE_FANCY_MATH_387
15156    && flag_unsafe_math_optimizations"
15157   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15158   [(set_attr "type" "frndint")
15159    (set_attr "i387_cw" "mask_pm")
15160    (set_attr "mode" "XF")])
15161
15162 (define_expand "nearbyintxf2"
15163   [(use (match_operand:XF 0 "register_operand" ""))
15164    (use (match_operand:XF 1 "register_operand" ""))]
15165   "TARGET_USE_FANCY_MATH_387
15166    && flag_unsafe_math_optimizations"
15167 {
15168   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15169   DONE;
15170 })
15171
15172 (define_expand "nearbyint<mode>2"
15173   [(use (match_operand:MODEF 0 "register_operand" ""))
15174    (use (match_operand:MODEF 1 "register_operand" ""))]
15175   "TARGET_USE_FANCY_MATH_387
15176    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15177        || TARGET_MIX_SSE_I387)
15178    && flag_unsafe_math_optimizations"
15179 {
15180   rtx op0 = gen_reg_rtx (XFmode);
15181   rtx op1 = gen_reg_rtx (XFmode);
15182
15183   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15184   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15185
15186   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15187   DONE;
15188 })
15189
15190 (define_insn "fxam<mode>2_i387"
15191   [(set (match_operand:HI 0 "register_operand" "=a")
15192         (unspec:HI
15193           [(match_operand:X87MODEF 1 "register_operand" "f")]
15194           UNSPEC_FXAM))]
15195   "TARGET_USE_FANCY_MATH_387"
15196   "fxam\n\tfnstsw\t%0"
15197   [(set_attr "type" "multi")
15198    (set_attr "length" "4")
15199    (set_attr "unit" "i387")
15200    (set_attr "mode" "<MODE>")])
15201
15202 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15203   [(set (match_operand:HI 0 "register_operand" "")
15204         (unspec:HI
15205           [(match_operand:MODEF 1 "memory_operand" "")]
15206           UNSPEC_FXAM_MEM))]
15207   "TARGET_USE_FANCY_MATH_387
15208    && can_create_pseudo_p ()"
15209   "#"
15210   "&& 1"
15211   [(set (match_dup 2)(match_dup 1))
15212    (set (match_dup 0)
15213         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15214 {
15215   operands[2] = gen_reg_rtx (<MODE>mode);
15216
15217   MEM_VOLATILE_P (operands[1]) = 1;
15218 }
15219   [(set_attr "type" "multi")
15220    (set_attr "unit" "i387")
15221    (set_attr "mode" "<MODE>")])
15222
15223 (define_expand "isinfxf2"
15224   [(use (match_operand:SI 0 "register_operand" ""))
15225    (use (match_operand:XF 1 "register_operand" ""))]
15226   "TARGET_USE_FANCY_MATH_387
15227    && TARGET_C99_FUNCTIONS"
15228 {
15229   rtx mask = GEN_INT (0x45);
15230   rtx val = GEN_INT (0x05);
15231
15232   rtx cond;
15233
15234   rtx scratch = gen_reg_rtx (HImode);
15235   rtx res = gen_reg_rtx (QImode);
15236
15237   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15238
15239   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15240   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15241   cond = gen_rtx_fmt_ee (EQ, QImode,
15242                          gen_rtx_REG (CCmode, FLAGS_REG),
15243                          const0_rtx);
15244   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15245   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15246   DONE;
15247 })
15248
15249 (define_expand "isinf<mode>2"
15250   [(use (match_operand:SI 0 "register_operand" ""))
15251    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15252   "TARGET_USE_FANCY_MATH_387
15253    && TARGET_C99_FUNCTIONS
15254    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15255 {
15256   rtx mask = GEN_INT (0x45);
15257   rtx val = GEN_INT (0x05);
15258
15259   rtx cond;
15260
15261   rtx scratch = gen_reg_rtx (HImode);
15262   rtx res = gen_reg_rtx (QImode);
15263
15264   /* Remove excess precision by forcing value through memory. */
15265   if (memory_operand (operands[1], VOIDmode))
15266     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15267   else
15268     {
15269       enum ix86_stack_slot slot = (virtuals_instantiated
15270                                    ? SLOT_TEMP
15271                                    : SLOT_VIRTUAL);
15272       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15273
15274       emit_move_insn (temp, operands[1]);
15275       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15276     }
15277
15278   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15279   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15280   cond = gen_rtx_fmt_ee (EQ, QImode,
15281                          gen_rtx_REG (CCmode, FLAGS_REG),
15282                          const0_rtx);
15283   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15284   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15285   DONE;
15286 })
15287
15288 (define_expand "signbitxf2"
15289   [(use (match_operand:SI 0 "register_operand" ""))
15290    (use (match_operand:XF 1 "register_operand" ""))]
15291   "TARGET_USE_FANCY_MATH_387"
15292 {
15293   rtx scratch = gen_reg_rtx (HImode);
15294
15295   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15296   emit_insn (gen_andsi3 (operands[0],
15297              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15298   DONE;
15299 })
15300
15301 (define_insn "movmsk_df"
15302   [(set (match_operand:SI 0 "register_operand" "=r")
15303         (unspec:SI
15304           [(match_operand:DF 1 "register_operand" "x")]
15305           UNSPEC_MOVMSK))]
15306   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15307   "%vmovmskpd\t{%1, %0|%0, %1}"
15308   [(set_attr "type" "ssemov")
15309    (set_attr "prefix" "maybe_vex")
15310    (set_attr "mode" "DF")])
15311
15312 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15313 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15314 (define_expand "signbitdf2"
15315   [(use (match_operand:SI 0 "register_operand" ""))
15316    (use (match_operand:DF 1 "register_operand" ""))]
15317   "TARGET_USE_FANCY_MATH_387
15318    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15319 {
15320   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15321     {
15322       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15323       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15324     }
15325   else
15326     {
15327       rtx scratch = gen_reg_rtx (HImode);
15328
15329       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15330       emit_insn (gen_andsi3 (operands[0],
15331                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15332     }
15333   DONE;
15334 })
15335
15336 (define_expand "signbitsf2"
15337   [(use (match_operand:SI 0 "register_operand" ""))
15338    (use (match_operand:SF 1 "register_operand" ""))]
15339   "TARGET_USE_FANCY_MATH_387
15340    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15341 {
15342   rtx scratch = gen_reg_rtx (HImode);
15343
15344   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15345   emit_insn (gen_andsi3 (operands[0],
15346              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15347   DONE;
15348 })
15349 \f
15350 ;; Block operation instructions
15351
15352 (define_insn "cld"
15353   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15354   ""
15355   "cld"
15356   [(set_attr "length" "1")
15357    (set_attr "length_immediate" "0")
15358    (set_attr "modrm" "0")])
15359
15360 (define_expand "movmem<mode>"
15361   [(use (match_operand:BLK 0 "memory_operand" ""))
15362    (use (match_operand:BLK 1 "memory_operand" ""))
15363    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15364    (use (match_operand:SWI48 3 "const_int_operand" ""))
15365    (use (match_operand:SI 4 "const_int_operand" ""))
15366    (use (match_operand:SI 5 "const_int_operand" ""))]
15367   ""
15368 {
15369  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15370                          operands[4], operands[5]))
15371    DONE;
15372  else
15373    FAIL;
15374 })
15375
15376 ;; Most CPUs don't like single string operations
15377 ;; Handle this case here to simplify previous expander.
15378
15379 (define_expand "strmov"
15380   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15381    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15382    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15383               (clobber (reg:CC FLAGS_REG))])
15384    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15385               (clobber (reg:CC FLAGS_REG))])]
15386   ""
15387 {
15388   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15389
15390   /* If .md ever supports :P for Pmode, these can be directly
15391      in the pattern above.  */
15392   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15393   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15394
15395   /* Can't use this if the user has appropriated esi or edi.  */
15396   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15397       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15398     {
15399       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15400                                       operands[2], operands[3],
15401                                       operands[5], operands[6]));
15402       DONE;
15403     }
15404
15405   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15406 })
15407
15408 (define_expand "strmov_singleop"
15409   [(parallel [(set (match_operand 1 "memory_operand" "")
15410                    (match_operand 3 "memory_operand" ""))
15411               (set (match_operand 0 "register_operand" "")
15412                    (match_operand 4 "" ""))
15413               (set (match_operand 2 "register_operand" "")
15414                    (match_operand 5 "" ""))])]
15415   ""
15416   "ix86_current_function_needs_cld = 1;")
15417
15418 (define_insn "*strmovdi_rex_1"
15419   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15420         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15421    (set (match_operand:DI 0 "register_operand" "=D")
15422         (plus:DI (match_dup 2)
15423                  (const_int 8)))
15424    (set (match_operand:DI 1 "register_operand" "=S")
15425         (plus:DI (match_dup 3)
15426                  (const_int 8)))]
15427   "TARGET_64BIT"
15428   "movsq"
15429   [(set_attr "type" "str")
15430    (set_attr "memory" "both")
15431    (set_attr "mode" "DI")])
15432
15433 (define_insn "*strmovsi_1"
15434   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15435         (mem:SI (match_operand:P 3 "register_operand" "1")))
15436    (set (match_operand:P 0 "register_operand" "=D")
15437         (plus:P (match_dup 2)
15438                 (const_int 4)))
15439    (set (match_operand:P 1 "register_operand" "=S")
15440         (plus:P (match_dup 3)
15441                 (const_int 4)))]
15442   ""
15443   "movs{l|d}"
15444   [(set_attr "type" "str")
15445    (set_attr "memory" "both")
15446    (set_attr "mode" "SI")])
15447
15448 (define_insn "*strmovhi_1"
15449   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15450         (mem:HI (match_operand:P 3 "register_operand" "1")))
15451    (set (match_operand:P 0 "register_operand" "=D")
15452         (plus:P (match_dup 2)
15453                 (const_int 2)))
15454    (set (match_operand:P 1 "register_operand" "=S")
15455         (plus:P (match_dup 3)
15456                 (const_int 2)))]
15457   ""
15458   "movsw"
15459   [(set_attr "type" "str")
15460    (set_attr "memory" "both")
15461    (set_attr "mode" "HI")])
15462
15463 (define_insn "*strmovqi_1"
15464   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15465         (mem:QI (match_operand:P 3 "register_operand" "1")))
15466    (set (match_operand:P 0 "register_operand" "=D")
15467         (plus:P (match_dup 2)
15468                 (const_int 1)))
15469    (set (match_operand:P 1 "register_operand" "=S")
15470         (plus:P (match_dup 3)
15471                 (const_int 1)))]
15472   ""
15473   "movsb"
15474   [(set_attr "type" "str")
15475    (set_attr "memory" "both")
15476    (set (attr "prefix_rex")
15477         (if_then_else
15478           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15479           (const_string "0")
15480           (const_string "*")))
15481    (set_attr "mode" "QI")])
15482
15483 (define_expand "rep_mov"
15484   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15485               (set (match_operand 0 "register_operand" "")
15486                    (match_operand 5 "" ""))
15487               (set (match_operand 2 "register_operand" "")
15488                    (match_operand 6 "" ""))
15489               (set (match_operand 1 "memory_operand" "")
15490                    (match_operand 3 "memory_operand" ""))
15491               (use (match_dup 4))])]
15492   ""
15493   "ix86_current_function_needs_cld = 1;")
15494
15495 (define_insn "*rep_movdi_rex64"
15496   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15497    (set (match_operand:DI 0 "register_operand" "=D")
15498         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15499                             (const_int 3))
15500                  (match_operand:DI 3 "register_operand" "0")))
15501    (set (match_operand:DI 1 "register_operand" "=S")
15502         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15503                  (match_operand:DI 4 "register_operand" "1")))
15504    (set (mem:BLK (match_dup 3))
15505         (mem:BLK (match_dup 4)))
15506    (use (match_dup 5))]
15507   "TARGET_64BIT"
15508   "rep{%;} movsq"
15509   [(set_attr "type" "str")
15510    (set_attr "prefix_rep" "1")
15511    (set_attr "memory" "both")
15512    (set_attr "mode" "DI")])
15513
15514 (define_insn "*rep_movsi"
15515   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15516    (set (match_operand:P 0 "register_operand" "=D")
15517         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15518                           (const_int 2))
15519                  (match_operand:P 3 "register_operand" "0")))
15520    (set (match_operand:P 1 "register_operand" "=S")
15521         (plus:P (ashift:P (match_dup 5) (const_int 2))
15522                 (match_operand:P 4 "register_operand" "1")))
15523    (set (mem:BLK (match_dup 3))
15524         (mem:BLK (match_dup 4)))
15525    (use (match_dup 5))]
15526   ""
15527   "rep{%;} movs{l|d}"
15528   [(set_attr "type" "str")
15529    (set_attr "prefix_rep" "1")
15530    (set_attr "memory" "both")
15531    (set_attr "mode" "SI")])
15532
15533 (define_insn "*rep_movqi"
15534   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15535    (set (match_operand:P 0 "register_operand" "=D")
15536         (plus:P (match_operand:P 3 "register_operand" "0")
15537                 (match_operand:P 5 "register_operand" "2")))
15538    (set (match_operand:P 1 "register_operand" "=S")
15539         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15540    (set (mem:BLK (match_dup 3))
15541         (mem:BLK (match_dup 4)))
15542    (use (match_dup 5))]
15543   ""
15544   "rep{%;} movsb"
15545   [(set_attr "type" "str")
15546    (set_attr "prefix_rep" "1")
15547    (set_attr "memory" "both")
15548    (set_attr "mode" "QI")])
15549
15550 (define_expand "setmem<mode>"
15551    [(use (match_operand:BLK 0 "memory_operand" ""))
15552     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15553     (use (match_operand:QI 2 "nonmemory_operand" ""))
15554     (use (match_operand 3 "const_int_operand" ""))
15555     (use (match_operand:SI 4 "const_int_operand" ""))
15556     (use (match_operand:SI 5 "const_int_operand" ""))]
15557   ""
15558 {
15559  if (ix86_expand_setmem (operands[0], operands[1],
15560                          operands[2], operands[3],
15561                          operands[4], operands[5]))
15562    DONE;
15563  else
15564    FAIL;
15565 })
15566
15567 ;; Most CPUs don't like single string operations
15568 ;; Handle this case here to simplify previous expander.
15569
15570 (define_expand "strset"
15571   [(set (match_operand 1 "memory_operand" "")
15572         (match_operand 2 "register_operand" ""))
15573    (parallel [(set (match_operand 0 "register_operand" "")
15574                    (match_dup 3))
15575               (clobber (reg:CC FLAGS_REG))])]
15576   ""
15577 {
15578   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15579     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15580
15581   /* If .md ever supports :P for Pmode, this can be directly
15582      in the pattern above.  */
15583   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15584                               GEN_INT (GET_MODE_SIZE (GET_MODE
15585                                                       (operands[2]))));
15586   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15587     {
15588       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15589                                       operands[3]));
15590       DONE;
15591     }
15592 })
15593
15594 (define_expand "strset_singleop"
15595   [(parallel [(set (match_operand 1 "memory_operand" "")
15596                    (match_operand 2 "register_operand" ""))
15597               (set (match_operand 0 "register_operand" "")
15598                    (match_operand 3 "" ""))])]
15599   ""
15600   "ix86_current_function_needs_cld = 1;")
15601
15602 (define_insn "*strsetdi_rex_1"
15603   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15604         (match_operand:DI 2 "register_operand" "a"))
15605    (set (match_operand:DI 0 "register_operand" "=D")
15606         (plus:DI (match_dup 1)
15607                  (const_int 8)))]
15608   "TARGET_64BIT"
15609   "stosq"
15610   [(set_attr "type" "str")
15611    (set_attr "memory" "store")
15612    (set_attr "mode" "DI")])
15613
15614 (define_insn "*strsetsi_1"
15615   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15616         (match_operand:SI 2 "register_operand" "a"))
15617    (set (match_operand:P 0 "register_operand" "=D")
15618         (plus:P (match_dup 1)
15619                 (const_int 4)))]
15620   ""
15621   "stos{l|d}"
15622   [(set_attr "type" "str")
15623    (set_attr "memory" "store")
15624    (set_attr "mode" "SI")])
15625
15626 (define_insn "*strsethi_1"
15627   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15628         (match_operand:HI 2 "register_operand" "a"))
15629    (set (match_operand:P 0 "register_operand" "=D")
15630         (plus:P (match_dup 1)
15631                 (const_int 2)))]
15632   ""
15633   "stosw"
15634   [(set_attr "type" "str")
15635    (set_attr "memory" "store")
15636    (set_attr "mode" "HI")])
15637
15638 (define_insn "*strsetqi_1"
15639   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15640         (match_operand:QI 2 "register_operand" "a"))
15641    (set (match_operand:P 0 "register_operand" "=D")
15642         (plus:P (match_dup 1)
15643                 (const_int 1)))]
15644   ""
15645   "stosb"
15646   [(set_attr "type" "str")
15647    (set_attr "memory" "store")
15648    (set (attr "prefix_rex")
15649         (if_then_else
15650           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15651           (const_string "0")
15652           (const_string "*")))
15653    (set_attr "mode" "QI")])
15654
15655 (define_expand "rep_stos"
15656   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15657               (set (match_operand 0 "register_operand" "")
15658                    (match_operand 4 "" ""))
15659               (set (match_operand 2 "memory_operand" "") (const_int 0))
15660               (use (match_operand 3 "register_operand" ""))
15661               (use (match_dup 1))])]
15662   ""
15663   "ix86_current_function_needs_cld = 1;")
15664
15665 (define_insn "*rep_stosdi_rex64"
15666   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15667    (set (match_operand:DI 0 "register_operand" "=D")
15668         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15669                             (const_int 3))
15670                  (match_operand:DI 3 "register_operand" "0")))
15671    (set (mem:BLK (match_dup 3))
15672         (const_int 0))
15673    (use (match_operand:DI 2 "register_operand" "a"))
15674    (use (match_dup 4))]
15675   "TARGET_64BIT"
15676   "rep{%;} stosq"
15677   [(set_attr "type" "str")
15678    (set_attr "prefix_rep" "1")
15679    (set_attr "memory" "store")
15680    (set_attr "mode" "DI")])
15681
15682 (define_insn "*rep_stossi"
15683   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15684    (set (match_operand:P 0 "register_operand" "=D")
15685         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15686                           (const_int 2))
15687                  (match_operand:P 3 "register_operand" "0")))
15688    (set (mem:BLK (match_dup 3))
15689         (const_int 0))
15690    (use (match_operand:SI 2 "register_operand" "a"))
15691    (use (match_dup 4))]
15692   ""
15693   "rep{%;} stos{l|d}"
15694   [(set_attr "type" "str")
15695    (set_attr "prefix_rep" "1")
15696    (set_attr "memory" "store")
15697    (set_attr "mode" "SI")])
15698
15699 (define_insn "*rep_stosqi"
15700   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15701    (set (match_operand:P 0 "register_operand" "=D")
15702         (plus:P (match_operand:P 3 "register_operand" "0")
15703                 (match_operand:P 4 "register_operand" "1")))
15704    (set (mem:BLK (match_dup 3))
15705         (const_int 0))
15706    (use (match_operand:QI 2 "register_operand" "a"))
15707    (use (match_dup 4))]
15708   ""
15709   "rep{%;} stosb"
15710   [(set_attr "type" "str")
15711    (set_attr "prefix_rep" "1")
15712    (set_attr "memory" "store")
15713    (set (attr "prefix_rex")
15714         (if_then_else
15715           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15716           (const_string "0")
15717           (const_string "*")))
15718    (set_attr "mode" "QI")])
15719
15720 (define_expand "cmpstrnsi"
15721   [(set (match_operand:SI 0 "register_operand" "")
15722         (compare:SI (match_operand:BLK 1 "general_operand" "")
15723                     (match_operand:BLK 2 "general_operand" "")))
15724    (use (match_operand 3 "general_operand" ""))
15725    (use (match_operand 4 "immediate_operand" ""))]
15726   ""
15727 {
15728   rtx addr1, addr2, out, outlow, count, countreg, align;
15729
15730   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15731     FAIL;
15732
15733   /* Can't use this if the user has appropriated esi or edi.  */
15734   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15735     FAIL;
15736
15737   out = operands[0];
15738   if (!REG_P (out))
15739     out = gen_reg_rtx (SImode);
15740
15741   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15742   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15743   if (addr1 != XEXP (operands[1], 0))
15744     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15745   if (addr2 != XEXP (operands[2], 0))
15746     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15747
15748   count = operands[3];
15749   countreg = ix86_zero_extend_to_Pmode (count);
15750
15751   /* %%% Iff we are testing strict equality, we can use known alignment
15752      to good advantage.  This may be possible with combine, particularly
15753      once cc0 is dead.  */
15754   align = operands[4];
15755
15756   if (CONST_INT_P (count))
15757     {
15758       if (INTVAL (count) == 0)
15759         {
15760           emit_move_insn (operands[0], const0_rtx);
15761           DONE;
15762         }
15763       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15764                                      operands[1], operands[2]));
15765     }
15766   else
15767     {
15768       rtx (*gen_cmp) (rtx, rtx);
15769
15770       gen_cmp = (TARGET_64BIT
15771                  ? gen_cmpdi_1 : gen_cmpsi_1);
15772
15773       emit_insn (gen_cmp (countreg, countreg));
15774       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15775                                   operands[1], operands[2]));
15776     }
15777
15778   outlow = gen_lowpart (QImode, out);
15779   emit_insn (gen_cmpintqi (outlow));
15780   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15781
15782   if (operands[0] != out)
15783     emit_move_insn (operands[0], out);
15784
15785   DONE;
15786 })
15787
15788 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15789
15790 (define_expand "cmpintqi"
15791   [(set (match_dup 1)
15792         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15793    (set (match_dup 2)
15794         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15795    (parallel [(set (match_operand:QI 0 "register_operand" "")
15796                    (minus:QI (match_dup 1)
15797                              (match_dup 2)))
15798               (clobber (reg:CC FLAGS_REG))])]
15799   ""
15800 {
15801   operands[1] = gen_reg_rtx (QImode);
15802   operands[2] = gen_reg_rtx (QImode);
15803 })
15804
15805 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15806 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15807
15808 (define_expand "cmpstrnqi_nz_1"
15809   [(parallel [(set (reg:CC FLAGS_REG)
15810                    (compare:CC (match_operand 4 "memory_operand" "")
15811                                (match_operand 5 "memory_operand" "")))
15812               (use (match_operand 2 "register_operand" ""))
15813               (use (match_operand:SI 3 "immediate_operand" ""))
15814               (clobber (match_operand 0 "register_operand" ""))
15815               (clobber (match_operand 1 "register_operand" ""))
15816               (clobber (match_dup 2))])]
15817   ""
15818   "ix86_current_function_needs_cld = 1;")
15819
15820 (define_insn "*cmpstrnqi_nz_1"
15821   [(set (reg:CC FLAGS_REG)
15822         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15823                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15824    (use (match_operand:P 6 "register_operand" "2"))
15825    (use (match_operand:SI 3 "immediate_operand" "i"))
15826    (clobber (match_operand:P 0 "register_operand" "=S"))
15827    (clobber (match_operand:P 1 "register_operand" "=D"))
15828    (clobber (match_operand:P 2 "register_operand" "=c"))]
15829   ""
15830   "repz{%;} cmpsb"
15831   [(set_attr "type" "str")
15832    (set_attr "mode" "QI")
15833    (set (attr "prefix_rex")
15834         (if_then_else
15835           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15836           (const_string "0")
15837           (const_string "*")))
15838    (set_attr "prefix_rep" "1")])
15839
15840 ;; The same, but the count is not known to not be zero.
15841
15842 (define_expand "cmpstrnqi_1"
15843   [(parallel [(set (reg:CC FLAGS_REG)
15844                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15845                                      (const_int 0))
15846                   (compare:CC (match_operand 4 "memory_operand" "")
15847                               (match_operand 5 "memory_operand" ""))
15848                   (const_int 0)))
15849               (use (match_operand:SI 3 "immediate_operand" ""))
15850               (use (reg:CC FLAGS_REG))
15851               (clobber (match_operand 0 "register_operand" ""))
15852               (clobber (match_operand 1 "register_operand" ""))
15853               (clobber (match_dup 2))])]
15854   ""
15855   "ix86_current_function_needs_cld = 1;")
15856
15857 (define_insn "*cmpstrnqi_1"
15858   [(set (reg:CC FLAGS_REG)
15859         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15860                              (const_int 0))
15861           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15862                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15863           (const_int 0)))
15864    (use (match_operand:SI 3 "immediate_operand" "i"))
15865    (use (reg:CC FLAGS_REG))
15866    (clobber (match_operand:P 0 "register_operand" "=S"))
15867    (clobber (match_operand:P 1 "register_operand" "=D"))
15868    (clobber (match_operand:P 2 "register_operand" "=c"))]
15869   ""
15870   "repz{%;} cmpsb"
15871   [(set_attr "type" "str")
15872    (set_attr "mode" "QI")
15873    (set (attr "prefix_rex")
15874         (if_then_else
15875           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15876           (const_string "0")
15877           (const_string "*")))
15878    (set_attr "prefix_rep" "1")])
15879
15880 (define_expand "strlen<mode>"
15881   [(set (match_operand:SWI48x 0 "register_operand" "")
15882         (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15883                         (match_operand:QI 2 "immediate_operand" "")
15884                         (match_operand 3 "immediate_operand" "")]
15885                        UNSPEC_SCAS))]
15886   ""
15887 {
15888  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15889    DONE;
15890  else
15891    FAIL;
15892 })
15893
15894 (define_expand "strlenqi_1"
15895   [(parallel [(set (match_operand 0 "register_operand" "")
15896                    (match_operand 2 "" ""))
15897               (clobber (match_operand 1 "register_operand" ""))
15898               (clobber (reg:CC FLAGS_REG))])]
15899   ""
15900   "ix86_current_function_needs_cld = 1;")
15901
15902 (define_insn "*strlenqi_1"
15903   [(set (match_operand:P 0 "register_operand" "=&c")
15904         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15905                    (match_operand:QI 2 "register_operand" "a")
15906                    (match_operand:P 3 "immediate_operand" "i")
15907                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15908    (clobber (match_operand:P 1 "register_operand" "=D"))
15909    (clobber (reg:CC FLAGS_REG))]
15910   ""
15911   "repnz{%;} scasb"
15912   [(set_attr "type" "str")
15913    (set_attr "mode" "QI")
15914    (set (attr "prefix_rex")
15915         (if_then_else
15916           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15917           (const_string "0")
15918           (const_string "*")))
15919    (set_attr "prefix_rep" "1")])
15920
15921 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15922 ;; handled in combine, but it is not currently up to the task.
15923 ;; When used for their truth value, the cmpstrn* expanders generate
15924 ;; code like this:
15925 ;;
15926 ;;   repz cmpsb
15927 ;;   seta       %al
15928 ;;   setb       %dl
15929 ;;   cmpb       %al, %dl
15930 ;;   jcc        label
15931 ;;
15932 ;; The intermediate three instructions are unnecessary.
15933
15934 ;; This one handles cmpstrn*_nz_1...
15935 (define_peephole2
15936   [(parallel[
15937      (set (reg:CC FLAGS_REG)
15938           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15939                       (mem:BLK (match_operand 5 "register_operand" ""))))
15940      (use (match_operand 6 "register_operand" ""))
15941      (use (match_operand:SI 3 "immediate_operand" ""))
15942      (clobber (match_operand 0 "register_operand" ""))
15943      (clobber (match_operand 1 "register_operand" ""))
15944      (clobber (match_operand 2 "register_operand" ""))])
15945    (set (match_operand:QI 7 "register_operand" "")
15946         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15947    (set (match_operand:QI 8 "register_operand" "")
15948         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15949    (set (reg FLAGS_REG)
15950         (compare (match_dup 7) (match_dup 8)))
15951   ]
15952   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15953   [(parallel[
15954      (set (reg:CC FLAGS_REG)
15955           (compare:CC (mem:BLK (match_dup 4))
15956                       (mem:BLK (match_dup 5))))
15957      (use (match_dup 6))
15958      (use (match_dup 3))
15959      (clobber (match_dup 0))
15960      (clobber (match_dup 1))
15961      (clobber (match_dup 2))])])
15962
15963 ;; ...and this one handles cmpstrn*_1.
15964 (define_peephole2
15965   [(parallel[
15966      (set (reg:CC FLAGS_REG)
15967           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15968                                (const_int 0))
15969             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15970                         (mem:BLK (match_operand 5 "register_operand" "")))
15971             (const_int 0)))
15972      (use (match_operand:SI 3 "immediate_operand" ""))
15973      (use (reg:CC FLAGS_REG))
15974      (clobber (match_operand 0 "register_operand" ""))
15975      (clobber (match_operand 1 "register_operand" ""))
15976      (clobber (match_operand 2 "register_operand" ""))])
15977    (set (match_operand:QI 7 "register_operand" "")
15978         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15979    (set (match_operand:QI 8 "register_operand" "")
15980         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15981    (set (reg FLAGS_REG)
15982         (compare (match_dup 7) (match_dup 8)))
15983   ]
15984   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15985   [(parallel[
15986      (set (reg:CC FLAGS_REG)
15987           (if_then_else:CC (ne (match_dup 6)
15988                                (const_int 0))
15989             (compare:CC (mem:BLK (match_dup 4))
15990                         (mem:BLK (match_dup 5)))
15991             (const_int 0)))
15992      (use (match_dup 3))
15993      (use (reg:CC FLAGS_REG))
15994      (clobber (match_dup 0))
15995      (clobber (match_dup 1))
15996      (clobber (match_dup 2))])])
15997 \f
15998 ;; Conditional move instructions.
15999
16000 (define_expand "mov<mode>cc"
16001   [(set (match_operand:SWIM 0 "register_operand" "")
16002         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16003                            (match_operand:SWIM 2 "general_operand" "")
16004                            (match_operand:SWIM 3 "general_operand" "")))]
16005   ""
16006   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16007
16008 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16009 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16010 ;; So just document what we're doing explicitly.
16011
16012 (define_expand "x86_mov<mode>cc_0_m1"
16013   [(parallel
16014     [(set (match_operand:SWI48 0 "register_operand" "")
16015           (if_then_else:SWI48
16016             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16017              [(match_operand 1 "flags_reg_operand" "")
16018               (const_int 0)])
16019             (const_int -1)
16020             (const_int 0)))
16021      (clobber (reg:CC FLAGS_REG))])])
16022
16023 (define_insn "*x86_mov<mode>cc_0_m1"
16024   [(set (match_operand:SWI48 0 "register_operand" "=r")
16025         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16026                              [(reg FLAGS_REG) (const_int 0)])
16027           (const_int -1)
16028           (const_int 0)))
16029    (clobber (reg:CC FLAGS_REG))]
16030   ""
16031   "sbb{<imodesuffix>}\t%0, %0"
16032   ; Since we don't have the proper number of operands for an alu insn,
16033   ; fill in all the blanks.
16034   [(set_attr "type" "alu")
16035    (set_attr "use_carry" "1")
16036    (set_attr "pent_pair" "pu")
16037    (set_attr "memory" "none")
16038    (set_attr "imm_disp" "false")
16039    (set_attr "mode" "<MODE>")
16040    (set_attr "length_immediate" "0")])
16041
16042 (define_insn "*x86_mov<mode>cc_0_m1_se"
16043   [(set (match_operand:SWI48 0 "register_operand" "=r")
16044         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16045                              [(reg FLAGS_REG) (const_int 0)])
16046                             (const_int 1)
16047                             (const_int 0)))
16048    (clobber (reg:CC FLAGS_REG))]
16049   ""
16050   "sbb{<imodesuffix>}\t%0, %0"
16051   [(set_attr "type" "alu")
16052    (set_attr "use_carry" "1")
16053    (set_attr "pent_pair" "pu")
16054    (set_attr "memory" "none")
16055    (set_attr "imm_disp" "false")
16056    (set_attr "mode" "<MODE>")
16057    (set_attr "length_immediate" "0")])
16058
16059 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16060   [(set (match_operand:SWI48 0 "register_operand" "=r")
16061         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16062                     [(reg FLAGS_REG) (const_int 0)])))]
16063   ""
16064   "sbb{<imodesuffix>}\t%0, %0"
16065   [(set_attr "type" "alu")
16066    (set_attr "use_carry" "1")
16067    (set_attr "pent_pair" "pu")
16068    (set_attr "memory" "none")
16069    (set_attr "imm_disp" "false")
16070    (set_attr "mode" "<MODE>")
16071    (set_attr "length_immediate" "0")])
16072
16073 (define_insn "*mov<mode>cc_noc"
16074   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16075         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16076                                [(reg FLAGS_REG) (const_int 0)])
16077           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16078           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16079   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16080   "@
16081    cmov%O2%C1\t{%2, %0|%0, %2}
16082    cmov%O2%c1\t{%3, %0|%0, %3}"
16083   [(set_attr "type" "icmov")
16084    (set_attr "mode" "<MODE>")])
16085
16086 (define_insn_and_split "*movqicc_noc"
16087   [(set (match_operand:QI 0 "register_operand" "=r,r")
16088         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16089                            [(match_operand 4 "flags_reg_operand" "")
16090                             (const_int 0)])
16091                       (match_operand:QI 2 "register_operand" "r,0")
16092                       (match_operand:QI 3 "register_operand" "0,r")))]
16093   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16094   "#"
16095   "&& reload_completed"
16096   [(set (match_dup 0)
16097         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16098                       (match_dup 2)
16099                       (match_dup 3)))]
16100   "operands[0] = gen_lowpart (SImode, operands[0]);
16101    operands[2] = gen_lowpart (SImode, operands[2]);
16102    operands[3] = gen_lowpart (SImode, operands[3]);"
16103   [(set_attr "type" "icmov")
16104    (set_attr "mode" "SI")])
16105
16106 (define_expand "mov<mode>cc"
16107   [(set (match_operand:X87MODEF 0 "register_operand" "")
16108         (if_then_else:X87MODEF
16109           (match_operand 1 "ix86_fp_comparison_operator" "")
16110           (match_operand:X87MODEF 2 "register_operand" "")
16111           (match_operand:X87MODEF 3 "register_operand" "")))]
16112   "(TARGET_80387 && TARGET_CMOVE)
16113    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16114   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16115
16116 (define_insn "*movxfcc_1"
16117   [(set (match_operand:XF 0 "register_operand" "=f,f")
16118         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16119                                 [(reg FLAGS_REG) (const_int 0)])
16120                       (match_operand:XF 2 "register_operand" "f,0")
16121                       (match_operand:XF 3 "register_operand" "0,f")))]
16122   "TARGET_80387 && TARGET_CMOVE"
16123   "@
16124    fcmov%F1\t{%2, %0|%0, %2}
16125    fcmov%f1\t{%3, %0|%0, %3}"
16126   [(set_attr "type" "fcmov")
16127    (set_attr "mode" "XF")])
16128
16129 (define_insn "*movdfcc_1_rex64"
16130   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16131         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16132                                 [(reg FLAGS_REG) (const_int 0)])
16133                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16134                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16135   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16136    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16137   "@
16138    fcmov%F1\t{%2, %0|%0, %2}
16139    fcmov%f1\t{%3, %0|%0, %3}
16140    cmov%O2%C1\t{%2, %0|%0, %2}
16141    cmov%O2%c1\t{%3, %0|%0, %3}"
16142   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16143    (set_attr "mode" "DF,DF,DI,DI")])
16144
16145 (define_insn "*movdfcc_1"
16146   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16147         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16148                                 [(reg FLAGS_REG) (const_int 0)])
16149                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16150                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16151   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16152    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16153   "@
16154    fcmov%F1\t{%2, %0|%0, %2}
16155    fcmov%f1\t{%3, %0|%0, %3}
16156    #
16157    #"
16158   [(set_attr "type" "fcmov,fcmov,multi,multi")
16159    (set_attr "mode" "DF,DF,DI,DI")])
16160
16161 (define_split
16162   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16163         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16164                                 [(match_operand 4 "flags_reg_operand" "")
16165                                  (const_int 0)])
16166                       (match_operand:DF 2 "nonimmediate_operand" "")
16167                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16168   "!TARGET_64BIT && reload_completed"
16169   [(set (match_dup 2)
16170         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16171                       (match_dup 5)
16172                       (match_dup 6)))
16173    (set (match_dup 3)
16174         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16175                       (match_dup 7)
16176                       (match_dup 8)))]
16177 {
16178   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16179   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16180 })
16181
16182 (define_insn "*movsfcc_1_387"
16183   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16184         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16185                                 [(reg FLAGS_REG) (const_int 0)])
16186                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16187                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16188   "TARGET_80387 && TARGET_CMOVE
16189    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16190   "@
16191    fcmov%F1\t{%2, %0|%0, %2}
16192    fcmov%f1\t{%3, %0|%0, %3}
16193    cmov%O2%C1\t{%2, %0|%0, %2}
16194    cmov%O2%c1\t{%3, %0|%0, %3}"
16195   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16196    (set_attr "mode" "SF,SF,SI,SI")])
16197
16198 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16199 ;; the scalar versions to have only XMM registers as operands.
16200
16201 ;; XOP conditional move
16202 (define_insn "*xop_pcmov_<mode>"
16203   [(set (match_operand:MODEF 0 "register_operand" "=x")
16204         (if_then_else:MODEF
16205           (match_operand:MODEF 1 "register_operand" "x")
16206           (match_operand:MODEF 2 "register_operand" "x")
16207           (match_operand:MODEF 3 "register_operand" "x")))]
16208   "TARGET_XOP"
16209   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16210   [(set_attr "type" "sse4arg")])
16211
16212 ;; These versions of the min/max patterns are intentionally ignorant of
16213 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16214 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16215 ;; are undefined in this condition, we're certain this is correct.
16216
16217 (define_insn "<code><mode>3"
16218   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16219         (smaxmin:MODEF
16220           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16221           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16222   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16223   "@
16224    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16225    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16226   [(set_attr "isa" "noavx,avx")
16227    (set_attr "prefix" "orig,vex")
16228    (set_attr "type" "sseadd")
16229    (set_attr "mode" "<MODE>")])
16230
16231 ;; These versions of the min/max patterns implement exactly the operations
16232 ;;   min = (op1 < op2 ? op1 : op2)
16233 ;;   max = (!(op1 < op2) ? op1 : op2)
16234 ;; Their operands are not commutative, and thus they may be used in the
16235 ;; presence of -0.0 and NaN.
16236
16237 (define_insn "*ieee_smin<mode>3"
16238   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16239         (unspec:MODEF
16240           [(match_operand:MODEF 1 "register_operand" "0,x")
16241            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16242          UNSPEC_IEEE_MIN))]
16243   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16244   "@
16245    min<ssemodesuffix>\t{%2, %0|%0, %2}
16246    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16247   [(set_attr "isa" "noavx,avx")
16248    (set_attr "prefix" "orig,vex")
16249    (set_attr "type" "sseadd")
16250    (set_attr "mode" "<MODE>")])
16251
16252 (define_insn "*ieee_smax<mode>3"
16253   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16254         (unspec:MODEF
16255           [(match_operand:MODEF 1 "register_operand" "0,x")
16256            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16257          UNSPEC_IEEE_MAX))]
16258   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16259   "@
16260    max<ssemodesuffix>\t{%2, %0|%0, %2}
16261    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16262   [(set_attr "isa" "noavx,avx")
16263    (set_attr "prefix" "orig,vex")
16264    (set_attr "type" "sseadd")
16265    (set_attr "mode" "<MODE>")])
16266
16267 ;; Make two stack loads independent:
16268 ;;   fld aa              fld aa
16269 ;;   fld %st(0)     ->   fld bb
16270 ;;   fmul bb             fmul %st(1), %st
16271 ;;
16272 ;; Actually we only match the last two instructions for simplicity.
16273 (define_peephole2
16274   [(set (match_operand 0 "fp_register_operand" "")
16275         (match_operand 1 "fp_register_operand" ""))
16276    (set (match_dup 0)
16277         (match_operator 2 "binary_fp_operator"
16278            [(match_dup 0)
16279             (match_operand 3 "memory_operand" "")]))]
16280   "REGNO (operands[0]) != REGNO (operands[1])"
16281   [(set (match_dup 0) (match_dup 3))
16282    (set (match_dup 0) (match_dup 4))]
16283
16284   ;; The % modifier is not operational anymore in peephole2's, so we have to
16285   ;; swap the operands manually in the case of addition and multiplication.
16286   "if (COMMUTATIVE_ARITH_P (operands[2]))
16287      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16288                                    GET_MODE (operands[2]),
16289                                    operands[0], operands[1]);
16290    else
16291      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16292                                    GET_MODE (operands[2]),
16293                                    operands[1], operands[0]);")
16294
16295 ;; Conditional addition patterns
16296 (define_expand "add<mode>cc"
16297   [(match_operand:SWI 0 "register_operand" "")
16298    (match_operand 1 "ordered_comparison_operator" "")
16299    (match_operand:SWI 2 "register_operand" "")
16300    (match_operand:SWI 3 "const_int_operand" "")]
16301   ""
16302   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16303 \f
16304 ;; Misc patterns (?)
16305
16306 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16307 ;; Otherwise there will be nothing to keep
16308 ;;
16309 ;; [(set (reg ebp) (reg esp))]
16310 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16311 ;;  (clobber (eflags)]
16312 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16313 ;;
16314 ;; in proper program order.
16315
16316 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16317   [(set (match_operand:P 0 "register_operand" "=r,r")
16318         (plus:P (match_operand:P 1 "register_operand" "0,r")
16319                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16320    (clobber (reg:CC FLAGS_REG))
16321    (clobber (mem:BLK (scratch)))]
16322   ""
16323 {
16324   switch (get_attr_type (insn))
16325     {
16326     case TYPE_IMOV:
16327       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16328
16329     case TYPE_ALU:
16330       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16331       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16332         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16333
16334       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16335
16336     default:
16337       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16338       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16339     }
16340 }
16341   [(set (attr "type")
16342         (cond [(and (eq_attr "alternative" "0")
16343                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16344                  (const_string "alu")
16345                (match_operand:<MODE> 2 "const0_operand" "")
16346                  (const_string "imov")
16347               ]
16348               (const_string "lea")))
16349    (set (attr "length_immediate")
16350         (cond [(eq_attr "type" "imov")
16351                  (const_string "0")
16352                (and (eq_attr "type" "alu")
16353                     (match_operand 2 "const128_operand" ""))
16354                  (const_string "1")
16355               ]
16356               (const_string "*")))
16357    (set_attr "mode" "<MODE>")])
16358
16359 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16360   [(set (match_operand:P 0 "register_operand" "=r")
16361         (minus:P (match_operand:P 1 "register_operand" "0")
16362                  (match_operand:P 2 "register_operand" "r")))
16363    (clobber (reg:CC FLAGS_REG))
16364    (clobber (mem:BLK (scratch)))]
16365   ""
16366   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16367   [(set_attr "type" "alu")
16368    (set_attr "mode" "<MODE>")])
16369
16370 (define_insn "allocate_stack_worker_probe_<mode>"
16371   [(set (match_operand:P 0 "register_operand" "=a")
16372         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16373                             UNSPECV_STACK_PROBE))
16374    (clobber (reg:CC FLAGS_REG))]
16375   "ix86_target_stack_probe ()"
16376   "call\t___chkstk_ms"
16377   [(set_attr "type" "multi")
16378    (set_attr "length" "5")])
16379
16380 (define_expand "allocate_stack"
16381   [(match_operand 0 "register_operand" "")
16382    (match_operand 1 "general_operand" "")]
16383   "ix86_target_stack_probe ()"
16384 {
16385   rtx x;
16386
16387 #ifndef CHECK_STACK_LIMIT
16388 #define CHECK_STACK_LIMIT 0
16389 #endif
16390
16391   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16392       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16393     {
16394       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16395                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16396       if (x != stack_pointer_rtx)
16397         emit_move_insn (stack_pointer_rtx, x);
16398     }
16399   else
16400     {
16401       x = copy_to_mode_reg (Pmode, operands[1]);
16402       if (TARGET_64BIT)
16403         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16404       else
16405         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16406       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16407                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16408       if (x != stack_pointer_rtx)
16409         emit_move_insn (stack_pointer_rtx, x);
16410     }
16411
16412   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16413   DONE;
16414 })
16415
16416 ;; Use IOR for stack probes, this is shorter.
16417 (define_expand "probe_stack"
16418   [(match_operand 0 "memory_operand" "")]
16419   ""
16420 {
16421   rtx (*gen_ior3) (rtx, rtx, rtx);
16422
16423   gen_ior3 = (GET_MODE (operands[0]) == DImode
16424               ? gen_iordi3 : gen_iorsi3);
16425
16426   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16427   DONE;
16428 })
16429
16430 (define_insn "adjust_stack_and_probe<mode>"
16431   [(set (match_operand:P 0 "register_operand" "=r")
16432         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16433                             UNSPECV_PROBE_STACK_RANGE))
16434    (set (reg:P SP_REG)
16435         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16436    (clobber (reg:CC FLAGS_REG))
16437    (clobber (mem:BLK (scratch)))]
16438   ""
16439   "* return output_adjust_stack_and_probe (operands[0]);"
16440   [(set_attr "type" "multi")])
16441
16442 (define_insn "probe_stack_range<mode>"
16443   [(set (match_operand:P 0 "register_operand" "=r")
16444         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16445                             (match_operand:P 2 "const_int_operand" "n")]
16446                             UNSPECV_PROBE_STACK_RANGE))
16447    (clobber (reg:CC FLAGS_REG))]
16448   ""
16449   "* return output_probe_stack_range (operands[0], operands[2]);"
16450   [(set_attr "type" "multi")])
16451
16452 (define_expand "builtin_setjmp_receiver"
16453   [(label_ref (match_operand 0 "" ""))]
16454   "!TARGET_64BIT && flag_pic"
16455 {
16456 #if TARGET_MACHO
16457   if (TARGET_MACHO)
16458     {
16459       rtx xops[3];
16460       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16461       rtx label_rtx = gen_label_rtx ();
16462       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16463       xops[0] = xops[1] = picreg;
16464       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16465       ix86_expand_binary_operator (MINUS, SImode, xops);
16466     }
16467   else
16468 #endif
16469     emit_insn (gen_set_got (pic_offset_table_rtx));
16470   DONE;
16471 })
16472 \f
16473 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16474
16475 (define_split
16476   [(set (match_operand 0 "register_operand" "")
16477         (match_operator 3 "promotable_binary_operator"
16478            [(match_operand 1 "register_operand" "")
16479             (match_operand 2 "aligned_operand" "")]))
16480    (clobber (reg:CC FLAGS_REG))]
16481   "! TARGET_PARTIAL_REG_STALL && reload_completed
16482    && ((GET_MODE (operands[0]) == HImode
16483         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16484             /* ??? next two lines just !satisfies_constraint_K (...) */
16485             || !CONST_INT_P (operands[2])
16486             || satisfies_constraint_K (operands[2])))
16487        || (GET_MODE (operands[0]) == QImode
16488            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16489   [(parallel [(set (match_dup 0)
16490                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16491               (clobber (reg:CC FLAGS_REG))])]
16492   "operands[0] = gen_lowpart (SImode, operands[0]);
16493    operands[1] = gen_lowpart (SImode, operands[1]);
16494    if (GET_CODE (operands[3]) != ASHIFT)
16495      operands[2] = gen_lowpart (SImode, operands[2]);
16496    PUT_MODE (operands[3], SImode);")
16497
16498 ; Promote the QImode tests, as i386 has encoding of the AND
16499 ; instruction with 32-bit sign-extended immediate and thus the
16500 ; instruction size is unchanged, except in the %eax case for
16501 ; which it is increased by one byte, hence the ! optimize_size.
16502 (define_split
16503   [(set (match_operand 0 "flags_reg_operand" "")
16504         (match_operator 2 "compare_operator"
16505           [(and (match_operand 3 "aligned_operand" "")
16506                 (match_operand 4 "const_int_operand" ""))
16507            (const_int 0)]))
16508    (set (match_operand 1 "register_operand" "")
16509         (and (match_dup 3) (match_dup 4)))]
16510   "! TARGET_PARTIAL_REG_STALL && reload_completed
16511    && optimize_insn_for_speed_p ()
16512    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16513        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16514    /* Ensure that the operand will remain sign-extended immediate.  */
16515    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16516   [(parallel [(set (match_dup 0)
16517                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16518                                     (const_int 0)]))
16519               (set (match_dup 1)
16520                    (and:SI (match_dup 3) (match_dup 4)))])]
16521 {
16522   operands[4]
16523     = gen_int_mode (INTVAL (operands[4])
16524                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16525   operands[1] = gen_lowpart (SImode, operands[1]);
16526   operands[3] = gen_lowpart (SImode, operands[3]);
16527 })
16528
16529 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16530 ; the TEST instruction with 32-bit sign-extended immediate and thus
16531 ; the instruction size would at least double, which is not what we
16532 ; want even with ! optimize_size.
16533 (define_split
16534   [(set (match_operand 0 "flags_reg_operand" "")
16535         (match_operator 1 "compare_operator"
16536           [(and (match_operand:HI 2 "aligned_operand" "")
16537                 (match_operand:HI 3 "const_int_operand" ""))
16538            (const_int 0)]))]
16539   "! TARGET_PARTIAL_REG_STALL && reload_completed
16540    && ! TARGET_FAST_PREFIX
16541    && optimize_insn_for_speed_p ()
16542    /* Ensure that the operand will remain sign-extended immediate.  */
16543    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16544   [(set (match_dup 0)
16545         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16546                          (const_int 0)]))]
16547 {
16548   operands[3]
16549     = gen_int_mode (INTVAL (operands[3])
16550                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16551   operands[2] = gen_lowpart (SImode, operands[2]);
16552 })
16553
16554 (define_split
16555   [(set (match_operand 0 "register_operand" "")
16556         (neg (match_operand 1 "register_operand" "")))
16557    (clobber (reg:CC FLAGS_REG))]
16558   "! TARGET_PARTIAL_REG_STALL && reload_completed
16559    && (GET_MODE (operands[0]) == HImode
16560        || (GET_MODE (operands[0]) == QImode
16561            && (TARGET_PROMOTE_QImode
16562                || optimize_insn_for_size_p ())))"
16563   [(parallel [(set (match_dup 0)
16564                    (neg:SI (match_dup 1)))
16565               (clobber (reg:CC FLAGS_REG))])]
16566   "operands[0] = gen_lowpart (SImode, operands[0]);
16567    operands[1] = gen_lowpart (SImode, operands[1]);")
16568
16569 (define_split
16570   [(set (match_operand 0 "register_operand" "")
16571         (not (match_operand 1 "register_operand" "")))]
16572   "! TARGET_PARTIAL_REG_STALL && reload_completed
16573    && (GET_MODE (operands[0]) == HImode
16574        || (GET_MODE (operands[0]) == QImode
16575            && (TARGET_PROMOTE_QImode
16576                || optimize_insn_for_size_p ())))"
16577   [(set (match_dup 0)
16578         (not:SI (match_dup 1)))]
16579   "operands[0] = gen_lowpart (SImode, operands[0]);
16580    operands[1] = gen_lowpart (SImode, operands[1]);")
16581
16582 (define_split
16583   [(set (match_operand 0 "register_operand" "")
16584         (if_then_else (match_operator 1 "ordered_comparison_operator"
16585                                 [(reg FLAGS_REG) (const_int 0)])
16586                       (match_operand 2 "register_operand" "")
16587                       (match_operand 3 "register_operand" "")))]
16588   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16589    && (GET_MODE (operands[0]) == HImode
16590        || (GET_MODE (operands[0]) == QImode
16591            && (TARGET_PROMOTE_QImode
16592                || optimize_insn_for_size_p ())))"
16593   [(set (match_dup 0)
16594         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16595   "operands[0] = gen_lowpart (SImode, operands[0]);
16596    operands[2] = gen_lowpart (SImode, operands[2]);
16597    operands[3] = gen_lowpart (SImode, operands[3]);")
16598 \f
16599 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16600 ;; transform a complex memory operation into two memory to register operations.
16601
16602 ;; Don't push memory operands
16603 (define_peephole2
16604   [(set (match_operand:SWI 0 "push_operand" "")
16605         (match_operand:SWI 1 "memory_operand" ""))
16606    (match_scratch:SWI 2 "<r>")]
16607   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16608    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16609   [(set (match_dup 2) (match_dup 1))
16610    (set (match_dup 0) (match_dup 2))])
16611
16612 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16613 ;; SImode pushes.
16614 (define_peephole2
16615   [(set (match_operand:SF 0 "push_operand" "")
16616         (match_operand:SF 1 "memory_operand" ""))
16617    (match_scratch:SF 2 "r")]
16618   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16619    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16620   [(set (match_dup 2) (match_dup 1))
16621    (set (match_dup 0) (match_dup 2))])
16622
16623 ;; Don't move an immediate directly to memory when the instruction
16624 ;; gets too big.
16625 (define_peephole2
16626   [(match_scratch:SWI124 1 "<r>")
16627    (set (match_operand:SWI124 0 "memory_operand" "")
16628         (const_int 0))]
16629   "optimize_insn_for_speed_p ()
16630    && !TARGET_USE_MOV0
16631    && TARGET_SPLIT_LONG_MOVES
16632    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16633    && peep2_regno_dead_p (0, FLAGS_REG)"
16634   [(parallel [(set (match_dup 2) (const_int 0))
16635               (clobber (reg:CC FLAGS_REG))])
16636    (set (match_dup 0) (match_dup 1))]
16637   "operands[2] = gen_lowpart (SImode, operands[1]);")
16638
16639 (define_peephole2
16640   [(match_scratch:SWI124 2 "<r>")
16641    (set (match_operand:SWI124 0 "memory_operand" "")
16642         (match_operand:SWI124 1 "immediate_operand" ""))]
16643   "optimize_insn_for_speed_p ()
16644    && TARGET_SPLIT_LONG_MOVES
16645    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16646   [(set (match_dup 2) (match_dup 1))
16647    (set (match_dup 0) (match_dup 2))])
16648
16649 ;; Don't compare memory with zero, load and use a test instead.
16650 (define_peephole2
16651   [(set (match_operand 0 "flags_reg_operand" "")
16652         (match_operator 1 "compare_operator"
16653           [(match_operand:SI 2 "memory_operand" "")
16654            (const_int 0)]))
16655    (match_scratch:SI 3 "r")]
16656   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16657   [(set (match_dup 3) (match_dup 2))
16658    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16659
16660 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16661 ;; Don't split NOTs with a displacement operand, because resulting XOR
16662 ;; will not be pairable anyway.
16663 ;;
16664 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16665 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16666 ;; so this split helps here as well.
16667 ;;
16668 ;; Note: Can't do this as a regular split because we can't get proper
16669 ;; lifetime information then.
16670
16671 (define_peephole2
16672   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16673         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16674   "optimize_insn_for_speed_p ()
16675    && ((TARGET_NOT_UNPAIRABLE
16676         && (!MEM_P (operands[0])
16677             || !memory_displacement_operand (operands[0], <MODE>mode)))
16678        || (TARGET_NOT_VECTORMODE
16679            && long_memory_operand (operands[0], <MODE>mode)))
16680    && peep2_regno_dead_p (0, FLAGS_REG)"
16681   [(parallel [(set (match_dup 0)
16682                    (xor:SWI124 (match_dup 1) (const_int -1)))
16683               (clobber (reg:CC FLAGS_REG))])])
16684
16685 ;; Non pairable "test imm, reg" instructions can be translated to
16686 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16687 ;; byte opcode instead of two, have a short form for byte operands),
16688 ;; so do it for other CPUs as well.  Given that the value was dead,
16689 ;; this should not create any new dependencies.  Pass on the sub-word
16690 ;; versions if we're concerned about partial register stalls.
16691
16692 (define_peephole2
16693   [(set (match_operand 0 "flags_reg_operand" "")
16694         (match_operator 1 "compare_operator"
16695           [(and:SI (match_operand:SI 2 "register_operand" "")
16696                    (match_operand:SI 3 "immediate_operand" ""))
16697            (const_int 0)]))]
16698   "ix86_match_ccmode (insn, CCNOmode)
16699    && (true_regnum (operands[2]) != AX_REG
16700        || satisfies_constraint_K (operands[3]))
16701    && peep2_reg_dead_p (1, operands[2])"
16702   [(parallel
16703      [(set (match_dup 0)
16704            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16705                             (const_int 0)]))
16706       (set (match_dup 2)
16707            (and:SI (match_dup 2) (match_dup 3)))])])
16708
16709 ;; We don't need to handle HImode case, because it will be promoted to SImode
16710 ;; on ! TARGET_PARTIAL_REG_STALL
16711
16712 (define_peephole2
16713   [(set (match_operand 0 "flags_reg_operand" "")
16714         (match_operator 1 "compare_operator"
16715           [(and:QI (match_operand:QI 2 "register_operand" "")
16716                    (match_operand:QI 3 "immediate_operand" ""))
16717            (const_int 0)]))]
16718   "! TARGET_PARTIAL_REG_STALL
16719    && ix86_match_ccmode (insn, CCNOmode)
16720    && true_regnum (operands[2]) != AX_REG
16721    && peep2_reg_dead_p (1, operands[2])"
16722   [(parallel
16723      [(set (match_dup 0)
16724            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16725                             (const_int 0)]))
16726       (set (match_dup 2)
16727            (and:QI (match_dup 2) (match_dup 3)))])])
16728
16729 (define_peephole2
16730   [(set (match_operand 0 "flags_reg_operand" "")
16731         (match_operator 1 "compare_operator"
16732           [(and:SI
16733              (zero_extract:SI
16734                (match_operand 2 "ext_register_operand" "")
16735                (const_int 8)
16736                (const_int 8))
16737              (match_operand 3 "const_int_operand" ""))
16738            (const_int 0)]))]
16739   "! TARGET_PARTIAL_REG_STALL
16740    && ix86_match_ccmode (insn, CCNOmode)
16741    && true_regnum (operands[2]) != AX_REG
16742    && peep2_reg_dead_p (1, operands[2])"
16743   [(parallel [(set (match_dup 0)
16744                    (match_op_dup 1
16745                      [(and:SI
16746                         (zero_extract:SI
16747                           (match_dup 2)
16748                           (const_int 8)
16749                           (const_int 8))
16750                         (match_dup 3))
16751                       (const_int 0)]))
16752               (set (zero_extract:SI (match_dup 2)
16753                                     (const_int 8)
16754                                     (const_int 8))
16755                    (and:SI
16756                      (zero_extract:SI
16757                        (match_dup 2)
16758                        (const_int 8)
16759                        (const_int 8))
16760                      (match_dup 3)))])])
16761
16762 ;; Don't do logical operations with memory inputs.
16763 (define_peephole2
16764   [(match_scratch:SI 2 "r")
16765    (parallel [(set (match_operand:SI 0 "register_operand" "")
16766                    (match_operator:SI 3 "arith_or_logical_operator"
16767                      [(match_dup 0)
16768                       (match_operand:SI 1 "memory_operand" "")]))
16769               (clobber (reg:CC FLAGS_REG))])]
16770   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16771   [(set (match_dup 2) (match_dup 1))
16772    (parallel [(set (match_dup 0)
16773                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16774               (clobber (reg:CC FLAGS_REG))])])
16775
16776 (define_peephole2
16777   [(match_scratch:SI 2 "r")
16778    (parallel [(set (match_operand:SI 0 "register_operand" "")
16779                    (match_operator:SI 3 "arith_or_logical_operator"
16780                      [(match_operand:SI 1 "memory_operand" "")
16781                       (match_dup 0)]))
16782               (clobber (reg:CC FLAGS_REG))])]
16783   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16784   [(set (match_dup 2) (match_dup 1))
16785    (parallel [(set (match_dup 0)
16786                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16787               (clobber (reg:CC FLAGS_REG))])])
16788
16789 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16790 ;; refers to the destination of the load!
16791
16792 (define_peephole2
16793   [(set (match_operand:SI 0 "register_operand" "")
16794         (match_operand:SI 1 "register_operand" ""))
16795    (parallel [(set (match_dup 0)
16796                    (match_operator:SI 3 "commutative_operator"
16797                      [(match_dup 0)
16798                       (match_operand:SI 2 "memory_operand" "")]))
16799               (clobber (reg:CC FLAGS_REG))])]
16800   "REGNO (operands[0]) != REGNO (operands[1])
16801    && GENERAL_REGNO_P (REGNO (operands[0]))
16802    && GENERAL_REGNO_P (REGNO (operands[1]))"
16803   [(set (match_dup 0) (match_dup 4))
16804    (parallel [(set (match_dup 0)
16805                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16806               (clobber (reg:CC FLAGS_REG))])]
16807   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16808
16809 (define_peephole2
16810   [(set (match_operand 0 "register_operand" "")
16811         (match_operand 1 "register_operand" ""))
16812    (set (match_dup 0)
16813                    (match_operator 3 "commutative_operator"
16814                      [(match_dup 0)
16815                       (match_operand 2 "memory_operand" "")]))]
16816   "REGNO (operands[0]) != REGNO (operands[1])
16817    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16818        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16819   [(set (match_dup 0) (match_dup 2))
16820    (set (match_dup 0)
16821         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16822
16823 ; Don't do logical operations with memory outputs
16824 ;
16825 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16826 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16827 ; the same decoder scheduling characteristics as the original.
16828
16829 (define_peephole2
16830   [(match_scratch:SI 2 "r")
16831    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16832                    (match_operator:SI 3 "arith_or_logical_operator"
16833                      [(match_dup 0)
16834                       (match_operand:SI 1 "nonmemory_operand" "")]))
16835               (clobber (reg:CC FLAGS_REG))])]
16836   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16837    /* Do not split stack checking probes.  */
16838    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16839   [(set (match_dup 2) (match_dup 0))
16840    (parallel [(set (match_dup 2)
16841                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16842               (clobber (reg:CC FLAGS_REG))])
16843    (set (match_dup 0) (match_dup 2))])
16844
16845 (define_peephole2
16846   [(match_scratch:SI 2 "r")
16847    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16848                    (match_operator:SI 3 "arith_or_logical_operator"
16849                      [(match_operand:SI 1 "nonmemory_operand" "")
16850                       (match_dup 0)]))
16851               (clobber (reg:CC FLAGS_REG))])]
16852   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16853    /* Do not split stack checking probes.  */
16854    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16855   [(set (match_dup 2) (match_dup 0))
16856    (parallel [(set (match_dup 2)
16857                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16858               (clobber (reg:CC FLAGS_REG))])
16859    (set (match_dup 0) (match_dup 2))])
16860
16861 ;; Attempt to use arith or logical operations with memory outputs with
16862 ;; setting of flags.
16863 (define_peephole2
16864   [(set (match_operand:SWI 0 "register_operand" "")
16865         (match_operand:SWI 1 "memory_operand" ""))
16866    (parallel [(set (match_dup 0)
16867                    (match_operator:SWI 3 "plusminuslogic_operator"
16868                      [(match_dup 0)
16869                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16870               (clobber (reg:CC FLAGS_REG))])
16871    (set (match_dup 1) (match_dup 0))
16872    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16873   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16874    && peep2_reg_dead_p (4, operands[0])
16875    && !reg_overlap_mentioned_p (operands[0], operands[1])
16876    && ix86_match_ccmode (peep2_next_insn (3),
16877                          (GET_CODE (operands[3]) == PLUS
16878                           || GET_CODE (operands[3]) == MINUS)
16879                          ? CCGOCmode : CCNOmode)"
16880   [(parallel [(set (match_dup 4) (match_dup 5))
16881               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16882                                                   (match_dup 2)]))])]
16883   "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16884    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16885                                  copy_rtx (operands[1]),
16886                                  copy_rtx (operands[2]));
16887    operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16888                                   operands[5], const0_rtx);")
16889
16890 (define_peephole2
16891   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16892                    (match_operator:SWI 2 "plusminuslogic_operator"
16893                      [(match_dup 0)
16894                       (match_operand:SWI 1 "memory_operand" "")]))
16895               (clobber (reg:CC FLAGS_REG))])
16896    (set (match_dup 1) (match_dup 0))
16897    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16898   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16899    && GET_CODE (operands[2]) != MINUS
16900    && peep2_reg_dead_p (3, operands[0])
16901    && !reg_overlap_mentioned_p (operands[0], operands[1])
16902    && ix86_match_ccmode (peep2_next_insn (2),
16903                          GET_CODE (operands[2]) == PLUS
16904                          ? CCGOCmode : CCNOmode)"
16905   [(parallel [(set (match_dup 3) (match_dup 4))
16906               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16907                                                   (match_dup 0)]))])]
16908   "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16909    operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16910                                  copy_rtx (operands[1]),
16911                                  copy_rtx (operands[0]));
16912    operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16913                                   operands[4], const0_rtx);")
16914
16915 (define_peephole2
16916   [(set (match_operand:SWI12 0 "register_operand" "")
16917         (match_operand:SWI12 1 "memory_operand" ""))
16918    (parallel [(set (match_operand:SI 4 "register_operand" "")
16919                    (match_operator:SI 3 "plusminuslogic_operator"
16920                      [(match_dup 4)
16921                       (match_operand:SI 2 "nonmemory_operand" "")]))
16922               (clobber (reg:CC FLAGS_REG))])
16923    (set (match_dup 1) (match_dup 0))
16924    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16925   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16926    && REG_P (operands[0]) && REG_P (operands[4])
16927    && REGNO (operands[0]) == REGNO (operands[4])
16928    && peep2_reg_dead_p (4, operands[0])
16929    && !reg_overlap_mentioned_p (operands[0], operands[1])
16930    && ix86_match_ccmode (peep2_next_insn (3),
16931                          (GET_CODE (operands[3]) == PLUS
16932                           || GET_CODE (operands[3]) == MINUS)
16933                          ? CCGOCmode : CCNOmode)"
16934   [(parallel [(set (match_dup 4) (match_dup 5))
16935               (set (match_dup 1) (match_dup 6))])]
16936   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16937    operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16938    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16939                                  copy_rtx (operands[1]), operands[2]);
16940    operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16941                                   operands[5], const0_rtx);
16942    operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16943                                  copy_rtx (operands[1]),
16944                                  copy_rtx (operands[2]));")
16945
16946 ;; Attempt to always use XOR for zeroing registers.
16947 (define_peephole2
16948   [(set (match_operand 0 "register_operand" "")
16949         (match_operand 1 "const0_operand" ""))]
16950   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16951    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16952    && GENERAL_REG_P (operands[0])
16953    && peep2_regno_dead_p (0, FLAGS_REG)"
16954   [(parallel [(set (match_dup 0) (const_int 0))
16955               (clobber (reg:CC FLAGS_REG))])]
16956   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16957
16958 (define_peephole2
16959   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16960         (const_int 0))]
16961   "(GET_MODE (operands[0]) == QImode
16962     || GET_MODE (operands[0]) == HImode)
16963    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16964    && peep2_regno_dead_p (0, FLAGS_REG)"
16965   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16966               (clobber (reg:CC FLAGS_REG))])])
16967
16968 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16969 (define_peephole2
16970   [(set (match_operand:SWI248 0 "register_operand" "")
16971         (const_int -1))]
16972   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16973    && peep2_regno_dead_p (0, FLAGS_REG)"
16974   [(parallel [(set (match_dup 0) (const_int -1))
16975               (clobber (reg:CC FLAGS_REG))])]
16976 {
16977   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16978     operands[0] = gen_lowpart (SImode, operands[0]);
16979 })
16980
16981 ;; Attempt to convert simple lea to add/shift.
16982 ;; These can be created by move expanders.
16983
16984 (define_peephole2
16985   [(set (match_operand:SWI48 0 "register_operand" "")
16986         (plus:SWI48 (match_dup 0)
16987                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16988   "peep2_regno_dead_p (0, FLAGS_REG)"
16989   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16990               (clobber (reg:CC FLAGS_REG))])])
16991
16992 (define_peephole2
16993   [(set (match_operand:SI 0 "register_operand" "")
16994         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16995                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16996   "TARGET_64BIT
16997    && peep2_regno_dead_p (0, FLAGS_REG)
16998    && REGNO (operands[0]) == REGNO (operands[1])"
16999   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17000               (clobber (reg:CC FLAGS_REG))])]
17001   "operands[2] = gen_lowpart (SImode, operands[2]);")
17002
17003 (define_peephole2
17004   [(set (match_operand:SWI48 0 "register_operand" "")
17005         (mult:SWI48 (match_dup 0)
17006                     (match_operand:SWI48 1 "const_int_operand" "")))]
17007   "exact_log2 (INTVAL (operands[1])) >= 0
17008    && peep2_regno_dead_p (0, FLAGS_REG)"
17009   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17010               (clobber (reg:CC FLAGS_REG))])]
17011   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17012
17013 (define_peephole2
17014   [(set (match_operand:SI 0 "register_operand" "")
17015         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17016                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17017   "TARGET_64BIT
17018    && exact_log2 (INTVAL (operands[2])) >= 0
17019    && REGNO (operands[0]) == REGNO (operands[1])
17020    && peep2_regno_dead_p (0, FLAGS_REG)"
17021   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17022               (clobber (reg:CC FLAGS_REG))])]
17023   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17024
17025 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17026 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17027 ;; On many CPUs it is also faster, since special hardware to avoid esp
17028 ;; dependencies is present.
17029
17030 ;; While some of these conversions may be done using splitters, we use
17031 ;; peepholes in order to allow combine_stack_adjustments pass to see
17032 ;; nonobfuscated RTL.
17033
17034 ;; Convert prologue esp subtractions to push.
17035 ;; We need register to push.  In order to keep verify_flow_info happy we have
17036 ;; two choices
17037 ;; - use scratch and clobber it in order to avoid dependencies
17038 ;; - use already live register
17039 ;; We can't use the second way right now, since there is no reliable way how to
17040 ;; verify that given register is live.  First choice will also most likely in
17041 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17042 ;; call clobbered registers are dead.  We may want to use base pointer as an
17043 ;; alternative when no register is available later.
17044
17045 (define_peephole2
17046   [(match_scratch:P 1 "r")
17047    (parallel [(set (reg:P SP_REG)
17048                    (plus:P (reg:P SP_REG)
17049                            (match_operand:P 0 "const_int_operand" "")))
17050               (clobber (reg:CC FLAGS_REG))
17051               (clobber (mem:BLK (scratch)))])]
17052   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17053    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17054   [(clobber (match_dup 1))
17055    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17056               (clobber (mem:BLK (scratch)))])])
17057
17058 (define_peephole2
17059   [(match_scratch:P 1 "r")
17060    (parallel [(set (reg:P SP_REG)
17061                    (plus:P (reg:P SP_REG)
17062                            (match_operand:P 0 "const_int_operand" "")))
17063               (clobber (reg:CC FLAGS_REG))
17064               (clobber (mem:BLK (scratch)))])]
17065   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17066    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17067   [(clobber (match_dup 1))
17068    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17069    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17070               (clobber (mem:BLK (scratch)))])])
17071
17072 ;; Convert esp subtractions to push.
17073 (define_peephole2
17074   [(match_scratch:P 1 "r")
17075    (parallel [(set (reg:P SP_REG)
17076                    (plus:P (reg:P SP_REG)
17077                            (match_operand:P 0 "const_int_operand" "")))
17078               (clobber (reg:CC FLAGS_REG))])]
17079   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17080    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17081   [(clobber (match_dup 1))
17082    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17083
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   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17091    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17092   [(clobber (match_dup 1))
17093    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17094    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17095
17096 ;; Convert epilogue deallocator to pop.
17097 (define_peephole2
17098   [(match_scratch:P 1 "r")
17099    (parallel [(set (reg:P SP_REG)
17100                    (plus:P (reg:P SP_REG)
17101                            (match_operand:P 0 "const_int_operand" "")))
17102               (clobber (reg:CC FLAGS_REG))
17103               (clobber (mem:BLK (scratch)))])]
17104   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17105    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17106   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17107               (clobber (mem:BLK (scratch)))])])
17108
17109 ;; Two pops case is tricky, since pop causes dependency
17110 ;; on destination register.  We use two registers if available.
17111 (define_peephole2
17112   [(match_scratch:P 1 "r")
17113    (match_scratch:P 2 "r")
17114    (parallel [(set (reg:P SP_REG)
17115                    (plus:P (reg:P SP_REG)
17116                            (match_operand:P 0 "const_int_operand" "")))
17117               (clobber (reg:CC FLAGS_REG))
17118               (clobber (mem:BLK (scratch)))])]
17119   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17120    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17121   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17122               (clobber (mem:BLK (scratch)))])
17123    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17124
17125 (define_peephole2
17126   [(match_scratch:P 1 "r")
17127    (parallel [(set (reg:P SP_REG)
17128                    (plus:P (reg:P SP_REG)
17129                            (match_operand:P 0 "const_int_operand" "")))
17130               (clobber (reg:CC FLAGS_REG))
17131               (clobber (mem:BLK (scratch)))])]
17132   "optimize_insn_for_size_p ()
17133    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17134   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17135               (clobber (mem:BLK (scratch)))])
17136    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17137
17138 ;; Convert esp additions to pop.
17139 (define_peephole2
17140   [(match_scratch:P 1 "r")
17141    (parallel [(set (reg:P SP_REG)
17142                    (plus:P (reg:P SP_REG)
17143                            (match_operand:P 0 "const_int_operand" "")))
17144               (clobber (reg:CC FLAGS_REG))])]
17145   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17146   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17147
17148 ;; Two pops case is tricky, since pop causes dependency
17149 ;; on destination register.  We use two registers if available.
17150 (define_peephole2
17151   [(match_scratch:P 1 "r")
17152    (match_scratch:P 2 "r")
17153    (parallel [(set (reg:P SP_REG)
17154                    (plus:P (reg:P SP_REG)
17155                            (match_operand:P 0 "const_int_operand" "")))
17156               (clobber (reg:CC FLAGS_REG))])]
17157   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17158   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17159    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17160
17161 (define_peephole2
17162   [(match_scratch:P 1 "r")
17163    (parallel [(set (reg:P SP_REG)
17164                    (plus:P (reg:P SP_REG)
17165                            (match_operand:P 0 "const_int_operand" "")))
17166               (clobber (reg:CC FLAGS_REG))])]
17167   "optimize_insn_for_size_p ()
17168    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17169   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17170    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17171 \f
17172 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17173 ;; required and register dies.  Similarly for 128 to -128.
17174 (define_peephole2
17175   [(set (match_operand 0 "flags_reg_operand" "")
17176         (match_operator 1 "compare_operator"
17177           [(match_operand 2 "register_operand" "")
17178            (match_operand 3 "const_int_operand" "")]))]
17179   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17180      && incdec_operand (operands[3], GET_MODE (operands[3])))
17181     || (!TARGET_FUSE_CMP_AND_BRANCH
17182         && INTVAL (operands[3]) == 128))
17183    && ix86_match_ccmode (insn, CCGCmode)
17184    && peep2_reg_dead_p (1, operands[2])"
17185   [(parallel [(set (match_dup 0)
17186                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17187               (clobber (match_dup 2))])])
17188 \f
17189 ;; Convert imul by three, five and nine into lea
17190 (define_peephole2
17191   [(parallel
17192     [(set (match_operand:SWI48 0 "register_operand" "")
17193           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17194                       (match_operand:SWI48 2 "const_int_operand" "")))
17195      (clobber (reg:CC FLAGS_REG))])]
17196   "INTVAL (operands[2]) == 3
17197    || INTVAL (operands[2]) == 5
17198    || INTVAL (operands[2]) == 9"
17199   [(set (match_dup 0)
17200         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17201                     (match_dup 1)))]
17202   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17203
17204 (define_peephole2
17205   [(parallel
17206     [(set (match_operand:SWI48 0 "register_operand" "")
17207           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17208                       (match_operand:SWI48 2 "const_int_operand" "")))
17209      (clobber (reg:CC FLAGS_REG))])]
17210   "optimize_insn_for_speed_p ()
17211    && (INTVAL (operands[2]) == 3
17212        || INTVAL (operands[2]) == 5
17213        || INTVAL (operands[2]) == 9)"
17214   [(set (match_dup 0) (match_dup 1))
17215    (set (match_dup 0)
17216         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17217                     (match_dup 0)))]
17218   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17219
17220 ;; imul $32bit_imm, mem, reg is vector decoded, while
17221 ;; imul $32bit_imm, reg, reg is direct decoded.
17222 (define_peephole2
17223   [(match_scratch:SWI48 3 "r")
17224    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17225                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17226                                (match_operand:SWI48 2 "immediate_operand" "")))
17227               (clobber (reg:CC FLAGS_REG))])]
17228   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17229    && !satisfies_constraint_K (operands[2])"
17230   [(set (match_dup 3) (match_dup 1))
17231    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17232               (clobber (reg:CC FLAGS_REG))])])
17233
17234 (define_peephole2
17235   [(match_scratch:SI 3 "r")
17236    (parallel [(set (match_operand:DI 0 "register_operand" "")
17237                    (zero_extend:DI
17238                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17239                               (match_operand:SI 2 "immediate_operand" ""))))
17240               (clobber (reg:CC FLAGS_REG))])]
17241   "TARGET_64BIT
17242    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17243    && !satisfies_constraint_K (operands[2])"
17244   [(set (match_dup 3) (match_dup 1))
17245    (parallel [(set (match_dup 0)
17246                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17247               (clobber (reg:CC FLAGS_REG))])])
17248
17249 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17250 ;; Convert it into imul reg, reg
17251 ;; It would be better to force assembler to encode instruction using long
17252 ;; immediate, but there is apparently no way to do so.
17253 (define_peephole2
17254   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17255                    (mult:SWI248
17256                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17257                     (match_operand:SWI248 2 "const_int_operand" "")))
17258               (clobber (reg:CC FLAGS_REG))])
17259    (match_scratch:SWI248 3 "r")]
17260   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17261    && satisfies_constraint_K (operands[2])"
17262   [(set (match_dup 3) (match_dup 2))
17263    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17264               (clobber (reg:CC FLAGS_REG))])]
17265 {
17266   if (!rtx_equal_p (operands[0], operands[1]))
17267     emit_move_insn (operands[0], operands[1]);
17268 })
17269
17270 ;; After splitting up read-modify operations, array accesses with memory
17271 ;; operands might end up in form:
17272 ;;  sall    $2, %eax
17273 ;;  movl    4(%esp), %edx
17274 ;;  addl    %edx, %eax
17275 ;; instead of pre-splitting:
17276 ;;  sall    $2, %eax
17277 ;;  addl    4(%esp), %eax
17278 ;; Turn it into:
17279 ;;  movl    4(%esp), %edx
17280 ;;  leal    (%edx,%eax,4), %eax
17281
17282 (define_peephole2
17283   [(match_scratch:P 5 "r")
17284    (parallel [(set (match_operand 0 "register_operand" "")
17285                    (ashift (match_operand 1 "register_operand" "")
17286                            (match_operand 2 "const_int_operand" "")))
17287                (clobber (reg:CC FLAGS_REG))])
17288    (parallel [(set (match_operand 3 "register_operand" "")
17289                    (plus (match_dup 0)
17290                          (match_operand 4 "x86_64_general_operand" "")))
17291                    (clobber (reg:CC FLAGS_REG))])]
17292   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17293    /* Validate MODE for lea.  */
17294    && ((!TARGET_PARTIAL_REG_STALL
17295         && (GET_MODE (operands[0]) == QImode
17296             || GET_MODE (operands[0]) == HImode))
17297        || GET_MODE (operands[0]) == SImode
17298        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17299    && (rtx_equal_p (operands[0], operands[3])
17300        || peep2_reg_dead_p (2, operands[0]))
17301    /* We reorder load and the shift.  */
17302    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17303   [(set (match_dup 5) (match_dup 4))
17304    (set (match_dup 0) (match_dup 1))]
17305 {
17306   enum machine_mode op1mode = GET_MODE (operands[1]);
17307   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17308   int scale = 1 << INTVAL (operands[2]);
17309   rtx index = gen_lowpart (Pmode, operands[1]);
17310   rtx base = gen_lowpart (Pmode, operands[5]);
17311   rtx dest = gen_lowpart (mode, operands[3]);
17312
17313   operands[1] = gen_rtx_PLUS (Pmode, base,
17314                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17315   operands[5] = base;
17316   if (mode != Pmode)
17317     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17318   if (op1mode != Pmode)
17319     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17320   operands[0] = dest;
17321 })
17322 \f
17323 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17324 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17325 ;; caught for use by garbage collectors and the like.  Using an insn that
17326 ;; maps to SIGILL makes it more likely the program will rightfully die.
17327 ;; Keeping with tradition, "6" is in honor of #UD.
17328 (define_insn "trap"
17329   [(trap_if (const_int 1) (const_int 6))]
17330   ""
17331   { return ASM_SHORT "0x0b0f"; }
17332   [(set_attr "length" "2")])
17333
17334 (define_expand "prefetch"
17335   [(prefetch (match_operand 0 "address_operand" "")
17336              (match_operand:SI 1 "const_int_operand" "")
17337              (match_operand:SI 2 "const_int_operand" ""))]
17338   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17339 {
17340   int rw = INTVAL (operands[1]);
17341   int locality = INTVAL (operands[2]);
17342
17343   gcc_assert (rw == 0 || rw == 1);
17344   gcc_assert (locality >= 0 && locality <= 3);
17345   gcc_assert (GET_MODE (operands[0]) == Pmode
17346               || GET_MODE (operands[0]) == VOIDmode);
17347
17348   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17349      supported by SSE counterpart or the SSE prefetch is not available
17350      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17351      of locality.  */
17352   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17353     operands[2] = GEN_INT (3);
17354   else
17355     operands[1] = const0_rtx;
17356 })
17357
17358 (define_insn "*prefetch_sse_<mode>"
17359   [(prefetch (match_operand:P 0 "address_operand" "p")
17360              (const_int 0)
17361              (match_operand:SI 1 "const_int_operand" ""))]
17362   "TARGET_PREFETCH_SSE"
17363 {
17364   static const char * const patterns[4] = {
17365    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17366   };
17367
17368   int locality = INTVAL (operands[1]);
17369   gcc_assert (locality >= 0 && locality <= 3);
17370
17371   return patterns[locality];
17372 }
17373   [(set_attr "type" "sse")
17374    (set_attr "atom_sse_attr" "prefetch")
17375    (set (attr "length_address")
17376         (symbol_ref "memory_address_length (operands[0])"))
17377    (set_attr "memory" "none")])
17378
17379 (define_insn "*prefetch_3dnow_<mode>"
17380   [(prefetch (match_operand:P 0 "address_operand" "p")
17381              (match_operand:SI 1 "const_int_operand" "n")
17382              (const_int 3))]
17383   "TARGET_3DNOW"
17384 {
17385   if (INTVAL (operands[1]) == 0)
17386     return "prefetch\t%a0";
17387   else
17388     return "prefetchw\t%a0";
17389 }
17390   [(set_attr "type" "mmx")
17391    (set (attr "length_address")
17392         (symbol_ref "memory_address_length (operands[0])"))
17393    (set_attr "memory" "none")])
17394
17395 (define_expand "stack_protect_set"
17396   [(match_operand 0 "memory_operand" "")
17397    (match_operand 1 "memory_operand" "")]
17398   ""
17399 {
17400   rtx (*insn)(rtx, rtx);
17401
17402 #ifdef TARGET_THREAD_SSP_OFFSET
17403   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17404   insn = (TARGET_64BIT
17405           ? gen_stack_tls_protect_set_di
17406           : gen_stack_tls_protect_set_si);
17407 #else
17408   insn = (TARGET_64BIT
17409           ? gen_stack_protect_set_di
17410           : gen_stack_protect_set_si);
17411 #endif
17412
17413   emit_insn (insn (operands[0], operands[1]));
17414   DONE;
17415 })
17416
17417 (define_insn "stack_protect_set_<mode>"
17418   [(set (match_operand:P 0 "memory_operand" "=m")
17419         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17420    (set (match_scratch:P 2 "=&r") (const_int 0))
17421    (clobber (reg:CC FLAGS_REG))]
17422   ""
17423   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17424   [(set_attr "type" "multi")])
17425
17426 (define_insn "stack_tls_protect_set_<mode>"
17427   [(set (match_operand:P 0 "memory_operand" "=m")
17428         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17429                   UNSPEC_SP_TLS_SET))
17430    (set (match_scratch:P 2 "=&r") (const_int 0))
17431    (clobber (reg:CC FLAGS_REG))]
17432   ""
17433   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17434   [(set_attr "type" "multi")])
17435
17436 (define_expand "stack_protect_test"
17437   [(match_operand 0 "memory_operand" "")
17438    (match_operand 1 "memory_operand" "")
17439    (match_operand 2 "" "")]
17440   ""
17441 {
17442   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17443
17444   rtx (*insn)(rtx, rtx, rtx);
17445
17446 #ifdef TARGET_THREAD_SSP_OFFSET
17447   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17448   insn = (TARGET_64BIT
17449           ? gen_stack_tls_protect_test_di
17450           : gen_stack_tls_protect_test_si);
17451 #else
17452   insn = (TARGET_64BIT
17453           ? gen_stack_protect_test_di
17454           : gen_stack_protect_test_si);
17455 #endif
17456
17457   emit_insn (insn (flags, operands[0], operands[1]));
17458
17459   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17460                                   flags, const0_rtx, operands[2]));
17461   DONE;
17462 })
17463
17464 (define_insn "stack_protect_test_<mode>"
17465   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17466         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17467                      (match_operand:P 2 "memory_operand" "m")]
17468                     UNSPEC_SP_TEST))
17469    (clobber (match_scratch:P 3 "=&r"))]
17470   ""
17471   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17472   [(set_attr "type" "multi")])
17473
17474 (define_insn "stack_tls_protect_test_<mode>"
17475   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17476         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17477                      (match_operand:P 2 "const_int_operand" "i")]
17478                     UNSPEC_SP_TLS_TEST))
17479    (clobber (match_scratch:P 3 "=r"))]
17480   ""
17481   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17482   [(set_attr "type" "multi")])
17483
17484 (define_insn "sse4_2_crc32<mode>"
17485   [(set (match_operand:SI 0 "register_operand" "=r")
17486         (unspec:SI
17487           [(match_operand:SI 1 "register_operand" "0")
17488            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17489           UNSPEC_CRC32))]
17490   "TARGET_SSE4_2 || TARGET_CRC32"
17491   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17492   [(set_attr "type" "sselog1")
17493    (set_attr "prefix_rep" "1")
17494    (set_attr "prefix_extra" "1")
17495    (set (attr "prefix_data16")
17496      (if_then_else (match_operand:HI 2 "" "")
17497        (const_string "1")
17498        (const_string "*")))
17499    (set (attr "prefix_rex")
17500      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17501        (const_string "1")
17502        (const_string "*")))
17503    (set_attr "mode" "SI")])
17504
17505 (define_insn "sse4_2_crc32di"
17506   [(set (match_operand:DI 0 "register_operand" "=r")
17507         (unspec:DI
17508           [(match_operand:DI 1 "register_operand" "0")
17509            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17510           UNSPEC_CRC32))]
17511   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17512   "crc32{q}\t{%2, %0|%0, %2}"
17513   [(set_attr "type" "sselog1")
17514    (set_attr "prefix_rep" "1")
17515    (set_attr "prefix_extra" "1")
17516    (set_attr "mode" "DI")])
17517
17518 (define_expand "rdpmc"
17519   [(match_operand:DI 0 "register_operand" "")
17520    (match_operand:SI 1 "register_operand" "")]
17521   ""
17522 {
17523   rtx reg = gen_reg_rtx (DImode);
17524   rtx si;
17525
17526   /* Force operand 1 into ECX.  */
17527   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17528   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17529   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17530                                 UNSPECV_RDPMC);
17531
17532   if (TARGET_64BIT)
17533     {
17534       rtvec vec = rtvec_alloc (2);
17535       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17536       rtx upper = gen_reg_rtx (DImode);
17537       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17538                                         gen_rtvec (1, const0_rtx),
17539                                         UNSPECV_RDPMC);
17540       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17541       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17542       emit_insn (load);
17543       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17544                                    NULL, 1, OPTAB_DIRECT);
17545       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17546                                  OPTAB_DIRECT);
17547     }
17548   else
17549     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17550   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17551   DONE;
17552 })
17553
17554 (define_insn "*rdpmc"
17555   [(set (match_operand:DI 0 "register_operand" "=A")
17556         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17557                             UNSPECV_RDPMC))]
17558   "!TARGET_64BIT"
17559   "rdpmc"
17560   [(set_attr "type" "other")
17561    (set_attr "length" "2")])
17562
17563 (define_insn "*rdpmc_rex64"
17564   [(set (match_operand:DI 0 "register_operand" "=a")
17565         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17566                             UNSPECV_RDPMC))
17567   (set (match_operand:DI 1 "register_operand" "=d")
17568        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17569   "TARGET_64BIT"
17570   "rdpmc"
17571   [(set_attr "type" "other")
17572    (set_attr "length" "2")])
17573
17574 (define_expand "rdtsc"
17575   [(set (match_operand:DI 0 "register_operand" "")
17576         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17577   ""
17578 {
17579   if (TARGET_64BIT)
17580     {
17581       rtvec vec = rtvec_alloc (2);
17582       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17583       rtx upper = gen_reg_rtx (DImode);
17584       rtx lower = gen_reg_rtx (DImode);
17585       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17586                                          gen_rtvec (1, const0_rtx),
17587                                          UNSPECV_RDTSC);
17588       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17589       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17590       emit_insn (load);
17591       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17592                                    NULL, 1, OPTAB_DIRECT);
17593       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17594                                    OPTAB_DIRECT);
17595       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17596       DONE;
17597     }
17598 })
17599
17600 (define_insn "*rdtsc"
17601   [(set (match_operand:DI 0 "register_operand" "=A")
17602         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17603   "!TARGET_64BIT"
17604   "rdtsc"
17605   [(set_attr "type" "other")
17606    (set_attr "length" "2")])
17607
17608 (define_insn "*rdtsc_rex64"
17609   [(set (match_operand:DI 0 "register_operand" "=a")
17610         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17611    (set (match_operand:DI 1 "register_operand" "=d")
17612         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17613   "TARGET_64BIT"
17614   "rdtsc"
17615   [(set_attr "type" "other")
17616    (set_attr "length" "2")])
17617
17618 (define_expand "rdtscp"
17619   [(match_operand:DI 0 "register_operand" "")
17620    (match_operand:SI 1 "memory_operand" "")]
17621   ""
17622 {
17623   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17624                                     gen_rtvec (1, const0_rtx),
17625                                     UNSPECV_RDTSCP);
17626   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17627                                     gen_rtvec (1, const0_rtx),
17628                                     UNSPECV_RDTSCP);
17629   rtx reg = gen_reg_rtx (DImode);
17630   rtx tmp = gen_reg_rtx (SImode);
17631
17632   if (TARGET_64BIT)
17633     {
17634       rtvec vec = rtvec_alloc (3);
17635       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17636       rtx upper = gen_reg_rtx (DImode);
17637       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17638       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17639       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17640       emit_insn (load);
17641       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17642                                    NULL, 1, OPTAB_DIRECT);
17643       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17644                                  OPTAB_DIRECT);
17645     }
17646   else
17647     {
17648       rtvec vec = rtvec_alloc (2);
17649       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17650       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17651       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17652       emit_insn (load);
17653     }
17654   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17655   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17656   DONE;
17657 })
17658
17659 (define_insn "*rdtscp"
17660   [(set (match_operand:DI 0 "register_operand" "=A")
17661         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17662    (set (match_operand:SI 1 "register_operand" "=c")
17663         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17664   "!TARGET_64BIT"
17665   "rdtscp"
17666   [(set_attr "type" "other")
17667    (set_attr "length" "3")])
17668
17669 (define_insn "*rdtscp_rex64"
17670   [(set (match_operand:DI 0 "register_operand" "=a")
17671         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17672    (set (match_operand:DI 1 "register_operand" "=d")
17673         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17674    (set (match_operand:SI 2 "register_operand" "=c")
17675         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17676   "TARGET_64BIT"
17677   "rdtscp"
17678   [(set_attr "type" "other")
17679    (set_attr "length" "3")])
17680
17681 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17682 ;;
17683 ;; LWP instructions
17684 ;;
17685 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17686
17687 (define_expand "lwp_llwpcb"
17688   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17689                     UNSPECV_LLWP_INTRINSIC)]
17690   "TARGET_LWP")
17691
17692 (define_insn "*lwp_llwpcb<mode>1"
17693   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17694                     UNSPECV_LLWP_INTRINSIC)]
17695   "TARGET_LWP"
17696   "llwpcb\t%0"
17697   [(set_attr "type" "lwp")
17698    (set_attr "mode" "<MODE>")
17699    (set_attr "length" "5")])
17700
17701 (define_expand "lwp_slwpcb"
17702   [(set (match_operand 0 "register_operand" "=r")
17703         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17704   "TARGET_LWP"
17705 {
17706   rtx (*insn)(rtx);
17707
17708   insn = (TARGET_64BIT
17709           ? gen_lwp_slwpcbdi
17710           : gen_lwp_slwpcbsi);
17711
17712   emit_insn (insn (operands[0]));
17713   DONE;
17714 })
17715
17716 (define_insn "lwp_slwpcb<mode>"
17717   [(set (match_operand:P 0 "register_operand" "=r")
17718         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17719   "TARGET_LWP"
17720   "slwpcb\t%0"
17721   [(set_attr "type" "lwp")
17722    (set_attr "mode" "<MODE>")
17723    (set_attr "length" "5")])
17724
17725 (define_expand "lwp_lwpval<mode>3"
17726   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17727                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17728                      (match_operand:SI 3 "const_int_operand" "i")]
17729                     UNSPECV_LWPVAL_INTRINSIC)]
17730   "TARGET_LWP"
17731   "/* Avoid unused variable warning.  */
17732    (void) operand0;")
17733
17734 (define_insn "*lwp_lwpval<mode>3_1"
17735   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17736                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17737                      (match_operand:SI 2 "const_int_operand" "i")]
17738                     UNSPECV_LWPVAL_INTRINSIC)]
17739   "TARGET_LWP"
17740   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17741   [(set_attr "type" "lwp")
17742    (set_attr "mode" "<MODE>")
17743    (set (attr "length")
17744         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17745
17746 (define_expand "lwp_lwpins<mode>3"
17747   [(set (reg:CCC FLAGS_REG)
17748         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17749                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17750                               (match_operand:SI 3 "const_int_operand" "i")]
17751                              UNSPECV_LWPINS_INTRINSIC))
17752    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17753         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17754   "TARGET_LWP")
17755
17756 (define_insn "*lwp_lwpins<mode>3_1"
17757   [(set (reg:CCC FLAGS_REG)
17758         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17759                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17760                               (match_operand:SI 2 "const_int_operand" "i")]
17761                              UNSPECV_LWPINS_INTRINSIC))]
17762   "TARGET_LWP"
17763   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17764   [(set_attr "type" "lwp")
17765    (set_attr "mode" "<MODE>")
17766    (set (attr "length")
17767         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17768
17769 (define_insn "rdfsbase<mode>"
17770   [(set (match_operand:SWI48 0 "register_operand" "=r")
17771         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17772   "TARGET_64BIT && TARGET_FSGSBASE"
17773   "rdfsbase %0"
17774   [(set_attr "type" "other")
17775    (set_attr "prefix_extra" "2")])
17776
17777 (define_insn "rdgsbase<mode>"
17778   [(set (match_operand:SWI48 0 "register_operand" "=r")
17779         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17780   "TARGET_64BIT && TARGET_FSGSBASE"
17781   "rdgsbase %0"
17782   [(set_attr "type" "other")
17783    (set_attr "prefix_extra" "2")])
17784
17785 (define_insn "wrfsbase<mode>"
17786   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17787                     UNSPECV_WRFSBASE)]
17788   "TARGET_64BIT && TARGET_FSGSBASE"
17789   "wrfsbase %0"
17790   [(set_attr "type" "other")
17791    (set_attr "prefix_extra" "2")])
17792
17793 (define_insn "wrgsbase<mode>"
17794   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17795                     UNSPECV_WRGSBASE)]
17796   "TARGET_64BIT && TARGET_FSGSBASE"
17797   "wrgsbase %0"
17798   [(set_attr "type" "other")
17799    (set_attr "prefix_extra" "2")])
17800
17801 (define_insn "rdrand<mode>_1"
17802   [(set (match_operand:SWI248 0 "register_operand" "=r")
17803         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17804    (set (reg:CCC FLAGS_REG)
17805         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17806   "TARGET_RDRND"
17807   "rdrand\t%0"
17808   [(set_attr "type" "other")
17809    (set_attr "prefix_extra" "1")])
17810
17811 (define_expand "pause"
17812   [(set (match_dup 0)
17813         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17814   ""
17815 {
17816   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17817   MEM_VOLATILE_P (operands[0]) = 1;
17818 })
17819
17820 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17821 ;; They have the same encoding.
17822 (define_insn "*pause"
17823   [(set (match_operand:BLK 0 "" "")
17824         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17825   ""
17826   "rep; nop"
17827   [(set_attr "length" "2")
17828    (set_attr "memory" "unknown")])
17829
17830 (include "mmx.md")
17831 (include "sse.md")
17832 (include "sync.md")