OSDN Git Service

bc6025323047a54936931528c09d55f4288010f6
[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 AVX2 support
235   UNSPEC_VPERMSI
236   UNSPEC_VPERMDF
237   UNSPEC_VPERMSF
238   UNSPEC_VPERMTI
239   UNSPEC_GATHER
240   UNSPEC_VSIBADDR
241
242   ;; For BMI support
243   UNSPEC_BEXTR
244
245   ;; For RDRAND support
246   UNSPEC_RDRAND
247
248   ;; For BMI2 support
249   UNSPEC_PDEP
250   UNSPEC_PEXT
251
252   ;; For __atomic support
253   UNSPEC_MOVA
254 ])
255
256 (define_c_enum "unspecv" [
257   UNSPECV_BLOCKAGE
258   UNSPECV_STACK_PROBE
259   UNSPECV_PROBE_STACK_RANGE
260   UNSPECV_EMMS
261   UNSPECV_LDMXCSR
262   UNSPECV_STMXCSR
263   UNSPECV_FEMMS
264   UNSPECV_CLFLUSH
265   UNSPECV_ALIGN
266   UNSPECV_MONITOR
267   UNSPECV_MWAIT
268   UNSPECV_CMPXCHG_1
269   UNSPECV_CMPXCHG_2
270   UNSPECV_CMPXCHG_3
271   UNSPECV_CMPXCHG_4
272   UNSPECV_XCHG
273   UNSPECV_LOCK
274   UNSPECV_PROLOGUE_USE
275   UNSPECV_CLD
276   UNSPECV_NOPS
277   UNSPECV_VZEROALL
278   UNSPECV_VZEROUPPER
279   UNSPECV_RDTSC
280   UNSPECV_RDTSCP
281   UNSPECV_RDPMC
282   UNSPECV_LLWP_INTRINSIC
283   UNSPECV_SLWP_INTRINSIC
284   UNSPECV_LWPVAL_INTRINSIC
285   UNSPECV_LWPINS_INTRINSIC
286   UNSPECV_RDFSBASE
287   UNSPECV_RDGSBASE
288   UNSPECV_WRFSBASE
289   UNSPECV_WRGSBASE
290   UNSPECV_SPLIT_STACK_RETURN
291 ])
292
293 ;; Constants to represent rounding modes in the ROUND instruction
294 (define_constants
295   [(ROUND_FLOOR                 0x1)
296    (ROUND_CEIL                  0x2)
297    (ROUND_TRUNC                 0x3)
298    (ROUND_MXCSR                 0x4)
299    (ROUND_NO_EXC                0x8)
300   ])
301
302 ;; Constants to represent pcomtrue/pcomfalse variants
303 (define_constants
304   [(PCOM_FALSE                  0)
305    (PCOM_TRUE                   1)
306    (COM_FALSE_S                 2)
307    (COM_FALSE_P                 3)
308    (COM_TRUE_S                  4)
309    (COM_TRUE_P                  5)
310   ])
311
312 ;; Constants used in the XOP pperm instruction
313 (define_constants
314   [(PPERM_SRC                   0x00)   /* copy source */
315    (PPERM_INVERT                0x20)   /* invert source */
316    (PPERM_REVERSE               0x40)   /* bit reverse source */
317    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
318    (PPERM_ZERO                  0x80)   /* all 0's */
319    (PPERM_ONES                  0xa0)   /* all 1's */
320    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
321    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
322    (PPERM_SRC1                  0x00)   /* use first source byte */
323    (PPERM_SRC2                  0x10)   /* use second source byte */
324    ])
325
326 ;; Registers by name.
327 (define_constants
328   [(AX_REG                       0)
329    (DX_REG                       1)
330    (CX_REG                       2)
331    (BX_REG                       3)
332    (SI_REG                       4)
333    (DI_REG                       5)
334    (BP_REG                       6)
335    (SP_REG                       7)
336    (ST0_REG                      8)
337    (ST1_REG                      9)
338    (ST2_REG                     10)
339    (ST3_REG                     11)
340    (ST4_REG                     12)
341    (ST5_REG                     13)
342    (ST6_REG                     14)
343    (ST7_REG                     15)
344    (FLAGS_REG                   17)
345    (FPSR_REG                    18)
346    (FPCR_REG                    19)
347    (XMM0_REG                    21)
348    (XMM1_REG                    22)
349    (XMM2_REG                    23)
350    (XMM3_REG                    24)
351    (XMM4_REG                    25)
352    (XMM5_REG                    26)
353    (XMM6_REG                    27)
354    (XMM7_REG                    28)
355    (MM0_REG                     29)
356    (MM1_REG                     30)
357    (MM2_REG                     31)
358    (MM3_REG                     32)
359    (MM4_REG                     33)
360    (MM5_REG                     34)
361    (MM6_REG                     35)
362    (MM7_REG                     36)
363    (R8_REG                      37)
364    (R9_REG                      38)
365    (R10_REG                     39)
366    (R11_REG                     40)
367    (R12_REG                     41)
368    (R13_REG                     42)
369    (XMM8_REG                    45)
370    (XMM9_REG                    46)
371    (XMM10_REG                   47)
372    (XMM11_REG                   48)
373    (XMM12_REG                   49)
374    (XMM13_REG                   50)
375    (XMM14_REG                   51)
376    (XMM15_REG                   52)
377   ])
378
379 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
380 ;; from i386.c.
381
382 ;; In C guard expressions, put expressions which may be compile-time
383 ;; constants first.  This allows for better optimization.  For
384 ;; example, write "TARGET_64BIT && reload_completed", not
385 ;; "reload_completed && TARGET_64BIT".
386
387 \f
388 ;; Processor type.
389 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
390                     atom,generic64,amdfam10,bdver1,bdver2,btver1"
391   (const (symbol_ref "ix86_schedule")))
392
393 ;; A basic instruction type.  Refinements due to arguments to be
394 ;; provided in other attributes.
395 (define_attr "type"
396   "other,multi,
397    alu,alu1,negnot,imov,imovx,lea,
398    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
399    icmp,test,ibr,setcc,icmov,
400    push,pop,call,callv,leave,
401    str,bitmanip,
402    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
403    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
404    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
405    ssemuladd,sse4arg,lwp,
406    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
407   (const_string "other"))
408
409 ;; Main data type used by the insn
410 (define_attr "mode"
411   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
412   (const_string "unknown"))
413
414 ;; The CPU unit operations uses.
415 (define_attr "unit" "integer,i387,sse,mmx,unknown"
416   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
417            (const_string "i387")
418          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
419                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
420                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
421            (const_string "sse")
422          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
423            (const_string "mmx")
424          (eq_attr "type" "other")
425            (const_string "unknown")]
426          (const_string "integer")))
427
428 ;; The (bounding maximum) length of an instruction immediate.
429 (define_attr "length_immediate" ""
430   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
431                           bitmanip,imulx")
432            (const_int 0)
433          (eq_attr "unit" "i387,sse,mmx")
434            (const_int 0)
435          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
436                           rotate,rotatex,rotate1,imul,icmp,push,pop")
437            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
438          (eq_attr "type" "imov,test")
439            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
440          (eq_attr "type" "call")
441            (if_then_else (match_operand 0 "constant_call_address_operand" "")
442              (const_int 4)
443              (const_int 0))
444          (eq_attr "type" "callv")
445            (if_then_else (match_operand 1 "constant_call_address_operand" "")
446              (const_int 4)
447              (const_int 0))
448          ;; We don't know the size before shorten_branches.  Expect
449          ;; the instruction to fit for better scheduling.
450          (eq_attr "type" "ibr")
451            (const_int 1)
452          ]
453          (symbol_ref "/* Update immediate_length and other attributes! */
454                       gcc_unreachable (),1")))
455
456 ;; The (bounding maximum) length of an instruction address.
457 (define_attr "length_address" ""
458   (cond [(eq_attr "type" "str,other,multi,fxch")
459            (const_int 0)
460          (and (eq_attr "type" "call")
461               (match_operand 0 "constant_call_address_operand" ""))
462              (const_int 0)
463          (and (eq_attr "type" "callv")
464               (match_operand 1 "constant_call_address_operand" ""))
465              (const_int 0)
466          ]
467          (symbol_ref "ix86_attr_length_address_default (insn)")))
468
469 ;; Set when length prefix is used.
470 (define_attr "prefix_data16" ""
471   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
472            (const_int 0)
473          (eq_attr "mode" "HI")
474            (const_int 1)
475          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
476            (const_int 1)
477         ]
478         (const_int 0)))
479
480 ;; Set when string REP prefix is used.
481 (define_attr "prefix_rep" ""
482   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
483            (const_int 0)
484          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
485            (const_int 1)
486         ]
487         (const_int 0)))
488
489 ;; Set when 0f opcode prefix is used.
490 (define_attr "prefix_0f" ""
491   (if_then_else
492     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
493          (eq_attr "unit" "sse,mmx"))
494     (const_int 1)
495     (const_int 0)))
496
497 ;; Set when REX opcode prefix is used.
498 (define_attr "prefix_rex" ""
499   (cond [(not (match_test "TARGET_64BIT"))
500            (const_int 0)
501          (and (eq_attr "mode" "DI")
502               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
503                    (eq_attr "unit" "!mmx")))
504            (const_int 1)
505          (and (eq_attr "mode" "QI")
506               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
507            (const_int 1)
508          (match_test "x86_extended_reg_mentioned_p (insn)")
509            (const_int 1)
510          (and (eq_attr "type" "imovx")
511               (match_operand:QI 1 "ext_QIreg_operand" ""))
512            (const_int 1)
513         ]
514         (const_int 0)))
515
516 ;; There are also additional prefixes in 3DNOW, SSSE3.
517 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
518 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
519 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
520 (define_attr "prefix_extra" ""
521   (cond [(eq_attr "type" "ssemuladd,sse4arg")
522            (const_int 2)
523          (eq_attr "type" "sseiadd1,ssecvt1")
524            (const_int 1)
525         ]
526         (const_int 0)))
527
528 ;; Prefix used: original, VEX or maybe VEX.
529 (define_attr "prefix" "orig,vex,maybe_vex"
530   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
531     (const_string "vex")
532     (const_string "orig")))
533
534 ;; VEX W bit is used.
535 (define_attr "prefix_vex_w" "" (const_int 0))
536
537 ;; The length of VEX prefix
538 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
539 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
540 ;; still prefix_0f 1, with prefix_extra 1.
541 (define_attr "length_vex" ""
542   (if_then_else (and (eq_attr "prefix_0f" "1")
543                      (eq_attr "prefix_extra" "0"))
544     (if_then_else (eq_attr "prefix_vex_w" "1")
545       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
546       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
547     (if_then_else (eq_attr "prefix_vex_w" "1")
548       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
549       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
550
551 ;; Set when modrm byte is used.
552 (define_attr "modrm" ""
553   (cond [(eq_attr "type" "str,leave")
554            (const_int 0)
555          (eq_attr "unit" "i387")
556            (const_int 0)
557          (and (eq_attr "type" "incdec")
558               (and (not (match_test "TARGET_64BIT"))
559                    (ior (match_operand:SI 1 "register_operand" "")
560                         (match_operand:HI 1 "register_operand" ""))))
561            (const_int 0)
562          (and (eq_attr "type" "push")
563               (not (match_operand 1 "memory_operand" "")))
564            (const_int 0)
565          (and (eq_attr "type" "pop")
566               (not (match_operand 0 "memory_operand" "")))
567            (const_int 0)
568          (and (eq_attr "type" "imov")
569               (and (not (eq_attr "mode" "DI"))
570                    (ior (and (match_operand 0 "register_operand" "")
571                              (match_operand 1 "immediate_operand" ""))
572                         (ior (and (match_operand 0 "ax_reg_operand" "")
573                                   (match_operand 1 "memory_displacement_only_operand" ""))
574                              (and (match_operand 0 "memory_displacement_only_operand" "")
575                                   (match_operand 1 "ax_reg_operand" ""))))))
576            (const_int 0)
577          (and (eq_attr "type" "call")
578               (match_operand 0 "constant_call_address_operand" ""))
579              (const_int 0)
580          (and (eq_attr "type" "callv")
581               (match_operand 1 "constant_call_address_operand" ""))
582              (const_int 0)
583          (and (eq_attr "type" "alu,alu1,icmp,test")
584               (match_operand 0 "ax_reg_operand" ""))
585              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
586          ]
587          (const_int 1)))
588
589 ;; The (bounding maximum) length of an instruction in bytes.
590 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
591 ;; Later we may want to split them and compute proper length as for
592 ;; other insns.
593 (define_attr "length" ""
594   (cond [(eq_attr "type" "other,multi,fistp,frndint")
595            (const_int 16)
596          (eq_attr "type" "fcmp")
597            (const_int 4)
598          (eq_attr "unit" "i387")
599            (plus (const_int 2)
600                  (plus (attr "prefix_data16")
601                        (attr "length_address")))
602          (ior (eq_attr "prefix" "vex")
603               (and (eq_attr "prefix" "maybe_vex")
604                    (match_test "TARGET_AVX")))
605            (plus (attr "length_vex")
606                  (plus (attr "length_immediate")
607                        (plus (attr "modrm")
608                              (attr "length_address"))))]
609          (plus (plus (attr "modrm")
610                      (plus (attr "prefix_0f")
611                            (plus (attr "prefix_rex")
612                                  (plus (attr "prefix_extra")
613                                        (const_int 1)))))
614                (plus (attr "prefix_rep")
615                      (plus (attr "prefix_data16")
616                            (plus (attr "length_immediate")
617                                  (attr "length_address")))))))
618
619 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
620 ;; `store' if there is a simple memory reference therein, or `unknown'
621 ;; if the instruction is complex.
622
623 (define_attr "memory" "none,load,store,both,unknown"
624   (cond [(eq_attr "type" "other,multi,str,lwp")
625            (const_string "unknown")
626          (eq_attr "type" "lea,fcmov,fpspc")
627            (const_string "none")
628          (eq_attr "type" "fistp,leave")
629            (const_string "both")
630          (eq_attr "type" "frndint")
631            (const_string "load")
632          (eq_attr "type" "push")
633            (if_then_else (match_operand 1 "memory_operand" "")
634              (const_string "both")
635              (const_string "store"))
636          (eq_attr "type" "pop")
637            (if_then_else (match_operand 0 "memory_operand" "")
638              (const_string "both")
639              (const_string "load"))
640          (eq_attr "type" "setcc")
641            (if_then_else (match_operand 0 "memory_operand" "")
642              (const_string "store")
643              (const_string "none"))
644          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
645            (if_then_else (ior (match_operand 0 "memory_operand" "")
646                               (match_operand 1 "memory_operand" ""))
647              (const_string "load")
648              (const_string "none"))
649          (eq_attr "type" "ibr")
650            (if_then_else (match_operand 0 "memory_operand" "")
651              (const_string "load")
652              (const_string "none"))
653          (eq_attr "type" "call")
654            (if_then_else (match_operand 0 "constant_call_address_operand" "")
655              (const_string "none")
656              (const_string "load"))
657          (eq_attr "type" "callv")
658            (if_then_else (match_operand 1 "constant_call_address_operand" "")
659              (const_string "none")
660              (const_string "load"))
661          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
662               (match_operand 1 "memory_operand" ""))
663            (const_string "both")
664          (and (match_operand 0 "memory_operand" "")
665               (match_operand 1 "memory_operand" ""))
666            (const_string "both")
667          (match_operand 0 "memory_operand" "")
668            (const_string "store")
669          (match_operand 1 "memory_operand" "")
670            (const_string "load")
671          (and (eq_attr "type"
672                  "!alu1,negnot,ishift1,
673                    imov,imovx,icmp,test,bitmanip,
674                    fmov,fcmp,fsgn,
675                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
676                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
677               (match_operand 2 "memory_operand" ""))
678            (const_string "load")
679          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
680               (match_operand 3 "memory_operand" ""))
681            (const_string "load")
682         ]
683         (const_string "none")))
684
685 ;; Indicates if an instruction has both an immediate and a displacement.
686
687 (define_attr "imm_disp" "false,true,unknown"
688   (cond [(eq_attr "type" "other,multi")
689            (const_string "unknown")
690          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
691               (and (match_operand 0 "memory_displacement_operand" "")
692                    (match_operand 1 "immediate_operand" "")))
693            (const_string "true")
694          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
695               (and (match_operand 0 "memory_displacement_operand" "")
696                    (match_operand 2 "immediate_operand" "")))
697            (const_string "true")
698         ]
699         (const_string "false")))
700
701 ;; Indicates if an FP operation has an integer source.
702
703 (define_attr "fp_int_src" "false,true"
704   (const_string "false"))
705
706 ;; Defines rounding mode of an FP operation.
707
708 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
709   (const_string "any"))
710
711 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
712 (define_attr "use_carry" "0,1" (const_string "0"))
713
714 ;; Define attribute to indicate unaligned ssemov insns
715 (define_attr "movu" "0,1" (const_string "0"))
716
717 ;; Used to control the "enabled" attribute on a per-instruction basis.
718 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
719   (const_string "base"))
720
721 (define_attr "enabled" ""
722   (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
723          (eq_attr "isa" "sse2_noavx")
724            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
725          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
726          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
727          (eq_attr "isa" "sse4_noavx")
728            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
729          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
730          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
731          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
732         ]
733         (const_int 1)))
734
735 ;; Describe a user's asm statement.
736 (define_asm_attributes
737   [(set_attr "length" "128")
738    (set_attr "type" "multi")])
739
740 (define_code_iterator plusminus [plus minus])
741
742 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
743
744 ;; Base name for define_insn
745 (define_code_attr plusminus_insn
746   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
747    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
748
749 ;; Base name for insn mnemonic.
750 (define_code_attr plusminus_mnemonic
751   [(plus "add") (ss_plus "adds") (us_plus "addus")
752    (minus "sub") (ss_minus "subs") (us_minus "subus")])
753 (define_code_attr plusminus_carry_mnemonic
754   [(plus "adc") (minus "sbb")])
755
756 ;; Mark commutative operators as such in constraints.
757 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
758                         (minus "") (ss_minus "") (us_minus "")])
759
760 ;; Mapping of max and min
761 (define_code_iterator maxmin [smax smin umax umin])
762
763 ;; Mapping of signed max and min
764 (define_code_iterator smaxmin [smax smin])
765
766 ;; Mapping of unsigned max and min
767 (define_code_iterator umaxmin [umax umin])
768
769 ;; Base name for integer and FP insn mnemonic
770 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
771                               (umax "maxu") (umin "minu")])
772 (define_code_attr maxmin_float [(smax "max") (smin "min")])
773
774 ;; Mapping of logic operators
775 (define_code_iterator any_logic [and ior xor])
776 (define_code_iterator any_or [ior xor])
777
778 ;; Base name for insn mnemonic.
779 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
780
781 ;; Mapping of logic-shift operators
782 (define_code_iterator any_lshift [ashift lshiftrt])
783
784 ;; Mapping of shift-right operators
785 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
786
787 ;; Base name for define_insn
788 (define_code_attr shift_insn
789   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
790
791 ;; Base name for insn mnemonic.
792 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
793 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
794
795 ;; Mapping of rotate operators
796 (define_code_iterator any_rotate [rotate rotatert])
797
798 ;; Base name for define_insn
799 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
800
801 ;; Base name for insn mnemonic.
802 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
803
804 ;; Mapping of abs neg operators
805 (define_code_iterator absneg [abs neg])
806
807 ;; Base name for x87 insn mnemonic.
808 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
809
810 ;; Used in signed and unsigned widening multiplications.
811 (define_code_iterator any_extend [sign_extend zero_extend])
812
813 ;; Prefix for insn menmonic.
814 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
815
816 ;; Prefix for define_insn
817 (define_code_attr u [(sign_extend "") (zero_extend "u")])
818 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
819
820 ;; All integer modes.
821 (define_mode_iterator SWI1248x [QI HI SI DI])
822
823 ;; All integer modes without QImode.
824 (define_mode_iterator SWI248x [HI SI DI])
825
826 ;; All integer modes without QImode and HImode.
827 (define_mode_iterator SWI48x [SI DI])
828
829 ;; All integer modes without SImode and DImode.
830 (define_mode_iterator SWI12 [QI HI])
831
832 ;; All integer modes without DImode.
833 (define_mode_iterator SWI124 [QI HI SI])
834
835 ;; All integer modes without QImode and DImode.
836 (define_mode_iterator SWI24 [HI SI])
837
838 ;; Single word integer modes.
839 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
840
841 ;; Single word integer modes without QImode.
842 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
843
844 ;; Single word integer modes without QImode and HImode.
845 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
846
847 ;; All math-dependant single and double word integer modes.
848 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
849                              (HI "TARGET_HIMODE_MATH")
850                              SI DI (TI "TARGET_64BIT")])
851
852 ;; Math-dependant single word integer modes.
853 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
854                             (HI "TARGET_HIMODE_MATH")
855                             SI (DI "TARGET_64BIT")])
856
857 ;; Math-dependant integer modes without DImode.
858 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
859                                (HI "TARGET_HIMODE_MATH")
860                                SI])
861
862 ;; Math-dependant single word integer modes without QImode.
863 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
864                                SI (DI "TARGET_64BIT")])
865
866 ;; Double word integer modes.
867 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
868                            (TI "TARGET_64BIT")])
869
870 ;; Double word integer modes as mode attribute.
871 (define_mode_attr DWI [(SI "DI") (DI "TI")])
872 (define_mode_attr dwi [(SI "di") (DI "ti")])
873
874 ;; Half mode for double word integer modes.
875 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
876                             (DI "TARGET_64BIT")])
877
878 ;; Instruction suffix for integer modes.
879 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
880
881 ;; Pointer size prefix for integer modes (Intel asm dialect)
882 (define_mode_attr iptrsize [(QI "BYTE")
883                             (HI "WORD")
884                             (SI "DWORD")
885                             (DI "QWORD")])
886
887 ;; Register class for integer modes.
888 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
889
890 ;; Immediate operand constraint for integer modes.
891 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
892
893 ;; General operand constraint for word modes.
894 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
895
896 ;; Immediate operand constraint for double integer modes.
897 (define_mode_attr di [(SI "nF") (DI "e")])
898
899 ;; Immediate operand constraint for shifts.
900 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
901
902 ;; General operand predicate for integer modes.
903 (define_mode_attr general_operand
904         [(QI "general_operand")
905          (HI "general_operand")
906          (SI "x86_64_general_operand")
907          (DI "x86_64_general_operand")
908          (TI "x86_64_general_operand")])
909
910 ;; General sign/zero extend operand predicate for integer modes.
911 (define_mode_attr general_szext_operand
912         [(QI "general_operand")
913          (HI "general_operand")
914          (SI "x86_64_szext_general_operand")
915          (DI "x86_64_szext_general_operand")])
916
917 ;; Immediate operand predicate for integer modes.
918 (define_mode_attr immediate_operand
919         [(QI "immediate_operand")
920          (HI "immediate_operand")
921          (SI "x86_64_immediate_operand")
922          (DI "x86_64_immediate_operand")])
923
924 ;; Nonmemory operand predicate for integer modes.
925 (define_mode_attr nonmemory_operand
926         [(QI "nonmemory_operand")
927          (HI "nonmemory_operand")
928          (SI "x86_64_nonmemory_operand")
929          (DI "x86_64_nonmemory_operand")])
930
931 ;; Operand predicate for shifts.
932 (define_mode_attr shift_operand
933         [(QI "nonimmediate_operand")
934          (HI "nonimmediate_operand")
935          (SI "nonimmediate_operand")
936          (DI "shiftdi_operand")
937          (TI "register_operand")])
938
939 ;; Operand predicate for shift argument.
940 (define_mode_attr shift_immediate_operand
941         [(QI "const_1_to_31_operand")
942          (HI "const_1_to_31_operand")
943          (SI "const_1_to_31_operand")
944          (DI "const_1_to_63_operand")])
945
946 ;; Input operand predicate for arithmetic left shifts.
947 (define_mode_attr ashl_input_operand
948         [(QI "nonimmediate_operand")
949          (HI "nonimmediate_operand")
950          (SI "nonimmediate_operand")
951          (DI "ashldi_input_operand")
952          (TI "reg_or_pm1_operand")])
953
954 ;; SSE and x87 SFmode and DFmode floating point modes
955 (define_mode_iterator MODEF [SF DF])
956
957 ;; All x87 floating point modes
958 (define_mode_iterator X87MODEF [SF DF XF])
959
960 ;; SSE instruction suffix for various modes
961 (define_mode_attr ssemodesuffix
962   [(SF "ss") (DF "sd")
963    (V8SF "ps") (V4DF "pd")
964    (V4SF "ps") (V2DF "pd")
965    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
966    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
967
968 ;; SSE vector suffix for floating point modes
969 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
970
971 ;; SSE vector mode corresponding to a scalar mode
972 (define_mode_attr ssevecmode
973   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
974
975 ;; Instruction suffix for REX 64bit operators.
976 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
977
978 ;; This mode iterator allows :P to be used for patterns that operate on
979 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
980 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
981
982 ;; This mode iterator allows :PTR to be used for patterns that operate on
983 ;; ptr_mode sized quantities.
984 (define_mode_iterator PTR
985   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
986 \f
987 ;; Scheduling descriptions
988
989 (include "pentium.md")
990 (include "ppro.md")
991 (include "k6.md")
992 (include "athlon.md")
993 (include "bdver1.md")
994 (include "geode.md")
995 (include "atom.md")
996 (include "core2.md")
997
998 \f
999 ;; Operand and operator predicates and constraints
1000
1001 (include "predicates.md")
1002 (include "constraints.md")
1003
1004 \f
1005 ;; Compare and branch/compare and store instructions.
1006
1007 (define_expand "cbranch<mode>4"
1008   [(set (reg:CC FLAGS_REG)
1009         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
1010                     (match_operand:SDWIM 2 "<general_operand>" "")))
1011    (set (pc) (if_then_else
1012                (match_operator 0 "ordered_comparison_operator"
1013                 [(reg:CC FLAGS_REG) (const_int 0)])
1014                (label_ref (match_operand 3 "" ""))
1015                (pc)))]
1016   ""
1017 {
1018   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1019     operands[1] = force_reg (<MODE>mode, operands[1]);
1020   ix86_expand_branch (GET_CODE (operands[0]),
1021                       operands[1], operands[2], operands[3]);
1022   DONE;
1023 })
1024
1025 (define_expand "cstore<mode>4"
1026   [(set (reg:CC FLAGS_REG)
1027         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
1028                     (match_operand:SWIM 3 "<general_operand>" "")))
1029    (set (match_operand:QI 0 "register_operand" "")
1030         (match_operator 1 "ordered_comparison_operator"
1031           [(reg:CC FLAGS_REG) (const_int 0)]))]
1032   ""
1033 {
1034   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1035     operands[2] = force_reg (<MODE>mode, operands[2]);
1036   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1037                      operands[2], operands[3]);
1038   DONE;
1039 })
1040
1041 (define_expand "cmp<mode>_1"
1042   [(set (reg:CC FLAGS_REG)
1043         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1044                     (match_operand:SWI48 1 "<general_operand>" "")))])
1045
1046 (define_insn "*cmp<mode>_ccno_1"
1047   [(set (reg FLAGS_REG)
1048         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1049                  (match_operand:SWI 1 "const0_operand" "")))]
1050   "ix86_match_ccmode (insn, CCNOmode)"
1051   "@
1052    test{<imodesuffix>}\t%0, %0
1053    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1054   [(set_attr "type" "test,icmp")
1055    (set_attr "length_immediate" "0,1")
1056    (set_attr "mode" "<MODE>")])
1057
1058 (define_insn "*cmp<mode>_1"
1059   [(set (reg FLAGS_REG)
1060         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1061                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1062   "ix86_match_ccmode (insn, CCmode)"
1063   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1064   [(set_attr "type" "icmp")
1065    (set_attr "mode" "<MODE>")])
1066
1067 (define_insn "*cmp<mode>_minus_1"
1068   [(set (reg FLAGS_REG)
1069         (compare
1070           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1071                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1072           (const_int 0)))]
1073   "ix86_match_ccmode (insn, CCGOCmode)"
1074   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1075   [(set_attr "type" "icmp")
1076    (set_attr "mode" "<MODE>")])
1077
1078 (define_insn "*cmpqi_ext_1"
1079   [(set (reg FLAGS_REG)
1080         (compare
1081           (match_operand:QI 0 "general_operand" "Qm")
1082           (subreg:QI
1083             (zero_extract:SI
1084               (match_operand 1 "ext_register_operand" "Q")
1085               (const_int 8)
1086               (const_int 8)) 0)))]
1087   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1088   "cmp{b}\t{%h1, %0|%0, %h1}"
1089   [(set_attr "type" "icmp")
1090    (set_attr "mode" "QI")])
1091
1092 (define_insn "*cmpqi_ext_1_rex64"
1093   [(set (reg FLAGS_REG)
1094         (compare
1095           (match_operand:QI 0 "register_operand" "Q")
1096           (subreg:QI
1097             (zero_extract:SI
1098               (match_operand 1 "ext_register_operand" "Q")
1099               (const_int 8)
1100               (const_int 8)) 0)))]
1101   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1102   "cmp{b}\t{%h1, %0|%0, %h1}"
1103   [(set_attr "type" "icmp")
1104    (set_attr "mode" "QI")])
1105
1106 (define_insn "*cmpqi_ext_2"
1107   [(set (reg FLAGS_REG)
1108         (compare
1109           (subreg:QI
1110             (zero_extract:SI
1111               (match_operand 0 "ext_register_operand" "Q")
1112               (const_int 8)
1113               (const_int 8)) 0)
1114           (match_operand:QI 1 "const0_operand" "")))]
1115   "ix86_match_ccmode (insn, CCNOmode)"
1116   "test{b}\t%h0, %h0"
1117   [(set_attr "type" "test")
1118    (set_attr "length_immediate" "0")
1119    (set_attr "mode" "QI")])
1120
1121 (define_expand "cmpqi_ext_3"
1122   [(set (reg:CC FLAGS_REG)
1123         (compare:CC
1124           (subreg:QI
1125             (zero_extract:SI
1126               (match_operand 0 "ext_register_operand" "")
1127               (const_int 8)
1128               (const_int 8)) 0)
1129           (match_operand:QI 1 "immediate_operand" "")))])
1130
1131 (define_insn "*cmpqi_ext_3_insn"
1132   [(set (reg FLAGS_REG)
1133         (compare
1134           (subreg:QI
1135             (zero_extract:SI
1136               (match_operand 0 "ext_register_operand" "Q")
1137               (const_int 8)
1138               (const_int 8)) 0)
1139           (match_operand:QI 1 "general_operand" "Qmn")))]
1140   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1141   "cmp{b}\t{%1, %h0|%h0, %1}"
1142   [(set_attr "type" "icmp")
1143    (set_attr "modrm" "1")
1144    (set_attr "mode" "QI")])
1145
1146 (define_insn "*cmpqi_ext_3_insn_rex64"
1147   [(set (reg FLAGS_REG)
1148         (compare
1149           (subreg:QI
1150             (zero_extract:SI
1151               (match_operand 0 "ext_register_operand" "Q")
1152               (const_int 8)
1153               (const_int 8)) 0)
1154           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1155   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1156   "cmp{b}\t{%1, %h0|%h0, %1}"
1157   [(set_attr "type" "icmp")
1158    (set_attr "modrm" "1")
1159    (set_attr "mode" "QI")])
1160
1161 (define_insn "*cmpqi_ext_4"
1162   [(set (reg FLAGS_REG)
1163         (compare
1164           (subreg:QI
1165             (zero_extract:SI
1166               (match_operand 0 "ext_register_operand" "Q")
1167               (const_int 8)
1168               (const_int 8)) 0)
1169           (subreg:QI
1170             (zero_extract:SI
1171               (match_operand 1 "ext_register_operand" "Q")
1172               (const_int 8)
1173               (const_int 8)) 0)))]
1174   "ix86_match_ccmode (insn, CCmode)"
1175   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1176   [(set_attr "type" "icmp")
1177    (set_attr "mode" "QI")])
1178
1179 ;; These implement float point compares.
1180 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1181 ;; which would allow mix and match FP modes on the compares.  Which is what
1182 ;; the old patterns did, but with many more of them.
1183
1184 (define_expand "cbranchxf4"
1185   [(set (reg:CC FLAGS_REG)
1186         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1187                     (match_operand:XF 2 "nonmemory_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"
1195 {
1196   ix86_expand_branch (GET_CODE (operands[0]),
1197                       operands[1], operands[2], operands[3]);
1198   DONE;
1199 })
1200
1201 (define_expand "cstorexf4"
1202   [(set (reg:CC FLAGS_REG)
1203         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1204                     (match_operand:XF 3 "nonmemory_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"
1210 {
1211   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212                      operands[2], operands[3]);
1213   DONE;
1214 })
1215
1216 (define_expand "cbranch<mode>4"
1217   [(set (reg:CC FLAGS_REG)
1218         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1219                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1220    (set (pc) (if_then_else
1221               (match_operator 0 "ix86_fp_comparison_operator"
1222                [(reg:CC FLAGS_REG)
1223                 (const_int 0)])
1224               (label_ref (match_operand 3 "" ""))
1225               (pc)))]
1226   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1227 {
1228   ix86_expand_branch (GET_CODE (operands[0]),
1229                       operands[1], operands[2], operands[3]);
1230   DONE;
1231 })
1232
1233 (define_expand "cstore<mode>4"
1234   [(set (reg:CC FLAGS_REG)
1235         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1236                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1237    (set (match_operand:QI 0 "register_operand" "")
1238               (match_operator 1 "ix86_fp_comparison_operator"
1239                [(reg:CC FLAGS_REG)
1240                 (const_int 0)]))]
1241   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1242 {
1243   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1244                      operands[2], operands[3]);
1245   DONE;
1246 })
1247
1248 (define_expand "cbranchcc4"
1249   [(set (pc) (if_then_else
1250               (match_operator 0 "comparison_operator"
1251                [(match_operand 1 "flags_reg_operand" "")
1252                 (match_operand 2 "const0_operand" "")])
1253               (label_ref (match_operand 3 "" ""))
1254               (pc)))]
1255   ""
1256 {
1257   ix86_expand_branch (GET_CODE (operands[0]),
1258                       operands[1], operands[2], operands[3]);
1259   DONE;
1260 })
1261
1262 (define_expand "cstorecc4"
1263   [(set (match_operand:QI 0 "register_operand" "")
1264               (match_operator 1 "comparison_operator"
1265                [(match_operand 2 "flags_reg_operand" "")
1266                 (match_operand 3 "const0_operand" "")]))]
1267   ""
1268 {
1269   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1270                      operands[2], operands[3]);
1271   DONE;
1272 })
1273
1274
1275 ;; FP compares, step 1:
1276 ;; Set the FP condition codes.
1277 ;;
1278 ;; CCFPmode     compare with exceptions
1279 ;; CCFPUmode    compare with no exceptions
1280
1281 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1282 ;; used to manage the reg stack popping would not be preserved.
1283
1284 (define_insn "*cmpfp_0"
1285   [(set (match_operand:HI 0 "register_operand" "=a")
1286         (unspec:HI
1287           [(compare:CCFP
1288              (match_operand 1 "register_operand" "f")
1289              (match_operand 2 "const0_operand" ""))]
1290         UNSPEC_FNSTSW))]
1291   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1292    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1293   "* return output_fp_compare (insn, operands, false, false);"
1294   [(set_attr "type" "multi")
1295    (set_attr "unit" "i387")
1296    (set (attr "mode")
1297      (cond [(match_operand:SF 1 "" "")
1298               (const_string "SF")
1299             (match_operand:DF 1 "" "")
1300               (const_string "DF")
1301            ]
1302            (const_string "XF")))])
1303
1304 (define_insn_and_split "*cmpfp_0_cc"
1305   [(set (reg:CCFP FLAGS_REG)
1306         (compare:CCFP
1307           (match_operand 1 "register_operand" "f")
1308           (match_operand 2 "const0_operand" "")))
1309    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1310   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1311    && TARGET_SAHF && !TARGET_CMOVE
1312    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1313   "#"
1314   "&& reload_completed"
1315   [(set (match_dup 0)
1316         (unspec:HI
1317           [(compare:CCFP (match_dup 1)(match_dup 2))]
1318         UNSPEC_FNSTSW))
1319    (set (reg:CC FLAGS_REG)
1320         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1321   ""
1322   [(set_attr "type" "multi")
1323    (set_attr "unit" "i387")
1324    (set (attr "mode")
1325      (cond [(match_operand:SF 1 "" "")
1326               (const_string "SF")
1327             (match_operand:DF 1 "" "")
1328               (const_string "DF")
1329            ]
1330            (const_string "XF")))])
1331
1332 (define_insn "*cmpfp_xf"
1333   [(set (match_operand:HI 0 "register_operand" "=a")
1334         (unspec:HI
1335           [(compare:CCFP
1336              (match_operand:XF 1 "register_operand" "f")
1337              (match_operand:XF 2 "register_operand" "f"))]
1338           UNSPEC_FNSTSW))]
1339   "TARGET_80387"
1340   "* return output_fp_compare (insn, operands, false, false);"
1341   [(set_attr "type" "multi")
1342    (set_attr "unit" "i387")
1343    (set_attr "mode" "XF")])
1344
1345 (define_insn_and_split "*cmpfp_xf_cc"
1346   [(set (reg:CCFP FLAGS_REG)
1347         (compare:CCFP
1348           (match_operand:XF 1 "register_operand" "f")
1349           (match_operand:XF 2 "register_operand" "f")))
1350    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1351   "TARGET_80387
1352    && TARGET_SAHF && !TARGET_CMOVE"
1353   "#"
1354   "&& reload_completed"
1355   [(set (match_dup 0)
1356         (unspec:HI
1357           [(compare:CCFP (match_dup 1)(match_dup 2))]
1358         UNSPEC_FNSTSW))
1359    (set (reg:CC FLAGS_REG)
1360         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1361   ""
1362   [(set_attr "type" "multi")
1363    (set_attr "unit" "i387")
1364    (set_attr "mode" "XF")])
1365
1366 (define_insn "*cmpfp_<mode>"
1367   [(set (match_operand:HI 0 "register_operand" "=a")
1368         (unspec:HI
1369           [(compare:CCFP
1370              (match_operand:MODEF 1 "register_operand" "f")
1371              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1372           UNSPEC_FNSTSW))]
1373   "TARGET_80387"
1374   "* return output_fp_compare (insn, operands, false, false);"
1375   [(set_attr "type" "multi")
1376    (set_attr "unit" "i387")
1377    (set_attr "mode" "<MODE>")])
1378
1379 (define_insn_and_split "*cmpfp_<mode>_cc"
1380   [(set (reg:CCFP FLAGS_REG)
1381         (compare:CCFP
1382           (match_operand:MODEF 1 "register_operand" "f")
1383           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1384    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1385   "TARGET_80387
1386    && TARGET_SAHF && !TARGET_CMOVE"
1387   "#"
1388   "&& reload_completed"
1389   [(set (match_dup 0)
1390         (unspec:HI
1391           [(compare:CCFP (match_dup 1)(match_dup 2))]
1392         UNSPEC_FNSTSW))
1393    (set (reg:CC FLAGS_REG)
1394         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1395   ""
1396   [(set_attr "type" "multi")
1397    (set_attr "unit" "i387")
1398    (set_attr "mode" "<MODE>")])
1399
1400 (define_insn "*cmpfp_u"
1401   [(set (match_operand:HI 0 "register_operand" "=a")
1402         (unspec:HI
1403           [(compare:CCFPU
1404              (match_operand 1 "register_operand" "f")
1405              (match_operand 2 "register_operand" "f"))]
1406           UNSPEC_FNSTSW))]
1407   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1408    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1409   "* return output_fp_compare (insn, operands, false, true);"
1410   [(set_attr "type" "multi")
1411    (set_attr "unit" "i387")
1412    (set (attr "mode")
1413      (cond [(match_operand:SF 1 "" "")
1414               (const_string "SF")
1415             (match_operand:DF 1 "" "")
1416               (const_string "DF")
1417            ]
1418            (const_string "XF")))])
1419
1420 (define_insn_and_split "*cmpfp_u_cc"
1421   [(set (reg:CCFPU FLAGS_REG)
1422         (compare:CCFPU
1423           (match_operand 1 "register_operand" "f")
1424           (match_operand 2 "register_operand" "f")))
1425    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1426   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1427    && TARGET_SAHF && !TARGET_CMOVE
1428    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1429   "#"
1430   "&& reload_completed"
1431   [(set (match_dup 0)
1432         (unspec:HI
1433           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1434         UNSPEC_FNSTSW))
1435    (set (reg:CC FLAGS_REG)
1436         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1437   ""
1438   [(set_attr "type" "multi")
1439    (set_attr "unit" "i387")
1440    (set (attr "mode")
1441      (cond [(match_operand:SF 1 "" "")
1442               (const_string "SF")
1443             (match_operand:DF 1 "" "")
1444               (const_string "DF")
1445            ]
1446            (const_string "XF")))])
1447
1448 (define_insn "*cmpfp_<mode>"
1449   [(set (match_operand:HI 0 "register_operand" "=a")
1450         (unspec:HI
1451           [(compare:CCFP
1452              (match_operand 1 "register_operand" "f")
1453              (match_operator 3 "float_operator"
1454                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1455           UNSPEC_FNSTSW))]
1456   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1457    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1458    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1459   "* return output_fp_compare (insn, operands, false, false);"
1460   [(set_attr "type" "multi")
1461    (set_attr "unit" "i387")
1462    (set_attr "fp_int_src" "true")
1463    (set_attr "mode" "<MODE>")])
1464
1465 (define_insn_and_split "*cmpfp_<mode>_cc"
1466   [(set (reg:CCFP FLAGS_REG)
1467         (compare:CCFP
1468           (match_operand 1 "register_operand" "f")
1469           (match_operator 3 "float_operator"
1470             [(match_operand:SWI24 2 "memory_operand" "m")])))
1471    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1472   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1473    && TARGET_SAHF && !TARGET_CMOVE
1474    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1475    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1476   "#"
1477   "&& reload_completed"
1478   [(set (match_dup 0)
1479         (unspec:HI
1480           [(compare:CCFP
1481              (match_dup 1)
1482              (match_op_dup 3 [(match_dup 2)]))]
1483         UNSPEC_FNSTSW))
1484    (set (reg:CC FLAGS_REG)
1485         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1486   ""
1487   [(set_attr "type" "multi")
1488    (set_attr "unit" "i387")
1489    (set_attr "fp_int_src" "true")
1490    (set_attr "mode" "<MODE>")])
1491
1492 ;; FP compares, step 2
1493 ;; Move the fpsw to ax.
1494
1495 (define_insn "x86_fnstsw_1"
1496   [(set (match_operand:HI 0 "register_operand" "=a")
1497         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1498   "TARGET_80387"
1499   "fnstsw\t%0"
1500   [(set (attr "length")
1501         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1502    (set_attr "mode" "SI")
1503    (set_attr "unit" "i387")])
1504
1505 ;; FP compares, step 3
1506 ;; Get ax into flags, general case.
1507
1508 (define_insn "x86_sahf_1"
1509   [(set (reg:CC FLAGS_REG)
1510         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1511                    UNSPEC_SAHF))]
1512   "TARGET_SAHF"
1513 {
1514 #ifndef HAVE_AS_IX86_SAHF
1515   if (TARGET_64BIT)
1516     return ASM_BYTE "0x9e";
1517   else
1518 #endif
1519   return "sahf";
1520 }
1521   [(set_attr "length" "1")
1522    (set_attr "athlon_decode" "vector")
1523    (set_attr "amdfam10_decode" "direct")
1524    (set_attr "bdver1_decode" "direct")
1525    (set_attr "mode" "SI")])
1526
1527 ;; Pentium Pro can do steps 1 through 3 in one go.
1528 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1529 ;; (these i387 instructions set flags directly)
1530 (define_insn "*cmpfp_i_mixed"
1531   [(set (reg:CCFP FLAGS_REG)
1532         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1533                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1534   "TARGET_MIX_SSE_I387
1535    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1536    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1537   "* return output_fp_compare (insn, operands, true, false);"
1538   [(set_attr "type" "fcmp,ssecomi")
1539    (set_attr "prefix" "orig,maybe_vex")
1540    (set (attr "mode")
1541      (if_then_else (match_operand:SF 1 "" "")
1542         (const_string "SF")
1543         (const_string "DF")))
1544    (set (attr "prefix_rep")
1545         (if_then_else (eq_attr "type" "ssecomi")
1546                       (const_string "0")
1547                       (const_string "*")))
1548    (set (attr "prefix_data16")
1549         (cond [(eq_attr "type" "fcmp")
1550                  (const_string "*")
1551                (eq_attr "mode" "DF")
1552                  (const_string "1")
1553               ]
1554               (const_string "0")))
1555    (set_attr "athlon_decode" "vector")
1556    (set_attr "amdfam10_decode" "direct")
1557    (set_attr "bdver1_decode" "double")])
1558
1559 (define_insn "*cmpfp_i_sse"
1560   [(set (reg:CCFP FLAGS_REG)
1561         (compare:CCFP (match_operand 0 "register_operand" "x")
1562                       (match_operand 1 "nonimmediate_operand" "xm")))]
1563   "TARGET_SSE_MATH
1564    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1565    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1566   "* return output_fp_compare (insn, operands, true, false);"
1567   [(set_attr "type" "ssecomi")
1568    (set_attr "prefix" "maybe_vex")
1569    (set (attr "mode")
1570      (if_then_else (match_operand:SF 1 "" "")
1571         (const_string "SF")
1572         (const_string "DF")))
1573    (set_attr "prefix_rep" "0")
1574    (set (attr "prefix_data16")
1575         (if_then_else (eq_attr "mode" "DF")
1576                       (const_string "1")
1577                       (const_string "0")))
1578    (set_attr "athlon_decode" "vector")
1579    (set_attr "amdfam10_decode" "direct")
1580    (set_attr "bdver1_decode" "double")])
1581
1582 (define_insn "*cmpfp_i_i387"
1583   [(set (reg:CCFP FLAGS_REG)
1584         (compare:CCFP (match_operand 0 "register_operand" "f")
1585                       (match_operand 1 "register_operand" "f")))]
1586   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1587    && TARGET_CMOVE
1588    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1589    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1590   "* return output_fp_compare (insn, operands, true, false);"
1591   [(set_attr "type" "fcmp")
1592    (set (attr "mode")
1593      (cond [(match_operand:SF 1 "" "")
1594               (const_string "SF")
1595             (match_operand:DF 1 "" "")
1596               (const_string "DF")
1597            ]
1598            (const_string "XF")))
1599    (set_attr "athlon_decode" "vector")
1600    (set_attr "amdfam10_decode" "direct")
1601    (set_attr "bdver1_decode" "double")])
1602
1603 (define_insn "*cmpfp_iu_mixed"
1604   [(set (reg:CCFPU FLAGS_REG)
1605         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1606                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1607   "TARGET_MIX_SSE_I387
1608    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1609    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1610   "* return output_fp_compare (insn, operands, true, true);"
1611   [(set_attr "type" "fcmp,ssecomi")
1612    (set_attr "prefix" "orig,maybe_vex")
1613    (set (attr "mode")
1614      (if_then_else (match_operand:SF 1 "" "")
1615         (const_string "SF")
1616         (const_string "DF")))
1617    (set (attr "prefix_rep")
1618         (if_then_else (eq_attr "type" "ssecomi")
1619                       (const_string "0")
1620                       (const_string "*")))
1621    (set (attr "prefix_data16")
1622         (cond [(eq_attr "type" "fcmp")
1623                  (const_string "*")
1624                (eq_attr "mode" "DF")
1625                  (const_string "1")
1626               ]
1627               (const_string "0")))
1628    (set_attr "athlon_decode" "vector")
1629    (set_attr "amdfam10_decode" "direct")
1630    (set_attr "bdver1_decode" "double")])
1631
1632 (define_insn "*cmpfp_iu_sse"
1633   [(set (reg:CCFPU FLAGS_REG)
1634         (compare:CCFPU (match_operand 0 "register_operand" "x")
1635                        (match_operand 1 "nonimmediate_operand" "xm")))]
1636   "TARGET_SSE_MATH
1637    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1638    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1639   "* return output_fp_compare (insn, operands, true, true);"
1640   [(set_attr "type" "ssecomi")
1641    (set_attr "prefix" "maybe_vex")
1642    (set (attr "mode")
1643      (if_then_else (match_operand:SF 1 "" "")
1644         (const_string "SF")
1645         (const_string "DF")))
1646    (set_attr "prefix_rep" "0")
1647    (set (attr "prefix_data16")
1648         (if_then_else (eq_attr "mode" "DF")
1649                       (const_string "1")
1650                       (const_string "0")))
1651    (set_attr "athlon_decode" "vector")
1652    (set_attr "amdfam10_decode" "direct")
1653    (set_attr "bdver1_decode" "double")])
1654
1655 (define_insn "*cmpfp_iu_387"
1656   [(set (reg:CCFPU FLAGS_REG)
1657         (compare:CCFPU (match_operand 0 "register_operand" "f")
1658                        (match_operand 1 "register_operand" "f")))]
1659   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1660    && TARGET_CMOVE
1661    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1662    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1663   "* return output_fp_compare (insn, operands, true, true);"
1664   [(set_attr "type" "fcmp")
1665    (set (attr "mode")
1666      (cond [(match_operand:SF 1 "" "")
1667               (const_string "SF")
1668             (match_operand:DF 1 "" "")
1669               (const_string "DF")
1670            ]
1671            (const_string "XF")))
1672    (set_attr "athlon_decode" "vector")
1673    (set_attr "amdfam10_decode" "direct")
1674    (set_attr "bdver1_decode" "direct")])
1675 \f
1676 ;; Push/pop instructions.
1677
1678 (define_insn "*push<mode>2"
1679   [(set (match_operand:DWI 0 "push_operand" "=<")
1680         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1681   ""
1682   "#"
1683   [(set_attr "type" "multi")
1684    (set_attr "mode" "<MODE>")])
1685
1686 (define_split
1687   [(set (match_operand:TI 0 "push_operand" "")
1688         (match_operand:TI 1 "general_operand" ""))]
1689   "TARGET_64BIT && reload_completed
1690    && !SSE_REG_P (operands[1])"
1691   [(const_int 0)]
1692   "ix86_split_long_move (operands); DONE;")
1693
1694 (define_insn "*pushdi2_rex64"
1695   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1696         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1697   "TARGET_64BIT"
1698   "@
1699    push{q}\t%1
1700    #"
1701   [(set_attr "type" "push,multi")
1702    (set_attr "mode" "DI")])
1703
1704 ;; Convert impossible pushes of immediate to existing instructions.
1705 ;; First try to get scratch register and go through it.  In case this
1706 ;; fails, push sign extended lower part first and then overwrite
1707 ;; upper part by 32bit move.
1708 (define_peephole2
1709   [(match_scratch:DI 2 "r")
1710    (set (match_operand:DI 0 "push_operand" "")
1711         (match_operand:DI 1 "immediate_operand" ""))]
1712   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1713    && !x86_64_immediate_operand (operands[1], DImode)"
1714   [(set (match_dup 2) (match_dup 1))
1715    (set (match_dup 0) (match_dup 2))])
1716
1717 ;; We need to define this as both peepholer and splitter for case
1718 ;; peephole2 pass is not run.
1719 ;; "&& 1" is needed to keep it from matching the previous pattern.
1720 (define_peephole2
1721   [(set (match_operand:DI 0 "push_operand" "")
1722         (match_operand:DI 1 "immediate_operand" ""))]
1723   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1724    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1725   [(set (match_dup 0) (match_dup 1))
1726    (set (match_dup 2) (match_dup 3))]
1727 {
1728   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1729
1730   operands[1] = gen_lowpart (DImode, operands[2]);
1731   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1732                                                    GEN_INT (4)));
1733 })
1734
1735 (define_split
1736   [(set (match_operand:DI 0 "push_operand" "")
1737         (match_operand:DI 1 "immediate_operand" ""))]
1738   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1739                     ? epilogue_completed : reload_completed)
1740    && !symbolic_operand (operands[1], DImode)
1741    && !x86_64_immediate_operand (operands[1], DImode)"
1742   [(set (match_dup 0) (match_dup 1))
1743    (set (match_dup 2) (match_dup 3))]
1744 {
1745   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1746
1747   operands[1] = gen_lowpart (DImode, operands[2]);
1748   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1749                                                    GEN_INT (4)));
1750 })
1751
1752 (define_split
1753   [(set (match_operand:DI 0 "push_operand" "")
1754         (match_operand:DI 1 "general_operand" ""))]
1755   "!TARGET_64BIT && reload_completed
1756    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1757   [(const_int 0)]
1758   "ix86_split_long_move (operands); DONE;")
1759
1760 (define_insn "*pushsi2"
1761   [(set (match_operand:SI 0 "push_operand" "=<")
1762         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1763   "!TARGET_64BIT"
1764   "push{l}\t%1"
1765   [(set_attr "type" "push")
1766    (set_attr "mode" "SI")])
1767
1768 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1769 ;; "push a byte/word".  But actually we use pushl, which has the effect
1770 ;; of rounding the amount pushed up to a word.
1771
1772 ;; For TARGET_64BIT we always round up to 8 bytes.
1773 (define_insn "*push<mode>2_rex64"
1774   [(set (match_operand:SWI124 0 "push_operand" "=X")
1775         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1776   "TARGET_64BIT"
1777   "push{q}\t%q1"
1778   [(set_attr "type" "push")
1779    (set_attr "mode" "DI")])
1780
1781 (define_insn "*push<mode>2"
1782   [(set (match_operand:SWI12 0 "push_operand" "=X")
1783         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1784   "!TARGET_64BIT"
1785   "push{l}\t%k1"
1786   [(set_attr "type" "push")
1787    (set_attr "mode" "SI")])
1788
1789 (define_insn "*push<mode>2_prologue"
1790   [(set (match_operand:P 0 "push_operand" "=<")
1791         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1792    (clobber (mem:BLK (scratch)))]
1793   ""
1794   "push{<imodesuffix>}\t%1"
1795   [(set_attr "type" "push")
1796    (set_attr "mode" "<MODE>")])
1797
1798 (define_insn "*pop<mode>1"
1799   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1800         (match_operand:P 1 "pop_operand" ">"))]
1801   ""
1802   "pop{<imodesuffix>}\t%0"
1803   [(set_attr "type" "pop")
1804    (set_attr "mode" "<MODE>")])
1805
1806 (define_insn "*pop<mode>1_epilogue"
1807   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1808         (match_operand:P 1 "pop_operand" ">"))
1809    (clobber (mem:BLK (scratch)))]
1810   ""
1811   "pop{<imodesuffix>}\t%0"
1812   [(set_attr "type" "pop")
1813    (set_attr "mode" "<MODE>")])
1814 \f
1815 ;; Move instructions.
1816
1817 (define_expand "movoi"
1818   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1819         (match_operand:OI 1 "general_operand" ""))]
1820   "TARGET_AVX"
1821   "ix86_expand_move (OImode, operands); DONE;")
1822
1823 (define_expand "movti"
1824   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1825         (match_operand:TI 1 "nonimmediate_operand" ""))]
1826   "TARGET_64BIT || TARGET_SSE"
1827 {
1828   if (TARGET_64BIT)
1829     ix86_expand_move (TImode, operands);
1830   else if (push_operand (operands[0], TImode))
1831     ix86_expand_push (TImode, operands[1]);
1832   else
1833     ix86_expand_vector_move (TImode, operands);
1834   DONE;
1835 })
1836
1837 ;; This expands to what emit_move_complex would generate if we didn't
1838 ;; have a movti pattern.  Having this avoids problems with reload on
1839 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1840 ;; to have around all the time.
1841 (define_expand "movcdi"
1842   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1843         (match_operand:CDI 1 "general_operand" ""))]
1844   ""
1845 {
1846   if (push_operand (operands[0], CDImode))
1847     emit_move_complex_push (CDImode, operands[0], operands[1]);
1848   else
1849     emit_move_complex_parts (operands[0], operands[1]);
1850   DONE;
1851 })
1852
1853 (define_expand "mov<mode>"
1854   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1855         (match_operand:SWI1248x 1 "general_operand" ""))]
1856   ""
1857   "ix86_expand_move (<MODE>mode, operands); DONE;")
1858
1859 (define_insn "*mov<mode>_xor"
1860   [(set (match_operand:SWI48 0 "register_operand" "=r")
1861         (match_operand:SWI48 1 "const0_operand" ""))
1862    (clobber (reg:CC FLAGS_REG))]
1863   "reload_completed"
1864   "xor{l}\t%k0, %k0"
1865   [(set_attr "type" "alu1")
1866    (set_attr "mode" "SI")
1867    (set_attr "length_immediate" "0")])
1868
1869 (define_insn "*mov<mode>_or"
1870   [(set (match_operand:SWI48 0 "register_operand" "=r")
1871         (match_operand:SWI48 1 "const_int_operand" ""))
1872    (clobber (reg:CC FLAGS_REG))]
1873   "reload_completed
1874    && operands[1] == constm1_rtx"
1875   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1876   [(set_attr "type" "alu1")
1877    (set_attr "mode" "<MODE>")
1878    (set_attr "length_immediate" "1")])
1879
1880 (define_insn "*movoi_internal_avx"
1881   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1882         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1883   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1884 {
1885   switch (which_alternative)
1886     {
1887     case 0:
1888       return standard_sse_constant_opcode (insn, operands[1]);
1889     case 1:
1890     case 2:
1891       if (misaligned_operand (operands[0], OImode)
1892           || misaligned_operand (operands[1], OImode))
1893         return "vmovdqu\t{%1, %0|%0, %1}";
1894       else
1895         return "vmovdqa\t{%1, %0|%0, %1}";
1896     default:
1897       gcc_unreachable ();
1898     }
1899 }
1900   [(set_attr "type" "sselog1,ssemov,ssemov")
1901    (set_attr "prefix" "vex")
1902    (set_attr "mode" "OI")])
1903
1904 (define_insn "*movti_internal_rex64"
1905   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1906         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1907   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1908 {
1909   switch (which_alternative)
1910     {
1911     case 0:
1912     case 1:
1913       return "#";
1914     case 2:
1915       return standard_sse_constant_opcode (insn, operands[1]);
1916     case 3:
1917     case 4:
1918       /* TDmode values are passed as TImode on the stack.  Moving them
1919          to stack may result in unaligned memory access.  */
1920       if (misaligned_operand (operands[0], TImode)
1921           || misaligned_operand (operands[1], TImode))
1922         {
1923           if (get_attr_mode (insn) == MODE_V4SF)
1924             return "%vmovups\t{%1, %0|%0, %1}";
1925           else
1926             return "%vmovdqu\t{%1, %0|%0, %1}";
1927         }
1928       else
1929         {
1930           if (get_attr_mode (insn) == MODE_V4SF)
1931             return "%vmovaps\t{%1, %0|%0, %1}";
1932           else
1933             return "%vmovdqa\t{%1, %0|%0, %1}";
1934         }
1935     default:
1936       gcc_unreachable ();
1937     }
1938 }
1939   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1940    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1941    (set (attr "mode")
1942         (cond [(eq_attr "alternative" "2,3")
1943                  (if_then_else
1944                    (match_test "optimize_function_for_size_p (cfun)")
1945                    (const_string "V4SF")
1946                    (const_string "TI"))
1947                (eq_attr "alternative" "4")
1948                  (if_then_else
1949                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1950                         (match_test "optimize_function_for_size_p (cfun)"))
1951                    (const_string "V4SF")
1952                    (const_string "TI"))]
1953                (const_string "DI")))])
1954
1955 (define_split
1956   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1957         (match_operand:TI 1 "general_operand" ""))]
1958   "reload_completed
1959    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1960   [(const_int 0)]
1961   "ix86_split_long_move (operands); DONE;")
1962
1963 (define_insn "*movti_internal_sse"
1964   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1965         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1966   "TARGET_SSE && !TARGET_64BIT
1967    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1968 {
1969   switch (which_alternative)
1970     {
1971     case 0:
1972       return standard_sse_constant_opcode (insn, operands[1]);
1973     case 1:
1974     case 2:
1975       /* TDmode values are passed as TImode on the stack.  Moving them
1976          to stack may result in unaligned memory access.  */
1977       if (misaligned_operand (operands[0], TImode)
1978           || misaligned_operand (operands[1], TImode))
1979         {
1980           if (get_attr_mode (insn) == MODE_V4SF)
1981             return "%vmovups\t{%1, %0|%0, %1}";
1982           else
1983             return "%vmovdqu\t{%1, %0|%0, %1}";
1984         }
1985       else
1986         {
1987           if (get_attr_mode (insn) == MODE_V4SF)
1988             return "%vmovaps\t{%1, %0|%0, %1}";
1989           else
1990             return "%vmovdqa\t{%1, %0|%0, %1}";
1991         }
1992     default:
1993       gcc_unreachable ();
1994     }
1995 }
1996   [(set_attr "type" "sselog1,ssemov,ssemov")
1997    (set_attr "prefix" "maybe_vex")
1998    (set (attr "mode")
1999         (cond [(ior (not (match_test "TARGET_SSE2"))
2000                     (match_test "optimize_function_for_size_p (cfun)"))
2001                  (const_string "V4SF")
2002                (and (eq_attr "alternative" "2")
2003                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2004                  (const_string "V4SF")]
2005               (const_string "TI")))])
2006
2007 (define_insn "*movdi_internal_rex64"
2008   [(set (match_operand:DI 0 "nonimmediate_operand"
2009           "=r,r  ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
2010         (match_operand:DI 1 "general_operand"
2011           "Z ,rem,i,re,n ,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
2012   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2013 {
2014   switch (get_attr_type (insn))
2015     {
2016     case TYPE_SSECVT:
2017       if (SSE_REG_P (operands[0]))
2018         return "movq2dq\t{%1, %0|%0, %1}";
2019       else
2020         return "movdq2q\t{%1, %0|%0, %1}";
2021
2022     case TYPE_SSEMOV:
2023       if (get_attr_mode (insn) == MODE_TI)
2024         return "%vmovdqa\t{%1, %0|%0, %1}";
2025       /* Handle broken assemblers that require movd instead of movq.  */
2026       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2027         return "%vmovd\t{%1, %0|%0, %1}";
2028       else
2029         return "%vmovq\t{%1, %0|%0, %1}";
2030
2031     case TYPE_MMXMOV:
2032       /* Handle broken assemblers that require movd instead of movq.  */
2033       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2034         return "movd\t{%1, %0|%0, %1}";
2035       else
2036         return "movq\t{%1, %0|%0, %1}";
2037
2038     case TYPE_SSELOG1:
2039       return standard_sse_constant_opcode (insn, operands[1]);
2040
2041     case TYPE_MMX:
2042       return "pxor\t%0, %0";
2043
2044     case TYPE_MULTI:
2045       return "#";
2046
2047     case TYPE_LEA:
2048       return "lea{q}\t{%a1, %0|%0, %a1}";
2049
2050     default:
2051       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2052       if (get_attr_mode (insn) == MODE_SI)
2053         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2054       else if (which_alternative == 2)
2055         return "movabs{q}\t{%1, %0|%0, %1}";
2056       else if (ix86_use_lea_for_mov (insn, operands))
2057         return "lea{q}\t{%a1, %0|%0, %a1}";
2058       else
2059         return "mov{q}\t{%1, %0|%0, %1}";
2060     }
2061 }
2062   [(set (attr "type")
2063      (cond [(eq_attr "alternative" "4")
2064               (const_string "multi")
2065             (eq_attr "alternative" "5")
2066               (const_string "mmx")
2067             (eq_attr "alternative" "6,7,8,9")
2068               (const_string "mmxmov")
2069             (eq_attr "alternative" "10")
2070               (const_string "sselog1")
2071             (eq_attr "alternative" "11,12,13,14,15")
2072               (const_string "ssemov")
2073             (eq_attr "alternative" "16,17")
2074               (const_string "ssecvt")
2075             (match_operand 1 "pic_32bit_operand" "")
2076               (const_string "lea")
2077            ]
2078            (const_string "imov")))
2079    (set (attr "modrm")
2080      (if_then_else
2081        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2082          (const_string "0")
2083          (const_string "*")))
2084    (set (attr "length_immediate")
2085      (if_then_else
2086        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2087          (const_string "8")
2088          (const_string "*")))
2089    (set (attr "prefix_rex")
2090      (if_then_else (eq_attr "alternative" "8,9")
2091        (const_string "1")
2092        (const_string "*")))
2093    (set (attr "prefix_data16")
2094      (if_then_else (eq_attr "alternative" "11")
2095        (const_string "1")
2096        (const_string "*")))
2097    (set (attr "prefix")
2098      (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2099        (const_string "maybe_vex")
2100        (const_string "orig")))
2101    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2102
2103 ;; Reload patterns to support multi-word load/store
2104 ;; with non-offsetable address.
2105 (define_expand "reload_noff_store"
2106   [(parallel [(match_operand 0 "memory_operand" "=m")
2107               (match_operand 1 "register_operand" "r")
2108               (match_operand:DI 2 "register_operand" "=&r")])]
2109   "TARGET_64BIT"
2110 {
2111   rtx mem = operands[0];
2112   rtx addr = XEXP (mem, 0);
2113
2114   emit_move_insn (operands[2], addr);
2115   mem = replace_equiv_address_nv (mem, operands[2]);
2116
2117   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2118   DONE;
2119 })
2120
2121 (define_expand "reload_noff_load"
2122   [(parallel [(match_operand 0 "register_operand" "=r")
2123               (match_operand 1 "memory_operand" "m")
2124               (match_operand:DI 2 "register_operand" "=r")])]
2125   "TARGET_64BIT"
2126 {
2127   rtx mem = operands[1];
2128   rtx addr = XEXP (mem, 0);
2129
2130   emit_move_insn (operands[2], addr);
2131   mem = replace_equiv_address_nv (mem, operands[2]);
2132
2133   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2134   DONE;
2135 })
2136
2137 ;; Convert impossible stores of immediate to existing instructions.
2138 ;; First try to get scratch register and go through it.  In case this
2139 ;; fails, move by 32bit parts.
2140 (define_peephole2
2141   [(match_scratch:DI 2 "r")
2142    (set (match_operand:DI 0 "memory_operand" "")
2143         (match_operand:DI 1 "immediate_operand" ""))]
2144   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2145    && !x86_64_immediate_operand (operands[1], DImode)"
2146   [(set (match_dup 2) (match_dup 1))
2147    (set (match_dup 0) (match_dup 2))])
2148
2149 ;; We need to define this as both peepholer and splitter for case
2150 ;; peephole2 pass is not run.
2151 ;; "&& 1" is needed to keep it from matching the previous pattern.
2152 (define_peephole2
2153   [(set (match_operand:DI 0 "memory_operand" "")
2154         (match_operand:DI 1 "immediate_operand" ""))]
2155   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2156    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2157   [(set (match_dup 2) (match_dup 3))
2158    (set (match_dup 4) (match_dup 5))]
2159   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2160
2161 (define_split
2162   [(set (match_operand:DI 0 "memory_operand" "")
2163         (match_operand:DI 1 "immediate_operand" ""))]
2164   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2165                     ? epilogue_completed : reload_completed)
2166    && !symbolic_operand (operands[1], DImode)
2167    && !x86_64_immediate_operand (operands[1], DImode)"
2168   [(set (match_dup 2) (match_dup 3))
2169    (set (match_dup 4) (match_dup 5))]
2170   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2171
2172 (define_insn "*movdi_internal"
2173   [(set (match_operand:DI 0 "nonimmediate_operand"
2174           "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2175         (match_operand:DI 1 "general_operand"
2176           "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2177   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2178 {
2179   switch (get_attr_type (insn))
2180     {
2181     case TYPE_SSECVT:
2182       if (SSE_REG_P (operands[0]))
2183         return "movq2dq\t{%1, %0|%0, %1}";
2184       else
2185         return "movdq2q\t{%1, %0|%0, %1}";
2186
2187     case TYPE_SSEMOV:
2188       switch (get_attr_mode (insn))
2189         {
2190         case MODE_TI:
2191           return "%vmovdqa\t{%1, %0|%0, %1}";
2192         case MODE_DI:
2193            return "%vmovq\t{%1, %0|%0, %1}";
2194         case MODE_V4SF:
2195           return "movaps\t{%1, %0|%0, %1}";
2196         case MODE_V2SF:
2197           return "movlps\t{%1, %0|%0, %1}";
2198         default:
2199           gcc_unreachable ();
2200         }
2201
2202     case TYPE_MMXMOV:
2203       return "movq\t{%1, %0|%0, %1}";
2204
2205     case TYPE_SSELOG1:
2206       return standard_sse_constant_opcode (insn, operands[1]);
2207
2208     case TYPE_MMX:
2209       return "pxor\t%0, %0";
2210
2211     case TYPE_MULTI:
2212       return "#";
2213
2214     default:
2215       gcc_unreachable ();
2216     }
2217 }
2218   [(set (attr "isa")
2219      (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2220               (const_string "sse2")
2221             (eq_attr "alternative" "9,10,11,12")
2222               (const_string "noavx")
2223            ]
2224            (const_string "*")))
2225    (set (attr "type")
2226      (cond [(eq_attr "alternative" "0,1")
2227               (const_string "multi")
2228             (eq_attr "alternative" "2")
2229               (const_string "mmx")
2230             (eq_attr "alternative" "3,4")
2231               (const_string "mmxmov")
2232             (eq_attr "alternative" "5,9")
2233               (const_string "sselog1")
2234             (eq_attr "alternative" "13,14")
2235               (const_string "ssecvt")
2236            ]
2237            (const_string "ssemov")))
2238    (set (attr "prefix")
2239      (if_then_else (eq_attr "alternative" "5,6,7,8")
2240        (const_string "maybe_vex")
2241        (const_string "orig")))
2242    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2243
2244 (define_split
2245   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2246         (match_operand:DI 1 "general_operand" ""))]
2247   "!TARGET_64BIT && reload_completed
2248    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2249    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2250   [(const_int 0)]
2251   "ix86_split_long_move (operands); DONE;")
2252
2253 (define_insn "*movsi_internal"
2254   [(set (match_operand:SI 0 "nonimmediate_operand"
2255                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2256         (match_operand:SI 1 "general_operand"
2257                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2258   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2259 {
2260   switch (get_attr_type (insn))
2261     {
2262     case TYPE_SSELOG1:
2263       return standard_sse_constant_opcode (insn, operands[1]);
2264
2265     case TYPE_SSEMOV:
2266       switch (get_attr_mode (insn))
2267         {
2268         case MODE_TI:
2269           return "%vmovdqa\t{%1, %0|%0, %1}";
2270         case MODE_V4SF:
2271           return "%vmovaps\t{%1, %0|%0, %1}";
2272         case MODE_SI:
2273           return "%vmovd\t{%1, %0|%0, %1}";
2274         case MODE_SF:
2275           return "%vmovss\t{%1, %0|%0, %1}";
2276         default:
2277           gcc_unreachable ();
2278         }
2279
2280     case TYPE_MMX:
2281       return "pxor\t%0, %0";
2282
2283     case TYPE_MMXMOV:
2284       if (get_attr_mode (insn) == MODE_DI)
2285         return "movq\t{%1, %0|%0, %1}";
2286       return "movd\t{%1, %0|%0, %1}";
2287
2288     case TYPE_LEA:
2289       return "lea{l}\t{%a1, %0|%0, %a1}";
2290
2291     default:
2292       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2293       if (ix86_use_lea_for_mov (insn, operands))
2294         return "lea{l}\t{%a1, %0|%0, %a1}";
2295       else
2296         return "mov{l}\t{%1, %0|%0, %1}";
2297     }
2298 }
2299   [(set (attr "type")
2300      (cond [(eq_attr "alternative" "2")
2301               (const_string "mmx")
2302             (eq_attr "alternative" "3,4,5")
2303               (const_string "mmxmov")
2304             (eq_attr "alternative" "6")
2305               (const_string "sselog1")
2306             (eq_attr "alternative" "7,8,9,10,11")
2307               (const_string "ssemov")
2308             (match_operand 1 "pic_32bit_operand" "")
2309               (const_string "lea")
2310            ]
2311            (const_string "imov")))
2312    (set (attr "prefix")
2313      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2314        (const_string "orig")
2315        (const_string "maybe_vex")))
2316    (set (attr "prefix_data16")
2317      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2318        (const_string "1")
2319        (const_string "*")))
2320    (set (attr "mode")
2321      (cond [(eq_attr "alternative" "2,3")
2322               (const_string "DI")
2323             (eq_attr "alternative" "6,7")
2324               (if_then_else
2325                 (not (match_test "TARGET_SSE2"))
2326                 (const_string "V4SF")
2327                 (const_string "TI"))
2328             (and (eq_attr "alternative" "8,9,10,11")
2329                  (not (match_test "TARGET_SSE2")))
2330               (const_string "SF")
2331            ]
2332            (const_string "SI")))])
2333
2334 (define_insn "*movhi_internal"
2335   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2336         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2337   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2338 {
2339   switch (get_attr_type (insn))
2340     {
2341     case TYPE_IMOVX:
2342       /* movzwl is faster than movw on p2 due to partial word stalls,
2343          though not as fast as an aligned movl.  */
2344       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2345     default:
2346       if (get_attr_mode (insn) == MODE_SI)
2347         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2348       else
2349         return "mov{w}\t{%1, %0|%0, %1}";
2350     }
2351 }
2352   [(set (attr "type")
2353      (cond [(match_test "optimize_function_for_size_p (cfun)")
2354               (const_string "imov")
2355             (and (eq_attr "alternative" "0")
2356                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2357                       (not (match_test "TARGET_HIMODE_MATH"))))
2358               (const_string "imov")
2359             (and (eq_attr "alternative" "1,2")
2360                  (match_operand:HI 1 "aligned_operand" ""))
2361               (const_string "imov")
2362             (and (match_test "TARGET_MOVX")
2363                  (eq_attr "alternative" "0,2"))
2364               (const_string "imovx")
2365            ]
2366            (const_string "imov")))
2367     (set (attr "mode")
2368       (cond [(eq_attr "type" "imovx")
2369                (const_string "SI")
2370              (and (eq_attr "alternative" "1,2")
2371                   (match_operand:HI 1 "aligned_operand" ""))
2372                (const_string "SI")
2373              (and (eq_attr "alternative" "0")
2374                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2375                        (not (match_test "TARGET_HIMODE_MATH"))))
2376                (const_string "SI")
2377             ]
2378             (const_string "HI")))])
2379
2380 ;; Situation is quite tricky about when to choose full sized (SImode) move
2381 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2382 ;; partial register dependency machines (such as AMD Athlon), where QImode
2383 ;; moves issue extra dependency and for partial register stalls machines
2384 ;; that don't use QImode patterns (and QImode move cause stall on the next
2385 ;; instruction).
2386 ;;
2387 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2388 ;; register stall machines with, where we use QImode instructions, since
2389 ;; partial register stall can be caused there.  Then we use movzx.
2390 (define_insn "*movqi_internal"
2391   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2392         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2393   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2394 {
2395   switch (get_attr_type (insn))
2396     {
2397     case TYPE_IMOVX:
2398       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2399       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2400     default:
2401       if (get_attr_mode (insn) == MODE_SI)
2402         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2403       else
2404         return "mov{b}\t{%1, %0|%0, %1}";
2405     }
2406 }
2407   [(set (attr "type")
2408      (cond [(and (eq_attr "alternative" "5")
2409                  (not (match_operand:QI 1 "aligned_operand" "")))
2410               (const_string "imovx")
2411             (match_test "optimize_function_for_size_p (cfun)")
2412               (const_string "imov")
2413             (and (eq_attr "alternative" "3")
2414                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2415                       (not (match_test "TARGET_QIMODE_MATH"))))
2416               (const_string "imov")
2417             (eq_attr "alternative" "3,5")
2418               (const_string "imovx")
2419             (and (match_test "TARGET_MOVX")
2420                  (eq_attr "alternative" "2"))
2421               (const_string "imovx")
2422            ]
2423            (const_string "imov")))
2424    (set (attr "mode")
2425       (cond [(eq_attr "alternative" "3,4,5")
2426                (const_string "SI")
2427              (eq_attr "alternative" "6")
2428                (const_string "QI")
2429              (eq_attr "type" "imovx")
2430                (const_string "SI")
2431              (and (eq_attr "type" "imov")
2432                   (and (eq_attr "alternative" "0,1")
2433                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2434                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2435                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2436                (const_string "SI")
2437              ;; Avoid partial register stalls when not using QImode arithmetic
2438              (and (eq_attr "type" "imov")
2439                   (and (eq_attr "alternative" "0,1")
2440                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2441                             (not (match_test "TARGET_QIMODE_MATH")))))
2442                (const_string "SI")
2443            ]
2444            (const_string "QI")))])
2445
2446 ;; Stores and loads of ax to arbitrary constant address.
2447 ;; We fake an second form of instruction to force reload to load address
2448 ;; into register when rax is not available
2449 (define_insn "*movabs<mode>_1"
2450   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2451         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2452   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2453   "@
2454    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2455    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2456   [(set_attr "type" "imov")
2457    (set_attr "modrm" "0,*")
2458    (set_attr "length_address" "8,0")
2459    (set_attr "length_immediate" "0,*")
2460    (set_attr "memory" "store")
2461    (set_attr "mode" "<MODE>")])
2462
2463 (define_insn "*movabs<mode>_2"
2464   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2465         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2466   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2467   "@
2468    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2469    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2470   [(set_attr "type" "imov")
2471    (set_attr "modrm" "0,*")
2472    (set_attr "length_address" "8,0")
2473    (set_attr "length_immediate" "0")
2474    (set_attr "memory" "load")
2475    (set_attr "mode" "<MODE>")])
2476
2477 (define_insn "*swap<mode>"
2478   [(set (match_operand:SWI48 0 "register_operand" "+r")
2479         (match_operand:SWI48 1 "register_operand" "+r"))
2480    (set (match_dup 1)
2481         (match_dup 0))]
2482   ""
2483   "xchg{<imodesuffix>}\t%1, %0"
2484   [(set_attr "type" "imov")
2485    (set_attr "mode" "<MODE>")
2486    (set_attr "pent_pair" "np")
2487    (set_attr "athlon_decode" "vector")
2488    (set_attr "amdfam10_decode" "double")
2489    (set_attr "bdver1_decode" "double")])
2490
2491 (define_insn "*swap<mode>_1"
2492   [(set (match_operand:SWI12 0 "register_operand" "+r")
2493         (match_operand:SWI12 1 "register_operand" "+r"))
2494    (set (match_dup 1)
2495         (match_dup 0))]
2496   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2497   "xchg{l}\t%k1, %k0"
2498   [(set_attr "type" "imov")
2499    (set_attr "mode" "SI")
2500    (set_attr "pent_pair" "np")
2501    (set_attr "athlon_decode" "vector")
2502    (set_attr "amdfam10_decode" "double")
2503    (set_attr "bdver1_decode" "double")])
2504
2505 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2506 ;; is disabled for AMDFAM10
2507 (define_insn "*swap<mode>_2"
2508   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2509         (match_operand:SWI12 1 "register_operand" "+<r>"))
2510    (set (match_dup 1)
2511         (match_dup 0))]
2512   "TARGET_PARTIAL_REG_STALL"
2513   "xchg{<imodesuffix>}\t%1, %0"
2514   [(set_attr "type" "imov")
2515    (set_attr "mode" "<MODE>")
2516    (set_attr "pent_pair" "np")
2517    (set_attr "athlon_decode" "vector")])
2518
2519 (define_expand "movstrict<mode>"
2520   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2521         (match_operand:SWI12 1 "general_operand" ""))]
2522   ""
2523 {
2524   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2525     FAIL;
2526   if (GET_CODE (operands[0]) == SUBREG
2527       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2528     FAIL;
2529   /* Don't generate memory->memory moves, go through a register */
2530   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2531     operands[1] = force_reg (<MODE>mode, operands[1]);
2532 })
2533
2534 (define_insn "*movstrict<mode>_1"
2535   [(set (strict_low_part
2536           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2537         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2538   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2539    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2540   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2541   [(set_attr "type" "imov")
2542    (set_attr "mode" "<MODE>")])
2543
2544 (define_insn "*movstrict<mode>_xor"
2545   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2546         (match_operand:SWI12 1 "const0_operand" ""))
2547    (clobber (reg:CC FLAGS_REG))]
2548   "reload_completed"
2549   "xor{<imodesuffix>}\t%0, %0"
2550   [(set_attr "type" "alu1")
2551    (set_attr "mode" "<MODE>")
2552    (set_attr "length_immediate" "0")])
2553
2554 (define_insn "*mov<mode>_extv_1"
2555   [(set (match_operand:SWI24 0 "register_operand" "=R")
2556         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2557                             (const_int 8)
2558                             (const_int 8)))]
2559   ""
2560   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2561   [(set_attr "type" "imovx")
2562    (set_attr "mode" "SI")])
2563
2564 (define_insn "*movqi_extv_1_rex64"
2565   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2566         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2567                          (const_int 8)
2568                          (const_int 8)))]
2569   "TARGET_64BIT"
2570 {
2571   switch (get_attr_type (insn))
2572     {
2573     case TYPE_IMOVX:
2574       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2575     default:
2576       return "mov{b}\t{%h1, %0|%0, %h1}";
2577     }
2578 }
2579   [(set (attr "type")
2580      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2581                         (match_test "TARGET_MOVX"))
2582         (const_string "imovx")
2583         (const_string "imov")))
2584    (set (attr "mode")
2585      (if_then_else (eq_attr "type" "imovx")
2586         (const_string "SI")
2587         (const_string "QI")))])
2588
2589 (define_insn "*movqi_extv_1"
2590   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2591         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2592                          (const_int 8)
2593                          (const_int 8)))]
2594   "!TARGET_64BIT"
2595 {
2596   switch (get_attr_type (insn))
2597     {
2598     case TYPE_IMOVX:
2599       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2600     default:
2601       return "mov{b}\t{%h1, %0|%0, %h1}";
2602     }
2603 }
2604   [(set (attr "type")
2605      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2606                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2607                              (match_test "TARGET_MOVX")))
2608         (const_string "imovx")
2609         (const_string "imov")))
2610    (set (attr "mode")
2611      (if_then_else (eq_attr "type" "imovx")
2612         (const_string "SI")
2613         (const_string "QI")))])
2614
2615 (define_insn "*mov<mode>_extzv_1"
2616   [(set (match_operand:SWI48 0 "register_operand" "=R")
2617         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2618                             (const_int 8)
2619                             (const_int 8)))]
2620   ""
2621   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2622   [(set_attr "type" "imovx")
2623    (set_attr "mode" "SI")])
2624
2625 (define_insn "*movqi_extzv_2_rex64"
2626   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2627         (subreg:QI
2628           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2629                            (const_int 8)
2630                            (const_int 8)) 0))]
2631   "TARGET_64BIT"
2632 {
2633   switch (get_attr_type (insn))
2634     {
2635     case TYPE_IMOVX:
2636       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2637     default:
2638       return "mov{b}\t{%h1, %0|%0, %h1}";
2639     }
2640 }
2641   [(set (attr "type")
2642      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2643                         (match_test "TARGET_MOVX"))
2644         (const_string "imovx")
2645         (const_string "imov")))
2646    (set (attr "mode")
2647      (if_then_else (eq_attr "type" "imovx")
2648         (const_string "SI")
2649         (const_string "QI")))])
2650
2651 (define_insn "*movqi_extzv_2"
2652   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2653         (subreg:QI
2654           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2655                            (const_int 8)
2656                            (const_int 8)) 0))]
2657   "!TARGET_64BIT"
2658 {
2659   switch (get_attr_type (insn))
2660     {
2661     case TYPE_IMOVX:
2662       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2663     default:
2664       return "mov{b}\t{%h1, %0|%0, %h1}";
2665     }
2666 }
2667   [(set (attr "type")
2668      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2669                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2670                              (match_test "TARGET_MOVX")))
2671         (const_string "imovx")
2672         (const_string "imov")))
2673    (set (attr "mode")
2674      (if_then_else (eq_attr "type" "imovx")
2675         (const_string "SI")
2676         (const_string "QI")))])
2677
2678 (define_expand "mov<mode>_insv_1"
2679   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2680                             (const_int 8)
2681                             (const_int 8))
2682         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2683
2684 (define_insn "*mov<mode>_insv_1_rex64"
2685   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2686                              (const_int 8)
2687                              (const_int 8))
2688         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2689   "TARGET_64BIT"
2690   "mov{b}\t{%b1, %h0|%h0, %b1}"
2691   [(set_attr "type" "imov")
2692    (set_attr "mode" "QI")])
2693
2694 (define_insn "*movsi_insv_1"
2695   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2696                          (const_int 8)
2697                          (const_int 8))
2698         (match_operand:SI 1 "general_operand" "Qmn"))]
2699   "!TARGET_64BIT"
2700   "mov{b}\t{%b1, %h0|%h0, %b1}"
2701   [(set_attr "type" "imov")
2702    (set_attr "mode" "QI")])
2703
2704 (define_insn "*movqi_insv_2"
2705   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2706                          (const_int 8)
2707                          (const_int 8))
2708         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2709                      (const_int 8)))]
2710   ""
2711   "mov{b}\t{%h1, %h0|%h0, %h1}"
2712   [(set_attr "type" "imov")
2713    (set_attr "mode" "QI")])
2714 \f
2715 ;; Floating point push instructions.
2716
2717 (define_insn "*pushtf"
2718   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2719         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2720   "TARGET_SSE2"
2721 {
2722   /* This insn should be already split before reg-stack.  */
2723   gcc_unreachable ();
2724 }
2725   [(set_attr "type" "multi")
2726    (set_attr "unit" "sse,*,*")
2727    (set_attr "mode" "TF,SI,SI")])
2728
2729 ;; %%% Kill this when call knows how to work this out.
2730 (define_split
2731   [(set (match_operand:TF 0 "push_operand" "")
2732         (match_operand:TF 1 "sse_reg_operand" ""))]
2733   "TARGET_SSE2 && reload_completed"
2734   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2735    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2736
2737 (define_insn "*pushxf"
2738   [(set (match_operand:XF 0 "push_operand" "=<,<")
2739         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2740   "optimize_function_for_speed_p (cfun)"
2741 {
2742   /* This insn should be already split before reg-stack.  */
2743   gcc_unreachable ();
2744 }
2745   [(set_attr "type" "multi")
2746    (set_attr "unit" "i387,*")
2747    (set_attr "mode" "XF,SI")])
2748
2749 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2750 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2751 ;; Pushing using integer instructions is longer except for constants
2752 ;; and direct memory references (assuming that any given constant is pushed
2753 ;; only once, but this ought to be handled elsewhere).
2754
2755 (define_insn "*pushxf_nointeger"
2756   [(set (match_operand:XF 0 "push_operand" "=<,<")
2757         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2758   "optimize_function_for_size_p (cfun)"
2759 {
2760   /* This insn should be already split before reg-stack.  */
2761   gcc_unreachable ();
2762 }
2763   [(set_attr "type" "multi")
2764    (set_attr "unit" "i387,*")
2765    (set_attr "mode" "XF,SI")])
2766
2767 ;; %%% Kill this when call knows how to work this out.
2768 (define_split
2769   [(set (match_operand:XF 0 "push_operand" "")
2770         (match_operand:XF 1 "fp_register_operand" ""))]
2771   "reload_completed"
2772   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2773    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2774   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2775
2776 (define_insn "*pushdf_rex64"
2777   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2778         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2779   "TARGET_64BIT"
2780 {
2781   /* This insn should be already split before reg-stack.  */
2782   gcc_unreachable ();
2783 }
2784   [(set_attr "type" "multi")
2785    (set_attr "unit" "i387,*,*")
2786    (set_attr "mode" "DF,DI,DF")])
2787
2788 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2789 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2790 ;; On the average, pushdf using integers can be still shorter.
2791
2792 (define_insn "*pushdf"
2793   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2794         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2795   "!TARGET_64BIT"
2796 {
2797   /* This insn should be already split before reg-stack.  */
2798   gcc_unreachable ();
2799 }
2800   [(set_attr "isa" "*,*,sse2")
2801    (set_attr "type" "multi")
2802    (set_attr "unit" "i387,*,*")
2803    (set_attr "mode" "DF,DI,DF")])
2804
2805 ;; %%% Kill this when call knows how to work this out.
2806 (define_split
2807   [(set (match_operand:DF 0 "push_operand" "")
2808         (match_operand:DF 1 "any_fp_register_operand" ""))]
2809   "reload_completed"
2810   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2811    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2812
2813 (define_insn "*pushsf_rex64"
2814   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2815         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2816   "TARGET_64BIT"
2817 {
2818   /* Anything else should be already split before reg-stack.  */
2819   gcc_assert (which_alternative == 1);
2820   return "push{q}\t%q1";
2821 }
2822   [(set_attr "type" "multi,push,multi")
2823    (set_attr "unit" "i387,*,*")
2824    (set_attr "mode" "SF,DI,SF")])
2825
2826 (define_insn "*pushsf"
2827   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2828         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2829   "!TARGET_64BIT"
2830 {
2831   /* Anything else should be already split before reg-stack.  */
2832   gcc_assert (which_alternative == 1);
2833   return "push{l}\t%1";
2834 }
2835   [(set_attr "type" "multi,push,multi")
2836    (set_attr "unit" "i387,*,*")
2837    (set_attr "mode" "SF,SI,SF")])
2838
2839 ;; %%% Kill this when call knows how to work this out.
2840 (define_split
2841   [(set (match_operand:SF 0 "push_operand" "")
2842         (match_operand:SF 1 "any_fp_register_operand" ""))]
2843   "reload_completed"
2844   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2845    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2846   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2847
2848 (define_split
2849   [(set (match_operand:SF 0 "push_operand" "")
2850         (match_operand:SF 1 "memory_operand" ""))]
2851   "reload_completed
2852    && (operands[2] = find_constant_src (insn))"
2853   [(set (match_dup 0) (match_dup 2))])
2854
2855 (define_split
2856   [(set (match_operand 0 "push_operand" "")
2857         (match_operand 1 "general_operand" ""))]
2858   "reload_completed
2859    && (GET_MODE (operands[0]) == TFmode
2860        || GET_MODE (operands[0]) == XFmode
2861        || GET_MODE (operands[0]) == DFmode)
2862    && !ANY_FP_REG_P (operands[1])"
2863   [(const_int 0)]
2864   "ix86_split_long_move (operands); DONE;")
2865 \f
2866 ;; Floating point move instructions.
2867
2868 (define_expand "movtf"
2869   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2870         (match_operand:TF 1 "nonimmediate_operand" ""))]
2871   "TARGET_SSE2"
2872 {
2873   ix86_expand_move (TFmode, operands);
2874   DONE;
2875 })
2876
2877 (define_expand "mov<mode>"
2878   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2879         (match_operand:X87MODEF 1 "general_operand" ""))]
2880   ""
2881   "ix86_expand_move (<MODE>mode, operands); DONE;")
2882
2883 (define_insn "*movtf_internal"
2884   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2885         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,F*r"))]
2886   "TARGET_SSE2
2887    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2888    && (!can_create_pseudo_p ()
2889        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2890        || GET_CODE (operands[1]) != CONST_DOUBLE
2891        || (optimize_function_for_size_p (cfun)
2892            && standard_sse_constant_p (operands[1])
2893            && !memory_operand (operands[0], TFmode))
2894        || (!TARGET_MEMORY_MISMATCH_STALL
2895            && memory_operand (operands[0], TFmode)))"
2896 {
2897   switch (which_alternative)
2898     {
2899     case 0:
2900     case 1:
2901       /* Handle misaligned load/store since we
2902          don't have movmisaligntf pattern. */
2903       if (misaligned_operand (operands[0], TFmode)
2904           || misaligned_operand (operands[1], TFmode))
2905         {
2906           if (get_attr_mode (insn) == MODE_V4SF)
2907             return "%vmovups\t{%1, %0|%0, %1}";
2908           else
2909             return "%vmovdqu\t{%1, %0|%0, %1}";
2910         }
2911       else
2912         {
2913           if (get_attr_mode (insn) == MODE_V4SF)
2914             return "%vmovaps\t{%1, %0|%0, %1}";
2915           else
2916             return "%vmovdqa\t{%1, %0|%0, %1}";
2917         }
2918
2919     case 2:
2920       return standard_sse_constant_opcode (insn, operands[1]);
2921
2922     case 3:
2923     case 4:
2924         return "#";
2925
2926     default:
2927       gcc_unreachable ();
2928     }
2929 }
2930   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2931    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2932    (set (attr "mode")
2933         (cond [(eq_attr "alternative" "0,2")
2934                  (if_then_else
2935                    (match_test "optimize_function_for_size_p (cfun)")
2936                    (const_string "V4SF")
2937                    (const_string "TI"))
2938                (eq_attr "alternative" "1")
2939                  (if_then_else
2940                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2941                         (match_test "optimize_function_for_size_p (cfun)"))
2942                    (const_string "V4SF")
2943                    (const_string "TI"))]
2944                (const_string "DI")))])
2945
2946 ;; Possible store forwarding (partial memory) stall in alternative 4.
2947 (define_insn "*movxf_internal"
2948   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2949         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2950   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2951    && (!can_create_pseudo_p ()
2952        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2953        || GET_CODE (operands[1]) != CONST_DOUBLE
2954        || (optimize_function_for_size_p (cfun)
2955            && standard_80387_constant_p (operands[1]) > 0
2956            && !memory_operand (operands[0], XFmode))
2957        || (!TARGET_MEMORY_MISMATCH_STALL
2958            && memory_operand (operands[0], XFmode)))"
2959 {
2960   switch (which_alternative)
2961     {
2962     case 0:
2963     case 1:
2964       return output_387_reg_move (insn, operands);
2965
2966     case 2:
2967       return standard_80387_constant_opcode (operands[1]);
2968
2969     case 3:
2970     case 4:
2971       return "#";
2972
2973     default:
2974       gcc_unreachable ();
2975     }
2976 }
2977   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2978    (set_attr "mode" "XF,XF,XF,SI,SI")])
2979
2980 (define_insn "*movdf_internal_rex64"
2981   [(set (match_operand:DF 0 "nonimmediate_operand"
2982                 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2983         (match_operand:DF 1 "general_operand"
2984                 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2985   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2986    && (!can_create_pseudo_p ()
2987        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2988        || GET_CODE (operands[1]) != CONST_DOUBLE
2989        || (optimize_function_for_size_p (cfun)
2990            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2991                 && standard_80387_constant_p (operands[1]) > 0)
2992                || (TARGET_SSE2 && TARGET_SSE_MATH
2993                    && standard_sse_constant_p (operands[1]))))
2994        || memory_operand (operands[0], DFmode))"
2995 {
2996   switch (which_alternative)
2997     {
2998     case 0:
2999     case 1:
3000       return output_387_reg_move (insn, operands);
3001
3002     case 2:
3003       return standard_80387_constant_opcode (operands[1]);
3004
3005     case 3:
3006     case 4:
3007       return "mov{q}\t{%1, %0|%0, %1}";
3008
3009     case 5:
3010       return "movabs{q}\t{%1, %0|%0, %1}";
3011
3012     case 6:
3013       return "#";
3014
3015     case 7:
3016       return standard_sse_constant_opcode (insn, operands[1]);
3017
3018     case 8:
3019     case 9:
3020     case 10:
3021       switch (get_attr_mode (insn))
3022         {
3023         case MODE_V2DF:
3024           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3025             return "%vmovapd\t{%1, %0|%0, %1}";
3026         case MODE_V4SF:
3027           return "%vmovaps\t{%1, %0|%0, %1}";
3028
3029         case MODE_DI:
3030           return "%vmovq\t{%1, %0|%0, %1}";
3031         case MODE_DF:
3032           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3033             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3034           return "%vmovsd\t{%1, %0|%0, %1}";
3035         case MODE_V1DF:
3036           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3037         case MODE_V2SF:
3038           return "%vmovlps\t{%1, %d0|%d0, %1}";
3039         default:
3040           gcc_unreachable ();
3041         }
3042
3043     case 11:
3044     case 12:
3045       /* Handle broken assemblers that require movd instead of movq.  */
3046       return "%vmovd\t{%1, %0|%0, %1}";
3047
3048     default:
3049       gcc_unreachable();
3050     }
3051 }
3052   [(set (attr "type")
3053         (cond [(eq_attr "alternative" "0,1,2")
3054                  (const_string "fmov")
3055                (eq_attr "alternative" "3,4,5")
3056                  (const_string "imov")
3057                (eq_attr "alternative" "6")
3058                  (const_string "multi")
3059                (eq_attr "alternative" "7")
3060                  (const_string "sselog1")
3061               ]
3062               (const_string "ssemov")))
3063    (set (attr "modrm")
3064      (if_then_else
3065        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3066          (const_string "0")
3067          (const_string "*")))
3068    (set (attr "length_immediate")
3069      (if_then_else
3070        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3071          (const_string "8")
3072          (const_string "*")))
3073    (set (attr "prefix")
3074      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3075        (const_string "orig")
3076        (const_string "maybe_vex")))
3077    (set (attr "prefix_data16")
3078      (if_then_else (eq_attr "mode" "V1DF")
3079        (const_string "1")
3080        (const_string "*")))
3081    (set (attr "mode")
3082         (cond [(eq_attr "alternative" "0,1,2")
3083                  (const_string "DF")
3084                (eq_attr "alternative" "3,4,5,6,11,12")
3085                  (const_string "DI")
3086
3087                /* xorps is one byte shorter.  */
3088                (eq_attr "alternative" "7")
3089                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3090                           (const_string "V4SF")
3091                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3092                           (const_string "TI")
3093                        ]
3094                        (const_string "V2DF"))
3095
3096                /* For architectures resolving dependencies on
3097                   whole SSE registers use APD move to break dependency
3098                   chains, otherwise use short move to avoid extra work.
3099
3100                   movaps encodes one byte shorter.  */
3101                (eq_attr "alternative" "8")
3102                  (cond
3103                    [(match_test "optimize_function_for_size_p (cfun)")
3104                       (const_string "V4SF")
3105                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3106                       (const_string "V2DF")
3107                    ]
3108                    (const_string "DF"))
3109                /* For architectures resolving dependencies on register
3110                   parts we may avoid extra work to zero out upper part
3111                   of register.  */
3112                (eq_attr "alternative" "9")
3113                  (if_then_else
3114                    (match_test "TARGET_SSE_SPLIT_REGS")
3115                    (const_string "V1DF")
3116                    (const_string "DF"))
3117               ]
3118               (const_string "DF")))])
3119
3120 ;; Possible store forwarding (partial memory) stall in alternative 4.
3121 (define_insn "*movdf_internal"
3122   [(set (match_operand:DF 0 "nonimmediate_operand"
3123                 "=f,m,f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3124         (match_operand:DF 1 "general_operand"
3125                 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3126   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3127    && (!can_create_pseudo_p ()
3128        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3129        || GET_CODE (operands[1]) != CONST_DOUBLE
3130        || (optimize_function_for_size_p (cfun)
3131            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3132                 && standard_80387_constant_p (operands[1]) > 0)
3133                || (TARGET_SSE2 && TARGET_SSE_MATH
3134                    && standard_sse_constant_p (operands[1])))
3135            && !memory_operand (operands[0], DFmode))
3136        || (!TARGET_MEMORY_MISMATCH_STALL
3137            && memory_operand (operands[0], DFmode)))"
3138 {
3139   switch (which_alternative)
3140     {
3141     case 0:
3142     case 1:
3143       return output_387_reg_move (insn, operands);
3144
3145     case 2:
3146       return standard_80387_constant_opcode (operands[1]);
3147
3148     case 3:
3149     case 4:
3150       return "#";
3151
3152     case 5:
3153     case 9:
3154       return standard_sse_constant_opcode (insn, operands[1]);
3155
3156     case 6:
3157     case 7:
3158     case 8:
3159     case 10:
3160     case 11:
3161     case 12:
3162       switch (get_attr_mode (insn))
3163         {
3164         case MODE_V2DF:
3165           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3166             return "%vmovapd\t{%1, %0|%0, %1}";
3167         case MODE_V4SF:
3168           return "%vmovaps\t{%1, %0|%0, %1}";
3169
3170         case MODE_DI:
3171           return "%vmovq\t{%1, %0|%0, %1}";
3172         case MODE_DF:
3173           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3174             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3175           return "%vmovsd\t{%1, %0|%0, %1}";
3176         case MODE_V1DF:
3177           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3178         case MODE_V2SF:
3179           return "%vmovlps\t{%1, %d0|%d0, %1}";
3180         default:
3181           gcc_unreachable ();
3182         }
3183
3184     default:
3185       gcc_unreachable ();
3186     }
3187 }
3188   [(set (attr "isa")
3189      (if_then_else (eq_attr "alternative" "5,6,7,8")
3190        (const_string "sse2")
3191        (const_string "*")))
3192    (set (attr "type")
3193         (cond [(eq_attr "alternative" "0,1,2")
3194                  (const_string "fmov")
3195                (eq_attr "alternative" "3,4")
3196                  (const_string "multi")
3197                (eq_attr "alternative" "5,9")
3198                  (const_string "sselog1")
3199               ]
3200               (const_string "ssemov")))
3201    (set (attr "prefix")
3202      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3203        (const_string "orig")
3204        (const_string "maybe_vex")))
3205    (set (attr "prefix_data16")
3206      (if_then_else (eq_attr "mode" "V1DF")
3207        (const_string "1")
3208        (const_string "*")))
3209    (set (attr "mode")
3210         (cond [(eq_attr "alternative" "0,1,2")
3211                  (const_string "DF")
3212                (eq_attr "alternative" "3,4")
3213                  (const_string "SI")
3214
3215                /* For SSE1, we have many fewer alternatives.  */
3216                (not (match_test "TARGET_SSE2"))
3217                  (if_then_else
3218                    (eq_attr "alternative" "5,6,9,10")
3219                    (const_string "V4SF")
3220                    (const_string "V2SF"))
3221
3222                /* xorps is one byte shorter.  */
3223                (eq_attr "alternative" "5,9")
3224                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3225                           (const_string "V4SF")
3226                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3227                           (const_string "TI")
3228                        ]
3229                        (const_string "V2DF"))
3230
3231                /* For architectures resolving dependencies on
3232                   whole SSE registers use APD move to break dependency
3233                   chains, otherwise use short move to avoid extra work.
3234
3235                   movaps encodes one byte shorter.  */
3236                (eq_attr "alternative" "6,10")
3237                  (cond
3238                    [(match_test "optimize_function_for_size_p (cfun)")
3239                       (const_string "V4SF")
3240                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3241                       (const_string "V2DF")
3242                    ]
3243                    (const_string "DF"))
3244                /* For architectures resolving dependencies on register
3245                   parts we may avoid extra work to zero out upper part
3246                   of register.  */
3247                (eq_attr "alternative" "7,11")
3248                  (if_then_else
3249                    (match_test "TARGET_SSE_SPLIT_REGS")
3250                    (const_string "V1DF")
3251                    (const_string "DF"))
3252               ]
3253               (const_string "DF")))])
3254
3255 (define_insn "*movsf_internal"
3256   [(set (match_operand:SF 0 "nonimmediate_operand"
3257           "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3258         (match_operand:SF 1 "general_operand"
3259           "fm,f,G,rmF,Fr,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3260   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3261    && (!can_create_pseudo_p ()
3262        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3263        || GET_CODE (operands[1]) != CONST_DOUBLE
3264        || (optimize_function_for_size_p (cfun)
3265            && ((!TARGET_SSE_MATH
3266                 && standard_80387_constant_p (operands[1]) > 0)
3267                || (TARGET_SSE_MATH
3268                    && standard_sse_constant_p (operands[1]))))
3269        || memory_operand (operands[0], SFmode))"
3270 {
3271   switch (which_alternative)
3272     {
3273     case 0:
3274     case 1:
3275       return output_387_reg_move (insn, operands);
3276
3277     case 2:
3278       return standard_80387_constant_opcode (operands[1]);
3279
3280     case 3:
3281     case 4:
3282       return "mov{l}\t{%1, %0|%0, %1}";
3283
3284     case 5:
3285       return standard_sse_constant_opcode (insn, operands[1]);
3286
3287     case 6:
3288       if (get_attr_mode (insn) == MODE_V4SF)
3289         return "%vmovaps\t{%1, %0|%0, %1}";
3290       if (TARGET_AVX)
3291         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3292
3293     case 7:
3294     case 8:
3295       return "%vmovss\t{%1, %0|%0, %1}";
3296
3297     case 9:
3298     case 10:
3299     case 14:
3300     case 15:
3301       return "movd\t{%1, %0|%0, %1}";
3302
3303     case 11:
3304       return "movq\t{%1, %0|%0, %1}";
3305
3306     case 12:
3307     case 13:
3308       return "%vmovd\t{%1, %0|%0, %1}";
3309
3310     default:
3311       gcc_unreachable ();
3312     }
3313 }
3314   [(set (attr "type")
3315         (cond [(eq_attr "alternative" "0,1,2")
3316                  (const_string "fmov")
3317                (eq_attr "alternative" "3,4")
3318                  (const_string "multi")
3319                (eq_attr "alternative" "5")
3320                  (const_string "sselog1")
3321                (eq_attr "alternative" "9,10,11,14,15")
3322                  (const_string "mmxmov")
3323               ]
3324               (const_string "ssemov")))
3325    (set (attr "prefix")
3326      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3327        (const_string "maybe_vex")
3328        (const_string "orig")))
3329    (set (attr "mode")
3330         (cond [(eq_attr "alternative" "3,4,9,10")
3331                  (const_string "SI")
3332                (eq_attr "alternative" "5")
3333                  (if_then_else
3334                    (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3335                              (match_test "TARGET_SSE2"))
3336                         (not (match_test "optimize_function_for_size_p (cfun)")))
3337                    (const_string "TI")
3338                    (const_string "V4SF"))
3339                /* For architectures resolving dependencies on
3340                   whole SSE registers use APS move to break dependency
3341                   chains, otherwise use short move to avoid extra work.
3342
3343                   Do the same for architectures resolving dependencies on
3344                   the parts.  While in DF mode it is better to always handle
3345                   just register parts, the SF mode is different due to lack
3346                   of instructions to load just part of the register.  It is
3347                   better to maintain the whole registers in single format
3348                   to avoid problems on using packed logical operations.  */
3349                (eq_attr "alternative" "6")
3350                  (if_then_else
3351                    (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3352                         (match_test "TARGET_SSE_SPLIT_REGS"))
3353                    (const_string "V4SF")
3354                    (const_string "SF"))
3355                (eq_attr "alternative" "11")
3356                  (const_string "DI")]
3357                (const_string "SF")))])
3358
3359 (define_split
3360   [(set (match_operand 0 "any_fp_register_operand" "")
3361         (match_operand 1 "memory_operand" ""))]
3362   "reload_completed
3363    && (GET_MODE (operands[0]) == TFmode
3364        || GET_MODE (operands[0]) == XFmode
3365        || GET_MODE (operands[0]) == DFmode
3366        || GET_MODE (operands[0]) == SFmode)
3367    && (operands[2] = find_constant_src (insn))"
3368   [(set (match_dup 0) (match_dup 2))]
3369 {
3370   rtx c = operands[2];
3371   int r = REGNO (operands[0]);
3372
3373   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3374       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3375     FAIL;
3376 })
3377
3378 (define_split
3379   [(set (match_operand 0 "any_fp_register_operand" "")
3380         (float_extend (match_operand 1 "memory_operand" "")))]
3381   "reload_completed
3382    && (GET_MODE (operands[0]) == TFmode
3383        || GET_MODE (operands[0]) == XFmode
3384        || GET_MODE (operands[0]) == DFmode)
3385    && (operands[2] = find_constant_src (insn))"
3386   [(set (match_dup 0) (match_dup 2))]
3387 {
3388   rtx c = operands[2];
3389   int r = REGNO (operands[0]);
3390
3391   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3392       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3393     FAIL;
3394 })
3395
3396 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3397 (define_split
3398   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3399         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3400   "reload_completed
3401    && (standard_80387_constant_p (operands[1]) == 8
3402        || standard_80387_constant_p (operands[1]) == 9)"
3403   [(set (match_dup 0)(match_dup 1))
3404    (set (match_dup 0)
3405         (neg:X87MODEF (match_dup 0)))]
3406 {
3407   REAL_VALUE_TYPE r;
3408
3409   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3410   if (real_isnegzero (&r))
3411     operands[1] = CONST0_RTX (<MODE>mode);
3412   else
3413     operands[1] = CONST1_RTX (<MODE>mode);
3414 })
3415
3416 (define_split
3417   [(set (match_operand 0 "nonimmediate_operand" "")
3418         (match_operand 1 "general_operand" ""))]
3419   "reload_completed
3420    && (GET_MODE (operands[0]) == TFmode
3421        || GET_MODE (operands[0]) == XFmode
3422        || GET_MODE (operands[0]) == DFmode)
3423    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3424   [(const_int 0)]
3425   "ix86_split_long_move (operands); DONE;")
3426
3427 (define_insn "swapxf"
3428   [(set (match_operand:XF 0 "register_operand" "+f")
3429         (match_operand:XF 1 "register_operand" "+f"))
3430    (set (match_dup 1)
3431         (match_dup 0))]
3432   "TARGET_80387"
3433 {
3434   if (STACK_TOP_P (operands[0]))
3435     return "fxch\t%1";
3436   else
3437     return "fxch\t%0";
3438 }
3439   [(set_attr "type" "fxch")
3440    (set_attr "mode" "XF")])
3441
3442 (define_insn "*swap<mode>"
3443   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3444         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3445    (set (match_dup 1)
3446         (match_dup 0))]
3447   "TARGET_80387 || reload_completed"
3448 {
3449   if (STACK_TOP_P (operands[0]))
3450     return "fxch\t%1";
3451   else
3452     return "fxch\t%0";
3453 }
3454   [(set_attr "type" "fxch")
3455    (set_attr "mode" "<MODE>")])
3456 \f
3457 ;; Zero extension instructions
3458
3459 (define_expand "zero_extendsidi2"
3460   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3461         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3462   ""
3463 {
3464   if (!TARGET_64BIT)
3465     {
3466       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3467       DONE;
3468     }
3469 })
3470
3471 (define_insn "*zero_extendsidi2_rex64"
3472   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*x")
3473         (zero_extend:DI
3474          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3475   "TARGET_64BIT"
3476   "@
3477    mov\t{%k1, %k0|%k0, %k1}
3478    #
3479    movd\t{%1, %0|%0, %1}
3480    movd\t{%1, %0|%0, %1}
3481    %vmovd\t{%1, %0|%0, %1}
3482    %vmovd\t{%1, %0|%0, %1}"
3483   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3484    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3485    (set_attr "prefix_0f" "0,*,*,*,*,*")
3486    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3487
3488 (define_split
3489   [(set (match_operand:DI 0 "memory_operand" "")
3490         (zero_extend:DI (match_dup 0)))]
3491   "TARGET_64BIT"
3492   [(set (match_dup 4) (const_int 0))]
3493   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3494
3495 ;; %%% Kill me once multi-word ops are sane.
3496 (define_insn "zero_extendsidi2_1"
3497   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3498         (zero_extend:DI
3499          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3500    (clobber (reg:CC FLAGS_REG))]
3501   "!TARGET_64BIT"
3502   "@
3503    #
3504    #
3505    #
3506    movd\t{%1, %0|%0, %1}
3507    movd\t{%1, %0|%0, %1}
3508    %vmovd\t{%1, %0|%0, %1}
3509    %vmovd\t{%1, %0|%0, %1}"
3510   [(set_attr "isa" "*,*,*,*,*,*,sse2")
3511    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3512    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3513    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3514
3515 (define_split
3516   [(set (match_operand:DI 0 "register_operand" "")
3517         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3518    (clobber (reg:CC FLAGS_REG))]
3519   "!TARGET_64BIT && reload_completed
3520    && true_regnum (operands[0]) == true_regnum (operands[1])"
3521   [(set (match_dup 4) (const_int 0))]
3522   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3523
3524 (define_split
3525   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3526         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3527    (clobber (reg:CC FLAGS_REG))]
3528   "!TARGET_64BIT && reload_completed
3529    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3530   [(set (match_dup 3) (match_dup 1))
3531    (set (match_dup 4) (const_int 0))]
3532   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3533
3534 (define_insn "zero_extend<mode>di2"
3535   [(set (match_operand:DI 0 "register_operand" "=r")
3536         (zero_extend:DI
3537          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3538   "TARGET_64BIT"
3539   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3540   [(set_attr "type" "imovx")
3541    (set_attr "mode" "SI")])
3542
3543 (define_expand "zero_extendhisi2"
3544   [(set (match_operand:SI 0 "register_operand" "")
3545         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3546   ""
3547 {
3548   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3549     {
3550       operands[1] = force_reg (HImode, operands[1]);
3551       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3552       DONE;
3553     }
3554 })
3555
3556 (define_insn_and_split "zero_extendhisi2_and"
3557   [(set (match_operand:SI 0 "register_operand" "=r")
3558         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3559    (clobber (reg:CC FLAGS_REG))]
3560   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3561   "#"
3562   "&& reload_completed"
3563   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3564               (clobber (reg:CC FLAGS_REG))])]
3565   ""
3566   [(set_attr "type" "alu1")
3567    (set_attr "mode" "SI")])
3568
3569 (define_insn "*zero_extendhisi2_movzwl"
3570   [(set (match_operand:SI 0 "register_operand" "=r")
3571         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3572   "!TARGET_ZERO_EXTEND_WITH_AND
3573    || optimize_function_for_size_p (cfun)"
3574   "movz{wl|x}\t{%1, %0|%0, %1}"
3575   [(set_attr "type" "imovx")
3576    (set_attr "mode" "SI")])
3577
3578 (define_expand "zero_extendqi<mode>2"
3579   [(parallel
3580     [(set (match_operand:SWI24 0 "register_operand" "")
3581           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3582      (clobber (reg:CC FLAGS_REG))])])
3583
3584 (define_insn "*zero_extendqi<mode>2_and"
3585   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3586         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3587    (clobber (reg:CC FLAGS_REG))]
3588   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3589   "#"
3590   [(set_attr "type" "alu1")
3591    (set_attr "mode" "<MODE>")])
3592
3593 ;; When source and destination does not overlap, clear destination
3594 ;; first and then do the movb
3595 (define_split
3596   [(set (match_operand:SWI24 0 "register_operand" "")
3597         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3598    (clobber (reg:CC FLAGS_REG))]
3599   "reload_completed
3600    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3601    && ANY_QI_REG_P (operands[0])
3602    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3603    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3604   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3605 {
3606   operands[2] = gen_lowpart (QImode, operands[0]);
3607   ix86_expand_clear (operands[0]);
3608 })
3609
3610 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3611   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3612         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3613    (clobber (reg:CC FLAGS_REG))]
3614   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3615   "#"
3616   [(set_attr "type" "imovx,alu1")
3617    (set_attr "mode" "<MODE>")])
3618
3619 ;; For the movzbl case strip only the clobber
3620 (define_split
3621   [(set (match_operand:SWI24 0 "register_operand" "")
3622         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3623    (clobber (reg:CC FLAGS_REG))]
3624   "reload_completed
3625    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3626    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3627   [(set (match_dup 0)
3628         (zero_extend:SWI24 (match_dup 1)))])
3629
3630 ; zero extend to SImode to avoid partial register stalls
3631 (define_insn "*zero_extendqi<mode>2_movzbl"
3632   [(set (match_operand:SWI24 0 "register_operand" "=r")
3633         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3634   "reload_completed
3635    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3636   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3637   [(set_attr "type" "imovx")
3638    (set_attr "mode" "SI")])
3639
3640 ;; Rest is handled by single and.
3641 (define_split
3642   [(set (match_operand:SWI24 0 "register_operand" "")
3643         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3644    (clobber (reg:CC FLAGS_REG))]
3645   "reload_completed
3646    && true_regnum (operands[0]) == true_regnum (operands[1])"
3647   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3648               (clobber (reg:CC FLAGS_REG))])])
3649 \f
3650 ;; Sign extension instructions
3651
3652 (define_expand "extendsidi2"
3653   [(set (match_operand:DI 0 "register_operand" "")
3654         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3655   ""
3656 {
3657   if (!TARGET_64BIT)
3658     {
3659       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3660       DONE;
3661     }
3662 })
3663
3664 (define_insn "*extendsidi2_rex64"
3665   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3666         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3667   "TARGET_64BIT"
3668   "@
3669    {cltq|cdqe}
3670    movs{lq|x}\t{%1, %0|%0, %1}"
3671   [(set_attr "type" "imovx")
3672    (set_attr "mode" "DI")
3673    (set_attr "prefix_0f" "0")
3674    (set_attr "modrm" "0,1")])
3675
3676 (define_insn "extendsidi2_1"
3677   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3678         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3679    (clobber (reg:CC FLAGS_REG))
3680    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3681   "!TARGET_64BIT"
3682   "#")
3683
3684 ;; Extend to memory case when source register does die.
3685 (define_split
3686   [(set (match_operand:DI 0 "memory_operand" "")
3687         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3688    (clobber (reg:CC FLAGS_REG))
3689    (clobber (match_operand:SI 2 "register_operand" ""))]
3690   "(reload_completed
3691     && dead_or_set_p (insn, operands[1])
3692     && !reg_mentioned_p (operands[1], operands[0]))"
3693   [(set (match_dup 3) (match_dup 1))
3694    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3695               (clobber (reg:CC FLAGS_REG))])
3696    (set (match_dup 4) (match_dup 1))]
3697   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3698
3699 ;; Extend to memory case when source register does not die.
3700 (define_split
3701   [(set (match_operand:DI 0 "memory_operand" "")
3702         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3703    (clobber (reg:CC FLAGS_REG))
3704    (clobber (match_operand:SI 2 "register_operand" ""))]
3705   "reload_completed"
3706   [(const_int 0)]
3707 {
3708   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3709
3710   emit_move_insn (operands[3], operands[1]);
3711
3712   /* Generate a cltd if possible and doing so it profitable.  */
3713   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3714       && true_regnum (operands[1]) == AX_REG
3715       && true_regnum (operands[2]) == DX_REG)
3716     {
3717       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3718     }
3719   else
3720     {
3721       emit_move_insn (operands[2], operands[1]);
3722       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3723     }
3724   emit_move_insn (operands[4], operands[2]);
3725   DONE;
3726 })
3727
3728 ;; Extend to register case.  Optimize case where source and destination
3729 ;; registers match and cases where we can use cltd.
3730 (define_split
3731   [(set (match_operand:DI 0 "register_operand" "")
3732         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3733    (clobber (reg:CC FLAGS_REG))
3734    (clobber (match_scratch:SI 2 ""))]
3735   "reload_completed"
3736   [(const_int 0)]
3737 {
3738   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3739
3740   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3741     emit_move_insn (operands[3], operands[1]);
3742
3743   /* Generate a cltd if possible and doing so it profitable.  */
3744   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3745       && true_regnum (operands[3]) == AX_REG
3746       && true_regnum (operands[4]) == DX_REG)
3747     {
3748       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3749       DONE;
3750     }
3751
3752   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3753     emit_move_insn (operands[4], operands[1]);
3754
3755   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3756   DONE;
3757 })
3758
3759 (define_insn "extend<mode>di2"
3760   [(set (match_operand:DI 0 "register_operand" "=r")
3761         (sign_extend:DI
3762          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3763   "TARGET_64BIT"
3764   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3765   [(set_attr "type" "imovx")
3766    (set_attr "mode" "DI")])
3767
3768 (define_insn "extendhisi2"
3769   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3770         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3771   ""
3772 {
3773   switch (get_attr_prefix_0f (insn))
3774     {
3775     case 0:
3776       return "{cwtl|cwde}";
3777     default:
3778       return "movs{wl|x}\t{%1, %0|%0, %1}";
3779     }
3780 }
3781   [(set_attr "type" "imovx")
3782    (set_attr "mode" "SI")
3783    (set (attr "prefix_0f")
3784      ;; movsx is short decodable while cwtl is vector decoded.
3785      (if_then_else (and (eq_attr "cpu" "!k6")
3786                         (eq_attr "alternative" "0"))
3787         (const_string "0")
3788         (const_string "1")))
3789    (set (attr "modrm")
3790      (if_then_else (eq_attr "prefix_0f" "0")
3791         (const_string "0")
3792         (const_string "1")))])
3793
3794 (define_insn "*extendhisi2_zext"
3795   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3796         (zero_extend:DI
3797          (sign_extend:SI
3798           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3799   "TARGET_64BIT"
3800 {
3801   switch (get_attr_prefix_0f (insn))
3802     {
3803     case 0:
3804       return "{cwtl|cwde}";
3805     default:
3806       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3807     }
3808 }
3809   [(set_attr "type" "imovx")
3810    (set_attr "mode" "SI")
3811    (set (attr "prefix_0f")
3812      ;; movsx is short decodable while cwtl is vector decoded.
3813      (if_then_else (and (eq_attr "cpu" "!k6")
3814                         (eq_attr "alternative" "0"))
3815         (const_string "0")
3816         (const_string "1")))
3817    (set (attr "modrm")
3818      (if_then_else (eq_attr "prefix_0f" "0")
3819         (const_string "0")
3820         (const_string "1")))])
3821
3822 (define_insn "extendqisi2"
3823   [(set (match_operand:SI 0 "register_operand" "=r")
3824         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3825   ""
3826   "movs{bl|x}\t{%1, %0|%0, %1}"
3827    [(set_attr "type" "imovx")
3828     (set_attr "mode" "SI")])
3829
3830 (define_insn "*extendqisi2_zext"
3831   [(set (match_operand:DI 0 "register_operand" "=r")
3832         (zero_extend:DI
3833           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3834   "TARGET_64BIT"
3835   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3836    [(set_attr "type" "imovx")
3837     (set_attr "mode" "SI")])
3838
3839 (define_insn "extendqihi2"
3840   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3841         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3842   ""
3843 {
3844   switch (get_attr_prefix_0f (insn))
3845     {
3846     case 0:
3847       return "{cbtw|cbw}";
3848     default:
3849       return "movs{bw|x}\t{%1, %0|%0, %1}";
3850     }
3851 }
3852   [(set_attr "type" "imovx")
3853    (set_attr "mode" "HI")
3854    (set (attr "prefix_0f")
3855      ;; movsx is short decodable while cwtl is vector decoded.
3856      (if_then_else (and (eq_attr "cpu" "!k6")
3857                         (eq_attr "alternative" "0"))
3858         (const_string "0")
3859         (const_string "1")))
3860    (set (attr "modrm")
3861      (if_then_else (eq_attr "prefix_0f" "0")
3862         (const_string "0")
3863         (const_string "1")))])
3864 \f
3865 ;; Conversions between float and double.
3866
3867 ;; These are all no-ops in the model used for the 80387.
3868 ;; So just emit moves.
3869
3870 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3871 (define_split
3872   [(set (match_operand:DF 0 "push_operand" "")
3873         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3874   "reload_completed"
3875   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3876    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3877
3878 (define_split
3879   [(set (match_operand:XF 0 "push_operand" "")
3880         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3881   "reload_completed"
3882   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3883    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3884   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3885
3886 (define_expand "extendsfdf2"
3887   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3888         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3889   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3890 {
3891   /* ??? Needed for compress_float_constant since all fp constants
3892      are TARGET_LEGITIMATE_CONSTANT_P.  */
3893   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3894     {
3895       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3896           && standard_80387_constant_p (operands[1]) > 0)
3897         {
3898           operands[1] = simplify_const_unary_operation
3899             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3900           emit_move_insn_1 (operands[0], operands[1]);
3901           DONE;
3902         }
3903       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3904     }
3905 })
3906
3907 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3908    cvtss2sd:
3909       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3910       cvtps2pd xmm2,xmm1
3911    We do the conversion post reload to avoid producing of 128bit spills
3912    that might lead to ICE on 32bit target.  The sequence unlikely combine
3913    anyway.  */
3914 (define_split
3915   [(set (match_operand:DF 0 "register_operand" "")
3916         (float_extend:DF
3917           (match_operand:SF 1 "nonimmediate_operand" "")))]
3918   "TARGET_USE_VECTOR_FP_CONVERTS
3919    && optimize_insn_for_speed_p ()
3920    && reload_completed && SSE_REG_P (operands[0])"
3921    [(set (match_dup 2)
3922          (float_extend:V2DF
3923            (vec_select:V2SF
3924              (match_dup 3)
3925              (parallel [(const_int 0) (const_int 1)]))))]
3926 {
3927   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3928   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3929   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3930      Try to avoid move when unpacking can be done in source.  */
3931   if (REG_P (operands[1]))
3932     {
3933       /* If it is unsafe to overwrite upper half of source, we need
3934          to move to destination and unpack there.  */
3935       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3936            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3937           && true_regnum (operands[0]) != true_regnum (operands[1]))
3938         {
3939           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3940           emit_move_insn (tmp, operands[1]);
3941         }
3942       else
3943         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3944       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3945                                              operands[3]));
3946     }
3947   else
3948     emit_insn (gen_vec_setv4sf_0 (operands[3],
3949                                   CONST0_RTX (V4SFmode), operands[1]));
3950 })
3951
3952 (define_insn "*extendsfdf2_mixed"
3953   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3954         (float_extend:DF
3955           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3956   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3957 {
3958   switch (which_alternative)
3959     {
3960     case 0:
3961     case 1:
3962       return output_387_reg_move (insn, operands);
3963
3964     case 2:
3965       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3966
3967     default:
3968       gcc_unreachable ();
3969     }
3970 }
3971   [(set_attr "type" "fmov,fmov,ssecvt")
3972    (set_attr "prefix" "orig,orig,maybe_vex")
3973    (set_attr "mode" "SF,XF,DF")])
3974
3975 (define_insn "*extendsfdf2_sse"
3976   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3977         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3978   "TARGET_SSE2 && TARGET_SSE_MATH"
3979   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3980   [(set_attr "type" "ssecvt")
3981    (set_attr "prefix" "maybe_vex")
3982    (set_attr "mode" "DF")])
3983
3984 (define_insn "*extendsfdf2_i387"
3985   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3986         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3987   "TARGET_80387"
3988   "* return output_387_reg_move (insn, operands);"
3989   [(set_attr "type" "fmov")
3990    (set_attr "mode" "SF,XF")])
3991
3992 (define_expand "extend<mode>xf2"
3993   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3994         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3995   "TARGET_80387"
3996 {
3997   /* ??? Needed for compress_float_constant since all fp constants
3998      are TARGET_LEGITIMATE_CONSTANT_P.  */
3999   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4000     {
4001       if (standard_80387_constant_p (operands[1]) > 0)
4002         {
4003           operands[1] = simplify_const_unary_operation
4004             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4005           emit_move_insn_1 (operands[0], operands[1]);
4006           DONE;
4007         }
4008       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4009     }
4010 })
4011
4012 (define_insn "*extend<mode>xf2_i387"
4013   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4014         (float_extend:XF
4015           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4016   "TARGET_80387"
4017   "* return output_387_reg_move (insn, operands);"
4018   [(set_attr "type" "fmov")
4019    (set_attr "mode" "<MODE>,XF")])
4020
4021 ;; %%% This seems bad bad news.
4022 ;; This cannot output into an f-reg because there is no way to be sure
4023 ;; of truncating in that case.  Otherwise this is just like a simple move
4024 ;; insn.  So we pretend we can output to a reg in order to get better
4025 ;; register preferencing, but we really use a stack slot.
4026
4027 ;; Conversion from DFmode to SFmode.
4028
4029 (define_expand "truncdfsf2"
4030   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4031         (float_truncate:SF
4032           (match_operand:DF 1 "nonimmediate_operand" "")))]
4033   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4034 {
4035   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4036     ;
4037   else if (flag_unsafe_math_optimizations)
4038     ;
4039   else
4040     {
4041       enum ix86_stack_slot slot = (virtuals_instantiated
4042                                    ? SLOT_TEMP
4043                                    : SLOT_VIRTUAL);
4044       rtx temp = assign_386_stack_local (SFmode, slot);
4045       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4046       DONE;
4047     }
4048 })
4049
4050 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4051    cvtsd2ss:
4052       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4053       cvtpd2ps xmm2,xmm1
4054    We do the conversion post reload to avoid producing of 128bit spills
4055    that might lead to ICE on 32bit target.  The sequence unlikely combine
4056    anyway.  */
4057 (define_split
4058   [(set (match_operand:SF 0 "register_operand" "")
4059         (float_truncate:SF
4060           (match_operand:DF 1 "nonimmediate_operand" "")))]
4061   "TARGET_USE_VECTOR_FP_CONVERTS
4062    && optimize_insn_for_speed_p ()
4063    && reload_completed && SSE_REG_P (operands[0])"
4064    [(set (match_dup 2)
4065          (vec_concat:V4SF
4066            (float_truncate:V2SF
4067              (match_dup 4))
4068            (match_dup 3)))]
4069 {
4070   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4071   operands[3] = CONST0_RTX (V2SFmode);
4072   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4073   /* Use movsd for loading from memory, unpcklpd for registers.
4074      Try to avoid move when unpacking can be done in source, or SSE3
4075      movddup is available.  */
4076   if (REG_P (operands[1]))
4077     {
4078       if (!TARGET_SSE3
4079           && true_regnum (operands[0]) != true_regnum (operands[1])
4080           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4081               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4082         {
4083           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4084           emit_move_insn (tmp, operands[1]);
4085           operands[1] = tmp;
4086         }
4087       else if (!TARGET_SSE3)
4088         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4089       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4090     }
4091   else
4092     emit_insn (gen_sse2_loadlpd (operands[4],
4093                                  CONST0_RTX (V2DFmode), operands[1]));
4094 })
4095
4096 (define_expand "truncdfsf2_with_temp"
4097   [(parallel [(set (match_operand:SF 0 "" "")
4098                    (float_truncate:SF (match_operand:DF 1 "" "")))
4099               (clobber (match_operand:SF 2 "" ""))])])
4100
4101 (define_insn "*truncdfsf_fast_mixed"
4102   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4103         (float_truncate:SF
4104           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4105   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4106 {
4107   switch (which_alternative)
4108     {
4109     case 0:
4110       return output_387_reg_move (insn, operands);
4111     case 1:
4112       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4113     default:
4114       gcc_unreachable ();
4115     }
4116 }
4117   [(set_attr "type" "fmov,ssecvt")
4118    (set_attr "prefix" "orig,maybe_vex")
4119    (set_attr "mode" "SF")])
4120
4121 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4122 ;; because nothing we do here is unsafe.
4123 (define_insn "*truncdfsf_fast_sse"
4124   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4125         (float_truncate:SF
4126           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4127   "TARGET_SSE2 && TARGET_SSE_MATH"
4128   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4129   [(set_attr "type" "ssecvt")
4130    (set_attr "prefix" "maybe_vex")
4131    (set_attr "mode" "SF")])
4132
4133 (define_insn "*truncdfsf_fast_i387"
4134   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4135         (float_truncate:SF
4136           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4137   "TARGET_80387 && flag_unsafe_math_optimizations"
4138   "* return output_387_reg_move (insn, operands);"
4139   [(set_attr "type" "fmov")
4140    (set_attr "mode" "SF")])
4141
4142 (define_insn "*truncdfsf_mixed"
4143   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4144         (float_truncate:SF
4145           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4146    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4147   "TARGET_MIX_SSE_I387"
4148 {
4149   switch (which_alternative)
4150     {
4151     case 0:
4152       return output_387_reg_move (insn, operands);
4153     case 1:
4154       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4155
4156     default:
4157       return "#";
4158     }
4159 }
4160   [(set_attr "isa" "*,sse2,*,*,*")
4161    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4162    (set_attr "unit" "*,*,i387,i387,i387")
4163    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4164    (set_attr "mode" "SF")])
4165
4166 (define_insn "*truncdfsf_i387"
4167   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4168         (float_truncate:SF
4169           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4170    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4171   "TARGET_80387"
4172 {
4173   switch (which_alternative)
4174     {
4175     case 0:
4176       return output_387_reg_move (insn, operands);
4177
4178     default:
4179       return "#";
4180     }
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 "*truncdfsf2_i387_1"
4187   [(set (match_operand:SF 0 "memory_operand" "=m")
4188         (float_truncate:SF
4189           (match_operand:DF 1 "register_operand" "f")))]
4190   "TARGET_80387
4191    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4192    && !TARGET_MIX_SSE_I387"
4193   "* return output_387_reg_move (insn, operands);"
4194   [(set_attr "type" "fmov")
4195    (set_attr "mode" "SF")])
4196
4197 (define_split
4198   [(set (match_operand:SF 0 "register_operand" "")
4199         (float_truncate:SF
4200          (match_operand:DF 1 "fp_register_operand" "")))
4201    (clobber (match_operand 2 "" ""))]
4202   "reload_completed"
4203   [(set (match_dup 2) (match_dup 1))
4204    (set (match_dup 0) (match_dup 2))]
4205   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4206
4207 ;; Conversion from XFmode to {SF,DF}mode
4208
4209 (define_expand "truncxf<mode>2"
4210   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4211                    (float_truncate:MODEF
4212                      (match_operand:XF 1 "register_operand" "")))
4213               (clobber (match_dup 2))])]
4214   "TARGET_80387"
4215 {
4216   if (flag_unsafe_math_optimizations)
4217     {
4218       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4219       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4220       if (reg != operands[0])
4221         emit_move_insn (operands[0], reg);
4222       DONE;
4223     }
4224   else
4225     {
4226       enum ix86_stack_slot slot = (virtuals_instantiated
4227                                    ? SLOT_TEMP
4228                                    : SLOT_VIRTUAL);
4229       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4230     }
4231 })
4232
4233 (define_insn "*truncxfsf2_mixed"
4234   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4235         (float_truncate:SF
4236           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4237    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4238   "TARGET_80387"
4239 {
4240   gcc_assert (!which_alternative);
4241   return output_387_reg_move (insn, operands);
4242 }
4243   [(set_attr "type" "fmov,multi,multi,multi")
4244    (set_attr "unit" "*,i387,i387,i387")
4245    (set_attr "mode" "SF")])
4246
4247 (define_insn "*truncxfdf2_mixed"
4248   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4249         (float_truncate:DF
4250           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4251    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4252   "TARGET_80387"
4253 {
4254   gcc_assert (!which_alternative);
4255   return output_387_reg_move (insn, operands);
4256 }
4257   [(set_attr "isa" "*,*,sse2,*")
4258    (set_attr "type" "fmov,multi,multi,multi")
4259    (set_attr "unit" "*,i387,i387,i387")
4260    (set_attr "mode" "DF")])
4261
4262 (define_insn "truncxf<mode>2_i387_noop"
4263   [(set (match_operand:MODEF 0 "register_operand" "=f")
4264         (float_truncate:MODEF
4265           (match_operand:XF 1 "register_operand" "f")))]
4266   "TARGET_80387 && flag_unsafe_math_optimizations"
4267   "* return output_387_reg_move (insn, operands);"
4268   [(set_attr "type" "fmov")
4269    (set_attr "mode" "<MODE>")])
4270
4271 (define_insn "*truncxf<mode>2_i387"
4272   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4273         (float_truncate:MODEF
4274           (match_operand:XF 1 "register_operand" "f")))]
4275   "TARGET_80387"
4276   "* return output_387_reg_move (insn, operands);"
4277   [(set_attr "type" "fmov")
4278    (set_attr "mode" "<MODE>")])
4279
4280 (define_split
4281   [(set (match_operand:MODEF 0 "register_operand" "")
4282         (float_truncate:MODEF
4283           (match_operand:XF 1 "register_operand" "")))
4284    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4285   "TARGET_80387 && reload_completed"
4286   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4287    (set (match_dup 0) (match_dup 2))])
4288
4289 (define_split
4290   [(set (match_operand:MODEF 0 "memory_operand" "")
4291         (float_truncate:MODEF
4292           (match_operand:XF 1 "register_operand" "")))
4293    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4294   "TARGET_80387"
4295   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4296 \f
4297 ;; Signed conversion to DImode.
4298
4299 (define_expand "fix_truncxfdi2"
4300   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4301                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4302               (clobber (reg:CC FLAGS_REG))])]
4303   "TARGET_80387"
4304 {
4305   if (TARGET_FISTTP)
4306    {
4307      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4308      DONE;
4309    }
4310 })
4311
4312 (define_expand "fix_trunc<mode>di2"
4313   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4314                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4315               (clobber (reg:CC FLAGS_REG))])]
4316   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4317 {
4318   if (TARGET_FISTTP
4319       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4320    {
4321      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4322      DONE;
4323    }
4324   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4325    {
4326      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4327      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4328      if (out != operands[0])
4329         emit_move_insn (operands[0], out);
4330      DONE;
4331    }
4332 })
4333
4334 ;; Signed conversion to SImode.
4335
4336 (define_expand "fix_truncxfsi2"
4337   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4338                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4339               (clobber (reg:CC FLAGS_REG))])]
4340   "TARGET_80387"
4341 {
4342   if (TARGET_FISTTP)
4343    {
4344      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4345      DONE;
4346    }
4347 })
4348
4349 (define_expand "fix_trunc<mode>si2"
4350   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4351                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4352               (clobber (reg:CC FLAGS_REG))])]
4353   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4354 {
4355   if (TARGET_FISTTP
4356       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4357    {
4358      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4359      DONE;
4360    }
4361   if (SSE_FLOAT_MODE_P (<MODE>mode))
4362    {
4363      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4364      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4365      if (out != operands[0])
4366         emit_move_insn (operands[0], out);
4367      DONE;
4368    }
4369 })
4370
4371 ;; Signed conversion to HImode.
4372
4373 (define_expand "fix_trunc<mode>hi2"
4374   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4375                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4376               (clobber (reg:CC FLAGS_REG))])]
4377   "TARGET_80387
4378    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4379 {
4380   if (TARGET_FISTTP)
4381    {
4382      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4383      DONE;
4384    }
4385 })
4386
4387 ;; Unsigned conversion to SImode.
4388
4389 (define_expand "fixuns_trunc<mode>si2"
4390   [(parallel
4391     [(set (match_operand:SI 0 "register_operand" "")
4392           (unsigned_fix:SI
4393             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4394      (use (match_dup 2))
4395      (clobber (match_scratch:<ssevecmode> 3 ""))
4396      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4397   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4398 {
4399   enum machine_mode mode = <MODE>mode;
4400   enum machine_mode vecmode = <ssevecmode>mode;
4401   REAL_VALUE_TYPE TWO31r;
4402   rtx two31;
4403
4404   if (optimize_insn_for_size_p ())
4405     FAIL;
4406
4407   real_ldexp (&TWO31r, &dconst1, 31);
4408   two31 = const_double_from_real_value (TWO31r, mode);
4409   two31 = ix86_build_const_vector (vecmode, true, two31);
4410   operands[2] = force_reg (vecmode, two31);
4411 })
4412
4413 (define_insn_and_split "*fixuns_trunc<mode>_1"
4414   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4415         (unsigned_fix:SI
4416           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4417    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4418    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4419    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4420   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4421    && optimize_function_for_speed_p (cfun)"
4422   "#"
4423   "&& reload_completed"
4424   [(const_int 0)]
4425 {
4426   ix86_split_convert_uns_si_sse (operands);
4427   DONE;
4428 })
4429
4430 ;; Unsigned conversion to HImode.
4431 ;; Without these patterns, we'll try the unsigned SI conversion which
4432 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4433
4434 (define_expand "fixuns_trunc<mode>hi2"
4435   [(set (match_dup 2)
4436         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4437    (set (match_operand:HI 0 "nonimmediate_operand" "")
4438         (subreg:HI (match_dup 2) 0))]
4439   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4440   "operands[2] = gen_reg_rtx (SImode);")
4441
4442 ;; When SSE is available, it is always faster to use it!
4443 (define_insn "fix_trunc<mode>di_sse"
4444   [(set (match_operand:DI 0 "register_operand" "=r,r")
4445         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4446   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4447    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4448   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4449   [(set_attr "type" "sseicvt")
4450    (set_attr "prefix" "maybe_vex")
4451    (set_attr "prefix_rex" "1")
4452    (set_attr "mode" "<MODE>")
4453    (set_attr "athlon_decode" "double,vector")
4454    (set_attr "amdfam10_decode" "double,double")
4455    (set_attr "bdver1_decode" "double,double")])
4456
4457 (define_insn "fix_trunc<mode>si_sse"
4458   [(set (match_operand:SI 0 "register_operand" "=r,r")
4459         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4460   "SSE_FLOAT_MODE_P (<MODE>mode)
4461    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4462   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4463   [(set_attr "type" "sseicvt")
4464    (set_attr "prefix" "maybe_vex")
4465    (set_attr "mode" "<MODE>")
4466    (set_attr "athlon_decode" "double,vector")
4467    (set_attr "amdfam10_decode" "double,double")
4468    (set_attr "bdver1_decode" "double,double")])
4469
4470 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4471 (define_peephole2
4472   [(set (match_operand:MODEF 0 "register_operand" "")
4473         (match_operand:MODEF 1 "memory_operand" ""))
4474    (set (match_operand:SWI48x 2 "register_operand" "")
4475         (fix:SWI48x (match_dup 0)))]
4476   "TARGET_SHORTEN_X87_SSE
4477    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4478    && peep2_reg_dead_p (2, operands[0])"
4479   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4480
4481 ;; Avoid vector decoded forms of the instruction.
4482 (define_peephole2
4483   [(match_scratch:DF 2 "x")
4484    (set (match_operand:SWI48x 0 "register_operand" "")
4485         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4486   "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4487   [(set (match_dup 2) (match_dup 1))
4488    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4489
4490 (define_peephole2
4491   [(match_scratch:SF 2 "x")
4492    (set (match_operand:SWI48x 0 "register_operand" "")
4493         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4494   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4495   [(set (match_dup 2) (match_dup 1))
4496    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4497
4498 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4499   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4500         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4501   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4502    && TARGET_FISTTP
4503    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4504          && (TARGET_64BIT || <MODE>mode != DImode))
4505         && TARGET_SSE_MATH)
4506    && can_create_pseudo_p ()"
4507   "#"
4508   "&& 1"
4509   [(const_int 0)]
4510 {
4511   if (memory_operand (operands[0], VOIDmode))
4512     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4513   else
4514     {
4515       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4516       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4517                                                             operands[1],
4518                                                             operands[2]));
4519     }
4520   DONE;
4521 }
4522   [(set_attr "type" "fisttp")
4523    (set_attr "mode" "<MODE>")])
4524
4525 (define_insn "fix_trunc<mode>_i387_fisttp"
4526   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4527         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4528    (clobber (match_scratch:XF 2 "=&1f"))]
4529   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4530    && TARGET_FISTTP
4531    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4532          && (TARGET_64BIT || <MODE>mode != DImode))
4533         && TARGET_SSE_MATH)"
4534   "* return output_fix_trunc (insn, operands, true);"
4535   [(set_attr "type" "fisttp")
4536    (set_attr "mode" "<MODE>")])
4537
4538 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4539   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4540         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4541    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4542    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4543   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4544    && TARGET_FISTTP
4545    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4546         && (TARGET_64BIT || <MODE>mode != DImode))
4547         && TARGET_SSE_MATH)"
4548   "#"
4549   [(set_attr "type" "fisttp")
4550    (set_attr "mode" "<MODE>")])
4551
4552 (define_split
4553   [(set (match_operand:SWI248x 0 "register_operand" "")
4554         (fix:SWI248x (match_operand 1 "register_operand" "")))
4555    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4556    (clobber (match_scratch 3 ""))]
4557   "reload_completed"
4558   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4559               (clobber (match_dup 3))])
4560    (set (match_dup 0) (match_dup 2))])
4561
4562 (define_split
4563   [(set (match_operand:SWI248x 0 "memory_operand" "")
4564         (fix:SWI248x (match_operand 1 "register_operand" "")))
4565    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4566    (clobber (match_scratch 3 ""))]
4567   "reload_completed"
4568   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4569               (clobber (match_dup 3))])])
4570
4571 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4572 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4573 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4574 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4575 ;; function in i386.c.
4576 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4577   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4578         (fix:SWI248x (match_operand 1 "register_operand" "")))
4579    (clobber (reg:CC FLAGS_REG))]
4580   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4581    && !TARGET_FISTTP
4582    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4583          && (TARGET_64BIT || <MODE>mode != DImode))
4584    && can_create_pseudo_p ()"
4585   "#"
4586   "&& 1"
4587   [(const_int 0)]
4588 {
4589   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4590
4591   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4592   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4593   if (memory_operand (operands[0], VOIDmode))
4594     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4595                                          operands[2], operands[3]));
4596   else
4597     {
4598       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4599       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4600                                                      operands[2], operands[3],
4601                                                      operands[4]));
4602     }
4603   DONE;
4604 }
4605   [(set_attr "type" "fistp")
4606    (set_attr "i387_cw" "trunc")
4607    (set_attr "mode" "<MODE>")])
4608
4609 (define_insn "fix_truncdi_i387"
4610   [(set (match_operand:DI 0 "memory_operand" "=m")
4611         (fix:DI (match_operand 1 "register_operand" "f")))
4612    (use (match_operand:HI 2 "memory_operand" "m"))
4613    (use (match_operand:HI 3 "memory_operand" "m"))
4614    (clobber (match_scratch:XF 4 "=&1f"))]
4615   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616    && !TARGET_FISTTP
4617    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4618   "* return output_fix_trunc (insn, operands, false);"
4619   [(set_attr "type" "fistp")
4620    (set_attr "i387_cw" "trunc")
4621    (set_attr "mode" "DI")])
4622
4623 (define_insn "fix_truncdi_i387_with_temp"
4624   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4625         (fix:DI (match_operand 1 "register_operand" "f,f")))
4626    (use (match_operand:HI 2 "memory_operand" "m,m"))
4627    (use (match_operand:HI 3 "memory_operand" "m,m"))
4628    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4629    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4630   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4631    && !TARGET_FISTTP
4632    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4633   "#"
4634   [(set_attr "type" "fistp")
4635    (set_attr "i387_cw" "trunc")
4636    (set_attr "mode" "DI")])
4637
4638 (define_split
4639   [(set (match_operand:DI 0 "register_operand" "")
4640         (fix:DI (match_operand 1 "register_operand" "")))
4641    (use (match_operand:HI 2 "memory_operand" ""))
4642    (use (match_operand:HI 3 "memory_operand" ""))
4643    (clobber (match_operand:DI 4 "memory_operand" ""))
4644    (clobber (match_scratch 5 ""))]
4645   "reload_completed"
4646   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4647               (use (match_dup 2))
4648               (use (match_dup 3))
4649               (clobber (match_dup 5))])
4650    (set (match_dup 0) (match_dup 4))])
4651
4652 (define_split
4653   [(set (match_operand:DI 0 "memory_operand" "")
4654         (fix:DI (match_operand 1 "register_operand" "")))
4655    (use (match_operand:HI 2 "memory_operand" ""))
4656    (use (match_operand:HI 3 "memory_operand" ""))
4657    (clobber (match_operand:DI 4 "memory_operand" ""))
4658    (clobber (match_scratch 5 ""))]
4659   "reload_completed"
4660   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4661               (use (match_dup 2))
4662               (use (match_dup 3))
4663               (clobber (match_dup 5))])])
4664
4665 (define_insn "fix_trunc<mode>_i387"
4666   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4667         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4668    (use (match_operand:HI 2 "memory_operand" "m"))
4669    (use (match_operand:HI 3 "memory_operand" "m"))]
4670   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4671    && !TARGET_FISTTP
4672    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4673   "* return output_fix_trunc (insn, operands, false);"
4674   [(set_attr "type" "fistp")
4675    (set_attr "i387_cw" "trunc")
4676    (set_attr "mode" "<MODE>")])
4677
4678 (define_insn "fix_trunc<mode>_i387_with_temp"
4679   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4680         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4681    (use (match_operand:HI 2 "memory_operand" "m,m"))
4682    (use (match_operand:HI 3 "memory_operand" "m,m"))
4683    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4684   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4685    && !TARGET_FISTTP
4686    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4687   "#"
4688   [(set_attr "type" "fistp")
4689    (set_attr "i387_cw" "trunc")
4690    (set_attr "mode" "<MODE>")])
4691
4692 (define_split
4693   [(set (match_operand:SWI24 0 "register_operand" "")
4694         (fix:SWI24 (match_operand 1 "register_operand" "")))
4695    (use (match_operand:HI 2 "memory_operand" ""))
4696    (use (match_operand:HI 3 "memory_operand" ""))
4697    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4698   "reload_completed"
4699   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4700               (use (match_dup 2))
4701               (use (match_dup 3))])
4702    (set (match_dup 0) (match_dup 4))])
4703
4704 (define_split
4705   [(set (match_operand:SWI24 0 "memory_operand" "")
4706         (fix:SWI24 (match_operand 1 "register_operand" "")))
4707    (use (match_operand:HI 2 "memory_operand" ""))
4708    (use (match_operand:HI 3 "memory_operand" ""))
4709    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4710   "reload_completed"
4711   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4712               (use (match_dup 2))
4713               (use (match_dup 3))])])
4714
4715 (define_insn "x86_fnstcw_1"
4716   [(set (match_operand:HI 0 "memory_operand" "=m")
4717         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4718   "TARGET_80387"
4719   "fnstcw\t%0"
4720   [(set (attr "length")
4721         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4722    (set_attr "mode" "HI")
4723    (set_attr "unit" "i387")
4724    (set_attr "bdver1_decode" "vector")])
4725
4726 (define_insn "x86_fldcw_1"
4727   [(set (reg:HI FPCR_REG)
4728         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4729   "TARGET_80387"
4730   "fldcw\t%0"
4731   [(set (attr "length")
4732         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4733    (set_attr "mode" "HI")
4734    (set_attr "unit" "i387")
4735    (set_attr "athlon_decode" "vector")
4736    (set_attr "amdfam10_decode" "vector")
4737    (set_attr "bdver1_decode" "vector")])
4738 \f
4739 ;; Conversion between fixed point and floating point.
4740
4741 ;; Even though we only accept memory inputs, the backend _really_
4742 ;; wants to be able to do this between registers.
4743
4744 (define_expand "floathi<mode>2"
4745   [(set (match_operand:X87MODEF 0 "register_operand" "")
4746         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4747   "TARGET_80387
4748    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4749        || TARGET_MIX_SSE_I387)")
4750
4751 ;; Pre-reload splitter to add memory clobber to the pattern.
4752 (define_insn_and_split "*floathi<mode>2_1"
4753   [(set (match_operand:X87MODEF 0 "register_operand" "")
4754         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4755   "TARGET_80387
4756    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4757        || TARGET_MIX_SSE_I387)
4758    && can_create_pseudo_p ()"
4759   "#"
4760   "&& 1"
4761   [(parallel [(set (match_dup 0)
4762               (float:X87MODEF (match_dup 1)))
4763    (clobber (match_dup 2))])]
4764   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4765
4766 (define_insn "*floathi<mode>2_i387_with_temp"
4767   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4768         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4769   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4770   "TARGET_80387
4771    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4772        || TARGET_MIX_SSE_I387)"
4773   "#"
4774   [(set_attr "type" "fmov,multi")
4775    (set_attr "mode" "<MODE>")
4776    (set_attr "unit" "*,i387")
4777    (set_attr "fp_int_src" "true")])
4778
4779 (define_insn "*floathi<mode>2_i387"
4780   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4781         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4782   "TARGET_80387
4783    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4784        || TARGET_MIX_SSE_I387)"
4785   "fild%Z1\t%1"
4786   [(set_attr "type" "fmov")
4787    (set_attr "mode" "<MODE>")
4788    (set_attr "fp_int_src" "true")])
4789
4790 (define_split
4791   [(set (match_operand:X87MODEF 0 "register_operand" "")
4792         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4793    (clobber (match_operand:HI 2 "memory_operand" ""))]
4794   "TARGET_80387
4795    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4796        || TARGET_MIX_SSE_I387)
4797    && reload_completed"
4798   [(set (match_dup 2) (match_dup 1))
4799    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4800
4801 (define_split
4802   [(set (match_operand:X87MODEF 0 "register_operand" "")
4803         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4804    (clobber (match_operand:HI 2 "memory_operand" ""))]
4805    "TARGET_80387
4806     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4807         || TARGET_MIX_SSE_I387)
4808     && reload_completed"
4809   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4810
4811 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4812   [(set (match_operand:X87MODEF 0 "register_operand" "")
4813         (float:X87MODEF
4814           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4815   "TARGET_80387
4816    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4817        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4818 {
4819   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4820         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4821       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4822     {
4823       rtx reg = gen_reg_rtx (XFmode);
4824       rtx (*insn)(rtx, rtx);
4825
4826       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4827
4828       if (<X87MODEF:MODE>mode == SFmode)
4829         insn = gen_truncxfsf2;
4830       else if (<X87MODEF:MODE>mode == DFmode)
4831         insn = gen_truncxfdf2;
4832       else
4833         gcc_unreachable ();
4834
4835       emit_insn (insn (operands[0], reg));
4836       DONE;
4837     }
4838 })
4839
4840 ;; Pre-reload splitter to add memory clobber to the pattern.
4841 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4842   [(set (match_operand:X87MODEF 0 "register_operand" "")
4843         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4844   "((TARGET_80387
4845      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4846      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4847            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4848          || TARGET_MIX_SSE_I387))
4849     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4850         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4851         && ((<SWI48x:MODE>mode == SImode
4852              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4853              && optimize_function_for_speed_p (cfun)
4854              && flag_trapping_math)
4855             || !(TARGET_INTER_UNIT_CONVERSIONS
4856                  || optimize_function_for_size_p (cfun)))))
4857    && can_create_pseudo_p ()"
4858   "#"
4859   "&& 1"
4860   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4861               (clobber (match_dup 2))])]
4862 {
4863   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4864
4865   /* Avoid store forwarding (partial memory) stall penalty
4866      by passing DImode value through XMM registers.  */
4867   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4868       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4869       && optimize_function_for_speed_p (cfun))
4870     {
4871       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4872                                                             operands[1],
4873                                                             operands[2]));
4874       DONE;
4875     }
4876 })
4877
4878 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4879   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4880         (float:MODEF
4881           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4882    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4883   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4884    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4885   "#"
4886   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4887    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4888    (set_attr "unit" "*,i387,*,*,*")
4889    (set_attr "athlon_decode" "*,*,double,direct,double")
4890    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4891    (set_attr "bdver1_decode" "*,*,double,direct,double")
4892    (set_attr "fp_int_src" "true")])
4893
4894 (define_insn "*floatsi<mode>2_vector_mixed"
4895   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4896         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4897   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4898    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4899   "@
4900    fild%Z1\t%1
4901    #"
4902   [(set_attr "type" "fmov,sseicvt")
4903    (set_attr "mode" "<MODE>,<ssevecmode>")
4904    (set_attr "unit" "i387,*")
4905    (set_attr "athlon_decode" "*,direct")
4906    (set_attr "amdfam10_decode" "*,double")
4907    (set_attr "bdver1_decode" "*,direct")
4908    (set_attr "fp_int_src" "true")])
4909
4910 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4911   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4912         (float:MODEF
4913           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4914    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4915   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4916    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4917   "#"
4918   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4919    (set_attr "mode" "<MODEF:MODE>")
4920    (set_attr "unit" "*,i387,*,*")
4921    (set_attr "athlon_decode" "*,*,double,direct")
4922    (set_attr "amdfam10_decode" "*,*,vector,double")
4923    (set_attr "bdver1_decode" "*,*,double,direct")
4924    (set_attr "fp_int_src" "true")])
4925
4926 (define_split
4927   [(set (match_operand:MODEF 0 "register_operand" "")
4928         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4929    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4930   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4931    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4932    && TARGET_INTER_UNIT_CONVERSIONS
4933    && reload_completed
4934    && (SSE_REG_P (operands[0])
4935        || (GET_CODE (operands[0]) == SUBREG
4936            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4937   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4938
4939 (define_split
4940   [(set (match_operand:MODEF 0 "register_operand" "")
4941         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4942    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4943   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4944    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4945    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4946    && reload_completed
4947    && (SSE_REG_P (operands[0])
4948        || (GET_CODE (operands[0]) == SUBREG
4949            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4950   [(set (match_dup 2) (match_dup 1))
4951    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4952
4953 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4954   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4955         (float:MODEF
4956           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4957   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4958    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4959    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4960   "@
4961    fild%Z1\t%1
4962    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4963    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4964   [(set_attr "type" "fmov,sseicvt,sseicvt")
4965    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4966    (set_attr "mode" "<MODEF:MODE>")
4967    (set (attr "prefix_rex")
4968      (if_then_else
4969        (and (eq_attr "prefix" "maybe_vex")
4970             (match_test "<SWI48x:MODE>mode == DImode"))
4971        (const_string "1")
4972        (const_string "*")))
4973    (set_attr "unit" "i387,*,*")
4974    (set_attr "athlon_decode" "*,double,direct")
4975    (set_attr "amdfam10_decode" "*,vector,double")
4976    (set_attr "bdver1_decode" "*,double,direct")
4977    (set_attr "fp_int_src" "true")])
4978
4979 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4980   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4981         (float:MODEF
4982           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4983   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4984    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4985    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4986   "@
4987    fild%Z1\t%1
4988    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4989   [(set_attr "type" "fmov,sseicvt")
4990    (set_attr "prefix" "orig,maybe_vex")
4991    (set_attr "mode" "<MODEF:MODE>")
4992    (set (attr "prefix_rex")
4993      (if_then_else
4994        (and (eq_attr "prefix" "maybe_vex")
4995             (match_test "<SWI48x:MODE>mode == DImode"))
4996        (const_string "1")
4997        (const_string "*")))
4998    (set_attr "athlon_decode" "*,direct")
4999    (set_attr "amdfam10_decode" "*,double")
5000    (set_attr "bdver1_decode" "*,direct")
5001    (set_attr "fp_int_src" "true")])
5002
5003 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5004   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5005         (float:MODEF
5006           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5007    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5008   "TARGET_SSE2 && TARGET_SSE_MATH
5009    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5010   "#"
5011   [(set_attr "type" "sseicvt")
5012    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5013    (set_attr "athlon_decode" "double,direct,double")
5014    (set_attr "amdfam10_decode" "vector,double,double")
5015    (set_attr "bdver1_decode" "double,direct,double")
5016    (set_attr "fp_int_src" "true")])
5017
5018 (define_insn "*floatsi<mode>2_vector_sse"
5019   [(set (match_operand:MODEF 0 "register_operand" "=x")
5020         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5021   "TARGET_SSE2 && TARGET_SSE_MATH
5022    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5023   "#"
5024   [(set_attr "type" "sseicvt")
5025    (set_attr "mode" "<MODE>")
5026    (set_attr "athlon_decode" "direct")
5027    (set_attr "amdfam10_decode" "double")
5028    (set_attr "bdver1_decode" "direct")
5029    (set_attr "fp_int_src" "true")])
5030
5031 (define_split
5032   [(set (match_operand:MODEF 0 "register_operand" "")
5033         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5034    (clobber (match_operand:SI 2 "memory_operand" ""))]
5035   "TARGET_SSE2 && TARGET_SSE_MATH
5036    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5037    && reload_completed
5038    && (SSE_REG_P (operands[0])
5039        || (GET_CODE (operands[0]) == SUBREG
5040            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5041   [(const_int 0)]
5042 {
5043   rtx op1 = operands[1];
5044
5045   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5046                                      <MODE>mode, 0);
5047   if (GET_CODE (op1) == SUBREG)
5048     op1 = SUBREG_REG (op1);
5049
5050   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5051     {
5052       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5053       emit_insn (gen_sse2_loadld (operands[4],
5054                                   CONST0_RTX (V4SImode), operands[1]));
5055     }
5056   /* We can ignore possible trapping value in the
5057      high part of SSE register for non-trapping math. */
5058   else if (SSE_REG_P (op1) && !flag_trapping_math)
5059     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5060   else
5061     {
5062       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5063       emit_move_insn (operands[2], operands[1]);
5064       emit_insn (gen_sse2_loadld (operands[4],
5065                                   CONST0_RTX (V4SImode), operands[2]));
5066     }
5067   if (<ssevecmode>mode == V4SFmode)
5068     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5069   else
5070     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5071   DONE;
5072 })
5073
5074 (define_split
5075   [(set (match_operand:MODEF 0 "register_operand" "")
5076         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5077    (clobber (match_operand:SI 2 "memory_operand" ""))]
5078   "TARGET_SSE2 && TARGET_SSE_MATH
5079    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5080    && reload_completed
5081    && (SSE_REG_P (operands[0])
5082        || (GET_CODE (operands[0]) == SUBREG
5083            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5084   [(const_int 0)]
5085 {
5086   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5087                                      <MODE>mode, 0);
5088   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5089
5090   emit_insn (gen_sse2_loadld (operands[4],
5091                               CONST0_RTX (V4SImode), operands[1]));
5092   if (<ssevecmode>mode == V4SFmode)
5093     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5094   else
5095     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5096   DONE;
5097 })
5098
5099 (define_split
5100   [(set (match_operand:MODEF 0 "register_operand" "")
5101         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5102   "TARGET_SSE2 && TARGET_SSE_MATH
5103    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5104    && reload_completed
5105    && (SSE_REG_P (operands[0])
5106        || (GET_CODE (operands[0]) == SUBREG
5107            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5108   [(const_int 0)]
5109 {
5110   rtx op1 = operands[1];
5111
5112   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5113                                      <MODE>mode, 0);
5114   if (GET_CODE (op1) == SUBREG)
5115     op1 = SUBREG_REG (op1);
5116
5117   if (GENERAL_REG_P (op1))
5118     {
5119       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5120       if (TARGET_INTER_UNIT_MOVES)
5121         emit_insn (gen_sse2_loadld (operands[4],
5122                                     CONST0_RTX (V4SImode), operands[1]));
5123       else
5124         {
5125           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5126                                               operands[1]);
5127           emit_insn (gen_sse2_loadld (operands[4],
5128                                       CONST0_RTX (V4SImode), operands[5]));
5129           ix86_free_from_memory (GET_MODE (operands[1]));
5130         }
5131     }
5132   /* We can ignore possible trapping value in the
5133      high part of SSE register for non-trapping math. */
5134   else if (SSE_REG_P (op1) && !flag_trapping_math)
5135     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5136   else
5137     gcc_unreachable ();
5138   if (<ssevecmode>mode == V4SFmode)
5139     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5140   else
5141     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5142   DONE;
5143 })
5144
5145 (define_split
5146   [(set (match_operand:MODEF 0 "register_operand" "")
5147         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5148   "TARGET_SSE2 && TARGET_SSE_MATH
5149    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5150    && reload_completed
5151    && (SSE_REG_P (operands[0])
5152        || (GET_CODE (operands[0]) == SUBREG
5153            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5154   [(const_int 0)]
5155 {
5156   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5157                                      <MODE>mode, 0);
5158   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5159
5160   emit_insn (gen_sse2_loadld (operands[4],
5161                               CONST0_RTX (V4SImode), operands[1]));
5162   if (<ssevecmode>mode == V4SFmode)
5163     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5164   else
5165     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5166   DONE;
5167 })
5168
5169 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5170   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5171         (float:MODEF
5172           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5173   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5174   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5175    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5176   "#"
5177   [(set_attr "type" "sseicvt")
5178    (set_attr "mode" "<MODEF:MODE>")
5179    (set_attr "athlon_decode" "double,direct")
5180    (set_attr "amdfam10_decode" "vector,double")
5181    (set_attr "bdver1_decode" "double,direct")
5182    (set_attr "fp_int_src" "true")])
5183
5184 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5185   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5186         (float:MODEF
5187           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5188   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5189    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5190    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5191   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5192   [(set_attr "type" "sseicvt")
5193    (set_attr "prefix" "maybe_vex")
5194    (set_attr "mode" "<MODEF:MODE>")
5195    (set (attr "prefix_rex")
5196      (if_then_else
5197        (and (eq_attr "prefix" "maybe_vex")
5198             (match_test "<SWI48x:MODE>mode == DImode"))
5199        (const_string "1")
5200        (const_string "*")))
5201    (set_attr "athlon_decode" "double,direct")
5202    (set_attr "amdfam10_decode" "vector,double")
5203    (set_attr "bdver1_decode" "double,direct")
5204    (set_attr "fp_int_src" "true")])
5205
5206 (define_split
5207   [(set (match_operand:MODEF 0 "register_operand" "")
5208         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5209    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5210   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5211    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5212    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5213    && reload_completed
5214    && (SSE_REG_P (operands[0])
5215        || (GET_CODE (operands[0]) == SUBREG
5216            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5217   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5218
5219 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5220   [(set (match_operand:MODEF 0 "register_operand" "=x")
5221         (float:MODEF
5222           (match_operand:SWI48x 1 "memory_operand" "m")))]
5223   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5224    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5225    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5226   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5227   [(set_attr "type" "sseicvt")
5228    (set_attr "prefix" "maybe_vex")
5229    (set_attr "mode" "<MODEF:MODE>")
5230    (set (attr "prefix_rex")
5231      (if_then_else
5232        (and (eq_attr "prefix" "maybe_vex")
5233             (match_test "<SWI48x:MODE>mode == DImode"))
5234        (const_string "1")
5235        (const_string "*")))
5236    (set_attr "athlon_decode" "direct")
5237    (set_attr "amdfam10_decode" "double")
5238    (set_attr "bdver1_decode" "direct")
5239    (set_attr "fp_int_src" "true")])
5240
5241 (define_split
5242   [(set (match_operand:MODEF 0 "register_operand" "")
5243         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5244    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5245   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5246    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5247    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5248    && reload_completed
5249    && (SSE_REG_P (operands[0])
5250        || (GET_CODE (operands[0]) == SUBREG
5251            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5252   [(set (match_dup 2) (match_dup 1))
5253    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5254
5255 (define_split
5256   [(set (match_operand:MODEF 0 "register_operand" "")
5257         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5258    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5259   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5260    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5261    && reload_completed
5262    && (SSE_REG_P (operands[0])
5263        || (GET_CODE (operands[0]) == SUBREG
5264            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5265   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5266
5267 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5268   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5269         (float:X87MODEF
5270           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5271   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5272   "TARGET_80387
5273    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5274   "@
5275    fild%Z1\t%1
5276    #"
5277   [(set_attr "type" "fmov,multi")
5278    (set_attr "mode" "<X87MODEF:MODE>")
5279    (set_attr "unit" "*,i387")
5280    (set_attr "fp_int_src" "true")])
5281
5282 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5283   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5284         (float:X87MODEF
5285           (match_operand:SWI48x 1 "memory_operand" "m")))]
5286   "TARGET_80387
5287    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5288   "fild%Z1\t%1"
5289   [(set_attr "type" "fmov")
5290    (set_attr "mode" "<X87MODEF:MODE>")
5291    (set_attr "fp_int_src" "true")])
5292
5293 (define_split
5294   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5295         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5296    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5297   "TARGET_80387
5298    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5299    && reload_completed"
5300   [(set (match_dup 2) (match_dup 1))
5301    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5302
5303 (define_split
5304   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5305         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5306    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5307   "TARGET_80387
5308    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5309    && reload_completed"
5310   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5311
5312 ;; Avoid store forwarding (partial memory) stall penalty
5313 ;; by passing DImode value through XMM registers.  */
5314
5315 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5316   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5317         (float:X87MODEF
5318           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5319    (clobber (match_scratch:V4SI 3 "=X,x"))
5320    (clobber (match_scratch:V4SI 4 "=X,x"))
5321    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5322   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5323    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5324    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5325   "#"
5326   [(set_attr "type" "multi")
5327    (set_attr "mode" "<X87MODEF:MODE>")
5328    (set_attr "unit" "i387")
5329    (set_attr "fp_int_src" "true")])
5330
5331 (define_split
5332   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5333         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5334    (clobber (match_scratch:V4SI 3 ""))
5335    (clobber (match_scratch:V4SI 4 ""))
5336    (clobber (match_operand:DI 2 "memory_operand" ""))]
5337   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5338    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5339    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5340    && reload_completed"
5341   [(set (match_dup 2) (match_dup 3))
5342    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5343 {
5344   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5345      Assemble the 64-bit DImode value in an xmm register.  */
5346   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5347                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5348   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5349                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5350   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5351                                          operands[4]));
5352
5353   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5354 })
5355
5356 (define_split
5357   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5358         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5359    (clobber (match_scratch:V4SI 3 ""))
5360    (clobber (match_scratch:V4SI 4 ""))
5361    (clobber (match_operand:DI 2 "memory_operand" ""))]
5362   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5363    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5364    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5365    && reload_completed"
5366   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5367
5368 ;; Avoid store forwarding (partial memory) stall penalty by extending
5369 ;; SImode value to DImode through XMM register instead of pushing two
5370 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5371 ;; targets benefit from this optimization. Also note that fild
5372 ;; loads from memory only.
5373
5374 (define_insn "*floatunssi<mode>2_1"
5375   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5376         (unsigned_float:X87MODEF
5377           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5378    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5379    (clobber (match_scratch:SI 3 "=X,x"))]
5380   "!TARGET_64BIT
5381    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5382    && TARGET_SSE"
5383   "#"
5384   [(set_attr "type" "multi")
5385    (set_attr "mode" "<MODE>")])
5386
5387 (define_split
5388   [(set (match_operand:X87MODEF 0 "register_operand" "")
5389         (unsigned_float:X87MODEF
5390           (match_operand:SI 1 "register_operand" "")))
5391    (clobber (match_operand:DI 2 "memory_operand" ""))
5392    (clobber (match_scratch:SI 3 ""))]
5393   "!TARGET_64BIT
5394    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5395    && TARGET_SSE
5396    && reload_completed"
5397   [(set (match_dup 2) (match_dup 1))
5398    (set (match_dup 0)
5399         (float:X87MODEF (match_dup 2)))]
5400   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5401
5402 (define_split
5403   [(set (match_operand:X87MODEF 0 "register_operand" "")
5404         (unsigned_float:X87MODEF
5405           (match_operand:SI 1 "memory_operand" "")))
5406    (clobber (match_operand:DI 2 "memory_operand" ""))
5407    (clobber (match_scratch:SI 3 ""))]
5408   "!TARGET_64BIT
5409    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5410    && TARGET_SSE
5411    && reload_completed"
5412   [(set (match_dup 2) (match_dup 3))
5413    (set (match_dup 0)
5414         (float:X87MODEF (match_dup 2)))]
5415 {
5416   emit_move_insn (operands[3], operands[1]);
5417   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5418 })
5419
5420 (define_expand "floatunssi<mode>2"
5421   [(parallel
5422      [(set (match_operand:X87MODEF 0 "register_operand" "")
5423            (unsigned_float:X87MODEF
5424              (match_operand:SI 1 "nonimmediate_operand" "")))
5425       (clobber (match_dup 2))
5426       (clobber (match_scratch:SI 3 ""))])]
5427   "!TARGET_64BIT
5428    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5429         && TARGET_SSE)
5430        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5431 {
5432   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5433     {
5434       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5435       DONE;
5436     }
5437   else
5438     {
5439       enum ix86_stack_slot slot = (virtuals_instantiated
5440                                    ? SLOT_TEMP
5441                                    : SLOT_VIRTUAL);
5442       operands[2] = assign_386_stack_local (DImode, slot);
5443     }
5444 })
5445
5446 (define_expand "floatunsdisf2"
5447   [(use (match_operand:SF 0 "register_operand" ""))
5448    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5449   "TARGET_64BIT && TARGET_SSE_MATH"
5450   "x86_emit_floatuns (operands); DONE;")
5451
5452 (define_expand "floatunsdidf2"
5453   [(use (match_operand:DF 0 "register_operand" ""))
5454    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5455   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5456    && TARGET_SSE2 && TARGET_SSE_MATH"
5457 {
5458   if (TARGET_64BIT)
5459     x86_emit_floatuns (operands);
5460   else
5461     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5462   DONE;
5463 })
5464 \f
5465 ;; Add instructions
5466
5467 (define_expand "add<mode>3"
5468   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5469         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5470                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5471   ""
5472   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5473
5474 (define_insn_and_split "*add<dwi>3_doubleword"
5475   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5476         (plus:<DWI>
5477           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5478           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5479    (clobber (reg:CC FLAGS_REG))]
5480   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5481   "#"
5482   "reload_completed"
5483   [(parallel [(set (reg:CC FLAGS_REG)
5484                    (unspec:CC [(match_dup 1) (match_dup 2)]
5485                               UNSPEC_ADD_CARRY))
5486               (set (match_dup 0)
5487                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5488    (parallel [(set (match_dup 3)
5489                    (plus:DWIH
5490                      (match_dup 4)
5491                      (plus:DWIH
5492                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5493                        (match_dup 5))))
5494               (clobber (reg:CC FLAGS_REG))])]
5495   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5496
5497 (define_insn "*add<mode>3_cc"
5498   [(set (reg:CC FLAGS_REG)
5499         (unspec:CC
5500           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5501            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5502           UNSPEC_ADD_CARRY))
5503    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5504         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5505   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5506   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5507   [(set_attr "type" "alu")
5508    (set_attr "mode" "<MODE>")])
5509
5510 (define_insn "addqi3_cc"
5511   [(set (reg:CC FLAGS_REG)
5512         (unspec:CC
5513           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5514            (match_operand:QI 2 "general_operand" "qn,qm")]
5515           UNSPEC_ADD_CARRY))
5516    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5517         (plus:QI (match_dup 1) (match_dup 2)))]
5518   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5519   "add{b}\t{%2, %0|%0, %2}"
5520   [(set_attr "type" "alu")
5521    (set_attr "mode" "QI")])
5522
5523 (define_insn_and_split "*lea_1"
5524   [(set (match_operand:SI 0 "register_operand" "=r")
5525         (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5526   "TARGET_64BIT"
5527   "lea{l}\t{%a1, %0|%0, %a1}"
5528   "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5529   [(const_int 0)]
5530 {
5531   ix86_split_lea_for_addr (operands, SImode);
5532   DONE;
5533 }
5534   [(set_attr "type" "lea")
5535    (set_attr "mode" "SI")])
5536
5537 (define_insn_and_split "*lea<mode>_2"
5538   [(set (match_operand:SWI48 0 "register_operand" "=r")
5539         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5540   ""
5541   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5542   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5543   [(const_int 0)]
5544 {
5545   ix86_split_lea_for_addr (operands, <MODE>mode);
5546   DONE;
5547 }
5548   [(set_attr "type" "lea")
5549    (set_attr "mode" "<MODE>")])
5550
5551 (define_insn "*lea_3_zext"
5552   [(set (match_operand:DI 0 "register_operand" "=r")
5553         (zero_extend:DI
5554           (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5555   "TARGET_64BIT"
5556   "lea{l}\t{%a1, %k0|%k0, %a1}"
5557   [(set_attr "type" "lea")
5558    (set_attr "mode" "SI")])
5559
5560 (define_insn "*lea_4_zext"
5561   [(set (match_operand:DI 0 "register_operand" "=r")
5562         (zero_extend:DI
5563           (match_operand:SI 1 "lea_address_operand" "j")))]
5564   "TARGET_64BIT"
5565   "lea{l}\t{%a1, %k0|%k0, %a1}"
5566   [(set_attr "type" "lea")
5567    (set_attr "mode" "SI")])
5568
5569 (define_insn "*lea_5_zext"
5570   [(set (match_operand:DI 0 "register_operand" "=r")
5571         (and:DI
5572           (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5573           (match_operand:DI 2 "const_32bit_mask" "n")))]
5574   "TARGET_64BIT"
5575   "lea{l}\t{%a1, %k0|%k0, %a1}"
5576   [(set_attr "type" "lea")
5577    (set_attr "mode" "SI")])
5578
5579 (define_insn "*lea_6_zext"
5580   [(set (match_operand:DI 0 "register_operand" "=r")
5581         (and:DI
5582           (match_operand:DI 1 "lea_address_operand" "p")
5583           (match_operand:DI 2 "const_32bit_mask" "n")))]
5584   "TARGET_64BIT"
5585   "lea{l}\t{%a1, %k0|%k0, %a1}"
5586   [(set_attr "type" "lea")
5587    (set_attr "mode" "SI")])
5588
5589 (define_insn "*add<mode>_1"
5590   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5591         (plus:SWI48
5592           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5593           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5594    (clobber (reg:CC FLAGS_REG))]
5595   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5596 {
5597   switch (get_attr_type (insn))
5598     {
5599     case TYPE_LEA:
5600       return "#";
5601
5602     case TYPE_INCDEC:
5603       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5604       if (operands[2] == const1_rtx)
5605         return "inc{<imodesuffix>}\t%0";
5606       else
5607         {
5608           gcc_assert (operands[2] == constm1_rtx);
5609           return "dec{<imodesuffix>}\t%0";
5610         }
5611
5612     default:
5613       /* For most processors, ADD is faster than LEA.  This alternative
5614          was added to use ADD as much as possible.  */
5615       if (which_alternative == 2)
5616         {
5617           rtx tmp;
5618           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5619         }
5620         
5621       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5622       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5623         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5624
5625       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5626     }
5627 }
5628   [(set (attr "type")
5629      (cond [(eq_attr "alternative" "3")
5630               (const_string "lea")
5631             (match_operand:SWI48 2 "incdec_operand" "")
5632               (const_string "incdec")
5633            ]
5634            (const_string "alu")))
5635    (set (attr "length_immediate")
5636       (if_then_else
5637         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5638         (const_string "1")
5639         (const_string "*")))
5640    (set_attr "mode" "<MODE>")])
5641
5642 ;; It may seem that nonimmediate operand is proper one for operand 1.
5643 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5644 ;; we take care in ix86_binary_operator_ok to not allow two memory
5645 ;; operands so proper swapping will be done in reload.  This allow
5646 ;; patterns constructed from addsi_1 to match.
5647
5648 (define_insn "addsi_1_zext"
5649   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5650         (zero_extend:DI
5651           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5652                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5653    (clobber (reg:CC FLAGS_REG))]
5654   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5655 {
5656   switch (get_attr_type (insn))
5657     {
5658     case TYPE_LEA:
5659       return "#";
5660
5661     case TYPE_INCDEC:
5662       if (operands[2] == const1_rtx)
5663         return "inc{l}\t%k0";
5664       else
5665         {
5666           gcc_assert (operands[2] == constm1_rtx);
5667           return "dec{l}\t%k0";
5668         }
5669
5670     default:
5671       /* For most processors, ADD is faster than LEA.  This alternative
5672          was added to use ADD as much as possible.  */
5673       if (which_alternative == 1)
5674         {
5675           rtx tmp;
5676           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5677         }
5678
5679       if (x86_maybe_negate_const_int (&operands[2], SImode))
5680         return "sub{l}\t{%2, %k0|%k0, %2}";
5681
5682       return "add{l}\t{%2, %k0|%k0, %2}";
5683     }
5684 }
5685   [(set (attr "type")
5686      (cond [(eq_attr "alternative" "2")
5687               (const_string "lea")
5688             (match_operand:SI 2 "incdec_operand" "")
5689               (const_string "incdec")
5690            ]
5691            (const_string "alu")))
5692    (set (attr "length_immediate")
5693       (if_then_else
5694         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5695         (const_string "1")
5696         (const_string "*")))
5697    (set_attr "mode" "SI")])
5698
5699 (define_insn "*addhi_1"
5700   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5701         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5702                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5703    (clobber (reg:CC FLAGS_REG))]
5704   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5705 {
5706   switch (get_attr_type (insn))
5707     {
5708     case TYPE_LEA:
5709       return "#";
5710
5711     case TYPE_INCDEC:
5712       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5713       if (operands[2] == const1_rtx)
5714         return "inc{w}\t%0";
5715       else
5716         {
5717           gcc_assert (operands[2] == constm1_rtx);
5718           return "dec{w}\t%0";
5719         }
5720
5721     default:
5722       /* For most processors, ADD is faster than LEA.  This alternative
5723          was added to use ADD as much as possible.  */
5724       if (which_alternative == 2)
5725         {
5726           rtx tmp;
5727           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5728         }
5729
5730       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5731       if (x86_maybe_negate_const_int (&operands[2], HImode))
5732         return "sub{w}\t{%2, %0|%0, %2}";
5733
5734       return "add{w}\t{%2, %0|%0, %2}";
5735     }
5736 }
5737   [(set (attr "type")
5738      (cond [(eq_attr "alternative" "3")
5739               (const_string "lea")
5740             (match_operand:HI 2 "incdec_operand" "")
5741               (const_string "incdec")
5742            ]
5743            (const_string "alu")))
5744    (set (attr "length_immediate")
5745       (if_then_else
5746         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5747         (const_string "1")
5748         (const_string "*")))
5749    (set_attr "mode" "HI,HI,HI,SI")])
5750
5751 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5752 (define_insn "*addqi_1"
5753   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5754         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5755                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5756    (clobber (reg:CC FLAGS_REG))]
5757   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5758 {
5759   bool widen = (which_alternative == 3 || which_alternative == 4);
5760
5761   switch (get_attr_type (insn))
5762     {
5763     case TYPE_LEA:
5764       return "#";
5765
5766     case TYPE_INCDEC:
5767       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5768       if (operands[2] == const1_rtx)
5769         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5770       else
5771         {
5772           gcc_assert (operands[2] == constm1_rtx);
5773           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5774         }
5775
5776     default:
5777       /* For most processors, ADD is faster than LEA.  These alternatives
5778          were added to use ADD as much as possible.  */
5779       if (which_alternative == 2 || which_alternative == 4)
5780         {
5781           rtx tmp;
5782           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5783         }
5784
5785       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5786       if (x86_maybe_negate_const_int (&operands[2], QImode))
5787         {
5788           if (widen)
5789             return "sub{l}\t{%2, %k0|%k0, %2}";
5790           else
5791             return "sub{b}\t{%2, %0|%0, %2}";
5792         }
5793       if (widen)
5794         return "add{l}\t{%k2, %k0|%k0, %k2}";
5795       else
5796         return "add{b}\t{%2, %0|%0, %2}";
5797     }
5798 }
5799   [(set (attr "type")
5800      (cond [(eq_attr "alternative" "5")
5801               (const_string "lea")
5802             (match_operand:QI 2 "incdec_operand" "")
5803               (const_string "incdec")
5804            ]
5805            (const_string "alu")))
5806    (set (attr "length_immediate")
5807       (if_then_else
5808         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5809         (const_string "1")
5810         (const_string "*")))
5811    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5812
5813 (define_insn "*addqi_1_slp"
5814   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5815         (plus:QI (match_dup 0)
5816                  (match_operand:QI 1 "general_operand" "qn,qm")))
5817    (clobber (reg:CC FLAGS_REG))]
5818   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5819    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5820 {
5821   switch (get_attr_type (insn))
5822     {
5823     case TYPE_INCDEC:
5824       if (operands[1] == const1_rtx)
5825         return "inc{b}\t%0";
5826       else
5827         {
5828           gcc_assert (operands[1] == constm1_rtx);
5829           return "dec{b}\t%0";
5830         }
5831
5832     default:
5833       if (x86_maybe_negate_const_int (&operands[1], QImode))
5834         return "sub{b}\t{%1, %0|%0, %1}";
5835
5836       return "add{b}\t{%1, %0|%0, %1}";
5837     }
5838 }
5839   [(set (attr "type")
5840      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5841         (const_string "incdec")
5842         (const_string "alu1")))
5843    (set (attr "memory")
5844      (if_then_else (match_operand 1 "memory_operand" "")
5845         (const_string "load")
5846         (const_string "none")))
5847    (set_attr "mode" "QI")])
5848
5849 ;; Split non destructive adds if we cannot use lea.
5850 (define_split
5851   [(set (match_operand:SWI48 0 "register_operand" "")
5852         (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5853               (match_operand:SWI48 2 "nonmemory_operand" "")))
5854    (clobber (reg:CC FLAGS_REG))]
5855   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5856   [(set (match_dup 0) (match_dup 1))
5857    (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5858               (clobber (reg:CC FLAGS_REG))])])
5859
5860 ;; Convert add to the lea pattern to avoid flags dependency.
5861 (define_split
5862   [(set (match_operand:SWI 0 "register_operand" "")
5863         (plus:SWI (match_operand:SWI 1 "register_operand" "")
5864                   (match_operand:SWI 2 "<nonmemory_operand>" "")))
5865    (clobber (reg:CC FLAGS_REG))]
5866   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5867   [(const_int 0)]
5868 {
5869   enum machine_mode mode = <MODE>mode;
5870   rtx pat;
5871
5872   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5873     { 
5874       mode = SImode; 
5875       operands[0] = gen_lowpart (mode, operands[0]);
5876       operands[1] = gen_lowpart (mode, operands[1]);
5877       operands[2] = gen_lowpart (mode, operands[2]);
5878     }
5879
5880   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5881
5882   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5883   DONE;
5884 })
5885
5886 ;; Convert add to the lea pattern to avoid flags dependency.
5887 (define_split
5888   [(set (match_operand:DI 0 "register_operand" "")
5889         (zero_extend:DI
5890           (plus:SI (match_operand:SI 1 "register_operand" "")
5891                    (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5892    (clobber (reg:CC FLAGS_REG))]
5893   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5894   [(set (match_dup 0)
5895         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5896
5897 (define_insn "*add<mode>_2"
5898   [(set (reg FLAGS_REG)
5899         (compare
5900           (plus:SWI
5901             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5902             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5903           (const_int 0)))
5904    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5905         (plus:SWI (match_dup 1) (match_dup 2)))]
5906   "ix86_match_ccmode (insn, CCGOCmode)
5907    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5908 {
5909   switch (get_attr_type (insn))
5910     {
5911     case TYPE_INCDEC:
5912       if (operands[2] == const1_rtx)
5913         return "inc{<imodesuffix>}\t%0";
5914       else
5915         {
5916           gcc_assert (operands[2] == constm1_rtx);
5917           return "dec{<imodesuffix>}\t%0";
5918         }
5919
5920     default:
5921       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5922         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5923
5924       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5925     }
5926 }
5927   [(set (attr "type")
5928      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5929         (const_string "incdec")
5930         (const_string "alu")))
5931    (set (attr "length_immediate")
5932       (if_then_else
5933         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5934         (const_string "1")
5935         (const_string "*")))
5936    (set_attr "mode" "<MODE>")])
5937
5938 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5939 (define_insn "*addsi_2_zext"
5940   [(set (reg FLAGS_REG)
5941         (compare
5942           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5943                    (match_operand:SI 2 "x86_64_general_operand" "rme"))
5944           (const_int 0)))
5945    (set (match_operand:DI 0 "register_operand" "=r")
5946         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5947   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5948    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5949 {
5950   switch (get_attr_type (insn))
5951     {
5952     case TYPE_INCDEC:
5953       if (operands[2] == const1_rtx)
5954         return "inc{l}\t%k0";
5955       else
5956         {
5957           gcc_assert (operands[2] == constm1_rtx);
5958           return "dec{l}\t%k0";
5959         }
5960
5961     default:
5962       if (x86_maybe_negate_const_int (&operands[2], SImode))
5963         return "sub{l}\t{%2, %k0|%k0, %2}";
5964
5965       return "add{l}\t{%2, %k0|%k0, %2}";
5966     }
5967 }
5968   [(set (attr "type")
5969      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5970         (const_string "incdec")
5971         (const_string "alu")))
5972    (set (attr "length_immediate")
5973       (if_then_else
5974         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5975         (const_string "1")
5976         (const_string "*")))
5977    (set_attr "mode" "SI")])
5978
5979 (define_insn "*add<mode>_3"
5980   [(set (reg FLAGS_REG)
5981         (compare
5982           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5983           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5984    (clobber (match_scratch:SWI 0 "=<r>"))]
5985   "ix86_match_ccmode (insn, CCZmode)
5986    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5987 {
5988   switch (get_attr_type (insn))
5989     {
5990     case TYPE_INCDEC:
5991       if (operands[2] == const1_rtx)
5992         return "inc{<imodesuffix>}\t%0";
5993       else
5994         {
5995           gcc_assert (operands[2] == constm1_rtx);
5996           return "dec{<imodesuffix>}\t%0";
5997         }
5998
5999     default:
6000       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6001         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6002
6003       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6004     }
6005 }
6006   [(set (attr "type")
6007      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6008         (const_string "incdec")
6009         (const_string "alu")))
6010    (set (attr "length_immediate")
6011       (if_then_else
6012         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6013         (const_string "1")
6014         (const_string "*")))
6015    (set_attr "mode" "<MODE>")])
6016
6017 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6018 (define_insn "*addsi_3_zext"
6019   [(set (reg FLAGS_REG)
6020         (compare
6021           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
6022           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6023    (set (match_operand:DI 0 "register_operand" "=r")
6024         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6025   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6026    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6027 {
6028   switch (get_attr_type (insn))
6029     {
6030     case TYPE_INCDEC:
6031       if (operands[2] == const1_rtx)
6032         return "inc{l}\t%k0";
6033       else
6034         {
6035           gcc_assert (operands[2] == constm1_rtx);
6036           return "dec{l}\t%k0";
6037         }
6038
6039     default:
6040       if (x86_maybe_negate_const_int (&operands[2], SImode))
6041         return "sub{l}\t{%2, %k0|%k0, %2}";
6042
6043       return "add{l}\t{%2, %k0|%k0, %2}";
6044     }
6045 }
6046   [(set (attr "type")
6047      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6048         (const_string "incdec")
6049         (const_string "alu")))
6050    (set (attr "length_immediate")
6051       (if_then_else
6052         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6053         (const_string "1")
6054         (const_string "*")))
6055    (set_attr "mode" "SI")])
6056
6057 ; For comparisons against 1, -1 and 128, we may generate better code
6058 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6059 ; is matched then.  We can't accept general immediate, because for
6060 ; case of overflows,  the result is messed up.
6061 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6062 ; only for comparisons not depending on it.
6063
6064 (define_insn "*adddi_4"
6065   [(set (reg FLAGS_REG)
6066         (compare
6067           (match_operand:DI 1 "nonimmediate_operand" "0")
6068           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6069    (clobber (match_scratch:DI 0 "=rm"))]
6070   "TARGET_64BIT
6071    && ix86_match_ccmode (insn, CCGCmode)"
6072 {
6073   switch (get_attr_type (insn))
6074     {
6075     case TYPE_INCDEC:
6076       if (operands[2] == constm1_rtx)
6077         return "inc{q}\t%0";
6078       else
6079         {
6080           gcc_assert (operands[2] == const1_rtx);
6081           return "dec{q}\t%0";
6082         }
6083
6084     default:
6085       if (x86_maybe_negate_const_int (&operands[2], DImode))
6086         return "add{q}\t{%2, %0|%0, %2}";
6087
6088       return "sub{q}\t{%2, %0|%0, %2}";
6089     }
6090 }
6091   [(set (attr "type")
6092      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6093         (const_string "incdec")
6094         (const_string "alu")))
6095    (set (attr "length_immediate")
6096       (if_then_else
6097         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6098         (const_string "1")
6099         (const_string "*")))
6100    (set_attr "mode" "DI")])
6101
6102 ; For comparisons against 1, -1 and 128, we may generate better code
6103 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6104 ; is matched then.  We can't accept general immediate, because for
6105 ; case of overflows,  the result is messed up.
6106 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6107 ; only for comparisons not depending on it.
6108
6109 (define_insn "*add<mode>_4"
6110   [(set (reg FLAGS_REG)
6111         (compare
6112           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6113           (match_operand:SWI124 2 "const_int_operand" "n")))
6114    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6115   "ix86_match_ccmode (insn, CCGCmode)"
6116 {
6117   switch (get_attr_type (insn))
6118     {
6119     case TYPE_INCDEC:
6120       if (operands[2] == constm1_rtx)
6121         return "inc{<imodesuffix>}\t%0";
6122       else
6123         {
6124           gcc_assert (operands[2] == const1_rtx);
6125           return "dec{<imodesuffix>}\t%0";
6126         }
6127
6128     default:
6129       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6130         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6131
6132       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6133     }
6134 }
6135   [(set (attr "type")
6136      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6137         (const_string "incdec")
6138         (const_string "alu")))
6139    (set (attr "length_immediate")
6140       (if_then_else
6141         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6142         (const_string "1")
6143         (const_string "*")))
6144    (set_attr "mode" "<MODE>")])
6145
6146 (define_insn "*add<mode>_5"
6147   [(set (reg FLAGS_REG)
6148         (compare
6149           (plus:SWI
6150             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6151             (match_operand:SWI 2 "<general_operand>" "<g>"))
6152           (const_int 0)))
6153    (clobber (match_scratch:SWI 0 "=<r>"))]
6154   "ix86_match_ccmode (insn, CCGOCmode)
6155    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6156 {
6157   switch (get_attr_type (insn))
6158     {
6159     case TYPE_INCDEC:
6160       if (operands[2] == const1_rtx)
6161         return "inc{<imodesuffix>}\t%0";
6162       else
6163         {
6164           gcc_assert (operands[2] == constm1_rtx);
6165           return "dec{<imodesuffix>}\t%0";
6166         }
6167
6168     default:
6169       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6170         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6171
6172       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6173     }
6174 }
6175   [(set (attr "type")
6176      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6177         (const_string "incdec")
6178         (const_string "alu")))
6179    (set (attr "length_immediate")
6180       (if_then_else
6181         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6182         (const_string "1")
6183         (const_string "*")))
6184    (set_attr "mode" "<MODE>")])
6185
6186 (define_insn "*addqi_ext_1_rex64"
6187   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6188                          (const_int 8)
6189                          (const_int 8))
6190         (plus:SI
6191           (zero_extract:SI
6192             (match_operand 1 "ext_register_operand" "0")
6193             (const_int 8)
6194             (const_int 8))
6195           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6196    (clobber (reg:CC FLAGS_REG))]
6197   "TARGET_64BIT"
6198 {
6199   switch (get_attr_type (insn))
6200     {
6201     case TYPE_INCDEC:
6202       if (operands[2] == const1_rtx)
6203         return "inc{b}\t%h0";
6204       else
6205         {
6206           gcc_assert (operands[2] == constm1_rtx);
6207           return "dec{b}\t%h0";
6208         }
6209
6210     default:
6211       return "add{b}\t{%2, %h0|%h0, %2}";
6212     }
6213 }
6214   [(set (attr "type")
6215      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6216         (const_string "incdec")
6217         (const_string "alu")))
6218    (set_attr "modrm" "1")
6219    (set_attr "mode" "QI")])
6220
6221 (define_insn "addqi_ext_1"
6222   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6223                          (const_int 8)
6224                          (const_int 8))
6225         (plus:SI
6226           (zero_extract:SI
6227             (match_operand 1 "ext_register_operand" "0")
6228             (const_int 8)
6229             (const_int 8))
6230           (match_operand:QI 2 "general_operand" "Qmn")))
6231    (clobber (reg:CC FLAGS_REG))]
6232   "!TARGET_64BIT"
6233 {
6234   switch (get_attr_type (insn))
6235     {
6236     case TYPE_INCDEC:
6237       if (operands[2] == const1_rtx)
6238         return "inc{b}\t%h0";
6239       else
6240         {
6241           gcc_assert (operands[2] == constm1_rtx);
6242           return "dec{b}\t%h0";
6243         }
6244
6245     default:
6246       return "add{b}\t{%2, %h0|%h0, %2}";
6247     }
6248 }
6249   [(set (attr "type")
6250      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6251         (const_string "incdec")
6252         (const_string "alu")))
6253    (set_attr "modrm" "1")
6254    (set_attr "mode" "QI")])
6255
6256 (define_insn "*addqi_ext_2"
6257   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6258                          (const_int 8)
6259                          (const_int 8))
6260         (plus:SI
6261           (zero_extract:SI
6262             (match_operand 1 "ext_register_operand" "%0")
6263             (const_int 8)
6264             (const_int 8))
6265           (zero_extract:SI
6266             (match_operand 2 "ext_register_operand" "Q")
6267             (const_int 8)
6268             (const_int 8))))
6269    (clobber (reg:CC FLAGS_REG))]
6270   ""
6271   "add{b}\t{%h2, %h0|%h0, %h2}"
6272   [(set_attr "type" "alu")
6273    (set_attr "mode" "QI")])
6274
6275 ;; The lea patterns for modes less than 32 bits need to be matched by
6276 ;; several insns converted to real lea by splitters.
6277
6278 (define_insn_and_split "*lea_general_1"
6279   [(set (match_operand 0 "register_operand" "=r")
6280         (plus (plus (match_operand 1 "index_register_operand" "l")
6281                     (match_operand 2 "register_operand" "r"))
6282               (match_operand 3 "immediate_operand" "i")))]
6283   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6284    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6285    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6286    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6287    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6288        || GET_MODE (operands[3]) == VOIDmode)"
6289   "#"
6290   "&& reload_completed"
6291   [(const_int 0)]
6292 {
6293   enum machine_mode mode = SImode;
6294   rtx pat;
6295
6296   operands[0] = gen_lowpart (mode, operands[0]);
6297   operands[1] = gen_lowpart (mode, operands[1]);
6298   operands[2] = gen_lowpart (mode, operands[2]);
6299   operands[3] = gen_lowpart (mode, operands[3]);
6300
6301   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6302                       operands[3]);
6303
6304   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6305   DONE;
6306 }
6307   [(set_attr "type" "lea")
6308    (set_attr "mode" "SI")])
6309
6310 (define_insn_and_split "*lea_general_2"
6311   [(set (match_operand 0 "register_operand" "=r")
6312         (plus (mult (match_operand 1 "index_register_operand" "l")
6313                     (match_operand 2 "const248_operand" "n"))
6314               (match_operand 3 "nonmemory_operand" "ri")))]
6315   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
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   enum machine_mode mode = SImode;
6325   rtx pat;
6326
6327   operands[0] = gen_lowpart (mode, operands[0]);
6328   operands[1] = gen_lowpart (mode, operands[1]);
6329   operands[3] = gen_lowpart (mode, operands[3]);
6330
6331   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6332                       operands[3]);
6333
6334   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6335   DONE;
6336 }
6337   [(set_attr "type" "lea")
6338    (set_attr "mode" "SI")])
6339
6340 (define_insn_and_split "*lea_general_3"
6341   [(set (match_operand 0 "register_operand" "=r")
6342         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6343                           (match_operand 2 "const248_operand" "n"))
6344                     (match_operand 3 "register_operand" "r"))
6345               (match_operand 4 "immediate_operand" "i")))]
6346   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6347    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6348    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6349    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6350   "#"
6351   "&& reload_completed"
6352   [(const_int 0)]
6353 {
6354   enum machine_mode mode = SImode;
6355   rtx pat;
6356
6357   operands[0] = gen_lowpart (mode, operands[0]);
6358   operands[1] = gen_lowpart (mode, operands[1]);
6359   operands[3] = gen_lowpart (mode, operands[3]);
6360   operands[4] = gen_lowpart (mode, operands[4]);
6361
6362   pat = gen_rtx_PLUS (mode,
6363                       gen_rtx_PLUS (mode,
6364                                     gen_rtx_MULT (mode, operands[1],
6365                                                         operands[2]),
6366                                     operands[3]),
6367                       operands[4]);
6368
6369   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6370   DONE;
6371 }
6372   [(set_attr "type" "lea")
6373    (set_attr "mode" "SI")])
6374
6375 (define_insn_and_split "*lea_general_4"
6376   [(set (match_operand 0 "register_operand" "=r")
6377         (any_or (ashift
6378                   (match_operand 1 "index_register_operand" "l")
6379                   (match_operand 2 "const_int_operand" "n"))
6380                 (match_operand 3 "const_int_operand" "n")))]
6381   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6382       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6383     || GET_MODE (operands[0]) == SImode
6384     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6385    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6386    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6387    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6388        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6389   "#"
6390   "&& reload_completed"
6391   [(const_int 0)]
6392 {
6393   enum machine_mode mode = GET_MODE (operands[0]);
6394   rtx pat;
6395
6396   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6397     { 
6398       mode = SImode; 
6399       operands[0] = gen_lowpart (mode, operands[0]);
6400       operands[1] = gen_lowpart (mode, operands[1]);
6401     }
6402
6403   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6404
6405   pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6406                        INTVAL (operands[3]));
6407
6408   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6409   DONE;
6410 }
6411   [(set_attr "type" "lea")
6412    (set (attr "mode")
6413       (if_then_else (match_operand:DI 0 "" "")
6414         (const_string "DI")
6415         (const_string "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 "x86_64_general_operand" "rme"))))
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 "x86_64_general_operand" "rme"))
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 "x86_64_general_operand" "rme")))
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 "x86_64_general_operand" "rme")))))
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 "x86_64_general_operand" "rme")))))
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 "x86_64_general_operand" "rme"))
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 "x86_64_general_operand" "K,e,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 "*bmi2_umulditi3_1"
6835   [(set (match_operand:DI 0 "register_operand" "=r")
6836         (mult:DI
6837           (match_operand:DI 2 "nonimmediate_operand" "%d")
6838           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6839    (set (match_operand:DI 1 "register_operand" "=r")
6840         (truncate:DI
6841           (lshiftrt:TI
6842             (mult:TI (zero_extend:TI (match_dup 2))
6843                      (zero_extend:TI (match_dup 3)))
6844             (const_int 64))))]
6845   "TARGET_64BIT && TARGET_BMI2
6846    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6847   "mulx\t{%3, %0, %1|%1, %0, %3}"
6848   [(set_attr "type" "imulx")
6849    (set_attr "prefix" "vex")
6850    (set_attr "mode" "DI")])
6851
6852 (define_insn "*bmi2_umulsidi3_1"
6853   [(set (match_operand:SI 0 "register_operand" "=r")
6854         (mult:SI
6855           (match_operand:SI 2 "nonimmediate_operand" "%d")
6856           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6857    (set (match_operand:SI 1 "register_operand" "=r")
6858         (truncate:SI
6859           (lshiftrt:DI
6860             (mult:DI (zero_extend:DI (match_dup 2))
6861                      (zero_extend:DI (match_dup 3)))
6862             (const_int 32))))]
6863   "!TARGET_64BIT && TARGET_BMI2
6864    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6865   "mulx\t{%3, %0, %1|%1, %0, %3}"
6866   [(set_attr "type" "imulx")
6867    (set_attr "prefix" "vex")
6868    (set_attr "mode" "SI")])
6869
6870 (define_insn "*umul<mode><dwi>3_1"
6871   [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6872         (mult:<DWI>
6873           (zero_extend:<DWI>
6874             (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6875           (zero_extend:<DWI>
6876             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6877    (clobber (reg:CC FLAGS_REG))]
6878   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6879   "@
6880    mul{<imodesuffix>}\t%2
6881    #"
6882   [(set_attr "isa" "*,bmi2")
6883    (set_attr "type" "imul,imulx")
6884    (set_attr "length_immediate" "0,*")
6885    (set (attr "athlon_decode")
6886         (cond [(eq_attr "alternative" "0")
6887                  (if_then_else (eq_attr "cpu" "athlon")
6888                    (const_string "vector")
6889                    (const_string "double"))]
6890               (const_string "*")))
6891    (set_attr "amdfam10_decode" "double,*")
6892    (set_attr "bdver1_decode" "direct,*")
6893    (set_attr "prefix" "orig,vex")
6894    (set_attr "mode" "<MODE>")])
6895
6896 ;; Convert mul to the mulx pattern to avoid flags dependency.
6897 (define_split
6898  [(set (match_operand:<DWI> 0 "register_operand" "")
6899        (mult:<DWI>
6900          (zero_extend:<DWI>
6901            (match_operand:DWIH 1 "register_operand" ""))
6902          (zero_extend:<DWI>
6903            (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6904   (clobber (reg:CC FLAGS_REG))]
6905  "TARGET_BMI2 && reload_completed
6906   && true_regnum (operands[1]) == DX_REG"
6907   [(parallel [(set (match_dup 3)
6908                    (mult:DWIH (match_dup 1) (match_dup 2)))
6909               (set (match_dup 4)
6910                    (truncate:DWIH
6911                      (lshiftrt:<DWI>
6912                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6913                                    (zero_extend:<DWI> (match_dup 2)))
6914                        (match_dup 5))))])]
6915 {
6916   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6917
6918   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6919 })
6920
6921 (define_insn "*mul<mode><dwi>3_1"
6922   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6923         (mult:<DWI>
6924           (sign_extend:<DWI>
6925             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6926           (sign_extend:<DWI>
6927             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6928    (clobber (reg:CC FLAGS_REG))]
6929   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6930   "imul{<imodesuffix>}\t%2"
6931   [(set_attr "type" "imul")
6932    (set_attr "length_immediate" "0")
6933    (set (attr "athlon_decode")
6934      (if_then_else (eq_attr "cpu" "athlon")
6935         (const_string "vector")
6936         (const_string "double")))
6937    (set_attr "amdfam10_decode" "double")
6938    (set_attr "bdver1_decode" "direct")
6939    (set_attr "mode" "<MODE>")])
6940
6941 (define_insn "*<u>mulqihi3_1"
6942   [(set (match_operand:HI 0 "register_operand" "=a")
6943         (mult:HI
6944           (any_extend:HI
6945             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6946           (any_extend:HI
6947             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6948    (clobber (reg:CC FLAGS_REG))]
6949   "TARGET_QIMODE_MATH
6950    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6951   "<sgnprefix>mul{b}\t%2"
6952   [(set_attr "type" "imul")
6953    (set_attr "length_immediate" "0")
6954    (set (attr "athlon_decode")
6955      (if_then_else (eq_attr "cpu" "athlon")
6956         (const_string "vector")
6957         (const_string "direct")))
6958    (set_attr "amdfam10_decode" "direct")
6959    (set_attr "bdver1_decode" "direct")
6960    (set_attr "mode" "QI")])
6961
6962 (define_expand "<s>mul<mode>3_highpart"
6963   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6964                    (truncate:SWI48
6965                      (lshiftrt:<DWI>
6966                        (mult:<DWI>
6967                          (any_extend:<DWI>
6968                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6969                          (any_extend:<DWI>
6970                            (match_operand:SWI48 2 "register_operand" "")))
6971                        (match_dup 4))))
6972               (clobber (match_scratch:SWI48 3 ""))
6973               (clobber (reg:CC FLAGS_REG))])]
6974   ""
6975   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6976
6977 (define_insn "*<s>muldi3_highpart_1"
6978   [(set (match_operand:DI 0 "register_operand" "=d")
6979         (truncate:DI
6980           (lshiftrt:TI
6981             (mult:TI
6982               (any_extend:TI
6983                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6984               (any_extend:TI
6985                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6986             (const_int 64))))
6987    (clobber (match_scratch:DI 3 "=1"))
6988    (clobber (reg:CC FLAGS_REG))]
6989   "TARGET_64BIT
6990    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6991   "<sgnprefix>mul{q}\t%2"
6992   [(set_attr "type" "imul")
6993    (set_attr "length_immediate" "0")
6994    (set (attr "athlon_decode")
6995      (if_then_else (eq_attr "cpu" "athlon")
6996         (const_string "vector")
6997         (const_string "double")))
6998    (set_attr "amdfam10_decode" "double")
6999    (set_attr "bdver1_decode" "direct")
7000    (set_attr "mode" "DI")])
7001
7002 (define_insn "*<s>mulsi3_highpart_1"
7003   [(set (match_operand:SI 0 "register_operand" "=d")
7004         (truncate:SI
7005           (lshiftrt:DI
7006             (mult:DI
7007               (any_extend:DI
7008                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7009               (any_extend:DI
7010                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7011             (const_int 32))))
7012    (clobber (match_scratch:SI 3 "=1"))
7013    (clobber (reg:CC FLAGS_REG))]
7014   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7015   "<sgnprefix>mul{l}\t%2"
7016   [(set_attr "type" "imul")
7017    (set_attr "length_immediate" "0")
7018    (set (attr "athlon_decode")
7019      (if_then_else (eq_attr "cpu" "athlon")
7020         (const_string "vector")
7021         (const_string "double")))
7022    (set_attr "amdfam10_decode" "double")
7023    (set_attr "bdver1_decode" "direct")
7024    (set_attr "mode" "SI")])
7025
7026 (define_insn "*<s>mulsi3_highpart_zext"
7027   [(set (match_operand:DI 0 "register_operand" "=d")
7028         (zero_extend:DI (truncate:SI
7029           (lshiftrt:DI
7030             (mult:DI (any_extend:DI
7031                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7032                      (any_extend:DI
7033                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7034             (const_int 32)))))
7035    (clobber (match_scratch:SI 3 "=1"))
7036    (clobber (reg:CC FLAGS_REG))]
7037   "TARGET_64BIT
7038    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7039   "<sgnprefix>mul{l}\t%2"
7040   [(set_attr "type" "imul")
7041    (set_attr "length_immediate" "0")
7042    (set (attr "athlon_decode")
7043      (if_then_else (eq_attr "cpu" "athlon")
7044         (const_string "vector")
7045         (const_string "double")))
7046    (set_attr "amdfam10_decode" "double")
7047    (set_attr "bdver1_decode" "direct")
7048    (set_attr "mode" "SI")])
7049
7050 ;; The patterns that match these are at the end of this file.
7051
7052 (define_expand "mulxf3"
7053   [(set (match_operand:XF 0 "register_operand" "")
7054         (mult:XF (match_operand:XF 1 "register_operand" "")
7055                  (match_operand:XF 2 "register_operand" "")))]
7056   "TARGET_80387")
7057
7058 (define_expand "mul<mode>3"
7059   [(set (match_operand:MODEF 0 "register_operand" "")
7060         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7061                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7062   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7063     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7064 \f
7065 ;; Divide instructions
7066
7067 ;; The patterns that match these are at the end of this file.
7068
7069 (define_expand "divxf3"
7070   [(set (match_operand:XF 0 "register_operand" "")
7071         (div:XF (match_operand:XF 1 "register_operand" "")
7072                 (match_operand:XF 2 "register_operand" "")))]
7073   "TARGET_80387")
7074
7075 (define_expand "divdf3"
7076   [(set (match_operand:DF 0 "register_operand" "")
7077         (div:DF (match_operand:DF 1 "register_operand" "")
7078                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7079    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7080     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7081
7082 (define_expand "divsf3"
7083   [(set (match_operand:SF 0 "register_operand" "")
7084         (div:SF (match_operand:SF 1 "register_operand" "")
7085                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7086   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7087     || TARGET_SSE_MATH"
7088 {
7089   if (TARGET_SSE_MATH
7090       && TARGET_RECIP_DIV
7091       && optimize_insn_for_speed_p ()
7092       && flag_finite_math_only && !flag_trapping_math
7093       && flag_unsafe_math_optimizations)
7094     {
7095       ix86_emit_swdivsf (operands[0], operands[1],
7096                          operands[2], SFmode);
7097       DONE;
7098     }
7099 })
7100 \f
7101 ;; Divmod instructions.
7102
7103 (define_expand "divmod<mode>4"
7104   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7105                    (div:SWIM248
7106                      (match_operand:SWIM248 1 "register_operand" "")
7107                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7108               (set (match_operand:SWIM248 3 "register_operand" "")
7109                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7110               (clobber (reg:CC FLAGS_REG))])])
7111
7112 ;; Split with 8bit unsigned divide:
7113 ;;      if (dividend an divisor are in [0-255])
7114 ;;         use 8bit unsigned integer divide
7115 ;;       else
7116 ;;         use original integer divide
7117 (define_split
7118   [(set (match_operand:SWI48 0 "register_operand" "")
7119         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7120                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7121    (set (match_operand:SWI48 1 "register_operand" "")
7122         (mod:SWI48 (match_dup 2) (match_dup 3)))
7123    (clobber (reg:CC FLAGS_REG))]
7124   "TARGET_USE_8BIT_IDIV
7125    && TARGET_QIMODE_MATH
7126    && can_create_pseudo_p ()
7127    && !optimize_insn_for_size_p ()"
7128   [(const_int 0)]
7129   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7130
7131 (define_insn_and_split "divmod<mode>4_1"
7132   [(set (match_operand:SWI48 0 "register_operand" "=a")
7133         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7134                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7135    (set (match_operand:SWI48 1 "register_operand" "=&d")
7136         (mod:SWI48 (match_dup 2) (match_dup 3)))
7137    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7138    (clobber (reg:CC FLAGS_REG))]
7139   ""
7140   "#"
7141   "reload_completed"
7142   [(parallel [(set (match_dup 1)
7143                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7144               (clobber (reg:CC FLAGS_REG))])
7145    (parallel [(set (match_dup 0)
7146                    (div:SWI48 (match_dup 2) (match_dup 3)))
7147               (set (match_dup 1)
7148                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7149               (use (match_dup 1))
7150               (clobber (reg:CC FLAGS_REG))])]
7151 {
7152   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7153
7154   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7155     operands[4] = operands[2];
7156   else
7157     {
7158       /* Avoid use of cltd in favor of a mov+shift.  */
7159       emit_move_insn (operands[1], operands[2]);
7160       operands[4] = operands[1];
7161     }
7162 }
7163   [(set_attr "type" "multi")
7164    (set_attr "mode" "<MODE>")])
7165
7166 (define_insn_and_split "*divmod<mode>4"
7167   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7168         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7169                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7170    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7171         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7172    (clobber (reg:CC FLAGS_REG))]
7173   ""
7174   "#"
7175   "reload_completed"
7176   [(parallel [(set (match_dup 1)
7177                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7178               (clobber (reg:CC FLAGS_REG))])
7179    (parallel [(set (match_dup 0)
7180                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7181               (set (match_dup 1)
7182                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7183               (use (match_dup 1))
7184               (clobber (reg:CC FLAGS_REG))])]
7185 {
7186   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7187
7188   if (<MODE>mode != HImode
7189       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7190     operands[4] = operands[2];
7191   else
7192     {
7193       /* Avoid use of cltd in favor of a mov+shift.  */
7194       emit_move_insn (operands[1], operands[2]);
7195       operands[4] = operands[1];
7196     }
7197 }
7198   [(set_attr "type" "multi")
7199    (set_attr "mode" "<MODE>")])
7200
7201 (define_insn "*divmod<mode>4_noext"
7202   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7203         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7204                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7205    (set (match_operand:SWIM248 1 "register_operand" "=d")
7206         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7207    (use (match_operand:SWIM248 4 "register_operand" "1"))
7208    (clobber (reg:CC FLAGS_REG))]
7209   ""
7210   "idiv{<imodesuffix>}\t%3"
7211   [(set_attr "type" "idiv")
7212    (set_attr "mode" "<MODE>")])
7213
7214 (define_expand "divmodqi4"
7215   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7216                    (div:QI
7217                      (match_operand:QI 1 "register_operand" "")
7218                      (match_operand:QI 2 "nonimmediate_operand" "")))
7219               (set (match_operand:QI 3 "register_operand" "")
7220                    (mod:QI (match_dup 1) (match_dup 2)))
7221               (clobber (reg:CC FLAGS_REG))])]
7222   "TARGET_QIMODE_MATH"
7223 {
7224   rtx div, mod, insn;
7225   rtx tmp0, tmp1;
7226   
7227   tmp0 = gen_reg_rtx (HImode);
7228   tmp1 = gen_reg_rtx (HImode);
7229
7230   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7231      in AX.  */
7232   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7233   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7234
7235   /* Extract remainder from AH.  */
7236   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7237   insn = emit_move_insn (operands[3], tmp1);
7238
7239   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7240   set_unique_reg_note (insn, REG_EQUAL, mod);
7241
7242   /* Extract quotient from AL.  */
7243   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7244
7245   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7246   set_unique_reg_note (insn, REG_EQUAL, div);
7247
7248   DONE;
7249 })
7250
7251 ;; Divide AX by r/m8, with result stored in
7252 ;; AL <- Quotient
7253 ;; AH <- Remainder
7254 ;; Change div/mod to HImode and extend the second argument to HImode
7255 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7256 ;; combine may fail.
7257 (define_insn "divmodhiqi3"
7258   [(set (match_operand:HI 0 "register_operand" "=a")
7259         (ior:HI
7260           (ashift:HI
7261             (zero_extend:HI
7262               (truncate:QI
7263                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7264                         (sign_extend:HI
7265                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7266             (const_int 8))
7267           (zero_extend:HI
7268             (truncate:QI
7269               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7270    (clobber (reg:CC FLAGS_REG))]
7271   "TARGET_QIMODE_MATH"
7272   "idiv{b}\t%2"
7273   [(set_attr "type" "idiv")
7274    (set_attr "mode" "QI")])
7275
7276 (define_expand "udivmod<mode>4"
7277   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7278                    (udiv:SWIM248
7279                      (match_operand:SWIM248 1 "register_operand" "")
7280                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7281               (set (match_operand:SWIM248 3 "register_operand" "")
7282                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7283               (clobber (reg:CC FLAGS_REG))])])
7284
7285 ;; Split with 8bit unsigned divide:
7286 ;;      if (dividend an divisor are in [0-255])
7287 ;;         use 8bit unsigned integer divide
7288 ;;       else
7289 ;;         use original integer divide
7290 (define_split
7291   [(set (match_operand:SWI48 0 "register_operand" "")
7292         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7293                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7294    (set (match_operand:SWI48 1 "register_operand" "")
7295         (umod:SWI48 (match_dup 2) (match_dup 3)))
7296    (clobber (reg:CC FLAGS_REG))]
7297   "TARGET_USE_8BIT_IDIV
7298    && TARGET_QIMODE_MATH
7299    && can_create_pseudo_p ()
7300    && !optimize_insn_for_size_p ()"
7301   [(const_int 0)]
7302   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7303
7304 (define_insn_and_split "udivmod<mode>4_1"
7305   [(set (match_operand:SWI48 0 "register_operand" "=a")
7306         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7307                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7308    (set (match_operand:SWI48 1 "register_operand" "=&d")
7309         (umod:SWI48 (match_dup 2) (match_dup 3)))
7310    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7311    (clobber (reg:CC FLAGS_REG))]
7312   ""
7313   "#"
7314   "reload_completed"
7315   [(set (match_dup 1) (const_int 0))
7316    (parallel [(set (match_dup 0)
7317                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7318               (set (match_dup 1)
7319                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7320               (use (match_dup 1))
7321               (clobber (reg:CC FLAGS_REG))])]
7322   ""
7323   [(set_attr "type" "multi")
7324    (set_attr "mode" "<MODE>")])
7325
7326 (define_insn_and_split "*udivmod<mode>4"
7327   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7328         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7329                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7330    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7331         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7332    (clobber (reg:CC FLAGS_REG))]
7333   ""
7334   "#"
7335   "reload_completed"
7336   [(set (match_dup 1) (const_int 0))
7337    (parallel [(set (match_dup 0)
7338                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7339               (set (match_dup 1)
7340                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7341               (use (match_dup 1))
7342               (clobber (reg:CC FLAGS_REG))])]
7343   ""
7344   [(set_attr "type" "multi")
7345    (set_attr "mode" "<MODE>")])
7346
7347 (define_insn "*udivmod<mode>4_noext"
7348   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7349         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7350                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7351    (set (match_operand:SWIM248 1 "register_operand" "=d")
7352         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7353    (use (match_operand:SWIM248 4 "register_operand" "1"))
7354    (clobber (reg:CC FLAGS_REG))]
7355   ""
7356   "div{<imodesuffix>}\t%3"
7357   [(set_attr "type" "idiv")
7358    (set_attr "mode" "<MODE>")])
7359
7360 (define_expand "udivmodqi4"
7361   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7362                    (udiv:QI
7363                      (match_operand:QI 1 "register_operand" "")
7364                      (match_operand:QI 2 "nonimmediate_operand" "")))
7365               (set (match_operand:QI 3 "register_operand" "")
7366                    (umod:QI (match_dup 1) (match_dup 2)))
7367               (clobber (reg:CC FLAGS_REG))])]
7368   "TARGET_QIMODE_MATH"
7369 {
7370   rtx div, mod, insn;
7371   rtx tmp0, tmp1;
7372   
7373   tmp0 = gen_reg_rtx (HImode);
7374   tmp1 = gen_reg_rtx (HImode);
7375
7376   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7377      in AX.  */
7378   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7379   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7380
7381   /* Extract remainder from AH.  */
7382   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7383   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7384   insn = emit_move_insn (operands[3], tmp1);
7385
7386   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7387   set_unique_reg_note (insn, REG_EQUAL, mod);
7388
7389   /* Extract quotient from AL.  */
7390   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7391
7392   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7393   set_unique_reg_note (insn, REG_EQUAL, div);
7394
7395   DONE;
7396 })
7397
7398 (define_insn "udivmodhiqi3"
7399   [(set (match_operand:HI 0 "register_operand" "=a")
7400         (ior:HI
7401           (ashift:HI
7402             (zero_extend:HI
7403               (truncate:QI
7404                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7405                         (zero_extend:HI
7406                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7407             (const_int 8))
7408           (zero_extend:HI
7409             (truncate:QI
7410               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7411    (clobber (reg:CC FLAGS_REG))]
7412   "TARGET_QIMODE_MATH"
7413   "div{b}\t%2"
7414   [(set_attr "type" "idiv")
7415    (set_attr "mode" "QI")])
7416
7417 ;; We cannot use div/idiv for double division, because it causes
7418 ;; "division by zero" on the overflow and that's not what we expect
7419 ;; from truncate.  Because true (non truncating) double division is
7420 ;; never generated, we can't create this insn anyway.
7421 ;
7422 ;(define_insn ""
7423 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7424 ;       (truncate:SI
7425 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7426 ;                  (zero_extend:DI
7427 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7428 ;   (set (match_operand:SI 3 "register_operand" "=d")
7429 ;       (truncate:SI
7430 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7431 ;   (clobber (reg:CC FLAGS_REG))]
7432 ;  ""
7433 ;  "div{l}\t{%2, %0|%0, %2}"
7434 ;  [(set_attr "type" "idiv")])
7435 \f
7436 ;;- Logical AND instructions
7437
7438 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7439 ;; Note that this excludes ah.
7440
7441 (define_expand "testsi_ccno_1"
7442   [(set (reg:CCNO FLAGS_REG)
7443         (compare:CCNO
7444           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7445                   (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7446           (const_int 0)))])
7447
7448 (define_expand "testqi_ccz_1"
7449   [(set (reg:CCZ FLAGS_REG)
7450         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7451                              (match_operand:QI 1 "nonmemory_operand" ""))
7452                  (const_int 0)))])
7453
7454 (define_expand "testdi_ccno_1"
7455   [(set (reg:CCNO FLAGS_REG)
7456         (compare:CCNO
7457           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7458                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7459           (const_int 0)))]
7460   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7461
7462 (define_insn "*testdi_1"
7463   [(set (reg FLAGS_REG)
7464         (compare
7465          (and:DI
7466           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7467           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7468          (const_int 0)))]
7469   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7470    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7471   "@
7472    test{l}\t{%k1, %k0|%k0, %k1}
7473    test{l}\t{%k1, %k0|%k0, %k1}
7474    test{q}\t{%1, %0|%0, %1}
7475    test{q}\t{%1, %0|%0, %1}
7476    test{q}\t{%1, %0|%0, %1}"
7477   [(set_attr "type" "test")
7478    (set_attr "modrm" "0,1,0,1,1")
7479    (set_attr "mode" "SI,SI,DI,DI,DI")])
7480
7481 (define_insn "*testqi_1_maybe_si"
7482   [(set (reg FLAGS_REG)
7483         (compare
7484           (and:QI
7485             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7486             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7487           (const_int 0)))]
7488    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7489     && ix86_match_ccmode (insn,
7490                          CONST_INT_P (operands[1])
7491                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7492 {
7493   if (which_alternative == 3)
7494     {
7495       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7496         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7497       return "test{l}\t{%1, %k0|%k0, %1}";
7498     }
7499   return "test{b}\t{%1, %0|%0, %1}";
7500 }
7501   [(set_attr "type" "test")
7502    (set_attr "modrm" "0,1,1,1")
7503    (set_attr "mode" "QI,QI,QI,SI")
7504    (set_attr "pent_pair" "uv,np,uv,np")])
7505
7506 (define_insn "*test<mode>_1"
7507   [(set (reg FLAGS_REG)
7508         (compare
7509          (and:SWI124
7510           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7511           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7512          (const_int 0)))]
7513   "ix86_match_ccmode (insn, CCNOmode)
7514    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7515   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7516   [(set_attr "type" "test")
7517    (set_attr "modrm" "0,1,1")
7518    (set_attr "mode" "<MODE>")
7519    (set_attr "pent_pair" "uv,np,uv")])
7520
7521 (define_expand "testqi_ext_ccno_0"
7522   [(set (reg:CCNO FLAGS_REG)
7523         (compare:CCNO
7524           (and:SI
7525             (zero_extract:SI
7526               (match_operand 0 "ext_register_operand" "")
7527               (const_int 8)
7528               (const_int 8))
7529             (match_operand 1 "const_int_operand" ""))
7530           (const_int 0)))])
7531
7532 (define_insn "*testqi_ext_0"
7533   [(set (reg FLAGS_REG)
7534         (compare
7535           (and:SI
7536             (zero_extract:SI
7537               (match_operand 0 "ext_register_operand" "Q")
7538               (const_int 8)
7539               (const_int 8))
7540             (match_operand 1 "const_int_operand" "n"))
7541           (const_int 0)))]
7542   "ix86_match_ccmode (insn, CCNOmode)"
7543   "test{b}\t{%1, %h0|%h0, %1}"
7544   [(set_attr "type" "test")
7545    (set_attr "mode" "QI")
7546    (set_attr "length_immediate" "1")
7547    (set_attr "modrm" "1")
7548    (set_attr "pent_pair" "np")])
7549
7550 (define_insn "*testqi_ext_1_rex64"
7551   [(set (reg FLAGS_REG)
7552         (compare
7553           (and:SI
7554             (zero_extract:SI
7555               (match_operand 0 "ext_register_operand" "Q")
7556               (const_int 8)
7557               (const_int 8))
7558             (zero_extend:SI
7559               (match_operand:QI 1 "register_operand" "Q")))
7560           (const_int 0)))]
7561   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7562   "test{b}\t{%1, %h0|%h0, %1}"
7563   [(set_attr "type" "test")
7564    (set_attr "mode" "QI")])
7565
7566 (define_insn "*testqi_ext_1"
7567   [(set (reg FLAGS_REG)
7568         (compare
7569           (and:SI
7570             (zero_extract:SI
7571               (match_operand 0 "ext_register_operand" "Q")
7572               (const_int 8)
7573               (const_int 8))
7574             (zero_extend:SI
7575               (match_operand:QI 1 "general_operand" "Qm")))
7576           (const_int 0)))]
7577   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7578   "test{b}\t{%1, %h0|%h0, %1}"
7579   [(set_attr "type" "test")
7580    (set_attr "mode" "QI")])
7581
7582 (define_insn "*testqi_ext_2"
7583   [(set (reg FLAGS_REG)
7584         (compare
7585           (and:SI
7586             (zero_extract:SI
7587               (match_operand 0 "ext_register_operand" "Q")
7588               (const_int 8)
7589               (const_int 8))
7590             (zero_extract:SI
7591               (match_operand 1 "ext_register_operand" "Q")
7592               (const_int 8)
7593               (const_int 8)))
7594           (const_int 0)))]
7595   "ix86_match_ccmode (insn, CCNOmode)"
7596   "test{b}\t{%h1, %h0|%h0, %h1}"
7597   [(set_attr "type" "test")
7598    (set_attr "mode" "QI")])
7599
7600 (define_insn "*testqi_ext_3_rex64"
7601   [(set (reg FLAGS_REG)
7602         (compare (zero_extract:DI
7603                    (match_operand 0 "nonimmediate_operand" "rm")
7604                    (match_operand:DI 1 "const_int_operand" "")
7605                    (match_operand:DI 2 "const_int_operand" ""))
7606                  (const_int 0)))]
7607   "TARGET_64BIT
7608    && ix86_match_ccmode (insn, CCNOmode)
7609    && INTVAL (operands[1]) > 0
7610    && INTVAL (operands[2]) >= 0
7611    /* Ensure that resulting mask is zero or sign extended operand.  */
7612    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7613        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7614            && INTVAL (operands[1]) > 32))
7615    && (GET_MODE (operands[0]) == SImode
7616        || GET_MODE (operands[0]) == DImode
7617        || GET_MODE (operands[0]) == HImode
7618        || GET_MODE (operands[0]) == QImode)"
7619   "#")
7620
7621 ;; Combine likes to form bit extractions for some tests.  Humor it.
7622 (define_insn "*testqi_ext_3"
7623   [(set (reg FLAGS_REG)
7624         (compare (zero_extract:SI
7625                    (match_operand 0 "nonimmediate_operand" "rm")
7626                    (match_operand:SI 1 "const_int_operand" "")
7627                    (match_operand:SI 2 "const_int_operand" ""))
7628                  (const_int 0)))]
7629   "ix86_match_ccmode (insn, CCNOmode)
7630    && INTVAL (operands[1]) > 0
7631    && INTVAL (operands[2]) >= 0
7632    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7633    && (GET_MODE (operands[0]) == SImode
7634        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7635        || GET_MODE (operands[0]) == HImode
7636        || GET_MODE (operands[0]) == QImode)"
7637   "#")
7638
7639 (define_split
7640   [(set (match_operand 0 "flags_reg_operand" "")
7641         (match_operator 1 "compare_operator"
7642           [(zero_extract
7643              (match_operand 2 "nonimmediate_operand" "")
7644              (match_operand 3 "const_int_operand" "")
7645              (match_operand 4 "const_int_operand" ""))
7646            (const_int 0)]))]
7647   "ix86_match_ccmode (insn, CCNOmode)"
7648   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7649 {
7650   rtx val = operands[2];
7651   HOST_WIDE_INT len = INTVAL (operands[3]);
7652   HOST_WIDE_INT pos = INTVAL (operands[4]);
7653   HOST_WIDE_INT mask;
7654   enum machine_mode mode, submode;
7655
7656   mode = GET_MODE (val);
7657   if (MEM_P (val))
7658     {
7659       /* ??? Combine likes to put non-volatile mem extractions in QImode
7660          no matter the size of the test.  So find a mode that works.  */
7661       if (! MEM_VOLATILE_P (val))
7662         {
7663           mode = smallest_mode_for_size (pos + len, MODE_INT);
7664           val = adjust_address (val, mode, 0);
7665         }
7666     }
7667   else if (GET_CODE (val) == SUBREG
7668            && (submode = GET_MODE (SUBREG_REG (val)),
7669                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7670            && pos + len <= GET_MODE_BITSIZE (submode)
7671            && GET_MODE_CLASS (submode) == MODE_INT)
7672     {
7673       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7674       mode = submode;
7675       val = SUBREG_REG (val);
7676     }
7677   else if (mode == HImode && pos + len <= 8)
7678     {
7679       /* Small HImode tests can be converted to QImode.  */
7680       mode = QImode;
7681       val = gen_lowpart (QImode, val);
7682     }
7683
7684   if (len == HOST_BITS_PER_WIDE_INT)
7685     mask = -1;
7686   else
7687     mask = ((HOST_WIDE_INT)1 << len) - 1;
7688   mask <<= pos;
7689
7690   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7691 })
7692
7693 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7694 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7695 ;; this is relatively important trick.
7696 ;; Do the conversion only post-reload to avoid limiting of the register class
7697 ;; to QI regs.
7698 (define_split
7699   [(set (match_operand 0 "flags_reg_operand" "")
7700         (match_operator 1 "compare_operator"
7701           [(and (match_operand 2 "register_operand" "")
7702                 (match_operand 3 "const_int_operand" ""))
7703            (const_int 0)]))]
7704    "reload_completed
7705     && QI_REG_P (operands[2])
7706     && GET_MODE (operands[2]) != QImode
7707     && ((ix86_match_ccmode (insn, CCZmode)
7708          && !(INTVAL (operands[3]) & ~(255 << 8)))
7709         || (ix86_match_ccmode (insn, CCNOmode)
7710             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7711   [(set (match_dup 0)
7712         (match_op_dup 1
7713           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7714                    (match_dup 3))
7715            (const_int 0)]))]
7716 {
7717   operands[2] = gen_lowpart (SImode, operands[2]);
7718   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7719 })
7720
7721 (define_split
7722   [(set (match_operand 0 "flags_reg_operand" "")
7723         (match_operator 1 "compare_operator"
7724           [(and (match_operand 2 "nonimmediate_operand" "")
7725                 (match_operand 3 "const_int_operand" ""))
7726            (const_int 0)]))]
7727    "reload_completed
7728     && GET_MODE (operands[2]) != QImode
7729     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7730     && ((ix86_match_ccmode (insn, CCZmode)
7731          && !(INTVAL (operands[3]) & ~255))
7732         || (ix86_match_ccmode (insn, CCNOmode)
7733             && !(INTVAL (operands[3]) & ~127)))"
7734   [(set (match_dup 0)
7735         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7736                          (const_int 0)]))]
7737 {
7738   operands[2] = gen_lowpart (QImode, operands[2]);
7739   operands[3] = gen_lowpart (QImode, operands[3]);
7740 })
7741
7742 ;; %%% This used to optimize known byte-wide and operations to memory,
7743 ;; and sometimes to QImode registers.  If this is considered useful,
7744 ;; it should be done with splitters.
7745
7746 (define_expand "and<mode>3"
7747   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7748         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7749                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7750   ""
7751   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7752
7753 (define_insn "*anddi_1"
7754   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7755         (and:DI
7756          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7757          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7758    (clobber (reg:CC FLAGS_REG))]
7759   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7760 {
7761   switch (get_attr_type (insn))
7762     {
7763     case TYPE_IMOVX:
7764       {
7765         enum machine_mode mode;
7766
7767         gcc_assert (CONST_INT_P (operands[2]));
7768         if (INTVAL (operands[2]) == 0xff)
7769           mode = QImode;
7770         else
7771           {
7772             gcc_assert (INTVAL (operands[2]) == 0xffff);
7773             mode = HImode;
7774           }
7775
7776         operands[1] = gen_lowpart (mode, operands[1]);
7777         if (mode == QImode)
7778           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7779         else
7780           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7781       }
7782
7783     default:
7784       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7785       if (get_attr_mode (insn) == MODE_SI)
7786         return "and{l}\t{%k2, %k0|%k0, %k2}";
7787       else
7788         return "and{q}\t{%2, %0|%0, %2}";
7789     }
7790 }
7791   [(set_attr "type" "alu,alu,alu,imovx")
7792    (set_attr "length_immediate" "*,*,*,0")
7793    (set (attr "prefix_rex")
7794      (if_then_else
7795        (and (eq_attr "type" "imovx")
7796             (and (match_test "INTVAL (operands[2]) == 0xff")
7797                  (match_operand 1 "ext_QIreg_operand" "")))
7798        (const_string "1")
7799        (const_string "*")))
7800    (set_attr "mode" "SI,DI,DI,SI")])
7801
7802 (define_insn "*andsi_1"
7803   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7804         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7805                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7806    (clobber (reg:CC FLAGS_REG))]
7807   "ix86_binary_operator_ok (AND, SImode, operands)"
7808 {
7809   switch (get_attr_type (insn))
7810     {
7811     case TYPE_IMOVX:
7812       {
7813         enum machine_mode mode;
7814
7815         gcc_assert (CONST_INT_P (operands[2]));
7816         if (INTVAL (operands[2]) == 0xff)
7817           mode = QImode;
7818         else
7819           {
7820             gcc_assert (INTVAL (operands[2]) == 0xffff);
7821             mode = HImode;
7822           }
7823
7824         operands[1] = gen_lowpart (mode, operands[1]);
7825         if (mode == QImode)
7826           return "movz{bl|x}\t{%1, %0|%0, %1}";
7827         else
7828           return "movz{wl|x}\t{%1, %0|%0, %1}";
7829       }
7830
7831     default:
7832       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7833       return "and{l}\t{%2, %0|%0, %2}";
7834     }
7835 }
7836   [(set_attr "type" "alu,alu,imovx")
7837    (set (attr "prefix_rex")
7838      (if_then_else
7839        (and (eq_attr "type" "imovx")
7840             (and (match_test "INTVAL (operands[2]) == 0xff")
7841                  (match_operand 1 "ext_QIreg_operand" "")))
7842        (const_string "1")
7843        (const_string "*")))
7844    (set_attr "length_immediate" "*,*,0")
7845    (set_attr "mode" "SI")])
7846
7847 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7848 (define_insn "*andsi_1_zext"
7849   [(set (match_operand:DI 0 "register_operand" "=r")
7850         (zero_extend:DI
7851           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7852                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7853    (clobber (reg:CC FLAGS_REG))]
7854   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7855   "and{l}\t{%2, %k0|%k0, %2}"
7856   [(set_attr "type" "alu")
7857    (set_attr "mode" "SI")])
7858
7859 (define_insn "*andhi_1"
7860   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7861         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7862                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7863    (clobber (reg:CC FLAGS_REG))]
7864   "ix86_binary_operator_ok (AND, HImode, operands)"
7865 {
7866   switch (get_attr_type (insn))
7867     {
7868     case TYPE_IMOVX:
7869       gcc_assert (CONST_INT_P (operands[2]));
7870       gcc_assert (INTVAL (operands[2]) == 0xff);
7871       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7872
7873     default:
7874       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7875
7876       return "and{w}\t{%2, %0|%0, %2}";
7877     }
7878 }
7879   [(set_attr "type" "alu,alu,imovx")
7880    (set_attr "length_immediate" "*,*,0")
7881    (set (attr "prefix_rex")
7882      (if_then_else
7883        (and (eq_attr "type" "imovx")
7884             (match_operand 1 "ext_QIreg_operand" ""))
7885        (const_string "1")
7886        (const_string "*")))
7887    (set_attr "mode" "HI,HI,SI")])
7888
7889 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7890 (define_insn "*andqi_1"
7891   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7892         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7893                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7894    (clobber (reg:CC FLAGS_REG))]
7895   "ix86_binary_operator_ok (AND, QImode, operands)"
7896   "@
7897    and{b}\t{%2, %0|%0, %2}
7898    and{b}\t{%2, %0|%0, %2}
7899    and{l}\t{%k2, %k0|%k0, %k2}"
7900   [(set_attr "type" "alu")
7901    (set_attr "mode" "QI,QI,SI")])
7902
7903 (define_insn "*andqi_1_slp"
7904   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7905         (and:QI (match_dup 0)
7906                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7907    (clobber (reg:CC FLAGS_REG))]
7908   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7909    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7910   "and{b}\t{%1, %0|%0, %1}"
7911   [(set_attr "type" "alu1")
7912    (set_attr "mode" "QI")])
7913
7914 (define_split
7915   [(set (match_operand 0 "register_operand" "")
7916         (and (match_dup 0)
7917              (const_int -65536)))
7918    (clobber (reg:CC FLAGS_REG))]
7919   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7920     || optimize_function_for_size_p (cfun)"
7921   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7922   "operands[1] = gen_lowpart (HImode, operands[0]);")
7923
7924 (define_split
7925   [(set (match_operand 0 "ext_register_operand" "")
7926         (and (match_dup 0)
7927              (const_int -256)))
7928    (clobber (reg:CC FLAGS_REG))]
7929   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7930    && reload_completed"
7931   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7932   "operands[1] = gen_lowpart (QImode, operands[0]);")
7933
7934 (define_split
7935   [(set (match_operand 0 "ext_register_operand" "")
7936         (and (match_dup 0)
7937              (const_int -65281)))
7938    (clobber (reg:CC FLAGS_REG))]
7939   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7940    && reload_completed"
7941   [(parallel [(set (zero_extract:SI (match_dup 0)
7942                                     (const_int 8)
7943                                     (const_int 8))
7944                    (xor:SI
7945                      (zero_extract:SI (match_dup 0)
7946                                       (const_int 8)
7947                                       (const_int 8))
7948                      (zero_extract:SI (match_dup 0)
7949                                       (const_int 8)
7950                                       (const_int 8))))
7951               (clobber (reg:CC FLAGS_REG))])]
7952   "operands[0] = gen_lowpart (SImode, operands[0]);")
7953
7954 (define_insn "*anddi_2"
7955   [(set (reg FLAGS_REG)
7956         (compare
7957          (and:DI
7958           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7959           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7960          (const_int 0)))
7961    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7962         (and:DI (match_dup 1) (match_dup 2)))]
7963   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7964    && ix86_binary_operator_ok (AND, DImode, operands)"
7965   "@
7966    and{l}\t{%k2, %k0|%k0, %k2}
7967    and{q}\t{%2, %0|%0, %2}
7968    and{q}\t{%2, %0|%0, %2}"
7969   [(set_attr "type" "alu")
7970    (set_attr "mode" "SI,DI,DI")])
7971
7972 (define_insn "*andqi_2_maybe_si"
7973   [(set (reg FLAGS_REG)
7974         (compare (and:QI
7975                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7976                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7977                  (const_int 0)))
7978    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7979         (and:QI (match_dup 1) (match_dup 2)))]
7980   "ix86_binary_operator_ok (AND, QImode, operands)
7981    && ix86_match_ccmode (insn,
7982                          CONST_INT_P (operands[2])
7983                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7984 {
7985   if (which_alternative == 2)
7986     {
7987       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7988         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7989       return "and{l}\t{%2, %k0|%k0, %2}";
7990     }
7991   return "and{b}\t{%2, %0|%0, %2}";
7992 }
7993   [(set_attr "type" "alu")
7994    (set_attr "mode" "QI,QI,SI")])
7995
7996 (define_insn "*and<mode>_2"
7997   [(set (reg FLAGS_REG)
7998         (compare (and:SWI124
7999                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8000                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8001                  (const_int 0)))
8002    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8003         (and:SWI124 (match_dup 1) (match_dup 2)))]
8004   "ix86_match_ccmode (insn, CCNOmode)
8005    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8006   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8007   [(set_attr "type" "alu")
8008    (set_attr "mode" "<MODE>")])
8009
8010 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8011 (define_insn "*andsi_2_zext"
8012   [(set (reg FLAGS_REG)
8013         (compare (and:SI
8014                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8015                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8016                  (const_int 0)))
8017    (set (match_operand:DI 0 "register_operand" "=r")
8018         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8019   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8020    && ix86_binary_operator_ok (AND, SImode, operands)"
8021   "and{l}\t{%2, %k0|%k0, %2}"
8022   [(set_attr "type" "alu")
8023    (set_attr "mode" "SI")])
8024
8025 (define_insn "*andqi_2_slp"
8026   [(set (reg FLAGS_REG)
8027         (compare (and:QI
8028                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8029                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8030                  (const_int 0)))
8031    (set (strict_low_part (match_dup 0))
8032         (and:QI (match_dup 0) (match_dup 1)))]
8033   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8034    && ix86_match_ccmode (insn, CCNOmode)
8035    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8036   "and{b}\t{%1, %0|%0, %1}"
8037   [(set_attr "type" "alu1")
8038    (set_attr "mode" "QI")])
8039
8040 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8041 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8042 ;; for a QImode operand, which of course failed.
8043 (define_insn "andqi_ext_0"
8044   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8045                          (const_int 8)
8046                          (const_int 8))
8047         (and:SI
8048           (zero_extract:SI
8049             (match_operand 1 "ext_register_operand" "0")
8050             (const_int 8)
8051             (const_int 8))
8052           (match_operand 2 "const_int_operand" "n")))
8053    (clobber (reg:CC FLAGS_REG))]
8054   ""
8055   "and{b}\t{%2, %h0|%h0, %2}"
8056   [(set_attr "type" "alu")
8057    (set_attr "length_immediate" "1")
8058    (set_attr "modrm" "1")
8059    (set_attr "mode" "QI")])
8060
8061 ;; Generated by peephole translating test to and.  This shows up
8062 ;; often in fp comparisons.
8063 (define_insn "*andqi_ext_0_cc"
8064   [(set (reg FLAGS_REG)
8065         (compare
8066           (and:SI
8067             (zero_extract:SI
8068               (match_operand 1 "ext_register_operand" "0")
8069               (const_int 8)
8070               (const_int 8))
8071             (match_operand 2 "const_int_operand" "n"))
8072           (const_int 0)))
8073    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8074                          (const_int 8)
8075                          (const_int 8))
8076         (and:SI
8077           (zero_extract:SI
8078             (match_dup 1)
8079             (const_int 8)
8080             (const_int 8))
8081           (match_dup 2)))]
8082   "ix86_match_ccmode (insn, CCNOmode)"
8083   "and{b}\t{%2, %h0|%h0, %2}"
8084   [(set_attr "type" "alu")
8085    (set_attr "length_immediate" "1")
8086    (set_attr "modrm" "1")
8087    (set_attr "mode" "QI")])
8088
8089 (define_insn "*andqi_ext_1_rex64"
8090   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8091                          (const_int 8)
8092                          (const_int 8))
8093         (and:SI
8094           (zero_extract:SI
8095             (match_operand 1 "ext_register_operand" "0")
8096             (const_int 8)
8097             (const_int 8))
8098           (zero_extend:SI
8099             (match_operand 2 "ext_register_operand" "Q"))))
8100    (clobber (reg:CC FLAGS_REG))]
8101   "TARGET_64BIT"
8102   "and{b}\t{%2, %h0|%h0, %2}"
8103   [(set_attr "type" "alu")
8104    (set_attr "length_immediate" "0")
8105    (set_attr "mode" "QI")])
8106
8107 (define_insn "*andqi_ext_1"
8108   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8109                          (const_int 8)
8110                          (const_int 8))
8111         (and:SI
8112           (zero_extract:SI
8113             (match_operand 1 "ext_register_operand" "0")
8114             (const_int 8)
8115             (const_int 8))
8116           (zero_extend:SI
8117             (match_operand:QI 2 "general_operand" "Qm"))))
8118    (clobber (reg:CC FLAGS_REG))]
8119   "!TARGET_64BIT"
8120   "and{b}\t{%2, %h0|%h0, %2}"
8121   [(set_attr "type" "alu")
8122    (set_attr "length_immediate" "0")
8123    (set_attr "mode" "QI")])
8124
8125 (define_insn "*andqi_ext_2"
8126   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8127                          (const_int 8)
8128                          (const_int 8))
8129         (and:SI
8130           (zero_extract:SI
8131             (match_operand 1 "ext_register_operand" "%0")
8132             (const_int 8)
8133             (const_int 8))
8134           (zero_extract:SI
8135             (match_operand 2 "ext_register_operand" "Q")
8136             (const_int 8)
8137             (const_int 8))))
8138    (clobber (reg:CC FLAGS_REG))]
8139   ""
8140   "and{b}\t{%h2, %h0|%h0, %h2}"
8141   [(set_attr "type" "alu")
8142    (set_attr "length_immediate" "0")
8143    (set_attr "mode" "QI")])
8144
8145 ;; Convert wide AND instructions with immediate operand to shorter QImode
8146 ;; equivalents when possible.
8147 ;; Don't do the splitting with memory operands, since it introduces risk
8148 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8149 ;; for size, but that can (should?) be handled by generic code instead.
8150 (define_split
8151   [(set (match_operand 0 "register_operand" "")
8152         (and (match_operand 1 "register_operand" "")
8153              (match_operand 2 "const_int_operand" "")))
8154    (clobber (reg:CC FLAGS_REG))]
8155    "reload_completed
8156     && QI_REG_P (operands[0])
8157     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8158     && !(~INTVAL (operands[2]) & ~(255 << 8))
8159     && GET_MODE (operands[0]) != QImode"
8160   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8161                    (and:SI (zero_extract:SI (match_dup 1)
8162                                             (const_int 8) (const_int 8))
8163                            (match_dup 2)))
8164               (clobber (reg:CC FLAGS_REG))])]
8165 {
8166   operands[0] = gen_lowpart (SImode, operands[0]);
8167   operands[1] = gen_lowpart (SImode, operands[1]);
8168   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8169 })
8170
8171 ;; Since AND can be encoded with sign extended immediate, this is only
8172 ;; profitable when 7th bit is not set.
8173 (define_split
8174   [(set (match_operand 0 "register_operand" "")
8175         (and (match_operand 1 "general_operand" "")
8176              (match_operand 2 "const_int_operand" "")))
8177    (clobber (reg:CC FLAGS_REG))]
8178    "reload_completed
8179     && ANY_QI_REG_P (operands[0])
8180     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8181     && !(~INTVAL (operands[2]) & ~255)
8182     && !(INTVAL (operands[2]) & 128)
8183     && GET_MODE (operands[0]) != QImode"
8184   [(parallel [(set (strict_low_part (match_dup 0))
8185                    (and:QI (match_dup 1)
8186                            (match_dup 2)))
8187               (clobber (reg:CC FLAGS_REG))])]
8188 {
8189   operands[0] = gen_lowpart (QImode, operands[0]);
8190   operands[1] = gen_lowpart (QImode, operands[1]);
8191   operands[2] = gen_lowpart (QImode, operands[2]);
8192 })
8193 \f
8194 ;; Logical inclusive and exclusive OR instructions
8195
8196 ;; %%% This used to optimize known byte-wide and operations to memory.
8197 ;; If this is considered useful, it should be done with splitters.
8198
8199 (define_expand "<code><mode>3"
8200   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8201         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8202                      (match_operand:SWIM 2 "<general_operand>" "")))]
8203   ""
8204   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8205
8206 (define_insn "*<code><mode>_1"
8207   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8208         (any_or:SWI248
8209          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8210          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8211    (clobber (reg:CC FLAGS_REG))]
8212   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8213   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8214   [(set_attr "type" "alu")
8215    (set_attr "mode" "<MODE>")])
8216
8217 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8218 (define_insn "*<code>qi_1"
8219   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8220         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8221                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8222    (clobber (reg:CC FLAGS_REG))]
8223   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8224   "@
8225    <logic>{b}\t{%2, %0|%0, %2}
8226    <logic>{b}\t{%2, %0|%0, %2}
8227    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8228   [(set_attr "type" "alu")
8229    (set_attr "mode" "QI,QI,SI")])
8230
8231 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8232 (define_insn "*<code>si_1_zext"
8233   [(set (match_operand:DI 0 "register_operand" "=r")
8234         (zero_extend:DI
8235          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8236                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8237    (clobber (reg:CC FLAGS_REG))]
8238   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8239   "<logic>{l}\t{%2, %k0|%k0, %2}"
8240   [(set_attr "type" "alu")
8241    (set_attr "mode" "SI")])
8242
8243 (define_insn "*<code>si_1_zext_imm"
8244   [(set (match_operand:DI 0 "register_operand" "=r")
8245         (any_or:DI
8246          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8247          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8248    (clobber (reg:CC FLAGS_REG))]
8249   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8250   "<logic>{l}\t{%2, %k0|%k0, %2}"
8251   [(set_attr "type" "alu")
8252    (set_attr "mode" "SI")])
8253
8254 (define_insn "*<code>qi_1_slp"
8255   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8256         (any_or:QI (match_dup 0)
8257                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8258    (clobber (reg:CC FLAGS_REG))]
8259   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8260    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8261   "<logic>{b}\t{%1, %0|%0, %1}"
8262   [(set_attr "type" "alu1")
8263    (set_attr "mode" "QI")])
8264
8265 (define_insn "*<code><mode>_2"
8266   [(set (reg FLAGS_REG)
8267         (compare (any_or:SWI
8268                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8269                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8270                  (const_int 0)))
8271    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8272         (any_or:SWI (match_dup 1) (match_dup 2)))]
8273   "ix86_match_ccmode (insn, CCNOmode)
8274    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8275   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8276   [(set_attr "type" "alu")
8277    (set_attr "mode" "<MODE>")])
8278
8279 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8280 ;; ??? Special case for immediate operand is missing - it is tricky.
8281 (define_insn "*<code>si_2_zext"
8282   [(set (reg FLAGS_REG)
8283         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8284                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8285                  (const_int 0)))
8286    (set (match_operand:DI 0 "register_operand" "=r")
8287         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8288   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8289    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8290   "<logic>{l}\t{%2, %k0|%k0, %2}"
8291   [(set_attr "type" "alu")
8292    (set_attr "mode" "SI")])
8293
8294 (define_insn "*<code>si_2_zext_imm"
8295   [(set (reg FLAGS_REG)
8296         (compare (any_or:SI
8297                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8298                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8299                  (const_int 0)))
8300    (set (match_operand:DI 0 "register_operand" "=r")
8301         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8302   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8303    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8304   "<logic>{l}\t{%2, %k0|%k0, %2}"
8305   [(set_attr "type" "alu")
8306    (set_attr "mode" "SI")])
8307
8308 (define_insn "*<code>qi_2_slp"
8309   [(set (reg FLAGS_REG)
8310         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8311                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8312                  (const_int 0)))
8313    (set (strict_low_part (match_dup 0))
8314         (any_or:QI (match_dup 0) (match_dup 1)))]
8315   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8316    && ix86_match_ccmode (insn, CCNOmode)
8317    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8318   "<logic>{b}\t{%1, %0|%0, %1}"
8319   [(set_attr "type" "alu1")
8320    (set_attr "mode" "QI")])
8321
8322 (define_insn "*<code><mode>_3"
8323   [(set (reg FLAGS_REG)
8324         (compare (any_or:SWI
8325                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8326                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8327                  (const_int 0)))
8328    (clobber (match_scratch:SWI 0 "=<r>"))]
8329   "ix86_match_ccmode (insn, CCNOmode)
8330    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8331   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8332   [(set_attr "type" "alu")
8333    (set_attr "mode" "<MODE>")])
8334
8335 (define_insn "*<code>qi_ext_0"
8336   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8337                          (const_int 8)
8338                          (const_int 8))
8339         (any_or:SI
8340           (zero_extract:SI
8341             (match_operand 1 "ext_register_operand" "0")
8342             (const_int 8)
8343             (const_int 8))
8344           (match_operand 2 "const_int_operand" "n")))
8345    (clobber (reg:CC FLAGS_REG))]
8346   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8347   "<logic>{b}\t{%2, %h0|%h0, %2}"
8348   [(set_attr "type" "alu")
8349    (set_attr "length_immediate" "1")
8350    (set_attr "modrm" "1")
8351    (set_attr "mode" "QI")])
8352
8353 (define_insn "*<code>qi_ext_1_rex64"
8354   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8355                          (const_int 8)
8356                          (const_int 8))
8357         (any_or:SI
8358           (zero_extract:SI
8359             (match_operand 1 "ext_register_operand" "0")
8360             (const_int 8)
8361             (const_int 8))
8362           (zero_extend:SI
8363             (match_operand 2 "ext_register_operand" "Q"))))
8364    (clobber (reg:CC FLAGS_REG))]
8365   "TARGET_64BIT
8366    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8367   "<logic>{b}\t{%2, %h0|%h0, %2}"
8368   [(set_attr "type" "alu")
8369    (set_attr "length_immediate" "0")
8370    (set_attr "mode" "QI")])
8371
8372 (define_insn "*<code>qi_ext_1"
8373   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8374                          (const_int 8)
8375                          (const_int 8))
8376         (any_or:SI
8377           (zero_extract:SI
8378             (match_operand 1 "ext_register_operand" "0")
8379             (const_int 8)
8380             (const_int 8))
8381           (zero_extend:SI
8382             (match_operand:QI 2 "general_operand" "Qm"))))
8383    (clobber (reg:CC FLAGS_REG))]
8384   "!TARGET_64BIT
8385    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8386   "<logic>{b}\t{%2, %h0|%h0, %2}"
8387   [(set_attr "type" "alu")
8388    (set_attr "length_immediate" "0")
8389    (set_attr "mode" "QI")])
8390
8391 (define_insn "*<code>qi_ext_2"
8392   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8393                          (const_int 8)
8394                          (const_int 8))
8395         (any_or:SI
8396           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8397                            (const_int 8)
8398                            (const_int 8))
8399           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8400                            (const_int 8)
8401                            (const_int 8))))
8402    (clobber (reg:CC FLAGS_REG))]
8403   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8404   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8405   [(set_attr "type" "alu")
8406    (set_attr "length_immediate" "0")
8407    (set_attr "mode" "QI")])
8408
8409 (define_split
8410   [(set (match_operand 0 "register_operand" "")
8411         (any_or (match_operand 1 "register_operand" "")
8412                 (match_operand 2 "const_int_operand" "")))
8413    (clobber (reg:CC FLAGS_REG))]
8414    "reload_completed
8415     && QI_REG_P (operands[0])
8416     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8417     && !(INTVAL (operands[2]) & ~(255 << 8))
8418     && GET_MODE (operands[0]) != QImode"
8419   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8420                    (any_or:SI (zero_extract:SI (match_dup 1)
8421                                                (const_int 8) (const_int 8))
8422                               (match_dup 2)))
8423               (clobber (reg:CC FLAGS_REG))])]
8424 {
8425   operands[0] = gen_lowpart (SImode, operands[0]);
8426   operands[1] = gen_lowpart (SImode, operands[1]);
8427   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8428 })
8429
8430 ;; Since OR can be encoded with sign extended immediate, this is only
8431 ;; profitable when 7th bit is set.
8432 (define_split
8433   [(set (match_operand 0 "register_operand" "")
8434         (any_or (match_operand 1 "general_operand" "")
8435                 (match_operand 2 "const_int_operand" "")))
8436    (clobber (reg:CC FLAGS_REG))]
8437    "reload_completed
8438     && ANY_QI_REG_P (operands[0])
8439     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8440     && !(INTVAL (operands[2]) & ~255)
8441     && (INTVAL (operands[2]) & 128)
8442     && GET_MODE (operands[0]) != QImode"
8443   [(parallel [(set (strict_low_part (match_dup 0))
8444                    (any_or:QI (match_dup 1)
8445                               (match_dup 2)))
8446               (clobber (reg:CC FLAGS_REG))])]
8447 {
8448   operands[0] = gen_lowpart (QImode, operands[0]);
8449   operands[1] = gen_lowpart (QImode, operands[1]);
8450   operands[2] = gen_lowpart (QImode, operands[2]);
8451 })
8452
8453 (define_expand "xorqi_cc_ext_1"
8454   [(parallel [
8455      (set (reg:CCNO FLAGS_REG)
8456           (compare:CCNO
8457             (xor:SI
8458               (zero_extract:SI
8459                 (match_operand 1 "ext_register_operand" "")
8460                 (const_int 8)
8461                 (const_int 8))
8462               (match_operand:QI 2 "general_operand" ""))
8463             (const_int 0)))
8464      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8465                            (const_int 8)
8466                            (const_int 8))
8467           (xor:SI
8468             (zero_extract:SI
8469              (match_dup 1)
8470              (const_int 8)
8471              (const_int 8))
8472             (match_dup 2)))])])
8473
8474 (define_insn "*xorqi_cc_ext_1_rex64"
8475   [(set (reg FLAGS_REG)
8476         (compare
8477           (xor:SI
8478             (zero_extract:SI
8479               (match_operand 1 "ext_register_operand" "0")
8480               (const_int 8)
8481               (const_int 8))
8482             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8483           (const_int 0)))
8484    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8485                          (const_int 8)
8486                          (const_int 8))
8487         (xor:SI
8488           (zero_extract:SI
8489            (match_dup 1)
8490            (const_int 8)
8491            (const_int 8))
8492           (match_dup 2)))]
8493   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8494   "xor{b}\t{%2, %h0|%h0, %2}"
8495   [(set_attr "type" "alu")
8496    (set_attr "modrm" "1")
8497    (set_attr "mode" "QI")])
8498
8499 (define_insn "*xorqi_cc_ext_1"
8500   [(set (reg FLAGS_REG)
8501         (compare
8502           (xor:SI
8503             (zero_extract:SI
8504               (match_operand 1 "ext_register_operand" "0")
8505               (const_int 8)
8506               (const_int 8))
8507             (match_operand:QI 2 "general_operand" "qmn"))
8508           (const_int 0)))
8509    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8510                          (const_int 8)
8511                          (const_int 8))
8512         (xor:SI
8513           (zero_extract:SI
8514            (match_dup 1)
8515            (const_int 8)
8516            (const_int 8))
8517           (match_dup 2)))]
8518   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8519   "xor{b}\t{%2, %h0|%h0, %2}"
8520   [(set_attr "type" "alu")
8521    (set_attr "modrm" "1")
8522    (set_attr "mode" "QI")])
8523 \f
8524 ;; Negation instructions
8525
8526 (define_expand "neg<mode>2"
8527   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8528         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8529   ""
8530   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8531
8532 (define_insn_and_split "*neg<dwi>2_doubleword"
8533   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8534         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8535    (clobber (reg:CC FLAGS_REG))]
8536   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8537   "#"
8538   "reload_completed"
8539   [(parallel
8540     [(set (reg:CCZ FLAGS_REG)
8541           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8542      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8543    (parallel
8544     [(set (match_dup 2)
8545           (plus:DWIH (match_dup 3)
8546                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8547                                 (const_int 0))))
8548      (clobber (reg:CC FLAGS_REG))])
8549    (parallel
8550     [(set (match_dup 2)
8551           (neg:DWIH (match_dup 2)))
8552      (clobber (reg:CC FLAGS_REG))])]
8553   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8554
8555 (define_insn "*neg<mode>2_1"
8556   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8557         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8558    (clobber (reg:CC FLAGS_REG))]
8559   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8560   "neg{<imodesuffix>}\t%0"
8561   [(set_attr "type" "negnot")
8562    (set_attr "mode" "<MODE>")])
8563
8564 ;; Combine is quite creative about this pattern.
8565 (define_insn "*negsi2_1_zext"
8566   [(set (match_operand:DI 0 "register_operand" "=r")
8567         (lshiftrt:DI
8568           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8569                              (const_int 32)))
8570         (const_int 32)))
8571    (clobber (reg:CC FLAGS_REG))]
8572   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8573   "neg{l}\t%k0"
8574   [(set_attr "type" "negnot")
8575    (set_attr "mode" "SI")])
8576
8577 ;; The problem with neg is that it does not perform (compare x 0),
8578 ;; it really performs (compare 0 x), which leaves us with the zero
8579 ;; flag being the only useful item.
8580
8581 (define_insn "*neg<mode>2_cmpz"
8582   [(set (reg:CCZ FLAGS_REG)
8583         (compare:CCZ
8584           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8585                    (const_int 0)))
8586    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8587         (neg:SWI (match_dup 1)))]
8588   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8589   "neg{<imodesuffix>}\t%0"
8590   [(set_attr "type" "negnot")
8591    (set_attr "mode" "<MODE>")])
8592
8593 (define_insn "*negsi2_cmpz_zext"
8594   [(set (reg:CCZ FLAGS_REG)
8595         (compare:CCZ
8596           (lshiftrt:DI
8597             (neg:DI (ashift:DI
8598                       (match_operand:DI 1 "register_operand" "0")
8599                       (const_int 32)))
8600             (const_int 32))
8601           (const_int 0)))
8602    (set (match_operand:DI 0 "register_operand" "=r")
8603         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8604                                         (const_int 32)))
8605                      (const_int 32)))]
8606   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8607   "neg{l}\t%k0"
8608   [(set_attr "type" "negnot")
8609    (set_attr "mode" "SI")])
8610
8611 ;; Changing of sign for FP values is doable using integer unit too.
8612
8613 (define_expand "<code><mode>2"
8614   [(set (match_operand:X87MODEF 0 "register_operand" "")
8615         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8616   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8617   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8618
8619 (define_insn "*absneg<mode>2_mixed"
8620   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8621         (match_operator:MODEF 3 "absneg_operator"
8622           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8623    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8624    (clobber (reg:CC FLAGS_REG))]
8625   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8626   "#")
8627
8628 (define_insn "*absneg<mode>2_sse"
8629   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8630         (match_operator:MODEF 3 "absneg_operator"
8631           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8632    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8633    (clobber (reg:CC FLAGS_REG))]
8634   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8635   "#")
8636
8637 (define_insn "*absneg<mode>2_i387"
8638   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8639         (match_operator:X87MODEF 3 "absneg_operator"
8640           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8641    (use (match_operand 2 "" ""))
8642    (clobber (reg:CC FLAGS_REG))]
8643   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8644   "#")
8645
8646 (define_expand "<code>tf2"
8647   [(set (match_operand:TF 0 "register_operand" "")
8648         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8649   "TARGET_SSE2"
8650   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8651
8652 (define_insn "*absnegtf2_sse"
8653   [(set (match_operand:TF 0 "register_operand" "=x,x")
8654         (match_operator:TF 3 "absneg_operator"
8655           [(match_operand:TF 1 "register_operand" "0,x")]))
8656    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8657    (clobber (reg:CC FLAGS_REG))]
8658   "TARGET_SSE2"
8659   "#")
8660
8661 ;; Splitters for fp abs and neg.
8662
8663 (define_split
8664   [(set (match_operand 0 "fp_register_operand" "")
8665         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8666    (use (match_operand 2 "" ""))
8667    (clobber (reg:CC FLAGS_REG))]
8668   "reload_completed"
8669   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8670
8671 (define_split
8672   [(set (match_operand 0 "register_operand" "")
8673         (match_operator 3 "absneg_operator"
8674           [(match_operand 1 "register_operand" "")]))
8675    (use (match_operand 2 "nonimmediate_operand" ""))
8676    (clobber (reg:CC FLAGS_REG))]
8677   "reload_completed && SSE_REG_P (operands[0])"
8678   [(set (match_dup 0) (match_dup 3))]
8679 {
8680   enum machine_mode mode = GET_MODE (operands[0]);
8681   enum machine_mode vmode = GET_MODE (operands[2]);
8682   rtx tmp;
8683
8684   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8685   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8686   if (operands_match_p (operands[0], operands[2]))
8687     {
8688       tmp = operands[1];
8689       operands[1] = operands[2];
8690       operands[2] = tmp;
8691     }
8692   if (GET_CODE (operands[3]) == ABS)
8693     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8694   else
8695     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8696   operands[3] = tmp;
8697 })
8698
8699 (define_split
8700   [(set (match_operand:SF 0 "register_operand" "")
8701         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8702    (use (match_operand:V4SF 2 "" ""))
8703    (clobber (reg:CC FLAGS_REG))]
8704   "reload_completed"
8705   [(parallel [(set (match_dup 0) (match_dup 1))
8706               (clobber (reg:CC FLAGS_REG))])]
8707 {
8708   rtx tmp;
8709   operands[0] = gen_lowpart (SImode, operands[0]);
8710   if (GET_CODE (operands[1]) == ABS)
8711     {
8712       tmp = gen_int_mode (0x7fffffff, SImode);
8713       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8714     }
8715   else
8716     {
8717       tmp = gen_int_mode (0x80000000, SImode);
8718       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8719     }
8720   operands[1] = tmp;
8721 })
8722
8723 (define_split
8724   [(set (match_operand:DF 0 "register_operand" "")
8725         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8726    (use (match_operand 2 "" ""))
8727    (clobber (reg:CC FLAGS_REG))]
8728   "reload_completed"
8729   [(parallel [(set (match_dup 0) (match_dup 1))
8730               (clobber (reg:CC FLAGS_REG))])]
8731 {
8732   rtx tmp;
8733   if (TARGET_64BIT)
8734     {
8735       tmp = gen_lowpart (DImode, operands[0]);
8736       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8737       operands[0] = tmp;
8738
8739       if (GET_CODE (operands[1]) == ABS)
8740         tmp = const0_rtx;
8741       else
8742         tmp = gen_rtx_NOT (DImode, tmp);
8743     }
8744   else
8745     {
8746       operands[0] = gen_highpart (SImode, operands[0]);
8747       if (GET_CODE (operands[1]) == ABS)
8748         {
8749           tmp = gen_int_mode (0x7fffffff, SImode);
8750           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8751         }
8752       else
8753         {
8754           tmp = gen_int_mode (0x80000000, SImode);
8755           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8756         }
8757     }
8758   operands[1] = tmp;
8759 })
8760
8761 (define_split
8762   [(set (match_operand:XF 0 "register_operand" "")
8763         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8764    (use (match_operand 2 "" ""))
8765    (clobber (reg:CC FLAGS_REG))]
8766   "reload_completed"
8767   [(parallel [(set (match_dup 0) (match_dup 1))
8768               (clobber (reg:CC FLAGS_REG))])]
8769 {
8770   rtx tmp;
8771   operands[0] = gen_rtx_REG (SImode,
8772                              true_regnum (operands[0])
8773                              + (TARGET_64BIT ? 1 : 2));
8774   if (GET_CODE (operands[1]) == ABS)
8775     {
8776       tmp = GEN_INT (0x7fff);
8777       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8778     }
8779   else
8780     {
8781       tmp = GEN_INT (0x8000);
8782       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8783     }
8784   operands[1] = tmp;
8785 })
8786
8787 ;; Conditionalize these after reload. If they match before reload, we
8788 ;; lose the clobber and ability to use integer instructions.
8789
8790 (define_insn "*<code><mode>2_1"
8791   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8792         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8793   "TARGET_80387
8794    && (reload_completed
8795        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8796   "f<absneg_mnemonic>"
8797   [(set_attr "type" "fsgn")
8798    (set_attr "mode" "<MODE>")])
8799
8800 (define_insn "*<code>extendsfdf2"
8801   [(set (match_operand:DF 0 "register_operand" "=f")
8802         (absneg:DF (float_extend:DF
8803                      (match_operand:SF 1 "register_operand" "0"))))]
8804   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8805   "f<absneg_mnemonic>"
8806   [(set_attr "type" "fsgn")
8807    (set_attr "mode" "DF")])
8808
8809 (define_insn "*<code>extendsfxf2"
8810   [(set (match_operand:XF 0 "register_operand" "=f")
8811         (absneg:XF (float_extend:XF
8812                      (match_operand:SF 1 "register_operand" "0"))))]
8813   "TARGET_80387"
8814   "f<absneg_mnemonic>"
8815   [(set_attr "type" "fsgn")
8816    (set_attr "mode" "XF")])
8817
8818 (define_insn "*<code>extenddfxf2"
8819   [(set (match_operand:XF 0 "register_operand" "=f")
8820         (absneg:XF (float_extend:XF
8821                      (match_operand:DF 1 "register_operand" "0"))))]
8822   "TARGET_80387"
8823   "f<absneg_mnemonic>"
8824   [(set_attr "type" "fsgn")
8825    (set_attr "mode" "XF")])
8826
8827 ;; Copysign instructions
8828
8829 (define_mode_iterator CSGNMODE [SF DF TF])
8830 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8831
8832 (define_expand "copysign<mode>3"
8833   [(match_operand:CSGNMODE 0 "register_operand" "")
8834    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8835    (match_operand:CSGNMODE 2 "register_operand" "")]
8836   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8837    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8838   "ix86_expand_copysign (operands); DONE;")
8839
8840 (define_insn_and_split "copysign<mode>3_const"
8841   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8842         (unspec:CSGNMODE
8843           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8844            (match_operand:CSGNMODE 2 "register_operand" "0")
8845            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8846           UNSPEC_COPYSIGN))]
8847   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8848    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8849   "#"
8850   "&& reload_completed"
8851   [(const_int 0)]
8852   "ix86_split_copysign_const (operands); DONE;")
8853
8854 (define_insn "copysign<mode>3_var"
8855   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8856         (unspec:CSGNMODE
8857           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8858            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8859            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8860            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8861           UNSPEC_COPYSIGN))
8862    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8863   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8864    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8865   "#")
8866
8867 (define_split
8868   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8869         (unspec:CSGNMODE
8870           [(match_operand:CSGNMODE 2 "register_operand" "")
8871            (match_operand:CSGNMODE 3 "register_operand" "")
8872            (match_operand:<CSGNVMODE> 4 "" "")
8873            (match_operand:<CSGNVMODE> 5 "" "")]
8874           UNSPEC_COPYSIGN))
8875    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8876   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8877     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8878    && reload_completed"
8879   [(const_int 0)]
8880   "ix86_split_copysign_var (operands); DONE;")
8881 \f
8882 ;; One complement instructions
8883
8884 (define_expand "one_cmpl<mode>2"
8885   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8886         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8887   ""
8888   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8889
8890 (define_insn "*one_cmpl<mode>2_1"
8891   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8892         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8893   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8894   "not{<imodesuffix>}\t%0"
8895   [(set_attr "type" "negnot")
8896    (set_attr "mode" "<MODE>")])
8897
8898 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8899 (define_insn "*one_cmplqi2_1"
8900   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8901         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8902   "ix86_unary_operator_ok (NOT, QImode, operands)"
8903   "@
8904    not{b}\t%0
8905    not{l}\t%k0"
8906   [(set_attr "type" "negnot")
8907    (set_attr "mode" "QI,SI")])
8908
8909 ;; ??? Currently never generated - xor is used instead.
8910 (define_insn "*one_cmplsi2_1_zext"
8911   [(set (match_operand:DI 0 "register_operand" "=r")
8912         (zero_extend:DI
8913           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8914   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8915   "not{l}\t%k0"
8916   [(set_attr "type" "negnot")
8917    (set_attr "mode" "SI")])
8918
8919 (define_insn "*one_cmpl<mode>2_2"
8920   [(set (reg FLAGS_REG)
8921         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8922                  (const_int 0)))
8923    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8924         (not:SWI (match_dup 1)))]
8925   "ix86_match_ccmode (insn, CCNOmode)
8926    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8927   "#"
8928   [(set_attr "type" "alu1")
8929    (set_attr "mode" "<MODE>")])
8930
8931 (define_split
8932   [(set (match_operand 0 "flags_reg_operand" "")
8933         (match_operator 2 "compare_operator"
8934           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8935            (const_int 0)]))
8936    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8937         (not:SWI (match_dup 3)))]
8938   "ix86_match_ccmode (insn, CCNOmode)"
8939   [(parallel [(set (match_dup 0)
8940                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8941                                     (const_int 0)]))
8942               (set (match_dup 1)
8943                    (xor:SWI (match_dup 3) (const_int -1)))])])
8944
8945 ;; ??? Currently never generated - xor is used instead.
8946 (define_insn "*one_cmplsi2_2_zext"
8947   [(set (reg FLAGS_REG)
8948         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8949                  (const_int 0)))
8950    (set (match_operand:DI 0 "register_operand" "=r")
8951         (zero_extend:DI (not:SI (match_dup 1))))]
8952   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8953    && ix86_unary_operator_ok (NOT, SImode, operands)"
8954   "#"
8955   [(set_attr "type" "alu1")
8956    (set_attr "mode" "SI")])
8957
8958 (define_split
8959   [(set (match_operand 0 "flags_reg_operand" "")
8960         (match_operator 2 "compare_operator"
8961           [(not:SI (match_operand:SI 3 "register_operand" ""))
8962            (const_int 0)]))
8963    (set (match_operand:DI 1 "register_operand" "")
8964         (zero_extend:DI (not:SI (match_dup 3))))]
8965   "ix86_match_ccmode (insn, CCNOmode)"
8966   [(parallel [(set (match_dup 0)
8967                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8968                                     (const_int 0)]))
8969               (set (match_dup 1)
8970                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8971 \f
8972 ;; Shift instructions
8973
8974 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8975 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8976 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8977 ;; from the assembler input.
8978 ;;
8979 ;; This instruction shifts the target reg/mem as usual, but instead of
8980 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8981 ;; is a left shift double, bits are taken from the high order bits of
8982 ;; reg, else if the insn is a shift right double, bits are taken from the
8983 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8984 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8985 ;;
8986 ;; Since sh[lr]d does not change the `reg' operand, that is done
8987 ;; separately, making all shifts emit pairs of shift double and normal
8988 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8989 ;; support a 63 bit shift, each shift where the count is in a reg expands
8990 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8991 ;;
8992 ;; If the shift count is a constant, we need never emit more than one
8993 ;; shift pair, instead using moves and sign extension for counts greater
8994 ;; than 31.
8995
8996 (define_expand "ashl<mode>3"
8997   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8998         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8999                       (match_operand:QI 2 "nonmemory_operand" "")))]
9000   ""
9001   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9002
9003 (define_insn "*ashl<mode>3_doubleword"
9004   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9005         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9006                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9007    (clobber (reg:CC FLAGS_REG))]
9008   ""
9009   "#"
9010   [(set_attr "type" "multi")])
9011
9012 (define_split
9013   [(set (match_operand:DWI 0 "register_operand" "")
9014         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9015                     (match_operand:QI 2 "nonmemory_operand" "")))
9016    (clobber (reg:CC FLAGS_REG))]
9017   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9018   [(const_int 0)]
9019   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9020
9021 ;; By default we don't ask for a scratch register, because when DWImode
9022 ;; values are manipulated, registers are already at a premium.  But if
9023 ;; we have one handy, we won't turn it away.
9024
9025 (define_peephole2
9026   [(match_scratch:DWIH 3 "r")
9027    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9028                    (ashift:<DWI>
9029                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9030                      (match_operand:QI 2 "nonmemory_operand" "")))
9031               (clobber (reg:CC FLAGS_REG))])
9032    (match_dup 3)]
9033   "TARGET_CMOVE"
9034   [(const_int 0)]
9035   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9036
9037 (define_insn "x86_64_shld"
9038   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9039         (ior:DI (ashift:DI (match_dup 0)
9040                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9041                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9042                   (minus:QI (const_int 64) (match_dup 2)))))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "TARGET_64BIT"
9045   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9046   [(set_attr "type" "ishift")
9047    (set_attr "prefix_0f" "1")
9048    (set_attr "mode" "DI")
9049    (set_attr "athlon_decode" "vector")
9050    (set_attr "amdfam10_decode" "vector")
9051    (set_attr "bdver1_decode" "vector")])
9052
9053 (define_insn "x86_shld"
9054   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9055         (ior:SI (ashift:SI (match_dup 0)
9056                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9057                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9058                   (minus:QI (const_int 32) (match_dup 2)))))
9059    (clobber (reg:CC FLAGS_REG))]
9060   ""
9061   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9062   [(set_attr "type" "ishift")
9063    (set_attr "prefix_0f" "1")
9064    (set_attr "mode" "SI")
9065    (set_attr "pent_pair" "np")
9066    (set_attr "athlon_decode" "vector")
9067    (set_attr "amdfam10_decode" "vector")
9068    (set_attr "bdver1_decode" "vector")])
9069
9070 (define_expand "x86_shift<mode>_adj_1"
9071   [(set (reg:CCZ FLAGS_REG)
9072         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9073                              (match_dup 4))
9074                      (const_int 0)))
9075    (set (match_operand:SWI48 0 "register_operand" "")
9076         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9077                             (match_operand:SWI48 1 "register_operand" "")
9078                             (match_dup 0)))
9079    (set (match_dup 1)
9080         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9081                             (match_operand:SWI48 3 "register_operand" "r")
9082                             (match_dup 1)))]
9083   "TARGET_CMOVE"
9084   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9085
9086 (define_expand "x86_shift<mode>_adj_2"
9087   [(use (match_operand:SWI48 0 "register_operand" ""))
9088    (use (match_operand:SWI48 1 "register_operand" ""))
9089    (use (match_operand:QI 2 "register_operand" ""))]
9090   ""
9091 {
9092   rtx label = gen_label_rtx ();
9093   rtx tmp;
9094
9095   emit_insn (gen_testqi_ccz_1 (operands[2],
9096                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9097
9098   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9099   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9100   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9101                               gen_rtx_LABEL_REF (VOIDmode, label),
9102                               pc_rtx);
9103   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9104   JUMP_LABEL (tmp) = label;
9105
9106   emit_move_insn (operands[0], operands[1]);
9107   ix86_expand_clear (operands[1]);
9108
9109   emit_label (label);
9110   LABEL_NUSES (label) = 1;
9111
9112   DONE;
9113 })
9114
9115 ;; Avoid useless masking of count operand.
9116 (define_insn_and_split "*ashl<mode>3_mask"
9117   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9118         (ashift:SWI48
9119           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9120           (subreg:QI
9121             (and:SI
9122               (match_operand:SI 2 "nonimmediate_operand" "c")
9123               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9124    (clobber (reg:CC FLAGS_REG))]
9125   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9126    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9127       == GET_MODE_BITSIZE (<MODE>mode)-1"
9128   "#"
9129   "&& 1"
9130   [(parallel [(set (match_dup 0)
9131                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9132               (clobber (reg:CC FLAGS_REG))])]
9133 {
9134   if (can_create_pseudo_p ())
9135     operands [2] = force_reg (SImode, operands[2]);
9136
9137   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9138 }
9139   [(set_attr "type" "ishift")
9140    (set_attr "mode" "<MODE>")])
9141
9142 (define_insn "*bmi2_ashl<mode>3_1"
9143   [(set (match_operand:SWI48 0 "register_operand" "=r")
9144         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9145                       (match_operand:SWI48 2 "register_operand" "r")))]
9146   "TARGET_BMI2"
9147   "shlx\t{%2, %1, %0|%0, %1, %2}"
9148   [(set_attr "type" "ishiftx")
9149    (set_attr "mode" "<MODE>")])
9150
9151 (define_insn "*ashl<mode>3_1"
9152   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9153         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9154                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9155    (clobber (reg:CC FLAGS_REG))]
9156   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9157 {
9158   switch (get_attr_type (insn))
9159     {
9160     case TYPE_LEA:
9161     case TYPE_ISHIFTX:
9162       return "#";
9163
9164     case TYPE_ALU:
9165       gcc_assert (operands[2] == const1_rtx);
9166       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9167       return "add{<imodesuffix>}\t%0, %0";
9168
9169     default:
9170       if (operands[2] == const1_rtx
9171           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9172         return "sal{<imodesuffix>}\t%0";
9173       else
9174         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9175     }
9176 }
9177   [(set_attr "isa" "*,*,bmi2")
9178    (set (attr "type")
9179      (cond [(eq_attr "alternative" "1")
9180               (const_string "lea")
9181             (eq_attr "alternative" "2")
9182               (const_string "ishiftx")
9183             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9184                       (match_operand 0 "register_operand" ""))
9185                  (match_operand 2 "const1_operand" ""))
9186               (const_string "alu")
9187            ]
9188            (const_string "ishift")))
9189    (set (attr "length_immediate")
9190      (if_then_else
9191        (ior (eq_attr "type" "alu")
9192             (and (eq_attr "type" "ishift")
9193                  (and (match_operand 2 "const1_operand" "")
9194                       (ior (match_test "TARGET_SHIFT1")
9195                            (match_test "optimize_function_for_size_p (cfun)")))))
9196        (const_string "0")
9197        (const_string "*")))
9198    (set_attr "mode" "<MODE>")])
9199
9200 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9201 (define_split
9202   [(set (match_operand:SWI48 0 "register_operand" "")
9203         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9204                       (match_operand:QI 2 "register_operand" "")))
9205    (clobber (reg:CC FLAGS_REG))]
9206   "TARGET_BMI2 && reload_completed"
9207   [(set (match_dup 0)
9208         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9209   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9210
9211 (define_insn "*bmi2_ashlsi3_1_zext"
9212   [(set (match_operand:DI 0 "register_operand" "=r")
9213         (zero_extend:DI
9214           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9215                      (match_operand:SI 2 "register_operand" "r"))))]
9216   "TARGET_64BIT && TARGET_BMI2"
9217   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9218   [(set_attr "type" "ishiftx")
9219    (set_attr "mode" "SI")])
9220
9221 (define_insn "*ashlsi3_1_zext"
9222   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9223         (zero_extend:DI
9224           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9225                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9226    (clobber (reg:CC FLAGS_REG))]
9227   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9228 {
9229   switch (get_attr_type (insn))
9230     {
9231     case TYPE_LEA:
9232     case TYPE_ISHIFTX:
9233       return "#";
9234
9235     case TYPE_ALU:
9236       gcc_assert (operands[2] == const1_rtx);
9237       return "add{l}\t%k0, %k0";
9238
9239     default:
9240       if (operands[2] == const1_rtx
9241           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9242         return "sal{l}\t%k0";
9243       else
9244         return "sal{l}\t{%2, %k0|%k0, %2}";
9245     }
9246 }
9247   [(set_attr "isa" "*,*,bmi2")
9248    (set (attr "type")
9249      (cond [(eq_attr "alternative" "1")
9250               (const_string "lea")
9251             (eq_attr "alternative" "2")
9252               (const_string "ishiftx")
9253             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9254                  (match_operand 2 "const1_operand" ""))
9255               (const_string "alu")
9256            ]
9257            (const_string "ishift")))
9258    (set (attr "length_immediate")
9259      (if_then_else
9260        (ior (eq_attr "type" "alu")
9261             (and (eq_attr "type" "ishift")
9262                  (and (match_operand 2 "const1_operand" "")
9263                       (ior (match_test "TARGET_SHIFT1")
9264                            (match_test "optimize_function_for_size_p (cfun)")))))
9265        (const_string "0")
9266        (const_string "*")))
9267    (set_attr "mode" "SI")])
9268
9269 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9270 (define_split
9271   [(set (match_operand:DI 0 "register_operand" "")
9272         (zero_extend:DI
9273           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9274                      (match_operand:QI 2 "register_operand" ""))))
9275    (clobber (reg:CC FLAGS_REG))]
9276   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9277   [(set (match_dup 0)
9278         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9279   "operands[2] = gen_lowpart (SImode, operands[2]);")
9280
9281 (define_insn "*ashlhi3_1"
9282   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9283         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9284                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9285    (clobber (reg:CC FLAGS_REG))]
9286   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9287 {
9288   switch (get_attr_type (insn))
9289     {
9290     case TYPE_LEA:
9291       return "#";
9292
9293     case TYPE_ALU:
9294       gcc_assert (operands[2] == const1_rtx);
9295       return "add{w}\t%0, %0";
9296
9297     default:
9298       if (operands[2] == const1_rtx
9299           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9300         return "sal{w}\t%0";
9301       else
9302         return "sal{w}\t{%2, %0|%0, %2}";
9303     }
9304 }
9305   [(set (attr "type")
9306      (cond [(eq_attr "alternative" "1")
9307               (const_string "lea")
9308             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9309                       (match_operand 0 "register_operand" ""))
9310                  (match_operand 2 "const1_operand" ""))
9311               (const_string "alu")
9312            ]
9313            (const_string "ishift")))
9314    (set (attr "length_immediate")
9315      (if_then_else
9316        (ior (eq_attr "type" "alu")
9317             (and (eq_attr "type" "ishift")
9318                  (and (match_operand 2 "const1_operand" "")
9319                       (ior (match_test "TARGET_SHIFT1")
9320                            (match_test "optimize_function_for_size_p (cfun)")))))
9321        (const_string "0")
9322        (const_string "*")))
9323    (set_attr "mode" "HI,SI")])
9324
9325 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9326 (define_insn "*ashlqi3_1"
9327   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9328         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9329                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9330    (clobber (reg:CC FLAGS_REG))]
9331   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9332 {
9333   switch (get_attr_type (insn))
9334     {
9335     case TYPE_LEA:
9336       return "#";
9337
9338     case TYPE_ALU:
9339       gcc_assert (operands[2] == const1_rtx);
9340       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9341         return "add{l}\t%k0, %k0";
9342       else
9343         return "add{b}\t%0, %0";
9344
9345     default:
9346       if (operands[2] == const1_rtx
9347           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9348         {
9349           if (get_attr_mode (insn) == MODE_SI)
9350             return "sal{l}\t%k0";
9351           else
9352             return "sal{b}\t%0";
9353         }
9354       else
9355         {
9356           if (get_attr_mode (insn) == MODE_SI)
9357             return "sal{l}\t{%2, %k0|%k0, %2}";
9358           else
9359             return "sal{b}\t{%2, %0|%0, %2}";
9360         }
9361     }
9362 }
9363   [(set (attr "type")
9364      (cond [(eq_attr "alternative" "2")
9365               (const_string "lea")
9366             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9367                       (match_operand 0 "register_operand" ""))
9368                  (match_operand 2 "const1_operand" ""))
9369               (const_string "alu")
9370            ]
9371            (const_string "ishift")))
9372    (set (attr "length_immediate")
9373      (if_then_else
9374        (ior (eq_attr "type" "alu")
9375             (and (eq_attr "type" "ishift")
9376                  (and (match_operand 2 "const1_operand" "")
9377                       (ior (match_test "TARGET_SHIFT1")
9378                            (match_test "optimize_function_for_size_p (cfun)")))))
9379        (const_string "0")
9380        (const_string "*")))
9381    (set_attr "mode" "QI,SI,SI")])
9382
9383 (define_insn "*ashlqi3_1_slp"
9384   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9385         (ashift:QI (match_dup 0)
9386                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9387    (clobber (reg:CC FLAGS_REG))]
9388   "(optimize_function_for_size_p (cfun)
9389     || !TARGET_PARTIAL_FLAG_REG_STALL
9390     || (operands[1] == const1_rtx
9391         && (TARGET_SHIFT1
9392             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9393 {
9394   switch (get_attr_type (insn))
9395     {
9396     case TYPE_ALU:
9397       gcc_assert (operands[1] == const1_rtx);
9398       return "add{b}\t%0, %0";
9399
9400     default:
9401       if (operands[1] == const1_rtx
9402           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9403         return "sal{b}\t%0";
9404       else
9405         return "sal{b}\t{%1, %0|%0, %1}";
9406     }
9407 }
9408   [(set (attr "type")
9409      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9410                       (match_operand 0 "register_operand" ""))
9411                  (match_operand 1 "const1_operand" ""))
9412               (const_string "alu")
9413            ]
9414            (const_string "ishift1")))
9415    (set (attr "length_immediate")
9416      (if_then_else
9417        (ior (eq_attr "type" "alu")
9418             (and (eq_attr "type" "ishift1")
9419                  (and (match_operand 1 "const1_operand" "")
9420                       (ior (match_test "TARGET_SHIFT1")
9421                            (match_test "optimize_function_for_size_p (cfun)")))))
9422        (const_string "0")
9423        (const_string "*")))
9424    (set_attr "mode" "QI")])
9425
9426 ;; Convert ashift to the lea pattern to avoid flags dependency.
9427 (define_split
9428   [(set (match_operand 0 "register_operand" "")
9429         (ashift (match_operand 1 "index_register_operand" "")
9430                 (match_operand:QI 2 "const_int_operand" "")))
9431    (clobber (reg:CC FLAGS_REG))]
9432   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9433    && reload_completed
9434    && true_regnum (operands[0]) != true_regnum (operands[1])"
9435   [(const_int 0)]
9436 {
9437   enum machine_mode mode = GET_MODE (operands[0]);
9438   rtx pat;
9439
9440   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9441     { 
9442       mode = SImode; 
9443       operands[0] = gen_lowpart (mode, operands[0]);
9444       operands[1] = gen_lowpart (mode, operands[1]);
9445     }
9446
9447   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9448
9449   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9450
9451   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9452   DONE;
9453 })
9454
9455 ;; Convert ashift to the lea pattern to avoid flags dependency.
9456 (define_split
9457   [(set (match_operand:DI 0 "register_operand" "")
9458         (zero_extend:DI
9459           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9460                      (match_operand:QI 2 "const_int_operand" ""))))
9461    (clobber (reg:CC FLAGS_REG))]
9462   "TARGET_64BIT && reload_completed
9463    && true_regnum (operands[0]) != true_regnum (operands[1])"
9464   [(set (match_dup 0)
9465         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9466 {
9467   operands[1] = gen_lowpart (DImode, operands[1]);
9468   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9469 })
9470
9471 ;; This pattern can't accept a variable shift count, since shifts by
9472 ;; zero don't affect the flags.  We assume that shifts by constant
9473 ;; zero are optimized away.
9474 (define_insn "*ashl<mode>3_cmp"
9475   [(set (reg FLAGS_REG)
9476         (compare
9477           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9478                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9479           (const_int 0)))
9480    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9481         (ashift:SWI (match_dup 1) (match_dup 2)))]
9482   "(optimize_function_for_size_p (cfun)
9483     || !TARGET_PARTIAL_FLAG_REG_STALL
9484     || (operands[2] == const1_rtx
9485         && (TARGET_SHIFT1
9486             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9487    && ix86_match_ccmode (insn, CCGOCmode)
9488    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9489 {
9490   switch (get_attr_type (insn))
9491     {
9492     case TYPE_ALU:
9493       gcc_assert (operands[2] == const1_rtx);
9494       return "add{<imodesuffix>}\t%0, %0";
9495
9496     default:
9497       if (operands[2] == const1_rtx
9498           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9499         return "sal{<imodesuffix>}\t%0";
9500       else
9501         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9502     }
9503 }
9504   [(set (attr "type")
9505      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9506                       (match_operand 0 "register_operand" ""))
9507                  (match_operand 2 "const1_operand" ""))
9508               (const_string "alu")
9509            ]
9510            (const_string "ishift")))
9511    (set (attr "length_immediate")
9512      (if_then_else
9513        (ior (eq_attr "type" "alu")
9514             (and (eq_attr "type" "ishift")
9515                  (and (match_operand 2 "const1_operand" "")
9516                       (ior (match_test "TARGET_SHIFT1")
9517                            (match_test "optimize_function_for_size_p (cfun)")))))
9518        (const_string "0")
9519        (const_string "*")))
9520    (set_attr "mode" "<MODE>")])
9521
9522 (define_insn "*ashlsi3_cmp_zext"
9523   [(set (reg FLAGS_REG)
9524         (compare
9525           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9526                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9527           (const_int 0)))
9528    (set (match_operand:DI 0 "register_operand" "=r")
9529         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9530   "TARGET_64BIT
9531    && (optimize_function_for_size_p (cfun)
9532        || !TARGET_PARTIAL_FLAG_REG_STALL
9533        || (operands[2] == const1_rtx
9534            && (TARGET_SHIFT1
9535                || TARGET_DOUBLE_WITH_ADD)))
9536    && ix86_match_ccmode (insn, CCGOCmode)
9537    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9538 {
9539   switch (get_attr_type (insn))
9540     {
9541     case TYPE_ALU:
9542       gcc_assert (operands[2] == const1_rtx);
9543       return "add{l}\t%k0, %k0";
9544
9545     default:
9546       if (operands[2] == const1_rtx
9547           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9548         return "sal{l}\t%k0";
9549       else
9550         return "sal{l}\t{%2, %k0|%k0, %2}";
9551     }
9552 }
9553   [(set (attr "type")
9554      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
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                       (ior (match_test "TARGET_SHIFT1")
9565                            (match_test "optimize_function_for_size_p (cfun)")))))
9566        (const_string "0")
9567        (const_string "*")))
9568    (set_attr "mode" "SI")])
9569
9570 (define_insn "*ashl<mode>3_cconly"
9571   [(set (reg FLAGS_REG)
9572         (compare
9573           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9574                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9575           (const_int 0)))
9576    (clobber (match_scratch:SWI 0 "=<r>"))]
9577   "(optimize_function_for_size_p (cfun)
9578     || !TARGET_PARTIAL_FLAG_REG_STALL
9579     || (operands[2] == const1_rtx
9580         && (TARGET_SHIFT1
9581             || TARGET_DOUBLE_WITH_ADD)))
9582    && ix86_match_ccmode (insn, CCGOCmode)"
9583 {
9584   switch (get_attr_type (insn))
9585     {
9586     case TYPE_ALU:
9587       gcc_assert (operands[2] == const1_rtx);
9588       return "add{<imodesuffix>}\t%0, %0";
9589
9590     default:
9591       if (operands[2] == const1_rtx
9592           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9593         return "sal{<imodesuffix>}\t%0";
9594       else
9595         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9596     }
9597 }
9598   [(set (attr "type")
9599      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9600                       (match_operand 0 "register_operand" ""))
9601                  (match_operand 2 "const1_operand" ""))
9602               (const_string "alu")
9603            ]
9604            (const_string "ishift")))
9605    (set (attr "length_immediate")
9606      (if_then_else
9607        (ior (eq_attr "type" "alu")
9608             (and (eq_attr "type" "ishift")
9609                  (and (match_operand 2 "const1_operand" "")
9610                       (ior (match_test "TARGET_SHIFT1")
9611                            (match_test "optimize_function_for_size_p (cfun)")))))
9612        (const_string "0")
9613        (const_string "*")))
9614    (set_attr "mode" "<MODE>")])
9615
9616 ;; See comment above `ashl<mode>3' about how this works.
9617
9618 (define_expand "<shift_insn><mode>3"
9619   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9620         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9621                            (match_operand:QI 2 "nonmemory_operand" "")))]
9622   ""
9623   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9624
9625 ;; Avoid useless masking of count operand.
9626 (define_insn_and_split "*<shift_insn><mode>3_mask"
9627   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9628         (any_shiftrt:SWI48
9629           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9630           (subreg:QI
9631             (and:SI
9632               (match_operand:SI 2 "nonimmediate_operand" "c")
9633               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9634    (clobber (reg:CC FLAGS_REG))]
9635   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9636    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9637       == GET_MODE_BITSIZE (<MODE>mode)-1"
9638   "#"
9639   "&& 1"
9640   [(parallel [(set (match_dup 0)
9641                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9642               (clobber (reg:CC FLAGS_REG))])]
9643 {
9644   if (can_create_pseudo_p ())
9645     operands [2] = force_reg (SImode, operands[2]);
9646
9647   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9648 }
9649   [(set_attr "type" "ishift")
9650    (set_attr "mode" "<MODE>")])
9651
9652 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9653   [(set (match_operand:DWI 0 "register_operand" "=r")
9654         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9655                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9656    (clobber (reg:CC FLAGS_REG))]
9657   ""
9658   "#"
9659   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9660   [(const_int 0)]
9661   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9662   [(set_attr "type" "multi")])
9663
9664 ;; By default we don't ask for a scratch register, because when DWImode
9665 ;; values are manipulated, registers are already at a premium.  But if
9666 ;; we have one handy, we won't turn it away.
9667
9668 (define_peephole2
9669   [(match_scratch:DWIH 3 "r")
9670    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9671                    (any_shiftrt:<DWI>
9672                      (match_operand:<DWI> 1 "register_operand" "")
9673                      (match_operand:QI 2 "nonmemory_operand" "")))
9674               (clobber (reg:CC FLAGS_REG))])
9675    (match_dup 3)]
9676   "TARGET_CMOVE"
9677   [(const_int 0)]
9678   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9679
9680 (define_insn "x86_64_shrd"
9681   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9682         (ior:DI (ashiftrt:DI (match_dup 0)
9683                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9684                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9685                   (minus:QI (const_int 64) (match_dup 2)))))
9686    (clobber (reg:CC FLAGS_REG))]
9687   "TARGET_64BIT"
9688   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9689   [(set_attr "type" "ishift")
9690    (set_attr "prefix_0f" "1")
9691    (set_attr "mode" "DI")
9692    (set_attr "athlon_decode" "vector")
9693    (set_attr "amdfam10_decode" "vector")
9694    (set_attr "bdver1_decode" "vector")])
9695
9696 (define_insn "x86_shrd"
9697   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9698         (ior:SI (ashiftrt:SI (match_dup 0)
9699                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9700                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9701                   (minus:QI (const_int 32) (match_dup 2)))))
9702    (clobber (reg:CC FLAGS_REG))]
9703   ""
9704   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9705   [(set_attr "type" "ishift")
9706    (set_attr "prefix_0f" "1")
9707    (set_attr "mode" "SI")
9708    (set_attr "pent_pair" "np")
9709    (set_attr "athlon_decode" "vector")
9710    (set_attr "amdfam10_decode" "vector")
9711    (set_attr "bdver1_decode" "vector")])
9712
9713 (define_insn "ashrdi3_cvt"
9714   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9715         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9716                      (match_operand:QI 2 "const_int_operand" "")))
9717    (clobber (reg:CC FLAGS_REG))]
9718   "TARGET_64BIT && INTVAL (operands[2]) == 63
9719    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9720    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9721   "@
9722    {cqto|cqo}
9723    sar{q}\t{%2, %0|%0, %2}"
9724   [(set_attr "type" "imovx,ishift")
9725    (set_attr "prefix_0f" "0,*")
9726    (set_attr "length_immediate" "0,*")
9727    (set_attr "modrm" "0,1")
9728    (set_attr "mode" "DI")])
9729
9730 (define_insn "ashrsi3_cvt"
9731   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9732         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9733                      (match_operand:QI 2 "const_int_operand" "")))
9734    (clobber (reg:CC FLAGS_REG))]
9735   "INTVAL (operands[2]) == 31
9736    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9737    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9738   "@
9739    {cltd|cdq}
9740    sar{l}\t{%2, %0|%0, %2}"
9741   [(set_attr "type" "imovx,ishift")
9742    (set_attr "prefix_0f" "0,*")
9743    (set_attr "length_immediate" "0,*")
9744    (set_attr "modrm" "0,1")
9745    (set_attr "mode" "SI")])
9746
9747 (define_insn "*ashrsi3_cvt_zext"
9748   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9749         (zero_extend:DI
9750           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9751                        (match_operand:QI 2 "const_int_operand" ""))))
9752    (clobber (reg:CC FLAGS_REG))]
9753   "TARGET_64BIT && INTVAL (operands[2]) == 31
9754    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9755    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9756   "@
9757    {cltd|cdq}
9758    sar{l}\t{%2, %k0|%k0, %2}"
9759   [(set_attr "type" "imovx,ishift")
9760    (set_attr "prefix_0f" "0,*")
9761    (set_attr "length_immediate" "0,*")
9762    (set_attr "modrm" "0,1")
9763    (set_attr "mode" "SI")])
9764
9765 (define_expand "x86_shift<mode>_adj_3"
9766   [(use (match_operand:SWI48 0 "register_operand" ""))
9767    (use (match_operand:SWI48 1 "register_operand" ""))
9768    (use (match_operand:QI 2 "register_operand" ""))]
9769   ""
9770 {
9771   rtx label = gen_label_rtx ();
9772   rtx tmp;
9773
9774   emit_insn (gen_testqi_ccz_1 (operands[2],
9775                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9776
9777   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9778   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9779   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9780                               gen_rtx_LABEL_REF (VOIDmode, label),
9781                               pc_rtx);
9782   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9783   JUMP_LABEL (tmp) = label;
9784
9785   emit_move_insn (operands[0], operands[1]);
9786   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9787                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9788   emit_label (label);
9789   LABEL_NUSES (label) = 1;
9790
9791   DONE;
9792 })
9793
9794 (define_insn "*bmi2_<shift_insn><mode>3_1"
9795   [(set (match_operand:SWI48 0 "register_operand" "=r")
9796         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9797                            (match_operand:SWI48 2 "register_operand" "r")))]
9798   "TARGET_BMI2"
9799   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9800   [(set_attr "type" "ishiftx")
9801    (set_attr "mode" "<MODE>")])
9802
9803 (define_insn "*<shift_insn><mode>3_1"
9804   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9805         (any_shiftrt:SWI48
9806           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9807           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9808    (clobber (reg:CC FLAGS_REG))]
9809   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9810 {
9811   switch (get_attr_type (insn))
9812     {
9813     case TYPE_ISHIFTX:
9814       return "#";
9815
9816     default:
9817       if (operands[2] == const1_rtx
9818           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9819         return "<shift>{<imodesuffix>}\t%0";
9820       else
9821         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9822     }
9823 }
9824   [(set_attr "isa" "*,bmi2")
9825    (set_attr "type" "ishift,ishiftx")
9826    (set (attr "length_immediate")
9827      (if_then_else
9828        (and (match_operand 2 "const1_operand" "")
9829             (ior (match_test "TARGET_SHIFT1")
9830                  (match_test "optimize_function_for_size_p (cfun)")))
9831        (const_string "0")
9832        (const_string "*")))
9833    (set_attr "mode" "<MODE>")])
9834
9835 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9836 (define_split
9837   [(set (match_operand:SWI48 0 "register_operand" "")
9838         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9839                            (match_operand:QI 2 "register_operand" "")))
9840    (clobber (reg:CC FLAGS_REG))]
9841   "TARGET_BMI2 && reload_completed"
9842   [(set (match_dup 0)
9843         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9844   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9845
9846 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9847   [(set (match_operand:DI 0 "register_operand" "=r")
9848         (zero_extend:DI
9849           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9850                           (match_operand:SI 2 "register_operand" "r"))))]
9851   "TARGET_64BIT && TARGET_BMI2"
9852   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9853   [(set_attr "type" "ishiftx")
9854    (set_attr "mode" "SI")])
9855
9856 (define_insn "*<shift_insn>si3_1_zext"
9857   [(set (match_operand:DI 0 "register_operand" "=r,r")
9858         (zero_extend:DI
9859           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9860                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9863 {
9864   switch (get_attr_type (insn))
9865     {
9866     case TYPE_ISHIFTX:
9867       return "#";
9868
9869     default:
9870       if (operands[2] == const1_rtx
9871           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9872         return "<shift>{l}\t%k0";
9873       else
9874         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9875     }
9876 }
9877   [(set_attr "isa" "*,bmi2")
9878    (set_attr "type" "ishift,ishiftx")
9879    (set (attr "length_immediate")
9880      (if_then_else
9881        (and (match_operand 2 "const1_operand" "")
9882             (ior (match_test "TARGET_SHIFT1")
9883                  (match_test "optimize_function_for_size_p (cfun)")))
9884        (const_string "0")
9885        (const_string "*")))
9886    (set_attr "mode" "SI")])
9887
9888 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9889 (define_split
9890   [(set (match_operand:DI 0 "register_operand" "")
9891         (zero_extend:DI
9892           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9893                           (match_operand:QI 2 "register_operand" ""))))
9894    (clobber (reg:CC FLAGS_REG))]
9895   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9896   [(set (match_dup 0)
9897         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9898   "operands[2] = gen_lowpart (SImode, operands[2]);")
9899
9900 (define_insn "*<shift_insn><mode>3_1"
9901   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9902         (any_shiftrt:SWI12
9903           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9904           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9905    (clobber (reg:CC FLAGS_REG))]
9906   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9907 {
9908   if (operands[2] == const1_rtx
9909       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9910     return "<shift>{<imodesuffix>}\t%0";
9911   else
9912     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9913 }
9914   [(set_attr "type" "ishift")
9915    (set (attr "length_immediate")
9916      (if_then_else
9917        (and (match_operand 2 "const1_operand" "")
9918             (ior (match_test "TARGET_SHIFT1")
9919                  (match_test "optimize_function_for_size_p (cfun)")))
9920        (const_string "0")
9921        (const_string "*")))
9922    (set_attr "mode" "<MODE>")])
9923
9924 (define_insn "*<shift_insn>qi3_1_slp"
9925   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9926         (any_shiftrt:QI (match_dup 0)
9927                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9928    (clobber (reg:CC FLAGS_REG))]
9929   "(optimize_function_for_size_p (cfun)
9930     || !TARGET_PARTIAL_REG_STALL
9931     || (operands[1] == const1_rtx
9932         && TARGET_SHIFT1))"
9933 {
9934   if (operands[1] == const1_rtx
9935       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9936     return "<shift>{b}\t%0";
9937   else
9938     return "<shift>{b}\t{%1, %0|%0, %1}";
9939 }
9940   [(set_attr "type" "ishift1")
9941    (set (attr "length_immediate")
9942      (if_then_else
9943        (and (match_operand 1 "const1_operand" "")
9944             (ior (match_test "TARGET_SHIFT1")
9945                  (match_test "optimize_function_for_size_p (cfun)")))
9946        (const_string "0")
9947        (const_string "*")))
9948    (set_attr "mode" "QI")])
9949
9950 ;; This pattern can't accept a variable shift count, since shifts by
9951 ;; zero don't affect the flags.  We assume that shifts by constant
9952 ;; zero are optimized away.
9953 (define_insn "*<shift_insn><mode>3_cmp"
9954   [(set (reg FLAGS_REG)
9955         (compare
9956           (any_shiftrt:SWI
9957             (match_operand:SWI 1 "nonimmediate_operand" "0")
9958             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9959           (const_int 0)))
9960    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9961         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9962   "(optimize_function_for_size_p (cfun)
9963     || !TARGET_PARTIAL_FLAG_REG_STALL
9964     || (operands[2] == const1_rtx
9965         && TARGET_SHIFT1))
9966    && ix86_match_ccmode (insn, CCGOCmode)
9967    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9968 {
9969   if (operands[2] == const1_rtx
9970       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9971     return "<shift>{<imodesuffix>}\t%0";
9972   else
9973     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9974 }
9975   [(set_attr "type" "ishift")
9976    (set (attr "length_immediate")
9977      (if_then_else
9978        (and (match_operand 2 "const1_operand" "")
9979             (ior (match_test "TARGET_SHIFT1")
9980                  (match_test "optimize_function_for_size_p (cfun)")))
9981        (const_string "0")
9982        (const_string "*")))
9983    (set_attr "mode" "<MODE>")])
9984
9985 (define_insn "*<shift_insn>si3_cmp_zext"
9986   [(set (reg FLAGS_REG)
9987         (compare
9988           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9989                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9990           (const_int 0)))
9991    (set (match_operand:DI 0 "register_operand" "=r")
9992         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9993   "TARGET_64BIT
9994    && (optimize_function_for_size_p (cfun)
9995        || !TARGET_PARTIAL_FLAG_REG_STALL
9996        || (operands[2] == const1_rtx
9997            && TARGET_SHIFT1))
9998    && ix86_match_ccmode (insn, CCGOCmode)
9999    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10000 {
10001   if (operands[2] == const1_rtx
10002       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10003     return "<shift>{l}\t%k0";
10004   else
10005     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10006 }
10007   [(set_attr "type" "ishift")
10008    (set (attr "length_immediate")
10009      (if_then_else
10010        (and (match_operand 2 "const1_operand" "")
10011             (ior (match_test "TARGET_SHIFT1")
10012                  (match_test "optimize_function_for_size_p (cfun)")))
10013        (const_string "0")
10014        (const_string "*")))
10015    (set_attr "mode" "SI")])
10016
10017 (define_insn "*<shift_insn><mode>3_cconly"
10018   [(set (reg FLAGS_REG)
10019         (compare
10020           (any_shiftrt:SWI
10021             (match_operand:SWI 1 "register_operand" "0")
10022             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10023           (const_int 0)))
10024    (clobber (match_scratch:SWI 0 "=<r>"))]
10025   "(optimize_function_for_size_p (cfun)
10026     || !TARGET_PARTIAL_FLAG_REG_STALL
10027     || (operands[2] == const1_rtx
10028         && TARGET_SHIFT1))
10029    && ix86_match_ccmode (insn, CCGOCmode)"
10030 {
10031   if (operands[2] == const1_rtx
10032       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10033     return "<shift>{<imodesuffix>}\t%0";
10034   else
10035     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10036 }
10037   [(set_attr "type" "ishift")
10038    (set (attr "length_immediate")
10039      (if_then_else
10040        (and (match_operand 2 "const1_operand" "")
10041             (ior (match_test "TARGET_SHIFT1")
10042                  (match_test "optimize_function_for_size_p (cfun)")))
10043        (const_string "0")
10044        (const_string "*")))
10045    (set_attr "mode" "<MODE>")])
10046 \f
10047 ;; Rotate instructions
10048
10049 (define_expand "<rotate_insn>ti3"
10050   [(set (match_operand:TI 0 "register_operand" "")
10051         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10052                        (match_operand:QI 2 "nonmemory_operand" "")))]
10053   "TARGET_64BIT"
10054 {
10055   if (const_1_to_63_operand (operands[2], VOIDmode))
10056     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10057                 (operands[0], operands[1], operands[2]));
10058   else
10059     FAIL;
10060
10061   DONE;
10062 })
10063
10064 (define_expand "<rotate_insn>di3"
10065   [(set (match_operand:DI 0 "shiftdi_operand" "")
10066         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10067                        (match_operand:QI 2 "nonmemory_operand" "")))]
10068  ""
10069 {
10070   if (TARGET_64BIT)
10071     ix86_expand_binary_operator (<CODE>, DImode, operands);
10072   else if (const_1_to_31_operand (operands[2], VOIDmode))
10073     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10074                 (operands[0], operands[1], operands[2]));
10075   else
10076     FAIL;
10077
10078   DONE;
10079 })
10080
10081 (define_expand "<rotate_insn><mode>3"
10082   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10083         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10084                             (match_operand:QI 2 "nonmemory_operand" "")))]
10085   ""
10086   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10087
10088 ;; Avoid useless masking of count operand.
10089 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10090   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10091         (any_rotate:SWI48
10092           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10093           (subreg:QI
10094             (and:SI
10095               (match_operand:SI 2 "nonimmediate_operand" "c")
10096               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10097    (clobber (reg:CC FLAGS_REG))]
10098   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10099    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10100       == GET_MODE_BITSIZE (<MODE>mode)-1"
10101   "#"
10102   "&& 1"
10103   [(parallel [(set (match_dup 0)
10104                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10105               (clobber (reg:CC FLAGS_REG))])]
10106 {
10107   if (can_create_pseudo_p ())
10108     operands [2] = force_reg (SImode, operands[2]);
10109
10110   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10111 }
10112   [(set_attr "type" "rotate")
10113    (set_attr "mode" "<MODE>")])
10114
10115 ;; Implement rotation using two double-precision
10116 ;; shift instructions and a scratch register.
10117
10118 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10119  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10120        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10121                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10122   (clobber (reg:CC FLAGS_REG))
10123   (clobber (match_scratch:DWIH 3 "=&r"))]
10124  ""
10125  "#"
10126  "reload_completed"
10127  [(set (match_dup 3) (match_dup 4))
10128   (parallel
10129    [(set (match_dup 4)
10130          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10131                    (lshiftrt:DWIH (match_dup 5)
10132                                   (minus:QI (match_dup 6) (match_dup 2)))))
10133     (clobber (reg:CC FLAGS_REG))])
10134   (parallel
10135    [(set (match_dup 5)
10136          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10137                    (lshiftrt:DWIH (match_dup 3)
10138                                   (minus:QI (match_dup 6) (match_dup 2)))))
10139     (clobber (reg:CC FLAGS_REG))])]
10140 {
10141   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10142
10143   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10144 })
10145
10146 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10147  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10148        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10149                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10150   (clobber (reg:CC FLAGS_REG))
10151   (clobber (match_scratch:DWIH 3 "=&r"))]
10152  ""
10153  "#"
10154  "reload_completed"
10155  [(set (match_dup 3) (match_dup 4))
10156   (parallel
10157    [(set (match_dup 4)
10158          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10159                    (ashift:DWIH (match_dup 5)
10160                                 (minus:QI (match_dup 6) (match_dup 2)))))
10161     (clobber (reg:CC FLAGS_REG))])
10162   (parallel
10163    [(set (match_dup 5)
10164          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10165                    (ashift:DWIH (match_dup 3)
10166                                 (minus:QI (match_dup 6) (match_dup 2)))))
10167     (clobber (reg:CC FLAGS_REG))])]
10168 {
10169   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10170
10171   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10172 })
10173
10174 (define_insn "*bmi2_rorx<mode>3_1"
10175   [(set (match_operand:SWI48 0 "register_operand" "=r")
10176         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10177                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10178   "TARGET_BMI2"
10179   "rorx\t{%2, %1, %0|%0, %1, %2}"
10180   [(set_attr "type" "rotatex")
10181    (set_attr "mode" "<MODE>")])
10182
10183 (define_insn "*<rotate_insn><mode>3_1"
10184   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10185         (any_rotate:SWI48
10186           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10187           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10188    (clobber (reg:CC FLAGS_REG))]
10189   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10190 {
10191   switch (get_attr_type (insn))
10192     {
10193     case TYPE_ROTATEX:
10194       return "#";
10195
10196     default:
10197       if (operands[2] == const1_rtx
10198           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10199         return "<rotate>{<imodesuffix>}\t%0";
10200       else
10201         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10202     }
10203 }
10204   [(set_attr "isa" "*,bmi2")
10205    (set_attr "type" "rotate,rotatex")
10206    (set (attr "length_immediate")
10207      (if_then_else
10208        (and (eq_attr "type" "rotate")
10209             (and (match_operand 2 "const1_operand" "")
10210                  (ior (match_test "TARGET_SHIFT1")
10211                       (match_test "optimize_function_for_size_p (cfun)"))))
10212        (const_string "0")
10213        (const_string "*")))
10214    (set_attr "mode" "<MODE>")])
10215
10216 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10217 (define_split
10218   [(set (match_operand:SWI48 0 "register_operand" "")
10219         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10220                       (match_operand:QI 2 "immediate_operand" "")))
10221    (clobber (reg:CC FLAGS_REG))]
10222   "TARGET_BMI2 && reload_completed"
10223   [(set (match_dup 0)
10224         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10225 {
10226   operands[2]
10227     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10228 })
10229
10230 (define_split
10231   [(set (match_operand:SWI48 0 "register_operand" "")
10232         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10233                         (match_operand:QI 2 "immediate_operand" "")))
10234    (clobber (reg:CC FLAGS_REG))]
10235   "TARGET_BMI2 && reload_completed"
10236   [(set (match_dup 0)
10237         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10238
10239 (define_insn "*bmi2_rorxsi3_1_zext"
10240   [(set (match_operand:DI 0 "register_operand" "=r")
10241         (zero_extend:DI
10242           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10243                        (match_operand:QI 2 "immediate_operand" "I"))))]
10244   "TARGET_64BIT && TARGET_BMI2"
10245   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10246   [(set_attr "type" "rotatex")
10247    (set_attr "mode" "SI")])
10248
10249 (define_insn "*<rotate_insn>si3_1_zext"
10250   [(set (match_operand:DI 0 "register_operand" "=r,r")
10251         (zero_extend:DI
10252           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10253                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10254    (clobber (reg:CC FLAGS_REG))]
10255   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10256 {
10257   switch (get_attr_type (insn))
10258     {
10259     case TYPE_ROTATEX:
10260       return "#";
10261
10262     default:
10263       if (operands[2] == const1_rtx
10264           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10265         return "<rotate>{l}\t%k0";
10266       else
10267         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10268     }
10269 }
10270   [(set_attr "isa" "*,bmi2")
10271    (set_attr "type" "rotate,rotatex")
10272    (set (attr "length_immediate")
10273      (if_then_else
10274        (and (eq_attr "type" "rotate")
10275             (and (match_operand 2 "const1_operand" "")
10276                  (ior (match_test "TARGET_SHIFT1")
10277                       (match_test "optimize_function_for_size_p (cfun)"))))
10278        (const_string "0")
10279        (const_string "*")))
10280    (set_attr "mode" "SI")])
10281
10282 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10283 (define_split
10284   [(set (match_operand:DI 0 "register_operand" "")
10285         (zero_extend:DI
10286           (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10287                      (match_operand:QI 2 "immediate_operand" ""))))
10288    (clobber (reg:CC FLAGS_REG))]
10289   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10290   [(set (match_dup 0)
10291         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10292 {
10293   operands[2]
10294     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10295 })
10296
10297 (define_split
10298   [(set (match_operand:DI 0 "register_operand" "")
10299         (zero_extend:DI
10300           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10301                        (match_operand:QI 2 "immediate_operand" ""))))
10302    (clobber (reg:CC FLAGS_REG))]
10303   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10304   [(set (match_dup 0)
10305         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10306
10307 (define_insn "*<rotate_insn><mode>3_1"
10308   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10309         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10310                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10311    (clobber (reg:CC FLAGS_REG))]
10312   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10313 {
10314   if (operands[2] == const1_rtx
10315       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10316     return "<rotate>{<imodesuffix>}\t%0";
10317   else
10318     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10319 }
10320   [(set_attr "type" "rotate")
10321    (set (attr "length_immediate")
10322      (if_then_else
10323        (and (match_operand 2 "const1_operand" "")
10324             (ior (match_test "TARGET_SHIFT1")
10325                  (match_test "optimize_function_for_size_p (cfun)")))
10326        (const_string "0")
10327        (const_string "*")))
10328    (set_attr "mode" "<MODE>")])
10329
10330 (define_insn "*<rotate_insn>qi3_1_slp"
10331   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10332         (any_rotate:QI (match_dup 0)
10333                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10334    (clobber (reg:CC FLAGS_REG))]
10335   "(optimize_function_for_size_p (cfun)
10336     || !TARGET_PARTIAL_REG_STALL
10337     || (operands[1] == const1_rtx
10338         && TARGET_SHIFT1))"
10339 {
10340   if (operands[1] == const1_rtx
10341       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10342     return "<rotate>{b}\t%0";
10343   else
10344     return "<rotate>{b}\t{%1, %0|%0, %1}";
10345 }
10346   [(set_attr "type" "rotate1")
10347    (set (attr "length_immediate")
10348      (if_then_else
10349        (and (match_operand 1 "const1_operand" "")
10350             (ior (match_test "TARGET_SHIFT1")
10351                  (match_test "optimize_function_for_size_p (cfun)")))
10352        (const_string "0")
10353        (const_string "*")))
10354    (set_attr "mode" "QI")])
10355
10356 (define_split
10357  [(set (match_operand:HI 0 "register_operand" "")
10358        (any_rotate:HI (match_dup 0) (const_int 8)))
10359   (clobber (reg:CC FLAGS_REG))]
10360  "reload_completed
10361   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10362  [(parallel [(set (strict_low_part (match_dup 0))
10363                   (bswap:HI (match_dup 0)))
10364              (clobber (reg:CC FLAGS_REG))])])
10365 \f
10366 ;; Bit set / bit test instructions
10367
10368 (define_expand "extv"
10369   [(set (match_operand:SI 0 "register_operand" "")
10370         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10371                          (match_operand:SI 2 "const8_operand" "")
10372                          (match_operand:SI 3 "const8_operand" "")))]
10373   ""
10374 {
10375   /* Handle extractions from %ah et al.  */
10376   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10377     FAIL;
10378
10379   /* From mips.md: extract_bit_field doesn't verify that our source
10380      matches the predicate, so check it again here.  */
10381   if (! ext_register_operand (operands[1], VOIDmode))
10382     FAIL;
10383 })
10384
10385 (define_expand "extzv"
10386   [(set (match_operand:SI 0 "register_operand" "")
10387         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10388                          (match_operand:SI 2 "const8_operand" "")
10389                          (match_operand:SI 3 "const8_operand" "")))]
10390   ""
10391 {
10392   /* Handle extractions from %ah et al.  */
10393   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10394     FAIL;
10395
10396   /* From mips.md: extract_bit_field doesn't verify that our source
10397      matches the predicate, so check it again here.  */
10398   if (! ext_register_operand (operands[1], VOIDmode))
10399     FAIL;
10400 })
10401
10402 (define_expand "insv"
10403   [(set (zero_extract (match_operand 0 "register_operand" "")
10404                       (match_operand 1 "const_int_operand" "")
10405                       (match_operand 2 "const_int_operand" ""))
10406         (match_operand 3 "register_operand" ""))]
10407   ""
10408 {
10409   rtx (*gen_mov_insv_1) (rtx, rtx);
10410
10411   if (ix86_expand_pinsr (operands))
10412     DONE;
10413
10414   /* Handle insertions to %ah et al.  */
10415   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10416     FAIL;
10417
10418   /* From mips.md: insert_bit_field doesn't verify that our source
10419      matches the predicate, so check it again here.  */
10420   if (! ext_register_operand (operands[0], VOIDmode))
10421     FAIL;
10422
10423   gen_mov_insv_1 = (TARGET_64BIT
10424                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10425
10426   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10427   DONE;
10428 })
10429
10430 ;; %%% bts, btr, btc, bt.
10431 ;; In general these instructions are *slow* when applied to memory,
10432 ;; since they enforce atomic operation.  When applied to registers,
10433 ;; it depends on the cpu implementation.  They're never faster than
10434 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10435 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10436 ;; within the instruction itself, so operating on bits in the high
10437 ;; 32-bits of a register becomes easier.
10438 ;;
10439 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10440 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10441 ;; negdf respectively, so they can never be disabled entirely.
10442
10443 (define_insn "*btsq"
10444   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10445                          (const_int 1)
10446                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10447         (const_int 1))
10448    (clobber (reg:CC FLAGS_REG))]
10449   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10450   "bts{q}\t{%1, %0|%0, %1}"
10451   [(set_attr "type" "alu1")
10452    (set_attr "prefix_0f" "1")
10453    (set_attr "mode" "DI")])
10454
10455 (define_insn "*btrq"
10456   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10457                          (const_int 1)
10458                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10459         (const_int 0))
10460    (clobber (reg:CC FLAGS_REG))]
10461   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10462   "btr{q}\t{%1, %0|%0, %1}"
10463   [(set_attr "type" "alu1")
10464    (set_attr "prefix_0f" "1")
10465    (set_attr "mode" "DI")])
10466
10467 (define_insn "*btcq"
10468   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10469                          (const_int 1)
10470                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10471         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10472    (clobber (reg:CC FLAGS_REG))]
10473   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10474   "btc{q}\t{%1, %0|%0, %1}"
10475   [(set_attr "type" "alu1")
10476    (set_attr "prefix_0f" "1")
10477    (set_attr "mode" "DI")])
10478
10479 ;; Allow Nocona to avoid these instructions if a register is available.
10480
10481 (define_peephole2
10482   [(match_scratch:DI 2 "r")
10483    (parallel [(set (zero_extract:DI
10484                      (match_operand:DI 0 "register_operand" "")
10485                      (const_int 1)
10486                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10487                    (const_int 1))
10488               (clobber (reg:CC FLAGS_REG))])]
10489   "TARGET_64BIT && !TARGET_USE_BT"
10490   [(const_int 0)]
10491 {
10492   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10493   rtx op1;
10494
10495   if (HOST_BITS_PER_WIDE_INT >= 64)
10496     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10497   else if (i < HOST_BITS_PER_WIDE_INT)
10498     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10499   else
10500     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10501
10502   op1 = immed_double_const (lo, hi, DImode);
10503   if (i >= 31)
10504     {
10505       emit_move_insn (operands[2], op1);
10506       op1 = operands[2];
10507     }
10508
10509   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10510   DONE;
10511 })
10512
10513 (define_peephole2
10514   [(match_scratch:DI 2 "r")
10515    (parallel [(set (zero_extract:DI
10516                      (match_operand:DI 0 "register_operand" "")
10517                      (const_int 1)
10518                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10519                    (const_int 0))
10520               (clobber (reg:CC FLAGS_REG))])]
10521   "TARGET_64BIT && !TARGET_USE_BT"
10522   [(const_int 0)]
10523 {
10524   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10525   rtx op1;
10526
10527   if (HOST_BITS_PER_WIDE_INT >= 64)
10528     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10529   else if (i < HOST_BITS_PER_WIDE_INT)
10530     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10531   else
10532     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10533
10534   op1 = immed_double_const (~lo, ~hi, DImode);
10535   if (i >= 32)
10536     {
10537       emit_move_insn (operands[2], op1);
10538       op1 = operands[2];
10539     }
10540
10541   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10542   DONE;
10543 })
10544
10545 (define_peephole2
10546   [(match_scratch:DI 2 "r")
10547    (parallel [(set (zero_extract:DI
10548                      (match_operand:DI 0 "register_operand" "")
10549                      (const_int 1)
10550                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10551               (not:DI (zero_extract:DI
10552                         (match_dup 0) (const_int 1) (match_dup 1))))
10553               (clobber (reg:CC FLAGS_REG))])]
10554   "TARGET_64BIT && !TARGET_USE_BT"
10555   [(const_int 0)]
10556 {
10557   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10558   rtx op1;
10559
10560   if (HOST_BITS_PER_WIDE_INT >= 64)
10561     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10562   else if (i < HOST_BITS_PER_WIDE_INT)
10563     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10564   else
10565     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10566
10567   op1 = immed_double_const (lo, hi, DImode);
10568   if (i >= 31)
10569     {
10570       emit_move_insn (operands[2], op1);
10571       op1 = operands[2];
10572     }
10573
10574   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10575   DONE;
10576 })
10577
10578 (define_insn "*bt<mode>"
10579   [(set (reg:CCC FLAGS_REG)
10580         (compare:CCC
10581           (zero_extract:SWI48
10582             (match_operand:SWI48 0 "register_operand" "r")
10583             (const_int 1)
10584             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10585           (const_int 0)))]
10586   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10587   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10588   [(set_attr "type" "alu1")
10589    (set_attr "prefix_0f" "1")
10590    (set_attr "mode" "<MODE>")])
10591 \f
10592 ;; Store-flag instructions.
10593
10594 ;; For all sCOND expanders, also expand the compare or test insn that
10595 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10596
10597 (define_insn_and_split "*setcc_di_1"
10598   [(set (match_operand:DI 0 "register_operand" "=q")
10599         (match_operator:DI 1 "ix86_comparison_operator"
10600           [(reg FLAGS_REG) (const_int 0)]))]
10601   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10602   "#"
10603   "&& reload_completed"
10604   [(set (match_dup 2) (match_dup 1))
10605    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10606 {
10607   PUT_MODE (operands[1], QImode);
10608   operands[2] = gen_lowpart (QImode, operands[0]);
10609 })
10610
10611 (define_insn_and_split "*setcc_si_1_and"
10612   [(set (match_operand:SI 0 "register_operand" "=q")
10613         (match_operator:SI 1 "ix86_comparison_operator"
10614           [(reg FLAGS_REG) (const_int 0)]))
10615    (clobber (reg:CC FLAGS_REG))]
10616   "!TARGET_PARTIAL_REG_STALL
10617    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10618   "#"
10619   "&& reload_completed"
10620   [(set (match_dup 2) (match_dup 1))
10621    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10622               (clobber (reg:CC FLAGS_REG))])]
10623 {
10624   PUT_MODE (operands[1], QImode);
10625   operands[2] = gen_lowpart (QImode, operands[0]);
10626 })
10627
10628 (define_insn_and_split "*setcc_si_1_movzbl"
10629   [(set (match_operand:SI 0 "register_operand" "=q")
10630         (match_operator:SI 1 "ix86_comparison_operator"
10631           [(reg FLAGS_REG) (const_int 0)]))]
10632   "!TARGET_PARTIAL_REG_STALL
10633    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10634   "#"
10635   "&& reload_completed"
10636   [(set (match_dup 2) (match_dup 1))
10637    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10638 {
10639   PUT_MODE (operands[1], QImode);
10640   operands[2] = gen_lowpart (QImode, operands[0]);
10641 })
10642
10643 (define_insn "*setcc_qi"
10644   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10645         (match_operator:QI 1 "ix86_comparison_operator"
10646           [(reg FLAGS_REG) (const_int 0)]))]
10647   ""
10648   "set%C1\t%0"
10649   [(set_attr "type" "setcc")
10650    (set_attr "mode" "QI")])
10651
10652 (define_insn "*setcc_qi_slp"
10653   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10654         (match_operator:QI 1 "ix86_comparison_operator"
10655           [(reg FLAGS_REG) (const_int 0)]))]
10656   ""
10657   "set%C1\t%0"
10658   [(set_attr "type" "setcc")
10659    (set_attr "mode" "QI")])
10660
10661 ;; In general it is not safe to assume too much about CCmode registers,
10662 ;; so simplify-rtx stops when it sees a second one.  Under certain
10663 ;; conditions this is safe on x86, so help combine not create
10664 ;;
10665 ;;      seta    %al
10666 ;;      testb   %al, %al
10667 ;;      sete    %al
10668
10669 (define_split
10670   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10671         (ne:QI (match_operator 1 "ix86_comparison_operator"
10672                  [(reg FLAGS_REG) (const_int 0)])
10673             (const_int 0)))]
10674   ""
10675   [(set (match_dup 0) (match_dup 1))]
10676   "PUT_MODE (operands[1], QImode);")
10677
10678 (define_split
10679   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10680         (ne:QI (match_operator 1 "ix86_comparison_operator"
10681                  [(reg FLAGS_REG) (const_int 0)])
10682             (const_int 0)))]
10683   ""
10684   [(set (match_dup 0) (match_dup 1))]
10685   "PUT_MODE (operands[1], QImode);")
10686
10687 (define_split
10688   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10689         (eq:QI (match_operator 1 "ix86_comparison_operator"
10690                  [(reg FLAGS_REG) (const_int 0)])
10691             (const_int 0)))]
10692   ""
10693   [(set (match_dup 0) (match_dup 1))]
10694 {
10695   rtx new_op1 = copy_rtx (operands[1]);
10696   operands[1] = new_op1;
10697   PUT_MODE (new_op1, QImode);
10698   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10699                                              GET_MODE (XEXP (new_op1, 0))));
10700
10701   /* Make sure that (a) the CCmode we have for the flags is strong
10702      enough for the reversed compare or (b) we have a valid FP compare.  */
10703   if (! ix86_comparison_operator (new_op1, VOIDmode))
10704     FAIL;
10705 })
10706
10707 (define_split
10708   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10709         (eq:QI (match_operator 1 "ix86_comparison_operator"
10710                  [(reg FLAGS_REG) (const_int 0)])
10711             (const_int 0)))]
10712   ""
10713   [(set (match_dup 0) (match_dup 1))]
10714 {
10715   rtx new_op1 = copy_rtx (operands[1]);
10716   operands[1] = new_op1;
10717   PUT_MODE (new_op1, QImode);
10718   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10719                                              GET_MODE (XEXP (new_op1, 0))));
10720
10721   /* Make sure that (a) the CCmode we have for the flags is strong
10722      enough for the reversed compare or (b) we have a valid FP compare.  */
10723   if (! ix86_comparison_operator (new_op1, VOIDmode))
10724     FAIL;
10725 })
10726
10727 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10728 ;; subsequent logical operations are used to imitate conditional moves.
10729 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10730 ;; it directly.
10731
10732 (define_insn "setcc_<mode>_sse"
10733   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10734         (match_operator:MODEF 3 "sse_comparison_operator"
10735           [(match_operand:MODEF 1 "register_operand" "0,x")
10736            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10737   "SSE_FLOAT_MODE_P (<MODE>mode)"
10738   "@
10739    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10740    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10741   [(set_attr "isa" "noavx,avx")
10742    (set_attr "type" "ssecmp")
10743    (set_attr "length_immediate" "1")
10744    (set_attr "prefix" "orig,vex")
10745    (set_attr "mode" "<MODE>")])
10746 \f
10747 ;; Basic conditional jump instructions.
10748 ;; We ignore the overflow flag for signed branch instructions.
10749
10750 (define_insn "*jcc_1"
10751   [(set (pc)
10752         (if_then_else (match_operator 1 "ix86_comparison_operator"
10753                                       [(reg FLAGS_REG) (const_int 0)])
10754                       (label_ref (match_operand 0 "" ""))
10755                       (pc)))]
10756   ""
10757   "%+j%C1\t%l0"
10758   [(set_attr "type" "ibr")
10759    (set_attr "modrm" "0")
10760    (set (attr "length")
10761            (if_then_else (and (ge (minus (match_dup 0) (pc))
10762                                   (const_int -126))
10763                               (lt (minus (match_dup 0) (pc))
10764                                   (const_int 128)))
10765              (const_int 2)
10766              (const_int 6)))])
10767
10768 (define_insn "*jcc_2"
10769   [(set (pc)
10770         (if_then_else (match_operator 1 "ix86_comparison_operator"
10771                                       [(reg FLAGS_REG) (const_int 0)])
10772                       (pc)
10773                       (label_ref (match_operand 0 "" ""))))]
10774   ""
10775   "%+j%c1\t%l0"
10776   [(set_attr "type" "ibr")
10777    (set_attr "modrm" "0")
10778    (set (attr "length")
10779            (if_then_else (and (ge (minus (match_dup 0) (pc))
10780                                   (const_int -126))
10781                               (lt (minus (match_dup 0) (pc))
10782                                   (const_int 128)))
10783              (const_int 2)
10784              (const_int 6)))])
10785
10786 ;; In general it is not safe to assume too much about CCmode registers,
10787 ;; so simplify-rtx stops when it sees a second one.  Under certain
10788 ;; conditions this is safe on x86, so help combine not create
10789 ;;
10790 ;;      seta    %al
10791 ;;      testb   %al, %al
10792 ;;      je      Lfoo
10793
10794 (define_split
10795   [(set (pc)
10796         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10797                                       [(reg FLAGS_REG) (const_int 0)])
10798                           (const_int 0))
10799                       (label_ref (match_operand 1 "" ""))
10800                       (pc)))]
10801   ""
10802   [(set (pc)
10803         (if_then_else (match_dup 0)
10804                       (label_ref (match_dup 1))
10805                       (pc)))]
10806   "PUT_MODE (operands[0], VOIDmode);")
10807
10808 (define_split
10809   [(set (pc)
10810         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10811                                       [(reg FLAGS_REG) (const_int 0)])
10812                           (const_int 0))
10813                       (label_ref (match_operand 1 "" ""))
10814                       (pc)))]
10815   ""
10816   [(set (pc)
10817         (if_then_else (match_dup 0)
10818                       (label_ref (match_dup 1))
10819                       (pc)))]
10820 {
10821   rtx new_op0 = copy_rtx (operands[0]);
10822   operands[0] = new_op0;
10823   PUT_MODE (new_op0, VOIDmode);
10824   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10825                                              GET_MODE (XEXP (new_op0, 0))));
10826
10827   /* Make sure that (a) the CCmode we have for the flags is strong
10828      enough for the reversed compare or (b) we have a valid FP compare.  */
10829   if (! ix86_comparison_operator (new_op0, VOIDmode))
10830     FAIL;
10831 })
10832
10833 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10834 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10835 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10836 ;; appropriate modulo of the bit offset value.
10837
10838 (define_insn_and_split "*jcc_bt<mode>"
10839   [(set (pc)
10840         (if_then_else (match_operator 0 "bt_comparison_operator"
10841                         [(zero_extract:SWI48
10842                            (match_operand:SWI48 1 "register_operand" "r")
10843                            (const_int 1)
10844                            (zero_extend:SI
10845                              (match_operand:QI 2 "register_operand" "r")))
10846                          (const_int 0)])
10847                       (label_ref (match_operand 3 "" ""))
10848                       (pc)))
10849    (clobber (reg:CC FLAGS_REG))]
10850   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10851   "#"
10852   "&& 1"
10853   [(set (reg:CCC FLAGS_REG)
10854         (compare:CCC
10855           (zero_extract:SWI48
10856             (match_dup 1)
10857             (const_int 1)
10858             (match_dup 2))
10859           (const_int 0)))
10860    (set (pc)
10861         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10862                       (label_ref (match_dup 3))
10863                       (pc)))]
10864 {
10865   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10866
10867   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10868 })
10869
10870 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10871 ;; also for DImode, this is what combine produces.
10872 (define_insn_and_split "*jcc_bt<mode>_mask"
10873   [(set (pc)
10874         (if_then_else (match_operator 0 "bt_comparison_operator"
10875                         [(zero_extract:SWI48
10876                            (match_operand:SWI48 1 "register_operand" "r")
10877                            (const_int 1)
10878                            (and:SI
10879                              (match_operand:SI 2 "register_operand" "r")
10880                              (match_operand:SI 3 "const_int_operand" "n")))])
10881                       (label_ref (match_operand 4 "" ""))
10882                       (pc)))
10883    (clobber (reg:CC FLAGS_REG))]
10884   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10885    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10886       == GET_MODE_BITSIZE (<MODE>mode)-1"
10887   "#"
10888   "&& 1"
10889   [(set (reg:CCC FLAGS_REG)
10890         (compare:CCC
10891           (zero_extract:SWI48
10892             (match_dup 1)
10893             (const_int 1)
10894             (match_dup 2))
10895           (const_int 0)))
10896    (set (pc)
10897         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10898                       (label_ref (match_dup 4))
10899                       (pc)))]
10900 {
10901   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10902
10903   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10904 })
10905
10906 (define_insn_and_split "*jcc_btsi_1"
10907   [(set (pc)
10908         (if_then_else (match_operator 0 "bt_comparison_operator"
10909                         [(and:SI
10910                            (lshiftrt:SI
10911                              (match_operand:SI 1 "register_operand" "r")
10912                              (match_operand:QI 2 "register_operand" "r"))
10913                            (const_int 1))
10914                          (const_int 0)])
10915                       (label_ref (match_operand 3 "" ""))
10916                       (pc)))
10917    (clobber (reg:CC FLAGS_REG))]
10918   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10919   "#"
10920   "&& 1"
10921   [(set (reg:CCC FLAGS_REG)
10922         (compare:CCC
10923           (zero_extract:SI
10924             (match_dup 1)
10925             (const_int 1)
10926             (match_dup 2))
10927           (const_int 0)))
10928    (set (pc)
10929         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10930                       (label_ref (match_dup 3))
10931                       (pc)))]
10932 {
10933   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10934
10935   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10936 })
10937
10938 ;; avoid useless masking of bit offset operand
10939 (define_insn_and_split "*jcc_btsi_mask_1"
10940   [(set (pc)
10941         (if_then_else
10942           (match_operator 0 "bt_comparison_operator"
10943             [(and:SI
10944                (lshiftrt:SI
10945                  (match_operand:SI 1 "register_operand" "r")
10946                  (subreg:QI
10947                    (and:SI
10948                      (match_operand:SI 2 "register_operand" "r")
10949                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10950                (const_int 1))
10951              (const_int 0)])
10952           (label_ref (match_operand 4 "" ""))
10953           (pc)))
10954    (clobber (reg:CC FLAGS_REG))]
10955   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10956    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10957   "#"
10958   "&& 1"
10959   [(set (reg:CCC FLAGS_REG)
10960         (compare:CCC
10961           (zero_extract:SI
10962             (match_dup 1)
10963             (const_int 1)
10964             (match_dup 2))
10965           (const_int 0)))
10966    (set (pc)
10967         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10968                       (label_ref (match_dup 4))
10969                       (pc)))]
10970   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10971
10972 ;; Define combination compare-and-branch fp compare instructions to help
10973 ;; combine.
10974
10975 (define_insn "*fp_jcc_1_387"
10976   [(set (pc)
10977         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10978                         [(match_operand 1 "register_operand" "f")
10979                          (match_operand 2 "nonimmediate_operand" "fm")])
10980           (label_ref (match_operand 3 "" ""))
10981           (pc)))
10982    (clobber (reg:CCFP FPSR_REG))
10983    (clobber (reg:CCFP FLAGS_REG))
10984    (clobber (match_scratch:HI 4 "=a"))]
10985   "TARGET_80387
10986    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10987    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10988    && SELECT_CC_MODE (GET_CODE (operands[0]),
10989                       operands[1], operands[2]) == CCFPmode
10990    && !TARGET_CMOVE"
10991   "#")
10992
10993 (define_insn "*fp_jcc_1r_387"
10994   [(set (pc)
10995         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10996                         [(match_operand 1 "register_operand" "f")
10997                          (match_operand 2 "nonimmediate_operand" "fm")])
10998           (pc)
10999           (label_ref (match_operand 3 "" ""))))
11000    (clobber (reg:CCFP FPSR_REG))
11001    (clobber (reg:CCFP FLAGS_REG))
11002    (clobber (match_scratch:HI 4 "=a"))]
11003   "TARGET_80387
11004    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11005    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11006    && SELECT_CC_MODE (GET_CODE (operands[0]),
11007                       operands[1], operands[2]) == CCFPmode
11008    && !TARGET_CMOVE"
11009   "#")
11010
11011 (define_insn "*fp_jcc_2_387"
11012   [(set (pc)
11013         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11014                         [(match_operand 1 "register_operand" "f")
11015                          (match_operand 2 "register_operand" "f")])
11016           (label_ref (match_operand 3 "" ""))
11017           (pc)))
11018    (clobber (reg:CCFP FPSR_REG))
11019    (clobber (reg:CCFP FLAGS_REG))
11020    (clobber (match_scratch:HI 4 "=a"))]
11021   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11022    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11023    && !TARGET_CMOVE"
11024   "#")
11025
11026 (define_insn "*fp_jcc_2r_387"
11027   [(set (pc)
11028         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11029                         [(match_operand 1 "register_operand" "f")
11030                          (match_operand 2 "register_operand" "f")])
11031           (pc)
11032           (label_ref (match_operand 3 "" ""))))
11033    (clobber (reg:CCFP FPSR_REG))
11034    (clobber (reg:CCFP FLAGS_REG))
11035    (clobber (match_scratch:HI 4 "=a"))]
11036   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11037    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11038    && !TARGET_CMOVE"
11039   "#")
11040
11041 (define_insn "*fp_jcc_3_387"
11042   [(set (pc)
11043         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11044                         [(match_operand 1 "register_operand" "f")
11045                          (match_operand 2 "const0_operand" "")])
11046           (label_ref (match_operand 3 "" ""))
11047           (pc)))
11048    (clobber (reg:CCFP FPSR_REG))
11049    (clobber (reg:CCFP FLAGS_REG))
11050    (clobber (match_scratch:HI 4 "=a"))]
11051   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11052    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11053    && SELECT_CC_MODE (GET_CODE (operands[0]),
11054                       operands[1], operands[2]) == CCFPmode
11055    && !TARGET_CMOVE"
11056   "#")
11057
11058 (define_split
11059   [(set (pc)
11060         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11061                         [(match_operand 1 "register_operand" "")
11062                          (match_operand 2 "nonimmediate_operand" "")])
11063           (match_operand 3 "" "")
11064           (match_operand 4 "" "")))
11065    (clobber (reg:CCFP FPSR_REG))
11066    (clobber (reg:CCFP FLAGS_REG))]
11067   "reload_completed"
11068   [(const_int 0)]
11069 {
11070   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11071                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11072   DONE;
11073 })
11074
11075 (define_split
11076   [(set (pc)
11077         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11078                         [(match_operand 1 "register_operand" "")
11079                          (match_operand 2 "general_operand" "")])
11080           (match_operand 3 "" "")
11081           (match_operand 4 "" "")))
11082    (clobber (reg:CCFP FPSR_REG))
11083    (clobber (reg:CCFP FLAGS_REG))
11084    (clobber (match_scratch:HI 5 "=a"))]
11085   "reload_completed"
11086   [(const_int 0)]
11087 {
11088   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11089                         operands[3], operands[4], operands[5], NULL_RTX);
11090   DONE;
11091 })
11092
11093 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11094 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11095 ;; with a precedence over other operators and is always put in the first
11096 ;; place. Swap condition and operands to match ficom instruction.
11097
11098 (define_insn "*fp_jcc_4_<mode>_387"
11099   [(set (pc)
11100         (if_then_else
11101           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11102             [(match_operator 1 "float_operator"
11103               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11104              (match_operand 3 "register_operand" "f,f")])
11105           (label_ref (match_operand 4 "" ""))
11106           (pc)))
11107    (clobber (reg:CCFP FPSR_REG))
11108    (clobber (reg:CCFP FLAGS_REG))
11109    (clobber (match_scratch:HI 5 "=a,a"))]
11110   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11111    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11112    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11113    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11114    && !TARGET_CMOVE"
11115   "#")
11116
11117 (define_split
11118   [(set (pc)
11119         (if_then_else
11120           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11121             [(match_operator 1 "float_operator"
11122               [(match_operand:SWI24 2 "memory_operand" "")])
11123              (match_operand 3 "register_operand" "")])
11124           (match_operand 4 "" "")
11125           (match_operand 5 "" "")))
11126    (clobber (reg:CCFP FPSR_REG))
11127    (clobber (reg:CCFP FLAGS_REG))
11128    (clobber (match_scratch:HI 6 "=a"))]
11129   "reload_completed"
11130   [(const_int 0)]
11131 {
11132   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11133
11134   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11135                         operands[3], operands[7],
11136                         operands[4], operands[5], operands[6], NULL_RTX);
11137   DONE;
11138 })
11139
11140 ;; %%% Kill this when reload knows how to do it.
11141 (define_split
11142   [(set (pc)
11143         (if_then_else
11144           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11145             [(match_operator 1 "float_operator"
11146               [(match_operand:SWI24 2 "register_operand" "")])
11147              (match_operand 3 "register_operand" "")])
11148           (match_operand 4 "" "")
11149           (match_operand 5 "" "")))
11150    (clobber (reg:CCFP FPSR_REG))
11151    (clobber (reg:CCFP FLAGS_REG))
11152    (clobber (match_scratch:HI 6 "=a"))]
11153   "reload_completed"
11154   [(const_int 0)]
11155 {
11156   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11157   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11158
11159   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11160                         operands[3], operands[7],
11161                         operands[4], operands[5], operands[6], operands[2]);
11162   DONE;
11163 })
11164 \f
11165 ;; Unconditional and other jump instructions
11166
11167 (define_insn "jump"
11168   [(set (pc)
11169         (label_ref (match_operand 0 "" "")))]
11170   ""
11171   "jmp\t%l0"
11172   [(set_attr "type" "ibr")
11173    (set (attr "length")
11174            (if_then_else (and (ge (minus (match_dup 0) (pc))
11175                                   (const_int -126))
11176                               (lt (minus (match_dup 0) (pc))
11177                                   (const_int 128)))
11178              (const_int 2)
11179              (const_int 5)))
11180    (set_attr "modrm" "0")])
11181
11182 (define_expand "indirect_jump"
11183   [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11184
11185 (define_insn "*indirect_jump"
11186   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11187   ""
11188   "jmp\t%A0"
11189   [(set_attr "type" "ibr")
11190    (set_attr "length_immediate" "0")])
11191
11192 (define_expand "tablejump"
11193   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11194               (use (label_ref (match_operand 1 "" "")))])]
11195   ""
11196 {
11197   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11198      relative.  Convert the relative address to an absolute address.  */
11199   if (flag_pic)
11200     {
11201       rtx op0, op1;
11202       enum rtx_code code;
11203
11204       /* We can't use @GOTOFF for text labels on VxWorks;
11205          see gotoff_operand.  */
11206       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11207         {
11208           code = PLUS;
11209           op0 = operands[0];
11210           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11211         }
11212       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11213         {
11214           code = PLUS;
11215           op0 = operands[0];
11216           op1 = pic_offset_table_rtx;
11217         }
11218       else
11219         {
11220           code = MINUS;
11221           op0 = pic_offset_table_rtx;
11222           op1 = operands[0];
11223         }
11224
11225       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11226                                          OPTAB_DIRECT);
11227     }
11228   else if (TARGET_X32)
11229     operands[0] = convert_memory_address (Pmode, operands[0]);
11230 })
11231
11232 (define_insn "*tablejump_1"
11233   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11234    (use (label_ref (match_operand 1 "" "")))]
11235   ""
11236   "jmp\t%A0"
11237   [(set_attr "type" "ibr")
11238    (set_attr "length_immediate" "0")])
11239 \f
11240 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11241
11242 (define_peephole2
11243   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11244    (set (match_operand:QI 1 "register_operand" "")
11245         (match_operator:QI 2 "ix86_comparison_operator"
11246           [(reg FLAGS_REG) (const_int 0)]))
11247    (set (match_operand 3 "q_regs_operand" "")
11248         (zero_extend (match_dup 1)))]
11249   "(peep2_reg_dead_p (3, operands[1])
11250     || operands_match_p (operands[1], operands[3]))
11251    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11252   [(set (match_dup 4) (match_dup 0))
11253    (set (strict_low_part (match_dup 5))
11254         (match_dup 2))]
11255 {
11256   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11257   operands[5] = gen_lowpart (QImode, operands[3]);
11258   ix86_expand_clear (operands[3]);
11259 })
11260
11261 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11262
11263 (define_peephole2
11264   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11265    (set (match_operand:QI 1 "register_operand" "")
11266         (match_operator:QI 2 "ix86_comparison_operator"
11267           [(reg FLAGS_REG) (const_int 0)]))
11268    (parallel [(set (match_operand 3 "q_regs_operand" "")
11269                    (zero_extend (match_dup 1)))
11270               (clobber (reg:CC FLAGS_REG))])]
11271   "(peep2_reg_dead_p (3, operands[1])
11272     || operands_match_p (operands[1], operands[3]))
11273    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11274   [(set (match_dup 4) (match_dup 0))
11275    (set (strict_low_part (match_dup 5))
11276         (match_dup 2))]
11277 {
11278   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11279   operands[5] = gen_lowpart (QImode, operands[3]);
11280   ix86_expand_clear (operands[3]);
11281 })
11282 \f
11283 ;; Call instructions.
11284
11285 ;; The predicates normally associated with named expanders are not properly
11286 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11287 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11288
11289 ;; P6 processors will jump to the address after the decrement when %esp
11290 ;; is used as a call operand, so they will execute return address as a code.
11291 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11292
11293 ;; Register constraint for call instruction.
11294 (define_mode_attr c [(SI "l") (DI "r")])
11295
11296 ;; Call subroutine returning no value.
11297
11298 (define_expand "call"
11299   [(call (match_operand:QI 0 "" "")
11300          (match_operand 1 "" ""))
11301    (use (match_operand 2 "" ""))]
11302   ""
11303 {
11304   ix86_expand_call (NULL, operands[0], operands[1],
11305                     operands[2], NULL, false);
11306   DONE;
11307 })
11308
11309 (define_expand "sibcall"
11310   [(call (match_operand:QI 0 "" "")
11311          (match_operand 1 "" ""))
11312    (use (match_operand 2 "" ""))]
11313   ""
11314 {
11315   ix86_expand_call (NULL, operands[0], operands[1],
11316                     operands[2], NULL, true);
11317   DONE;
11318 })
11319
11320 (define_insn_and_split "*call_vzeroupper"
11321   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11322          (match_operand 1 "" ""))
11323    (unspec [(match_operand 2 "const_int_operand" "")]
11324            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11325   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11326   "#"
11327   "&& reload_completed"
11328   [(const_int 0)]
11329   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11330   [(set_attr "type" "call")])
11331
11332 (define_insn "*call"
11333   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11334          (match_operand 1 "" ""))]
11335   "!SIBLING_CALL_P (insn)"
11336   "* return ix86_output_call_insn (insn, operands[0]);"
11337   [(set_attr "type" "call")])
11338
11339 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11340   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11341          (match_operand 1 "" ""))
11342    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11343    (clobber (reg:TI XMM6_REG))
11344    (clobber (reg:TI XMM7_REG))
11345    (clobber (reg:TI XMM8_REG))
11346    (clobber (reg:TI XMM9_REG))
11347    (clobber (reg:TI XMM10_REG))
11348    (clobber (reg:TI XMM11_REG))
11349    (clobber (reg:TI XMM12_REG))
11350    (clobber (reg:TI XMM13_REG))
11351    (clobber (reg:TI XMM14_REG))
11352    (clobber (reg:TI XMM15_REG))
11353    (clobber (reg:DI SI_REG))
11354    (clobber (reg:DI DI_REG))
11355    (unspec [(match_operand 2 "const_int_operand" "")]
11356            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11357   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11358   "#"
11359   "&& reload_completed"
11360   [(const_int 0)]
11361   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11362   [(set_attr "type" "call")])
11363
11364 (define_insn "*call_rex64_ms_sysv"
11365   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11366          (match_operand 1 "" ""))
11367    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11368    (clobber (reg:TI XMM6_REG))
11369    (clobber (reg:TI XMM7_REG))
11370    (clobber (reg:TI XMM8_REG))
11371    (clobber (reg:TI XMM9_REG))
11372    (clobber (reg:TI XMM10_REG))
11373    (clobber (reg:TI XMM11_REG))
11374    (clobber (reg:TI XMM12_REG))
11375    (clobber (reg:TI XMM13_REG))
11376    (clobber (reg:TI XMM14_REG))
11377    (clobber (reg:TI XMM15_REG))
11378    (clobber (reg:DI SI_REG))
11379    (clobber (reg:DI DI_REG))]
11380   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11381   "* return ix86_output_call_insn (insn, operands[0]);"
11382   [(set_attr "type" "call")])
11383
11384 (define_insn_and_split "*sibcall_vzeroupper"
11385   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11386          (match_operand 1 "" ""))
11387    (unspec [(match_operand 2 "const_int_operand" "")]
11388            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11389   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11390   "#"
11391   "&& reload_completed"
11392   [(const_int 0)]
11393   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11394   [(set_attr "type" "call")])
11395
11396 (define_insn "*sibcall"
11397   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11398          (match_operand 1 "" ""))]
11399   "SIBLING_CALL_P (insn)"
11400   "* return ix86_output_call_insn (insn, operands[0]);"
11401   [(set_attr "type" "call")])
11402
11403 (define_expand "call_pop"
11404   [(parallel [(call (match_operand:QI 0 "" "")
11405                     (match_operand:SI 1 "" ""))
11406               (set (reg:SI SP_REG)
11407                    (plus:SI (reg:SI SP_REG)
11408                             (match_operand:SI 3 "" "")))])]
11409   "!TARGET_64BIT"
11410 {
11411   ix86_expand_call (NULL, operands[0], operands[1],
11412                     operands[2], operands[3], false);
11413   DONE;
11414 })
11415
11416 (define_insn_and_split "*call_pop_vzeroupper"
11417   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11418          (match_operand:SI 1 "" ""))
11419    (set (reg:SI SP_REG)
11420         (plus:SI (reg:SI SP_REG)
11421                  (match_operand:SI 2 "immediate_operand" "i")))
11422    (unspec [(match_operand 3 "const_int_operand" "")]
11423            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11424   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11425   "#"
11426   "&& reload_completed"
11427   [(const_int 0)]
11428   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11429   [(set_attr "type" "call")])
11430
11431 (define_insn "*call_pop"
11432   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11433          (match_operand 1 "" ""))
11434    (set (reg:SI SP_REG)
11435         (plus:SI (reg:SI SP_REG)
11436                  (match_operand:SI 2 "immediate_operand" "i")))]
11437   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11438   "* return ix86_output_call_insn (insn, operands[0]);"
11439   [(set_attr "type" "call")])
11440
11441 (define_insn_and_split "*sibcall_pop_vzeroupper"
11442   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11443          (match_operand 1 "" ""))
11444    (set (reg:SI SP_REG)
11445         (plus:SI (reg:SI SP_REG)
11446                  (match_operand:SI 2 "immediate_operand" "i")))
11447    (unspec [(match_operand 3 "const_int_operand" "")]
11448            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11449   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11450   "#"
11451   "&& reload_completed"
11452   [(const_int 0)]
11453   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11454   [(set_attr "type" "call")])
11455
11456 (define_insn "*sibcall_pop"
11457   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11458          (match_operand 1 "" ""))
11459    (set (reg:SI SP_REG)
11460         (plus:SI (reg:SI SP_REG)
11461                  (match_operand:SI 2 "immediate_operand" "i")))]
11462   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11463   "* return ix86_output_call_insn (insn, operands[0]);"
11464   [(set_attr "type" "call")])
11465
11466 ;; Call subroutine, returning value in operand 0
11467
11468 (define_expand "call_value"
11469   [(set (match_operand 0 "" "")
11470         (call (match_operand:QI 1 "" "")
11471               (match_operand 2 "" "")))
11472    (use (match_operand 3 "" ""))]
11473   ""
11474 {
11475   ix86_expand_call (operands[0], operands[1], operands[2],
11476                     operands[3], NULL, false);
11477   DONE;
11478 })
11479
11480 (define_expand "sibcall_value"
11481   [(set (match_operand 0 "" "")
11482         (call (match_operand:QI 1 "" "")
11483               (match_operand 2 "" "")))
11484    (use (match_operand 3 "" ""))]
11485   ""
11486 {
11487   ix86_expand_call (operands[0], operands[1], operands[2],
11488                     operands[3], NULL, true);
11489   DONE;
11490 })
11491
11492 (define_insn_and_split "*call_value_vzeroupper"
11493   [(set (match_operand 0 "" "")
11494         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11495               (match_operand 2 "" "")))
11496    (unspec [(match_operand 3 "const_int_operand" "")]
11497            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11498   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11499   "#"
11500   "&& reload_completed"
11501   [(const_int 0)]
11502   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11503   [(set_attr "type" "callv")])
11504
11505 (define_insn "*call_value"
11506   [(set (match_operand 0 "" "")
11507         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11508               (match_operand 2 "" "")))]
11509   "!SIBLING_CALL_P (insn)"
11510   "* return ix86_output_call_insn (insn, operands[1]);"
11511   [(set_attr "type" "callv")])
11512
11513 (define_insn_and_split "*sibcall_value_vzeroupper"
11514   [(set (match_operand 0 "" "")
11515         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11516               (match_operand 2 "" "")))
11517    (unspec [(match_operand 3 "const_int_operand" "")]
11518            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11519   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11520   "#"
11521   "&& reload_completed"
11522   [(const_int 0)]
11523   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11524   [(set_attr "type" "callv")])
11525
11526 (define_insn "*sibcall_value"
11527   [(set (match_operand 0 "" "")
11528         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11529               (match_operand 2 "" "")))]
11530   "SIBLING_CALL_P (insn)"
11531   "* return ix86_output_call_insn (insn, operands[1]);"
11532   [(set_attr "type" "callv")])
11533
11534 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11535   [(set (match_operand 0 "" "")
11536         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11537               (match_operand 2 "" "")))
11538    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11539    (clobber (reg:TI XMM6_REG))
11540    (clobber (reg:TI XMM7_REG))
11541    (clobber (reg:TI XMM8_REG))
11542    (clobber (reg:TI XMM9_REG))
11543    (clobber (reg:TI XMM10_REG))
11544    (clobber (reg:TI XMM11_REG))
11545    (clobber (reg:TI XMM12_REG))
11546    (clobber (reg:TI XMM13_REG))
11547    (clobber (reg:TI XMM14_REG))
11548    (clobber (reg:TI XMM15_REG))
11549    (clobber (reg:DI SI_REG))
11550    (clobber (reg:DI DI_REG))
11551    (unspec [(match_operand 3 "const_int_operand" "")]
11552            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11553   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11554   "#"
11555   "&& reload_completed"
11556   [(const_int 0)]
11557   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11558   [(set_attr "type" "callv")])
11559
11560 (define_insn "*call_value_rex64_ms_sysv"
11561   [(set (match_operand 0 "" "")
11562         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11563               (match_operand 2 "" "")))
11564    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11565    (clobber (reg:TI XMM6_REG))
11566    (clobber (reg:TI XMM7_REG))
11567    (clobber (reg:TI XMM8_REG))
11568    (clobber (reg:TI XMM9_REG))
11569    (clobber (reg:TI XMM10_REG))
11570    (clobber (reg:TI XMM11_REG))
11571    (clobber (reg:TI XMM12_REG))
11572    (clobber (reg:TI XMM13_REG))
11573    (clobber (reg:TI XMM14_REG))
11574    (clobber (reg:TI XMM15_REG))
11575    (clobber (reg:DI SI_REG))
11576    (clobber (reg:DI DI_REG))]
11577   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11578   "* return ix86_output_call_insn (insn, operands[1]);"
11579   [(set_attr "type" "callv")])
11580
11581 (define_expand "call_value_pop"
11582   [(parallel [(set (match_operand 0 "" "")
11583                    (call (match_operand:QI 1 "" "")
11584                          (match_operand:SI 2 "" "")))
11585               (set (reg:SI SP_REG)
11586                    (plus:SI (reg:SI SP_REG)
11587                             (match_operand:SI 4 "" "")))])]
11588   "!TARGET_64BIT"
11589 {
11590   ix86_expand_call (operands[0], operands[1], operands[2],
11591                     operands[3], operands[4], false);
11592   DONE;
11593 })
11594
11595 (define_insn_and_split "*call_value_pop_vzeroupper"
11596   [(set (match_operand 0 "" "")
11597         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11598               (match_operand 2 "" "")))
11599    (set (reg:SI SP_REG)
11600         (plus:SI (reg:SI SP_REG)
11601                  (match_operand:SI 3 "immediate_operand" "i")))
11602    (unspec [(match_operand 4 "const_int_operand" "")]
11603            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11604   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11605   "#"
11606   "&& reload_completed"
11607   [(const_int 0)]
11608   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11609   [(set_attr "type" "callv")])
11610
11611 (define_insn "*call_value_pop"
11612   [(set (match_operand 0 "" "")
11613         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11614               (match_operand 2 "" "")))
11615    (set (reg:SI SP_REG)
11616         (plus:SI (reg:SI SP_REG)
11617                  (match_operand:SI 3 "immediate_operand" "i")))]
11618   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11619   "* return ix86_output_call_insn (insn, operands[1]);"
11620   [(set_attr "type" "callv")])
11621
11622 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11623   [(set (match_operand 0 "" "")
11624         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11625               (match_operand 2 "" "")))
11626    (set (reg:SI SP_REG)
11627         (plus:SI (reg:SI SP_REG)
11628                  (match_operand:SI 3 "immediate_operand" "i")))
11629    (unspec [(match_operand 4 "const_int_operand" "")]
11630            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11631   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11632   "#"
11633   "&& reload_completed"
11634   [(const_int 0)]
11635   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11636   [(set_attr "type" "callv")])
11637
11638 (define_insn "*sibcall_value_pop"
11639   [(set (match_operand 0 "" "")
11640         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11641               (match_operand 2 "" "")))
11642    (set (reg:SI SP_REG)
11643         (plus:SI (reg:SI SP_REG)
11644                  (match_operand:SI 3 "immediate_operand" "i")))]
11645   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11646   "* return ix86_output_call_insn (insn, operands[1]);"
11647   [(set_attr "type" "callv")])
11648
11649 ;; Call subroutine returning any type.
11650
11651 (define_expand "untyped_call"
11652   [(parallel [(call (match_operand 0 "" "")
11653                     (const_int 0))
11654               (match_operand 1 "" "")
11655               (match_operand 2 "" "")])]
11656   ""
11657 {
11658   int i;
11659
11660   /* In order to give reg-stack an easier job in validating two
11661      coprocessor registers as containing a possible return value,
11662      simply pretend the untyped call returns a complex long double
11663      value. 
11664
11665      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11666      and should have the default ABI.  */
11667
11668   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11669                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11670                     operands[0], const0_rtx,
11671                     GEN_INT ((TARGET_64BIT
11672                               ? (ix86_abi == SYSV_ABI
11673                                  ? X86_64_SSE_REGPARM_MAX
11674                                  : X86_64_MS_SSE_REGPARM_MAX)
11675                               : X86_32_SSE_REGPARM_MAX)
11676                              - 1),
11677                     NULL, false);
11678
11679   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11680     {
11681       rtx set = XVECEXP (operands[2], 0, i);
11682       emit_move_insn (SET_DEST (set), SET_SRC (set));
11683     }
11684
11685   /* The optimizer does not know that the call sets the function value
11686      registers we stored in the result block.  We avoid problems by
11687      claiming that all hard registers are used and clobbered at this
11688      point.  */
11689   emit_insn (gen_blockage ());
11690
11691   DONE;
11692 })
11693 \f
11694 ;; Prologue and epilogue instructions
11695
11696 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11697 ;; all of memory.  This blocks insns from being moved across this point.
11698
11699 (define_insn "blockage"
11700   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11701   ""
11702   ""
11703   [(set_attr "length" "0")])
11704
11705 ;; Do not schedule instructions accessing memory across this point.
11706
11707 (define_expand "memory_blockage"
11708   [(set (match_dup 0)
11709         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11710   ""
11711 {
11712   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11713   MEM_VOLATILE_P (operands[0]) = 1;
11714 })
11715
11716 (define_insn "*memory_blockage"
11717   [(set (match_operand:BLK 0 "" "")
11718         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11719   ""
11720   ""
11721   [(set_attr "length" "0")])
11722
11723 ;; As USE insns aren't meaningful after reload, this is used instead
11724 ;; to prevent deleting instructions setting registers for PIC code
11725 (define_insn "prologue_use"
11726   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11727   ""
11728   ""
11729   [(set_attr "length" "0")])
11730
11731 ;; Insn emitted into the body of a function to return from a function.
11732 ;; This is only done if the function's epilogue is known to be simple.
11733 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11734
11735 (define_expand "return"
11736   [(simple_return)]
11737   "ix86_can_use_return_insn_p ()"
11738 {
11739   ix86_maybe_emit_epilogue_vzeroupper ();
11740   if (crtl->args.pops_args)
11741     {
11742       rtx popc = GEN_INT (crtl->args.pops_args);
11743       emit_jump_insn (gen_simple_return_pop_internal (popc));
11744       DONE;
11745     }
11746 })
11747
11748 ;; We need to disable this for TARGET_SEH, as otherwise
11749 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11750 ;; the maximum size of prologue in unwind information.
11751
11752 (define_expand "simple_return"
11753   [(simple_return)]
11754   "!TARGET_SEH"
11755 {
11756   ix86_maybe_emit_epilogue_vzeroupper ();
11757   if (crtl->args.pops_args)
11758     {
11759       rtx popc = GEN_INT (crtl->args.pops_args);
11760       emit_jump_insn (gen_simple_return_pop_internal (popc));
11761       DONE;
11762     }
11763 })
11764
11765 (define_insn "simple_return_internal"
11766   [(simple_return)]
11767   "reload_completed"
11768   "ret"
11769   [(set_attr "length" "1")
11770    (set_attr "atom_unit" "jeu")
11771    (set_attr "length_immediate" "0")
11772    (set_attr "modrm" "0")])
11773
11774 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11775 ;; instruction Athlon and K8 have.
11776
11777 (define_insn "simple_return_internal_long"
11778   [(simple_return)
11779    (unspec [(const_int 0)] UNSPEC_REP)]
11780   "reload_completed"
11781   "rep\;ret"
11782   [(set_attr "length" "2")
11783    (set_attr "atom_unit" "jeu")
11784    (set_attr "length_immediate" "0")
11785    (set_attr "prefix_rep" "1")
11786    (set_attr "modrm" "0")])
11787
11788 (define_insn "simple_return_pop_internal"
11789   [(simple_return)
11790    (use (match_operand:SI 0 "const_int_operand" ""))]
11791   "reload_completed"
11792   "ret\t%0"
11793   [(set_attr "length" "3")
11794    (set_attr "atom_unit" "jeu")
11795    (set_attr "length_immediate" "2")
11796    (set_attr "modrm" "0")])
11797
11798 (define_insn "simple_return_indirect_internal"
11799   [(simple_return)
11800    (use (match_operand:SI 0 "register_operand" "r"))]
11801   "reload_completed"
11802   "jmp\t%A0"
11803   [(set_attr "type" "ibr")
11804    (set_attr "length_immediate" "0")])
11805
11806 (define_insn "nop"
11807   [(const_int 0)]
11808   ""
11809   "nop"
11810   [(set_attr "length" "1")
11811    (set_attr "length_immediate" "0")
11812    (set_attr "modrm" "0")])
11813
11814 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11815 (define_insn "nops"
11816   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11817                     UNSPECV_NOPS)]
11818   "reload_completed"
11819 {
11820   int num = INTVAL (operands[0]);
11821
11822   gcc_assert (num >= 1 && num <= 8);
11823
11824   while (num--)
11825     fputs ("\tnop\n", asm_out_file);
11826
11827   return "";
11828 }
11829   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11830    (set_attr "length_immediate" "0")
11831    (set_attr "modrm" "0")])
11832
11833 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11834 ;; branch prediction penalty for the third jump in a 16-byte
11835 ;; block on K8.
11836
11837 (define_insn "pad"
11838   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11839   ""
11840 {
11841 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11842   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11843 #else
11844   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11845      The align insn is used to avoid 3 jump instructions in the row to improve
11846      branch prediction and the benefits hardly outweigh the cost of extra 8
11847      nops on the average inserted by full alignment pseudo operation.  */
11848 #endif
11849   return "";
11850 }
11851   [(set_attr "length" "16")])
11852
11853 (define_expand "prologue"
11854   [(const_int 0)]
11855   ""
11856   "ix86_expand_prologue (); DONE;")
11857
11858 (define_insn "set_got"
11859   [(set (match_operand:SI 0 "register_operand" "=r")
11860         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11861    (clobber (reg:CC FLAGS_REG))]
11862   "!TARGET_64BIT"
11863   "* return output_set_got (operands[0], NULL_RTX);"
11864   [(set_attr "type" "multi")
11865    (set_attr "length" "12")])
11866
11867 (define_insn "set_got_labelled"
11868   [(set (match_operand:SI 0 "register_operand" "=r")
11869         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11870          UNSPEC_SET_GOT))
11871    (clobber (reg:CC FLAGS_REG))]
11872   "!TARGET_64BIT"
11873   "* return output_set_got (operands[0], operands[1]);"
11874   [(set_attr "type" "multi")
11875    (set_attr "length" "12")])
11876
11877 (define_insn "set_got_rex64"
11878   [(set (match_operand:DI 0 "register_operand" "=r")
11879         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11880   "TARGET_64BIT"
11881   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11882   [(set_attr "type" "lea")
11883    (set_attr "length_address" "4")
11884    (set_attr "mode" "DI")])
11885
11886 (define_insn "set_rip_rex64"
11887   [(set (match_operand:DI 0 "register_operand" "=r")
11888         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11889   "TARGET_64BIT"
11890   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11891   [(set_attr "type" "lea")
11892    (set_attr "length_address" "4")
11893    (set_attr "mode" "DI")])
11894
11895 (define_insn "set_got_offset_rex64"
11896   [(set (match_operand:DI 0 "register_operand" "=r")
11897         (unspec:DI
11898           [(label_ref (match_operand 1 "" ""))]
11899           UNSPEC_SET_GOT_OFFSET))]
11900   "TARGET_LP64"
11901   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11902   [(set_attr "type" "imov")
11903    (set_attr "length_immediate" "0")
11904    (set_attr "length_address" "8")
11905    (set_attr "mode" "DI")])
11906
11907 (define_expand "epilogue"
11908   [(const_int 0)]
11909   ""
11910   "ix86_expand_epilogue (1); DONE;")
11911
11912 (define_expand "sibcall_epilogue"
11913   [(const_int 0)]
11914   ""
11915   "ix86_expand_epilogue (0); DONE;")
11916
11917 (define_expand "eh_return"
11918   [(use (match_operand 0 "register_operand" ""))]
11919   ""
11920 {
11921   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11922
11923   /* Tricky bit: we write the address of the handler to which we will
11924      be returning into someone else's stack frame, one word below the
11925      stack address we wish to restore.  */
11926   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11927   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11928   tmp = gen_rtx_MEM (Pmode, tmp);
11929   emit_move_insn (tmp, ra);
11930
11931   emit_jump_insn (gen_eh_return_internal ());
11932   emit_barrier ();
11933   DONE;
11934 })
11935
11936 (define_insn_and_split "eh_return_internal"
11937   [(eh_return)]
11938   ""
11939   "#"
11940   "epilogue_completed"
11941   [(const_int 0)]
11942   "ix86_expand_epilogue (2); DONE;")
11943
11944 (define_insn "leave"
11945   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11946    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11947    (clobber (mem:BLK (scratch)))]
11948   "!TARGET_64BIT"
11949   "leave"
11950   [(set_attr "type" "leave")])
11951
11952 (define_insn "leave_rex64"
11953   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11954    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11955    (clobber (mem:BLK (scratch)))]
11956   "TARGET_64BIT"
11957   "leave"
11958   [(set_attr "type" "leave")])
11959 \f
11960 ;; Handle -fsplit-stack.
11961
11962 (define_expand "split_stack_prologue"
11963   [(const_int 0)]
11964   ""
11965 {
11966   ix86_expand_split_stack_prologue ();
11967   DONE;
11968 })
11969
11970 ;; In order to support the call/return predictor, we use a return
11971 ;; instruction which the middle-end doesn't see.
11972 (define_insn "split_stack_return"
11973   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11974                      UNSPECV_SPLIT_STACK_RETURN)]
11975   ""
11976 {
11977   if (operands[0] == const0_rtx)
11978     return "ret";
11979   else
11980     return "ret\t%0";
11981 }
11982   [(set_attr "atom_unit" "jeu")
11983    (set_attr "modrm" "0")
11984    (set (attr "length")
11985         (if_then_else (match_operand:SI 0 "const0_operand" "")
11986                       (const_int 1)
11987                       (const_int 3)))
11988    (set (attr "length_immediate")
11989         (if_then_else (match_operand:SI 0 "const0_operand" "")
11990                       (const_int 0)
11991                       (const_int 2)))])
11992
11993 ;; If there are operand 0 bytes available on the stack, jump to
11994 ;; operand 1.
11995
11996 (define_expand "split_stack_space_check"
11997   [(set (pc) (if_then_else
11998               (ltu (minus (reg SP_REG)
11999                           (match_operand 0 "register_operand" ""))
12000                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12001               (label_ref (match_operand 1 "" ""))
12002               (pc)))]
12003   ""
12004 {
12005   rtx reg, size, limit;
12006
12007   reg = gen_reg_rtx (Pmode);
12008   size = force_reg (Pmode, operands[0]);
12009   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12010   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12011                           UNSPEC_STACK_CHECK);
12012   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12013   ix86_expand_branch (GEU, reg, limit, operands[1]);
12014
12015   DONE;
12016 })
12017 \f
12018 ;; Bit manipulation instructions.
12019
12020 (define_expand "ffs<mode>2"
12021   [(set (match_dup 2) (const_int -1))
12022    (parallel [(set (reg:CCZ FLAGS_REG)
12023                    (compare:CCZ
12024                      (match_operand:SWI48 1 "nonimmediate_operand" "")
12025                      (const_int 0)))
12026               (set (match_operand:SWI48 0 "register_operand" "")
12027                    (ctz:SWI48 (match_dup 1)))])
12028    (set (match_dup 0) (if_then_else:SWI48
12029                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12030                         (match_dup 2)
12031                         (match_dup 0)))
12032    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12033               (clobber (reg:CC FLAGS_REG))])]
12034   ""
12035 {
12036   if (<MODE>mode == SImode && !TARGET_CMOVE)
12037     {
12038       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12039       DONE;
12040     }
12041   operands[2] = gen_reg_rtx (<MODE>mode);
12042 })
12043
12044 (define_insn_and_split "ffssi2_no_cmove"
12045   [(set (match_operand:SI 0 "register_operand" "=r")
12046         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12047    (clobber (match_scratch:SI 2 "=&q"))
12048    (clobber (reg:CC FLAGS_REG))]
12049   "!TARGET_CMOVE"
12050   "#"
12051   "&& reload_completed"
12052   [(parallel [(set (reg:CCZ FLAGS_REG)
12053                    (compare:CCZ (match_dup 1) (const_int 0)))
12054               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12055    (set (strict_low_part (match_dup 3))
12056         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12057    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12058               (clobber (reg:CC FLAGS_REG))])
12059    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12060               (clobber (reg:CC FLAGS_REG))])
12061    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12062               (clobber (reg:CC FLAGS_REG))])]
12063 {
12064   operands[3] = gen_lowpart (QImode, operands[2]);
12065   ix86_expand_clear (operands[2]);
12066 })
12067
12068 (define_insn "*ffs<mode>_1"
12069   [(set (reg:CCZ FLAGS_REG)
12070         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12071                      (const_int 0)))
12072    (set (match_operand:SWI48 0 "register_operand" "=r")
12073         (ctz:SWI48 (match_dup 1)))]
12074   ""
12075   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12076   [(set_attr "type" "alu1")
12077    (set_attr "prefix_0f" "1")
12078    (set_attr "mode" "<MODE>")])
12079
12080 (define_insn "ctz<mode>2"
12081   [(set (match_operand:SWI248 0 "register_operand" "=r")
12082         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12083    (clobber (reg:CC FLAGS_REG))]
12084   ""
12085 {
12086   if (TARGET_BMI)
12087     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12088   else
12089     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12090 }
12091   [(set_attr "type" "alu1")
12092    (set_attr "prefix_0f" "1")
12093    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12094    (set_attr "mode" "<MODE>")])
12095
12096 (define_expand "clz<mode>2"
12097   [(parallel
12098      [(set (match_operand:SWI248 0 "register_operand" "")
12099            (minus:SWI248
12100              (match_dup 2)
12101              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12102       (clobber (reg:CC FLAGS_REG))])
12103    (parallel
12104      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12105       (clobber (reg:CC FLAGS_REG))])]
12106   ""
12107 {
12108   if (TARGET_LZCNT)
12109     {
12110       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12111       DONE;
12112     }
12113   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12114 })
12115
12116 (define_insn "clz<mode>2_lzcnt"
12117   [(set (match_operand:SWI248 0 "register_operand" "=r")
12118         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12119    (clobber (reg:CC FLAGS_REG))]
12120   "TARGET_LZCNT"
12121   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12122   [(set_attr "prefix_rep" "1")
12123    (set_attr "type" "bitmanip")
12124    (set_attr "mode" "<MODE>")])
12125
12126 ;; BMI instructions.
12127 (define_insn "*bmi_andn_<mode>"
12128   [(set (match_operand:SWI48 0 "register_operand" "=r")
12129         (and:SWI48
12130           (not:SWI48
12131             (match_operand:SWI48 1 "register_operand" "r"))
12132             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12133    (clobber (reg:CC FLAGS_REG))]
12134   "TARGET_BMI"
12135   "andn\t{%2, %1, %0|%0, %1, %2}"
12136   [(set_attr "type" "bitmanip")
12137    (set_attr "mode" "<MODE>")])
12138
12139 (define_insn "bmi_bextr_<mode>"
12140   [(set (match_operand:SWI48 0 "register_operand" "=r")
12141         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12142                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12143                        UNSPEC_BEXTR))
12144    (clobber (reg:CC FLAGS_REG))]
12145   "TARGET_BMI"
12146   "bextr\t{%2, %1, %0|%0, %1, %2}"
12147   [(set_attr "type" "bitmanip")
12148    (set_attr "mode" "<MODE>")])
12149
12150 (define_insn "*bmi_blsi_<mode>"
12151   [(set (match_operand:SWI48 0 "register_operand" "=r")
12152         (and:SWI48
12153           (neg:SWI48
12154             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12155           (match_dup 1)))
12156    (clobber (reg:CC FLAGS_REG))]
12157   "TARGET_BMI"
12158   "blsi\t{%1, %0|%0, %1}"
12159   [(set_attr "type" "bitmanip")
12160    (set_attr "mode" "<MODE>")])
12161
12162 (define_insn "*bmi_blsmsk_<mode>"
12163   [(set (match_operand:SWI48 0 "register_operand" "=r")
12164         (xor:SWI48
12165           (plus:SWI48
12166             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12167             (const_int -1))
12168           (match_dup 1)))
12169    (clobber (reg:CC FLAGS_REG))]
12170   "TARGET_BMI"
12171   "blsmsk\t{%1, %0|%0, %1}"
12172   [(set_attr "type" "bitmanip")
12173    (set_attr "mode" "<MODE>")])
12174
12175 (define_insn "*bmi_blsr_<mode>"
12176   [(set (match_operand:SWI48 0 "register_operand" "=r")
12177         (and:SWI48
12178           (plus:SWI48
12179             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12180             (const_int -1))
12181           (match_dup 1)))
12182    (clobber (reg:CC FLAGS_REG))]
12183    "TARGET_BMI"
12184    "blsr\t{%1, %0|%0, %1}"
12185   [(set_attr "type" "bitmanip")
12186    (set_attr "mode" "<MODE>")])
12187
12188 ;; BMI2 instructions.
12189 (define_insn "bmi2_bzhi_<mode>3"
12190   [(set (match_operand:SWI48 0 "register_operand" "=r")
12191         (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12192                    (lshiftrt:SWI48 (const_int -1)
12193                                    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12194    (clobber (reg:CC FLAGS_REG))]
12195   "TARGET_BMI2"
12196   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12197   [(set_attr "type" "bitmanip")
12198    (set_attr "prefix" "vex")
12199    (set_attr "mode" "<MODE>")])
12200
12201 (define_insn "bmi2_pdep_<mode>3"
12202   [(set (match_operand:SWI48 0 "register_operand" "=r")
12203         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12204                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12205                        UNSPEC_PDEP))]
12206   "TARGET_BMI2"
12207   "pdep\t{%2, %1, %0|%0, %1, %2}"
12208   [(set_attr "type" "bitmanip")
12209    (set_attr "prefix" "vex")
12210    (set_attr "mode" "<MODE>")])
12211
12212 (define_insn "bmi2_pext_<mode>3"
12213   [(set (match_operand:SWI48 0 "register_operand" "=r")
12214         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12215                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12216                        UNSPEC_PEXT))]
12217   "TARGET_BMI2"
12218   "pext\t{%2, %1, %0|%0, %1, %2}"
12219   [(set_attr "type" "bitmanip")
12220    (set_attr "prefix" "vex")
12221    (set_attr "mode" "<MODE>")])
12222
12223 ;; TBM instructions.
12224 (define_insn "tbm_bextri_<mode>"
12225   [(set (match_operand:SWI48 0 "register_operand" "=r")
12226         (zero_extract:SWI48
12227           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12228           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12229           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12230    (clobber (reg:CC FLAGS_REG))]
12231    "TARGET_TBM"
12232 {
12233   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12234   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12235 }
12236   [(set_attr "type" "bitmanip")
12237    (set_attr "mode" "<MODE>")])
12238
12239 (define_insn "*tbm_blcfill_<mode>"
12240   [(set (match_operand:SWI48 0 "register_operand" "=r")
12241         (and:SWI48
12242           (plus:SWI48
12243             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12244             (const_int 1))
12245           (match_dup 1)))
12246    (clobber (reg:CC FLAGS_REG))]
12247    "TARGET_TBM"
12248    "blcfill\t{%1, %0|%0, %1}"
12249   [(set_attr "type" "bitmanip")
12250    (set_attr "mode" "<MODE>")])
12251
12252 (define_insn "*tbm_blci_<mode>"
12253   [(set (match_operand:SWI48 0 "register_operand" "=r")
12254         (ior:SWI48
12255           (not:SWI48
12256             (plus:SWI48
12257               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12258               (const_int 1)))
12259           (match_dup 1)))
12260    (clobber (reg:CC FLAGS_REG))]
12261    "TARGET_TBM"
12262    "blci\t{%1, %0|%0, %1}"
12263   [(set_attr "type" "bitmanip")
12264    (set_attr "mode" "<MODE>")])
12265
12266 (define_insn "*tbm_blcic_<mode>"
12267   [(set (match_operand:SWI48 0 "register_operand" "=r")
12268         (and:SWI48
12269           (plus:SWI48
12270             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12271             (const_int 1))
12272           (not:SWI48
12273             (match_dup 1))))
12274    (clobber (reg:CC FLAGS_REG))]
12275    "TARGET_TBM"
12276    "blcic\t{%1, %0|%0, %1}"
12277   [(set_attr "type" "bitmanip")
12278    (set_attr "mode" "<MODE>")])
12279
12280 (define_insn "*tbm_blcmsk_<mode>"
12281   [(set (match_operand:SWI48 0 "register_operand" "=r")
12282         (xor:SWI48
12283           (plus:SWI48
12284             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12285             (const_int 1))
12286           (match_dup 1)))
12287    (clobber (reg:CC FLAGS_REG))]
12288    "TARGET_TBM"
12289    "blcmsk\t{%1, %0|%0, %1}"
12290   [(set_attr "type" "bitmanip")
12291    (set_attr "mode" "<MODE>")])
12292
12293 (define_insn "*tbm_blcs_<mode>"
12294   [(set (match_operand:SWI48 0 "register_operand" "=r")
12295         (ior:SWI48
12296           (plus:SWI48
12297             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12298             (const_int 1))
12299           (match_dup 1)))
12300    (clobber (reg:CC FLAGS_REG))]
12301    "TARGET_TBM"
12302    "blcs\t{%1, %0|%0, %1}"
12303   [(set_attr "type" "bitmanip")
12304    (set_attr "mode" "<MODE>")])
12305
12306 (define_insn "*tbm_blsfill_<mode>"
12307   [(set (match_operand:SWI48 0 "register_operand" "=r")
12308         (ior:SWI48
12309           (plus:SWI48
12310             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12311             (const_int -1))
12312           (match_dup 1)))
12313    (clobber (reg:CC FLAGS_REG))]
12314    "TARGET_TBM"
12315    "blsfill\t{%1, %0|%0, %1}"
12316   [(set_attr "type" "bitmanip")
12317    (set_attr "mode" "<MODE>")])
12318
12319 (define_insn "*tbm_blsic_<mode>"
12320   [(set (match_operand:SWI48 0 "register_operand" "=r")
12321         (ior:SWI48
12322           (plus:SWI48
12323             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12324             (const_int -1))
12325           (not:SWI48
12326             (match_dup 1))))
12327    (clobber (reg:CC FLAGS_REG))]
12328    "TARGET_TBM"
12329    "blsic\t{%1, %0|%0, %1}"
12330   [(set_attr "type" "bitmanip")
12331    (set_attr "mode" "<MODE>")])
12332
12333 (define_insn "*tbm_t1mskc_<mode>"
12334   [(set (match_operand:SWI48 0 "register_operand" "=r")
12335         (ior:SWI48
12336           (plus:SWI48
12337             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12338             (const_int 1))
12339           (not:SWI48
12340             (match_dup 1))))
12341    (clobber (reg:CC FLAGS_REG))]
12342    "TARGET_TBM"
12343    "t1mskc\t{%1, %0|%0, %1}"
12344   [(set_attr "type" "bitmanip")
12345    (set_attr "mode" "<MODE>")])
12346
12347 (define_insn "*tbm_tzmsk_<mode>"
12348   [(set (match_operand:SWI48 0 "register_operand" "=r")
12349         (and:SWI48
12350           (plus:SWI48
12351             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12352             (const_int -1))
12353           (not:SWI48
12354             (match_dup 1))))
12355    (clobber (reg:CC FLAGS_REG))]
12356    "TARGET_TBM"
12357    "tzmsk\t{%1, %0|%0, %1}"
12358   [(set_attr "type" "bitmanip")
12359    (set_attr "mode" "<MODE>")])
12360
12361 (define_insn "bsr_rex64"
12362   [(set (match_operand:DI 0 "register_operand" "=r")
12363         (minus:DI (const_int 63)
12364                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12365    (clobber (reg:CC FLAGS_REG))]
12366   "TARGET_64BIT"
12367   "bsr{q}\t{%1, %0|%0, %1}"
12368   [(set_attr "type" "alu1")
12369    (set_attr "prefix_0f" "1")
12370    (set_attr "mode" "DI")])
12371
12372 (define_insn "bsr"
12373   [(set (match_operand:SI 0 "register_operand" "=r")
12374         (minus:SI (const_int 31)
12375                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12376    (clobber (reg:CC FLAGS_REG))]
12377   ""
12378   "bsr{l}\t{%1, %0|%0, %1}"
12379   [(set_attr "type" "alu1")
12380    (set_attr "prefix_0f" "1")
12381    (set_attr "mode" "SI")])
12382
12383 (define_insn "*bsrhi"
12384   [(set (match_operand:HI 0 "register_operand" "=r")
12385         (minus:HI (const_int 15)
12386                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12387    (clobber (reg:CC FLAGS_REG))]
12388   ""
12389   "bsr{w}\t{%1, %0|%0, %1}"
12390   [(set_attr "type" "alu1")
12391    (set_attr "prefix_0f" "1")
12392    (set_attr "mode" "HI")])
12393
12394 (define_insn "popcount<mode>2"
12395   [(set (match_operand:SWI248 0 "register_operand" "=r")
12396         (popcount:SWI248
12397           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12398    (clobber (reg:CC FLAGS_REG))]
12399   "TARGET_POPCNT"
12400 {
12401 #if TARGET_MACHO
12402   return "popcnt\t{%1, %0|%0, %1}";
12403 #else
12404   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12405 #endif
12406 }
12407   [(set_attr "prefix_rep" "1")
12408    (set_attr "type" "bitmanip")
12409    (set_attr "mode" "<MODE>")])
12410
12411 (define_insn "*popcount<mode>2_cmp"
12412   [(set (reg FLAGS_REG)
12413         (compare
12414           (popcount:SWI248
12415             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12416           (const_int 0)))
12417    (set (match_operand:SWI248 0 "register_operand" "=r")
12418         (popcount:SWI248 (match_dup 1)))]
12419   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12420 {
12421 #if TARGET_MACHO
12422   return "popcnt\t{%1, %0|%0, %1}";
12423 #else
12424   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12425 #endif
12426 }
12427   [(set_attr "prefix_rep" "1")
12428    (set_attr "type" "bitmanip")
12429    (set_attr "mode" "<MODE>")])
12430
12431 (define_insn "*popcountsi2_cmp_zext"
12432   [(set (reg FLAGS_REG)
12433         (compare
12434           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12435           (const_int 0)))
12436    (set (match_operand:DI 0 "register_operand" "=r")
12437         (zero_extend:DI(popcount:SI (match_dup 1))))]
12438   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12439 {
12440 #if TARGET_MACHO
12441   return "popcnt\t{%1, %0|%0, %1}";
12442 #else
12443   return "popcnt{l}\t{%1, %0|%0, %1}";
12444 #endif
12445 }
12446   [(set_attr "prefix_rep" "1")
12447    (set_attr "type" "bitmanip")
12448    (set_attr "mode" "SI")])
12449
12450 (define_expand "bswap<mode>2"
12451   [(set (match_operand:SWI48 0 "register_operand" "")
12452         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12453   ""
12454 {
12455   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12456     {
12457       rtx x = operands[0];
12458
12459       emit_move_insn (x, operands[1]);
12460       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12461       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12462       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12463       DONE;
12464     }
12465 })
12466
12467 (define_insn "*bswap<mode>2_movbe"
12468   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12469         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12470   "TARGET_MOVBE
12471    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12472   "@
12473     bswap\t%0
12474     movbe\t{%1, %0|%0, %1}
12475     movbe\t{%1, %0|%0, %1}"
12476   [(set_attr "type" "bitmanip,imov,imov")
12477    (set_attr "modrm" "0,1,1")
12478    (set_attr "prefix_0f" "*,1,1")
12479    (set_attr "prefix_extra" "*,1,1")
12480    (set_attr "mode" "<MODE>")])
12481
12482 (define_insn "*bswap<mode>2_1"
12483   [(set (match_operand:SWI48 0 "register_operand" "=r")
12484         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12485   "TARGET_BSWAP"
12486   "bswap\t%0"
12487   [(set_attr "type" "bitmanip")
12488    (set_attr "modrm" "0")
12489    (set_attr "mode" "<MODE>")])
12490
12491 (define_insn "*bswaphi_lowpart_1"
12492   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12493         (bswap:HI (match_dup 0)))
12494    (clobber (reg:CC FLAGS_REG))]
12495   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12496   "@
12497     xchg{b}\t{%h0, %b0|%b0, %h0}
12498     rol{w}\t{$8, %0|%0, 8}"
12499   [(set_attr "length" "2,4")
12500    (set_attr "mode" "QI,HI")])
12501
12502 (define_insn "bswaphi_lowpart"
12503   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12504         (bswap:HI (match_dup 0)))
12505    (clobber (reg:CC FLAGS_REG))]
12506   ""
12507   "rol{w}\t{$8, %0|%0, 8}"
12508   [(set_attr "length" "4")
12509    (set_attr "mode" "HI")])
12510
12511 (define_expand "paritydi2"
12512   [(set (match_operand:DI 0 "register_operand" "")
12513         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12514   "! TARGET_POPCNT"
12515 {
12516   rtx scratch = gen_reg_rtx (QImode);
12517   rtx cond;
12518
12519   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12520                                 NULL_RTX, operands[1]));
12521
12522   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12523                          gen_rtx_REG (CCmode, FLAGS_REG),
12524                          const0_rtx);
12525   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12526
12527   if (TARGET_64BIT)
12528     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12529   else
12530     {
12531       rtx tmp = gen_reg_rtx (SImode);
12532
12533       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12534       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12535     }
12536   DONE;
12537 })
12538
12539 (define_expand "paritysi2"
12540   [(set (match_operand:SI 0 "register_operand" "")
12541         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12542   "! TARGET_POPCNT"
12543 {
12544   rtx scratch = gen_reg_rtx (QImode);
12545   rtx cond;
12546
12547   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12548
12549   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12550                          gen_rtx_REG (CCmode, FLAGS_REG),
12551                          const0_rtx);
12552   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12553
12554   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12555   DONE;
12556 })
12557
12558 (define_insn_and_split "paritydi2_cmp"
12559   [(set (reg:CC FLAGS_REG)
12560         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12561                    UNSPEC_PARITY))
12562    (clobber (match_scratch:DI 0 "=r"))
12563    (clobber (match_scratch:SI 1 "=&r"))
12564    (clobber (match_scratch:HI 2 "=Q"))]
12565   "! TARGET_POPCNT"
12566   "#"
12567   "&& reload_completed"
12568   [(parallel
12569      [(set (match_dup 1)
12570            (xor:SI (match_dup 1) (match_dup 4)))
12571       (clobber (reg:CC FLAGS_REG))])
12572    (parallel
12573      [(set (reg:CC FLAGS_REG)
12574            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12575       (clobber (match_dup 1))
12576       (clobber (match_dup 2))])]
12577 {
12578   operands[4] = gen_lowpart (SImode, operands[3]);
12579
12580   if (TARGET_64BIT)
12581     {
12582       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12583       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12584     }
12585   else
12586     operands[1] = gen_highpart (SImode, operands[3]);
12587 })
12588
12589 (define_insn_and_split "paritysi2_cmp"
12590   [(set (reg:CC FLAGS_REG)
12591         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12592                    UNSPEC_PARITY))
12593    (clobber (match_scratch:SI 0 "=r"))
12594    (clobber (match_scratch:HI 1 "=&Q"))]
12595   "! TARGET_POPCNT"
12596   "#"
12597   "&& reload_completed"
12598   [(parallel
12599      [(set (match_dup 1)
12600            (xor:HI (match_dup 1) (match_dup 3)))
12601       (clobber (reg:CC FLAGS_REG))])
12602    (parallel
12603      [(set (reg:CC FLAGS_REG)
12604            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12605       (clobber (match_dup 1))])]
12606 {
12607   operands[3] = gen_lowpart (HImode, operands[2]);
12608
12609   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12610   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12611 })
12612
12613 (define_insn "*parityhi2_cmp"
12614   [(set (reg:CC FLAGS_REG)
12615         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12616                    UNSPEC_PARITY))
12617    (clobber (match_scratch:HI 0 "=Q"))]
12618   "! TARGET_POPCNT"
12619   "xor{b}\t{%h0, %b0|%b0, %h0}"
12620   [(set_attr "length" "2")
12621    (set_attr "mode" "HI")])
12622
12623 \f
12624 ;; Thread-local storage patterns for ELF.
12625 ;;
12626 ;; Note that these code sequences must appear exactly as shown
12627 ;; in order to allow linker relaxation.
12628
12629 (define_insn "*tls_global_dynamic_32_gnu"
12630   [(set (match_operand:SI 0 "register_operand" "=a")
12631         (unspec:SI
12632          [(match_operand:SI 1 "register_operand" "b")
12633           (match_operand:SI 2 "tls_symbolic_operand" "")
12634           (match_operand:SI 3 "constant_call_address_operand" "z")]
12635          UNSPEC_TLS_GD))
12636    (clobber (match_scratch:SI 4 "=d"))
12637    (clobber (match_scratch:SI 5 "=c"))
12638    (clobber (reg:CC FLAGS_REG))]
12639   "!TARGET_64BIT && TARGET_GNU_TLS"
12640 {
12641   output_asm_insn
12642     ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12643   if (TARGET_SUN_TLS)
12644 #ifdef HAVE_AS_IX86_TLSGDPLT
12645     return "call\t%a2@tlsgdplt";
12646 #else
12647     return "call\t%p3@plt";
12648 #endif
12649   return "call\t%P3";
12650 }
12651   [(set_attr "type" "multi")
12652    (set_attr "length" "12")])
12653
12654 (define_expand "tls_global_dynamic_32"
12655   [(parallel
12656     [(set (match_operand:SI 0 "register_operand" "")
12657           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12658                       (match_operand:SI 1 "tls_symbolic_operand" "")
12659                       (match_operand:SI 3 "constant_call_address_operand" "")]
12660                      UNSPEC_TLS_GD))
12661      (clobber (match_scratch:SI 4 ""))
12662      (clobber (match_scratch:SI 5 ""))
12663      (clobber (reg:CC FLAGS_REG))])])
12664
12665 (define_insn "*tls_global_dynamic_64"
12666   [(set (match_operand:DI 0 "register_operand" "=a")
12667         (call:DI
12668          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12669          (match_operand:DI 3 "" "")))
12670    (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12671               UNSPEC_TLS_GD)]
12672   "TARGET_64BIT"
12673 {
12674   if (!TARGET_X32)
12675     fputs (ASM_BYTE "0x66\n", asm_out_file);
12676   output_asm_insn
12677     ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12678   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12679   fputs ("\trex64\n", asm_out_file);
12680   if (TARGET_SUN_TLS)
12681     return "call\t%p2@plt";
12682   return "call\t%P2";
12683 }
12684   [(set_attr "type" "multi")
12685    (set (attr "length")
12686         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12687
12688 (define_expand "tls_global_dynamic_64"
12689   [(parallel
12690     [(set (match_operand:DI 0 "register_operand" "")
12691           (call:DI
12692            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12693            (const_int 0)))
12694      (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12695                 UNSPEC_TLS_GD)])])
12696
12697 (define_insn "*tls_local_dynamic_base_32_gnu"
12698   [(set (match_operand:SI 0 "register_operand" "=a")
12699         (unspec:SI
12700          [(match_operand:SI 1 "register_operand" "b")
12701           (match_operand:SI 2 "constant_call_address_operand" "z")]
12702          UNSPEC_TLS_LD_BASE))
12703    (clobber (match_scratch:SI 3 "=d"))
12704    (clobber (match_scratch:SI 4 "=c"))
12705    (clobber (reg:CC FLAGS_REG))]
12706   "!TARGET_64BIT && TARGET_GNU_TLS"
12707 {
12708   output_asm_insn
12709     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12710   if (TARGET_SUN_TLS)
12711 #ifdef HAVE_AS_IX86_TLSLDMPLT
12712     return "call\t%&@tlsldmplt";
12713 #else
12714     return "call\t%p2@plt";
12715 #endif
12716   return "call\t%P2";
12717 }
12718   [(set_attr "type" "multi")
12719    (set_attr "length" "11")])
12720
12721 (define_expand "tls_local_dynamic_base_32"
12722   [(parallel
12723      [(set (match_operand:SI 0 "register_operand" "")
12724            (unspec:SI
12725             [(match_operand:SI 1 "register_operand" "")
12726              (match_operand:SI 2 "constant_call_address_operand" "")]
12727             UNSPEC_TLS_LD_BASE))
12728       (clobber (match_scratch:SI 3 ""))
12729       (clobber (match_scratch:SI 4 ""))
12730       (clobber (reg:CC FLAGS_REG))])])
12731
12732 (define_insn "*tls_local_dynamic_base_64"
12733   [(set (match_operand:DI 0 "register_operand" "=a")
12734         (call:DI
12735          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12736          (match_operand:DI 2 "" "")))
12737    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12738   "TARGET_64BIT"
12739 {
12740   output_asm_insn
12741     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12742   if (TARGET_SUN_TLS)
12743     return "call\t%p1@plt";
12744   return "call\t%P1";
12745 }
12746   [(set_attr "type" "multi")
12747    (set_attr "length" "12")])
12748
12749 (define_expand "tls_local_dynamic_base_64"
12750   [(parallel
12751      [(set (match_operand:DI 0 "register_operand" "")
12752            (call:DI
12753             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12754             (const_int 0)))
12755       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12756
12757 ;; Local dynamic of a single variable is a lose.  Show combine how
12758 ;; to convert that back to global dynamic.
12759
12760 (define_insn_and_split "*tls_local_dynamic_32_once"
12761   [(set (match_operand:SI 0 "register_operand" "=a")
12762         (plus:SI
12763          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12764                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12765                     UNSPEC_TLS_LD_BASE)
12766          (const:SI (unspec:SI
12767                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12768                     UNSPEC_DTPOFF))))
12769    (clobber (match_scratch:SI 4 "=d"))
12770    (clobber (match_scratch:SI 5 "=c"))
12771    (clobber (reg:CC FLAGS_REG))]
12772   ""
12773   "#"
12774   ""
12775   [(parallel
12776      [(set (match_dup 0)
12777            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12778                       UNSPEC_TLS_GD))
12779       (clobber (match_dup 4))
12780       (clobber (match_dup 5))
12781       (clobber (reg:CC FLAGS_REG))])])
12782
12783 ;; Segment register for the thread base ptr load
12784 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12785
12786 ;; Load and add the thread base pointer from %<tp_seg>:0.
12787 (define_insn "*load_tp_x32"
12788   [(set (match_operand:SI 0 "register_operand" "=r")
12789         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12790   "TARGET_X32"
12791   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12792   [(set_attr "type" "imov")
12793    (set_attr "modrm" "0")
12794    (set_attr "length" "7")
12795    (set_attr "memory" "load")
12796    (set_attr "imm_disp" "false")])
12797
12798 (define_insn "*load_tp_x32_zext"
12799   [(set (match_operand:DI 0 "register_operand" "=r")
12800         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12801   "TARGET_X32"
12802   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12803   [(set_attr "type" "imov")
12804    (set_attr "modrm" "0")
12805    (set_attr "length" "7")
12806    (set_attr "memory" "load")
12807    (set_attr "imm_disp" "false")])
12808
12809 (define_insn "*load_tp_<mode>"
12810   [(set (match_operand:P 0 "register_operand" "=r")
12811         (unspec:P [(const_int 0)] UNSPEC_TP))]
12812   "!TARGET_X32"
12813   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12814   [(set_attr "type" "imov")
12815    (set_attr "modrm" "0")
12816    (set_attr "length" "7")
12817    (set_attr "memory" "load")
12818    (set_attr "imm_disp" "false")])
12819
12820 (define_insn "*add_tp_x32"
12821   [(set (match_operand:SI 0 "register_operand" "=r")
12822         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12823                  (match_operand:SI 1 "register_operand" "0")))
12824    (clobber (reg:CC FLAGS_REG))]
12825   "TARGET_X32"
12826   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12827   [(set_attr "type" "alu")
12828    (set_attr "modrm" "0")
12829    (set_attr "length" "7")
12830    (set_attr "memory" "load")
12831    (set_attr "imm_disp" "false")])
12832
12833 (define_insn "*add_tp_x32_zext"
12834   [(set (match_operand:DI 0 "register_operand" "=r")
12835         (zero_extend:DI
12836           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12837                    (match_operand:SI 1 "register_operand" "0"))))
12838    (clobber (reg:CC FLAGS_REG))]
12839   "TARGET_X32"
12840   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12841   [(set_attr "type" "alu")
12842    (set_attr "modrm" "0")
12843    (set_attr "length" "7")
12844    (set_attr "memory" "load")
12845    (set_attr "imm_disp" "false")])
12846
12847 (define_insn "*add_tp_<mode>"
12848   [(set (match_operand:P 0 "register_operand" "=r")
12849         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12850                 (match_operand:P 1 "register_operand" "0")))
12851    (clobber (reg:CC FLAGS_REG))]
12852   "!TARGET_X32"
12853   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12854   [(set_attr "type" "alu")
12855    (set_attr "modrm" "0")
12856    (set_attr "length" "7")
12857    (set_attr "memory" "load")
12858    (set_attr "imm_disp" "false")])
12859
12860 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12861 ;; %rax as destination of the initial executable code sequence.
12862 (define_insn "tls_initial_exec_64_sun"
12863   [(set (match_operand:DI 0 "register_operand" "=a")
12864         (unspec:DI
12865          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12866          UNSPEC_TLS_IE_SUN))
12867    (clobber (reg:CC FLAGS_REG))]
12868   "TARGET_64BIT && TARGET_SUN_TLS"
12869 {
12870   output_asm_insn
12871     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12872   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12873 }
12874   [(set_attr "type" "multi")])
12875
12876 ;; GNU2 TLS patterns can be split.
12877
12878 (define_expand "tls_dynamic_gnu2_32"
12879   [(set (match_dup 3)
12880         (plus:SI (match_operand:SI 2 "register_operand" "")
12881                  (const:SI
12882                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12883                              UNSPEC_TLSDESC))))
12884    (parallel
12885     [(set (match_operand:SI 0 "register_operand" "")
12886           (unspec:SI [(match_dup 1) (match_dup 3)
12887                       (match_dup 2) (reg:SI SP_REG)]
12888                       UNSPEC_TLSDESC))
12889      (clobber (reg:CC FLAGS_REG))])]
12890   "!TARGET_64BIT && TARGET_GNU2_TLS"
12891 {
12892   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12893   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12894 })
12895
12896 (define_insn "*tls_dynamic_gnu2_lea_32"
12897   [(set (match_operand:SI 0 "register_operand" "=r")
12898         (plus:SI (match_operand:SI 1 "register_operand" "b")
12899                  (const:SI
12900                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12901                               UNSPEC_TLSDESC))))]
12902   "!TARGET_64BIT && TARGET_GNU2_TLS"
12903   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12904   [(set_attr "type" "lea")
12905    (set_attr "mode" "SI")
12906    (set_attr "length" "6")
12907    (set_attr "length_address" "4")])
12908
12909 (define_insn "*tls_dynamic_gnu2_call_32"
12910   [(set (match_operand:SI 0 "register_operand" "=a")
12911         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12912                     (match_operand:SI 2 "register_operand" "0")
12913                     ;; we have to make sure %ebx still points to the GOT
12914                     (match_operand:SI 3 "register_operand" "b")
12915                     (reg:SI SP_REG)]
12916                    UNSPEC_TLSDESC))
12917    (clobber (reg:CC FLAGS_REG))]
12918   "!TARGET_64BIT && TARGET_GNU2_TLS"
12919   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12920   [(set_attr "type" "call")
12921    (set_attr "length" "2")
12922    (set_attr "length_address" "0")])
12923
12924 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12925   [(set (match_operand:SI 0 "register_operand" "=&a")
12926         (plus:SI
12927          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12928                      (match_operand:SI 4 "" "")
12929                      (match_operand:SI 2 "register_operand" "b")
12930                      (reg:SI SP_REG)]
12931                     UNSPEC_TLSDESC)
12932          (const:SI (unspec:SI
12933                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12934                     UNSPEC_DTPOFF))))
12935    (clobber (reg:CC FLAGS_REG))]
12936   "!TARGET_64BIT && TARGET_GNU2_TLS"
12937   "#"
12938   ""
12939   [(set (match_dup 0) (match_dup 5))]
12940 {
12941   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12942   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12943 })
12944
12945 (define_expand "tls_dynamic_gnu2_64"
12946   [(set (match_dup 2)
12947         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12948                    UNSPEC_TLSDESC))
12949    (parallel
12950     [(set (match_operand:DI 0 "register_operand" "")
12951           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12952                      UNSPEC_TLSDESC))
12953      (clobber (reg:CC FLAGS_REG))])]
12954   "TARGET_64BIT && TARGET_GNU2_TLS"
12955 {
12956   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12957   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12958 })
12959
12960 (define_insn "*tls_dynamic_gnu2_lea_64"
12961   [(set (match_operand:DI 0 "register_operand" "=r")
12962         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12963                    UNSPEC_TLSDESC))]
12964   "TARGET_64BIT && TARGET_GNU2_TLS"
12965   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12966   [(set_attr "type" "lea")
12967    (set_attr "mode" "DI")
12968    (set_attr "length" "7")
12969    (set_attr "length_address" "4")])
12970
12971 (define_insn "*tls_dynamic_gnu2_call_64"
12972   [(set (match_operand:DI 0 "register_operand" "=a")
12973         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12974                     (match_operand:DI 2 "register_operand" "0")
12975                     (reg:DI SP_REG)]
12976                    UNSPEC_TLSDESC))
12977    (clobber (reg:CC FLAGS_REG))]
12978   "TARGET_64BIT && TARGET_GNU2_TLS"
12979   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12980   [(set_attr "type" "call")
12981    (set_attr "length" "2")
12982    (set_attr "length_address" "0")])
12983
12984 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12985   [(set (match_operand:DI 0 "register_operand" "=&a")
12986         (plus:DI
12987          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12988                      (match_operand:DI 3 "" "")
12989                      (reg:DI SP_REG)]
12990                     UNSPEC_TLSDESC)
12991          (const:DI (unspec:DI
12992                     [(match_operand 1 "tls_symbolic_operand" "")]
12993                     UNSPEC_DTPOFF))))
12994    (clobber (reg:CC FLAGS_REG))]
12995   "TARGET_64BIT && TARGET_GNU2_TLS"
12996   "#"
12997   ""
12998   [(set (match_dup 0) (match_dup 4))]
12999 {
13000   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13001   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13002 })
13003 \f
13004 ;; These patterns match the binary 387 instructions for addM3, subM3,
13005 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13006 ;; SFmode.  The first is the normal insn, the second the same insn but
13007 ;; with one operand a conversion, and the third the same insn but with
13008 ;; the other operand a conversion.  The conversion may be SFmode or
13009 ;; SImode if the target mode DFmode, but only SImode if the target mode
13010 ;; is SFmode.
13011
13012 ;; Gcc is slightly more smart about handling normal two address instructions
13013 ;; so use special patterns for add and mull.
13014
13015 (define_insn "*fop_<mode>_comm_mixed"
13016   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13017         (match_operator:MODEF 3 "binary_fp_operator"
13018           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13019            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13020   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13021    && COMMUTATIVE_ARITH_P (operands[3])
13022    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13023   "* return output_387_binary_op (insn, operands);"
13024   [(set (attr "type")
13025         (if_then_else (eq_attr "alternative" "1,2")
13026            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13027               (const_string "ssemul")
13028               (const_string "sseadd"))
13029            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13030               (const_string "fmul")
13031               (const_string "fop"))))
13032    (set_attr "isa" "*,noavx,avx")
13033    (set_attr "prefix" "orig,orig,vex")
13034    (set_attr "mode" "<MODE>")])
13035
13036 (define_insn "*fop_<mode>_comm_sse"
13037   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13038         (match_operator:MODEF 3 "binary_fp_operator"
13039           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13040            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13041   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13042    && COMMUTATIVE_ARITH_P (operands[3])
13043    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13044   "* return output_387_binary_op (insn, operands);"
13045   [(set (attr "type")
13046         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13047            (const_string "ssemul")
13048            (const_string "sseadd")))
13049    (set_attr "isa" "noavx,avx")
13050    (set_attr "prefix" "orig,vex")
13051    (set_attr "mode" "<MODE>")])
13052
13053 (define_insn "*fop_<mode>_comm_i387"
13054   [(set (match_operand:MODEF 0 "register_operand" "=f")
13055         (match_operator:MODEF 3 "binary_fp_operator"
13056           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13057            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13058   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13059    && COMMUTATIVE_ARITH_P (operands[3])
13060    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13061   "* return output_387_binary_op (insn, operands);"
13062   [(set (attr "type")
13063         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13064            (const_string "fmul")
13065            (const_string "fop")))
13066    (set_attr "mode" "<MODE>")])
13067
13068 (define_insn "*fop_<mode>_1_mixed"
13069   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13070         (match_operator:MODEF 3 "binary_fp_operator"
13071           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13072            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13073   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13074    && !COMMUTATIVE_ARITH_P (operands[3])
13075    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13076   "* return output_387_binary_op (insn, operands);"
13077   [(set (attr "type")
13078         (cond [(and (eq_attr "alternative" "2,3")
13079                     (match_operand:MODEF 3 "mult_operator" ""))
13080                  (const_string "ssemul")
13081                (and (eq_attr "alternative" "2,3")
13082                     (match_operand:MODEF 3 "div_operator" ""))
13083                  (const_string "ssediv")
13084                (eq_attr "alternative" "2,3")
13085                  (const_string "sseadd")
13086                (match_operand:MODEF 3 "mult_operator" "")
13087                  (const_string "fmul")
13088                (match_operand:MODEF 3 "div_operator" "")
13089                  (const_string "fdiv")
13090               ]
13091               (const_string "fop")))
13092    (set_attr "isa" "*,*,noavx,avx")
13093    (set_attr "prefix" "orig,orig,orig,vex")
13094    (set_attr "mode" "<MODE>")])
13095
13096 (define_insn "*rcpsf2_sse"
13097   [(set (match_operand:SF 0 "register_operand" "=x")
13098         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13099                    UNSPEC_RCP))]
13100   "TARGET_SSE_MATH"
13101   "%vrcpss\t{%1, %d0|%d0, %1}"
13102   [(set_attr "type" "sse")
13103    (set_attr "atom_sse_attr" "rcp")
13104    (set_attr "prefix" "maybe_vex")
13105    (set_attr "mode" "SF")])
13106
13107 (define_insn "*fop_<mode>_1_sse"
13108   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13109         (match_operator:MODEF 3 "binary_fp_operator"
13110           [(match_operand:MODEF 1 "register_operand" "0,x")
13111            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13112   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13113    && !COMMUTATIVE_ARITH_P (operands[3])"
13114   "* return output_387_binary_op (insn, operands);"
13115   [(set (attr "type")
13116         (cond [(match_operand:MODEF 3 "mult_operator" "")
13117                  (const_string "ssemul")
13118                (match_operand:MODEF 3 "div_operator" "")
13119                  (const_string "ssediv")
13120               ]
13121               (const_string "sseadd")))
13122    (set_attr "isa" "noavx,avx")
13123    (set_attr "prefix" "orig,vex")
13124    (set_attr "mode" "<MODE>")])
13125
13126 ;; This pattern is not fully shadowed by the pattern above.
13127 (define_insn "*fop_<mode>_1_i387"
13128   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13129         (match_operator:MODEF 3 "binary_fp_operator"
13130           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13131            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13132   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13133    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13134    && !COMMUTATIVE_ARITH_P (operands[3])
13135    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13136   "* return output_387_binary_op (insn, operands);"
13137   [(set (attr "type")
13138         (cond [(match_operand:MODEF 3 "mult_operator" "")
13139                  (const_string "fmul")
13140                (match_operand:MODEF 3 "div_operator" "")
13141                  (const_string "fdiv")
13142               ]
13143               (const_string "fop")))
13144    (set_attr "mode" "<MODE>")])
13145
13146 ;; ??? Add SSE splitters for these!
13147 (define_insn "*fop_<MODEF:mode>_2_i387"
13148   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13149         (match_operator:MODEF 3 "binary_fp_operator"
13150           [(float:MODEF
13151              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13152            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13153   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13154    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13155    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13156   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13157   [(set (attr "type")
13158         (cond [(match_operand:MODEF 3 "mult_operator" "")
13159                  (const_string "fmul")
13160                (match_operand:MODEF 3 "div_operator" "")
13161                  (const_string "fdiv")
13162               ]
13163               (const_string "fop")))
13164    (set_attr "fp_int_src" "true")
13165    (set_attr "mode" "<SWI24:MODE>")])
13166
13167 (define_insn "*fop_<MODEF:mode>_3_i387"
13168   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13169         (match_operator:MODEF 3 "binary_fp_operator"
13170           [(match_operand:MODEF 1 "register_operand" "0,0")
13171            (float:MODEF
13172              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13173   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13174    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13175    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13176   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13177   [(set (attr "type")
13178         (cond [(match_operand:MODEF 3 "mult_operator" "")
13179                  (const_string "fmul")
13180                (match_operand:MODEF 3 "div_operator" "")
13181                  (const_string "fdiv")
13182               ]
13183               (const_string "fop")))
13184    (set_attr "fp_int_src" "true")
13185    (set_attr "mode" "<MODE>")])
13186
13187 (define_insn "*fop_df_4_i387"
13188   [(set (match_operand:DF 0 "register_operand" "=f,f")
13189         (match_operator:DF 3 "binary_fp_operator"
13190            [(float_extend:DF
13191              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13192             (match_operand:DF 2 "register_operand" "0,f")]))]
13193   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13194    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13195    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13196   "* return output_387_binary_op (insn, operands);"
13197   [(set (attr "type")
13198         (cond [(match_operand:DF 3 "mult_operator" "")
13199                  (const_string "fmul")
13200                (match_operand:DF 3 "div_operator" "")
13201                  (const_string "fdiv")
13202               ]
13203               (const_string "fop")))
13204    (set_attr "mode" "SF")])
13205
13206 (define_insn "*fop_df_5_i387"
13207   [(set (match_operand:DF 0 "register_operand" "=f,f")
13208         (match_operator:DF 3 "binary_fp_operator"
13209           [(match_operand:DF 1 "register_operand" "0,f")
13210            (float_extend:DF
13211             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13212   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13213    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13214   "* return output_387_binary_op (insn, operands);"
13215   [(set (attr "type")
13216         (cond [(match_operand:DF 3 "mult_operator" "")
13217                  (const_string "fmul")
13218                (match_operand:DF 3 "div_operator" "")
13219                  (const_string "fdiv")
13220               ]
13221               (const_string "fop")))
13222    (set_attr "mode" "SF")])
13223
13224 (define_insn "*fop_df_6_i387"
13225   [(set (match_operand:DF 0 "register_operand" "=f,f")
13226         (match_operator:DF 3 "binary_fp_operator"
13227           [(float_extend:DF
13228             (match_operand:SF 1 "register_operand" "0,f"))
13229            (float_extend:DF
13230             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13231   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13232    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13233   "* return output_387_binary_op (insn, operands);"
13234   [(set (attr "type")
13235         (cond [(match_operand:DF 3 "mult_operator" "")
13236                  (const_string "fmul")
13237                (match_operand:DF 3 "div_operator" "")
13238                  (const_string "fdiv")
13239               ]
13240               (const_string "fop")))
13241    (set_attr "mode" "SF")])
13242
13243 (define_insn "*fop_xf_comm_i387"
13244   [(set (match_operand:XF 0 "register_operand" "=f")
13245         (match_operator:XF 3 "binary_fp_operator"
13246                         [(match_operand:XF 1 "register_operand" "%0")
13247                          (match_operand:XF 2 "register_operand" "f")]))]
13248   "TARGET_80387
13249    && COMMUTATIVE_ARITH_P (operands[3])"
13250   "* return output_387_binary_op (insn, operands);"
13251   [(set (attr "type")
13252         (if_then_else (match_operand:XF 3 "mult_operator" "")
13253            (const_string "fmul")
13254            (const_string "fop")))
13255    (set_attr "mode" "XF")])
13256
13257 (define_insn "*fop_xf_1_i387"
13258   [(set (match_operand:XF 0 "register_operand" "=f,f")
13259         (match_operator:XF 3 "binary_fp_operator"
13260                         [(match_operand:XF 1 "register_operand" "0,f")
13261                          (match_operand:XF 2 "register_operand" "f,0")]))]
13262   "TARGET_80387
13263    && !COMMUTATIVE_ARITH_P (operands[3])"
13264   "* return output_387_binary_op (insn, operands);"
13265   [(set (attr "type")
13266         (cond [(match_operand:XF 3 "mult_operator" "")
13267                  (const_string "fmul")
13268                (match_operand:XF 3 "div_operator" "")
13269                  (const_string "fdiv")
13270               ]
13271               (const_string "fop")))
13272    (set_attr "mode" "XF")])
13273
13274 (define_insn "*fop_xf_2_i387"
13275   [(set (match_operand:XF 0 "register_operand" "=f,f")
13276         (match_operator:XF 3 "binary_fp_operator"
13277           [(float:XF
13278              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13279            (match_operand:XF 2 "register_operand" "0,0")]))]
13280   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13281   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13282   [(set (attr "type")
13283         (cond [(match_operand:XF 3 "mult_operator" "")
13284                  (const_string "fmul")
13285                (match_operand:XF 3 "div_operator" "")
13286                  (const_string "fdiv")
13287               ]
13288               (const_string "fop")))
13289    (set_attr "fp_int_src" "true")
13290    (set_attr "mode" "<MODE>")])
13291
13292 (define_insn "*fop_xf_3_i387"
13293   [(set (match_operand:XF 0 "register_operand" "=f,f")
13294         (match_operator:XF 3 "binary_fp_operator"
13295           [(match_operand:XF 1 "register_operand" "0,0")
13296            (float:XF
13297              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13298   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13299   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13300   [(set (attr "type")
13301         (cond [(match_operand:XF 3 "mult_operator" "")
13302                  (const_string "fmul")
13303                (match_operand:XF 3 "div_operator" "")
13304                  (const_string "fdiv")
13305               ]
13306               (const_string "fop")))
13307    (set_attr "fp_int_src" "true")
13308    (set_attr "mode" "<MODE>")])
13309
13310 (define_insn "*fop_xf_4_i387"
13311   [(set (match_operand:XF 0 "register_operand" "=f,f")
13312         (match_operator:XF 3 "binary_fp_operator"
13313            [(float_extend:XF
13314               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13315             (match_operand:XF 2 "register_operand" "0,f")]))]
13316   "TARGET_80387"
13317   "* return output_387_binary_op (insn, operands);"
13318   [(set (attr "type")
13319         (cond [(match_operand:XF 3 "mult_operator" "")
13320                  (const_string "fmul")
13321                (match_operand:XF 3 "div_operator" "")
13322                  (const_string "fdiv")
13323               ]
13324               (const_string "fop")))
13325    (set_attr "mode" "<MODE>")])
13326
13327 (define_insn "*fop_xf_5_i387"
13328   [(set (match_operand:XF 0 "register_operand" "=f,f")
13329         (match_operator:XF 3 "binary_fp_operator"
13330           [(match_operand:XF 1 "register_operand" "0,f")
13331            (float_extend:XF
13332              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13333   "TARGET_80387"
13334   "* return output_387_binary_op (insn, operands);"
13335   [(set (attr "type")
13336         (cond [(match_operand:XF 3 "mult_operator" "")
13337                  (const_string "fmul")
13338                (match_operand:XF 3 "div_operator" "")
13339                  (const_string "fdiv")
13340               ]
13341               (const_string "fop")))
13342    (set_attr "mode" "<MODE>")])
13343
13344 (define_insn "*fop_xf_6_i387"
13345   [(set (match_operand:XF 0 "register_operand" "=f,f")
13346         (match_operator:XF 3 "binary_fp_operator"
13347           [(float_extend:XF
13348              (match_operand:MODEF 1 "register_operand" "0,f"))
13349            (float_extend:XF
13350              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13351   "TARGET_80387"
13352   "* return output_387_binary_op (insn, operands);"
13353   [(set (attr "type")
13354         (cond [(match_operand:XF 3 "mult_operator" "")
13355                  (const_string "fmul")
13356                (match_operand:XF 3 "div_operator" "")
13357                  (const_string "fdiv")
13358               ]
13359               (const_string "fop")))
13360    (set_attr "mode" "<MODE>")])
13361
13362 (define_split
13363   [(set (match_operand 0 "register_operand" "")
13364         (match_operator 3 "binary_fp_operator"
13365            [(float (match_operand:SWI24 1 "register_operand" ""))
13366             (match_operand 2 "register_operand" "")]))]
13367   "reload_completed
13368    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13369    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13370   [(const_int 0)]
13371 {
13372   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13373   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13374   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13375                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13376                                           GET_MODE (operands[3]),
13377                                           operands[4],
13378                                           operands[2])));
13379   ix86_free_from_memory (GET_MODE (operands[1]));
13380   DONE;
13381 })
13382
13383 (define_split
13384   [(set (match_operand 0 "register_operand" "")
13385         (match_operator 3 "binary_fp_operator"
13386            [(match_operand 1 "register_operand" "")
13387             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13388   "reload_completed
13389    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13390    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13391   [(const_int 0)]
13392 {
13393   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13394   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13395   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13396                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13397                                           GET_MODE (operands[3]),
13398                                           operands[1],
13399                                           operands[4])));
13400   ix86_free_from_memory (GET_MODE (operands[2]));
13401   DONE;
13402 })
13403 \f
13404 ;; FPU special functions.
13405
13406 ;; This pattern implements a no-op XFmode truncation for
13407 ;; all fancy i386 XFmode math functions.
13408
13409 (define_insn "truncxf<mode>2_i387_noop_unspec"
13410   [(set (match_operand:MODEF 0 "register_operand" "=f")
13411         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13412         UNSPEC_TRUNC_NOOP))]
13413   "TARGET_USE_FANCY_MATH_387"
13414   "* return output_387_reg_move (insn, operands);"
13415   [(set_attr "type" "fmov")
13416    (set_attr "mode" "<MODE>")])
13417
13418 (define_insn "sqrtxf2"
13419   [(set (match_operand:XF 0 "register_operand" "=f")
13420         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13421   "TARGET_USE_FANCY_MATH_387"
13422   "fsqrt"
13423   [(set_attr "type" "fpspc")
13424    (set_attr "mode" "XF")
13425    (set_attr "athlon_decode" "direct")
13426    (set_attr "amdfam10_decode" "direct")
13427    (set_attr "bdver1_decode" "direct")])
13428
13429 (define_insn "sqrt_extend<mode>xf2_i387"
13430   [(set (match_operand:XF 0 "register_operand" "=f")
13431         (sqrt:XF
13432           (float_extend:XF
13433             (match_operand:MODEF 1 "register_operand" "0"))))]
13434   "TARGET_USE_FANCY_MATH_387"
13435   "fsqrt"
13436   [(set_attr "type" "fpspc")
13437    (set_attr "mode" "XF")
13438    (set_attr "athlon_decode" "direct")
13439    (set_attr "amdfam10_decode" "direct")
13440    (set_attr "bdver1_decode" "direct")])
13441
13442 (define_insn "*rsqrtsf2_sse"
13443   [(set (match_operand:SF 0 "register_operand" "=x")
13444         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13445                    UNSPEC_RSQRT))]
13446   "TARGET_SSE_MATH"
13447   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13448   [(set_attr "type" "sse")
13449    (set_attr "atom_sse_attr" "rcp")
13450    (set_attr "prefix" "maybe_vex")
13451    (set_attr "mode" "SF")])
13452
13453 (define_expand "rsqrtsf2"
13454   [(set (match_operand:SF 0 "register_operand" "")
13455         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13456                    UNSPEC_RSQRT))]
13457   "TARGET_SSE_MATH"
13458 {
13459   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13460   DONE;
13461 })
13462
13463 (define_insn "*sqrt<mode>2_sse"
13464   [(set (match_operand:MODEF 0 "register_operand" "=x")
13465         (sqrt:MODEF
13466           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13467   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13468   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13469   [(set_attr "type" "sse")
13470    (set_attr "atom_sse_attr" "sqrt")
13471    (set_attr "prefix" "maybe_vex")
13472    (set_attr "mode" "<MODE>")
13473    (set_attr "athlon_decode" "*")
13474    (set_attr "amdfam10_decode" "*")
13475    (set_attr "bdver1_decode" "*")])
13476
13477 (define_expand "sqrt<mode>2"
13478   [(set (match_operand:MODEF 0 "register_operand" "")
13479         (sqrt:MODEF
13480           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13481   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13482    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13483 {
13484   if (<MODE>mode == SFmode
13485       && TARGET_SSE_MATH
13486       && TARGET_RECIP_SQRT
13487       && !optimize_function_for_size_p (cfun)
13488       && flag_finite_math_only && !flag_trapping_math
13489       && flag_unsafe_math_optimizations)
13490     {
13491       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13492       DONE;
13493     }
13494
13495   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13496     {
13497       rtx op0 = gen_reg_rtx (XFmode);
13498       rtx op1 = force_reg (<MODE>mode, operands[1]);
13499
13500       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13501       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13502       DONE;
13503    }
13504 })
13505
13506 (define_insn "fpremxf4_i387"
13507   [(set (match_operand:XF 0 "register_operand" "=f")
13508         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13509                     (match_operand:XF 3 "register_operand" "1")]
13510                    UNSPEC_FPREM_F))
13511    (set (match_operand:XF 1 "register_operand" "=u")
13512         (unspec:XF [(match_dup 2) (match_dup 3)]
13513                    UNSPEC_FPREM_U))
13514    (set (reg:CCFP FPSR_REG)
13515         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13516                      UNSPEC_C2_FLAG))]
13517   "TARGET_USE_FANCY_MATH_387"
13518   "fprem"
13519   [(set_attr "type" "fpspc")
13520    (set_attr "mode" "XF")])
13521
13522 (define_expand "fmodxf3"
13523   [(use (match_operand:XF 0 "register_operand" ""))
13524    (use (match_operand:XF 1 "general_operand" ""))
13525    (use (match_operand:XF 2 "general_operand" ""))]
13526   "TARGET_USE_FANCY_MATH_387"
13527 {
13528   rtx label = gen_label_rtx ();
13529
13530   rtx op1 = gen_reg_rtx (XFmode);
13531   rtx op2 = gen_reg_rtx (XFmode);
13532
13533   emit_move_insn (op2, operands[2]);
13534   emit_move_insn (op1, operands[1]);
13535
13536   emit_label (label);
13537   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13538   ix86_emit_fp_unordered_jump (label);
13539   LABEL_NUSES (label) = 1;
13540
13541   emit_move_insn (operands[0], op1);
13542   DONE;
13543 })
13544
13545 (define_expand "fmod<mode>3"
13546   [(use (match_operand:MODEF 0 "register_operand" ""))
13547    (use (match_operand:MODEF 1 "general_operand" ""))
13548    (use (match_operand:MODEF 2 "general_operand" ""))]
13549   "TARGET_USE_FANCY_MATH_387"
13550 {
13551   rtx (*gen_truncxf) (rtx, rtx);
13552
13553   rtx label = gen_label_rtx ();
13554
13555   rtx op1 = gen_reg_rtx (XFmode);
13556   rtx op2 = gen_reg_rtx (XFmode);
13557
13558   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13559   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13560
13561   emit_label (label);
13562   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13563   ix86_emit_fp_unordered_jump (label);
13564   LABEL_NUSES (label) = 1;
13565
13566   /* Truncate the result properly for strict SSE math.  */
13567   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13568       && !TARGET_MIX_SSE_I387)
13569     gen_truncxf = gen_truncxf<mode>2;
13570   else
13571     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13572
13573   emit_insn (gen_truncxf (operands[0], op1));
13574   DONE;
13575 })
13576
13577 (define_insn "fprem1xf4_i387"
13578   [(set (match_operand:XF 0 "register_operand" "=f")
13579         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13580                     (match_operand:XF 3 "register_operand" "1")]
13581                    UNSPEC_FPREM1_F))
13582    (set (match_operand:XF 1 "register_operand" "=u")
13583         (unspec:XF [(match_dup 2) (match_dup 3)]
13584                    UNSPEC_FPREM1_U))
13585    (set (reg:CCFP FPSR_REG)
13586         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13587                      UNSPEC_C2_FLAG))]
13588   "TARGET_USE_FANCY_MATH_387"
13589   "fprem1"
13590   [(set_attr "type" "fpspc")
13591    (set_attr "mode" "XF")])
13592
13593 (define_expand "remainderxf3"
13594   [(use (match_operand:XF 0 "register_operand" ""))
13595    (use (match_operand:XF 1 "general_operand" ""))
13596    (use (match_operand:XF 2 "general_operand" ""))]
13597   "TARGET_USE_FANCY_MATH_387"
13598 {
13599   rtx label = gen_label_rtx ();
13600
13601   rtx op1 = gen_reg_rtx (XFmode);
13602   rtx op2 = gen_reg_rtx (XFmode);
13603
13604   emit_move_insn (op2, operands[2]);
13605   emit_move_insn (op1, operands[1]);
13606
13607   emit_label (label);
13608   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13609   ix86_emit_fp_unordered_jump (label);
13610   LABEL_NUSES (label) = 1;
13611
13612   emit_move_insn (operands[0], op1);
13613   DONE;
13614 })
13615
13616 (define_expand "remainder<mode>3"
13617   [(use (match_operand:MODEF 0 "register_operand" ""))
13618    (use (match_operand:MODEF 1 "general_operand" ""))
13619    (use (match_operand:MODEF 2 "general_operand" ""))]
13620   "TARGET_USE_FANCY_MATH_387"
13621 {
13622   rtx (*gen_truncxf) (rtx, rtx);
13623
13624   rtx label = gen_label_rtx ();
13625
13626   rtx op1 = gen_reg_rtx (XFmode);
13627   rtx op2 = gen_reg_rtx (XFmode);
13628
13629   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13630   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13631
13632   emit_label (label);
13633
13634   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13635   ix86_emit_fp_unordered_jump (label);
13636   LABEL_NUSES (label) = 1;
13637
13638   /* Truncate the result properly for strict SSE math.  */
13639   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13640       && !TARGET_MIX_SSE_I387)
13641     gen_truncxf = gen_truncxf<mode>2;
13642   else
13643     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13644
13645   emit_insn (gen_truncxf (operands[0], op1));
13646   DONE;
13647 })
13648
13649 (define_insn "*sinxf2_i387"
13650   [(set (match_operand:XF 0 "register_operand" "=f")
13651         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13652   "TARGET_USE_FANCY_MATH_387
13653    && flag_unsafe_math_optimizations"
13654   "fsin"
13655   [(set_attr "type" "fpspc")
13656    (set_attr "mode" "XF")])
13657
13658 (define_insn "*sin_extend<mode>xf2_i387"
13659   [(set (match_operand:XF 0 "register_operand" "=f")
13660         (unspec:XF [(float_extend:XF
13661                       (match_operand:MODEF 1 "register_operand" "0"))]
13662                    UNSPEC_SIN))]
13663   "TARGET_USE_FANCY_MATH_387
13664    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13665        || TARGET_MIX_SSE_I387)
13666    && flag_unsafe_math_optimizations"
13667   "fsin"
13668   [(set_attr "type" "fpspc")
13669    (set_attr "mode" "XF")])
13670
13671 (define_insn "*cosxf2_i387"
13672   [(set (match_operand:XF 0 "register_operand" "=f")
13673         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13674   "TARGET_USE_FANCY_MATH_387
13675    && flag_unsafe_math_optimizations"
13676   "fcos"
13677   [(set_attr "type" "fpspc")
13678    (set_attr "mode" "XF")])
13679
13680 (define_insn "*cos_extend<mode>xf2_i387"
13681   [(set (match_operand:XF 0 "register_operand" "=f")
13682         (unspec:XF [(float_extend:XF
13683                       (match_operand:MODEF 1 "register_operand" "0"))]
13684                    UNSPEC_COS))]
13685   "TARGET_USE_FANCY_MATH_387
13686    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13687        || TARGET_MIX_SSE_I387)
13688    && flag_unsafe_math_optimizations"
13689   "fcos"
13690   [(set_attr "type" "fpspc")
13691    (set_attr "mode" "XF")])
13692
13693 ;; When sincos pattern is defined, sin and cos builtin functions will be
13694 ;; expanded to sincos pattern with one of its outputs left unused.
13695 ;; CSE pass will figure out if two sincos patterns can be combined,
13696 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13697 ;; depending on the unused output.
13698
13699 (define_insn "sincosxf3"
13700   [(set (match_operand:XF 0 "register_operand" "=f")
13701         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13702                    UNSPEC_SINCOS_COS))
13703    (set (match_operand:XF 1 "register_operand" "=u")
13704         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13705   "TARGET_USE_FANCY_MATH_387
13706    && flag_unsafe_math_optimizations"
13707   "fsincos"
13708   [(set_attr "type" "fpspc")
13709    (set_attr "mode" "XF")])
13710
13711 (define_split
13712   [(set (match_operand:XF 0 "register_operand" "")
13713         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13714                    UNSPEC_SINCOS_COS))
13715    (set (match_operand:XF 1 "register_operand" "")
13716         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13717   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13718    && can_create_pseudo_p ()"
13719   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13720
13721 (define_split
13722   [(set (match_operand:XF 0 "register_operand" "")
13723         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13724                    UNSPEC_SINCOS_COS))
13725    (set (match_operand:XF 1 "register_operand" "")
13726         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13727   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13728    && can_create_pseudo_p ()"
13729   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13730
13731 (define_insn "sincos_extend<mode>xf3_i387"
13732   [(set (match_operand:XF 0 "register_operand" "=f")
13733         (unspec:XF [(float_extend:XF
13734                       (match_operand:MODEF 2 "register_operand" "0"))]
13735                    UNSPEC_SINCOS_COS))
13736    (set (match_operand:XF 1 "register_operand" "=u")
13737         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13738   "TARGET_USE_FANCY_MATH_387
13739    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13740        || TARGET_MIX_SSE_I387)
13741    && flag_unsafe_math_optimizations"
13742   "fsincos"
13743   [(set_attr "type" "fpspc")
13744    (set_attr "mode" "XF")])
13745
13746 (define_split
13747   [(set (match_operand:XF 0 "register_operand" "")
13748         (unspec:XF [(float_extend:XF
13749                       (match_operand:MODEF 2 "register_operand" ""))]
13750                    UNSPEC_SINCOS_COS))
13751    (set (match_operand:XF 1 "register_operand" "")
13752         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13753   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13754    && can_create_pseudo_p ()"
13755   [(set (match_dup 1)
13756         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13757
13758 (define_split
13759   [(set (match_operand:XF 0 "register_operand" "")
13760         (unspec:XF [(float_extend:XF
13761                       (match_operand:MODEF 2 "register_operand" ""))]
13762                    UNSPEC_SINCOS_COS))
13763    (set (match_operand:XF 1 "register_operand" "")
13764         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13765   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13766    && can_create_pseudo_p ()"
13767   [(set (match_dup 0)
13768         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13769
13770 (define_expand "sincos<mode>3"
13771   [(use (match_operand:MODEF 0 "register_operand" ""))
13772    (use (match_operand:MODEF 1 "register_operand" ""))
13773    (use (match_operand:MODEF 2 "register_operand" ""))]
13774   "TARGET_USE_FANCY_MATH_387
13775    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13776        || TARGET_MIX_SSE_I387)
13777    && flag_unsafe_math_optimizations"
13778 {
13779   rtx op0 = gen_reg_rtx (XFmode);
13780   rtx op1 = gen_reg_rtx (XFmode);
13781
13782   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13783   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13784   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13785   DONE;
13786 })
13787
13788 (define_insn "fptanxf4_i387"
13789   [(set (match_operand:XF 0 "register_operand" "=f")
13790         (match_operand:XF 3 "const_double_operand" "F"))
13791    (set (match_operand:XF 1 "register_operand" "=u")
13792         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13793                    UNSPEC_TAN))]
13794   "TARGET_USE_FANCY_MATH_387
13795    && flag_unsafe_math_optimizations
13796    && standard_80387_constant_p (operands[3]) == 2"
13797   "fptan"
13798   [(set_attr "type" "fpspc")
13799    (set_attr "mode" "XF")])
13800
13801 (define_insn "fptan_extend<mode>xf4_i387"
13802   [(set (match_operand:MODEF 0 "register_operand" "=f")
13803         (match_operand:MODEF 3 "const_double_operand" "F"))
13804    (set (match_operand:XF 1 "register_operand" "=u")
13805         (unspec:XF [(float_extend:XF
13806                       (match_operand:MODEF 2 "register_operand" "0"))]
13807                    UNSPEC_TAN))]
13808   "TARGET_USE_FANCY_MATH_387
13809    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13810        || TARGET_MIX_SSE_I387)
13811    && flag_unsafe_math_optimizations
13812    && standard_80387_constant_p (operands[3]) == 2"
13813   "fptan"
13814   [(set_attr "type" "fpspc")
13815    (set_attr "mode" "XF")])
13816
13817 (define_expand "tanxf2"
13818   [(use (match_operand:XF 0 "register_operand" ""))
13819    (use (match_operand:XF 1 "register_operand" ""))]
13820   "TARGET_USE_FANCY_MATH_387
13821    && flag_unsafe_math_optimizations"
13822 {
13823   rtx one = gen_reg_rtx (XFmode);
13824   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13825
13826   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13827   DONE;
13828 })
13829
13830 (define_expand "tan<mode>2"
13831   [(use (match_operand:MODEF 0 "register_operand" ""))
13832    (use (match_operand:MODEF 1 "register_operand" ""))]
13833   "TARGET_USE_FANCY_MATH_387
13834    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13835        || TARGET_MIX_SSE_I387)
13836    && flag_unsafe_math_optimizations"
13837 {
13838   rtx op0 = gen_reg_rtx (XFmode);
13839
13840   rtx one = gen_reg_rtx (<MODE>mode);
13841   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13842
13843   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13844                                              operands[1], op2));
13845   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13846   DONE;
13847 })
13848
13849 (define_insn "*fpatanxf3_i387"
13850   [(set (match_operand:XF 0 "register_operand" "=f")
13851         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13852                     (match_operand:XF 2 "register_operand" "u")]
13853                    UNSPEC_FPATAN))
13854    (clobber (match_scratch:XF 3 "=2"))]
13855   "TARGET_USE_FANCY_MATH_387
13856    && flag_unsafe_math_optimizations"
13857   "fpatan"
13858   [(set_attr "type" "fpspc")
13859    (set_attr "mode" "XF")])
13860
13861 (define_insn "fpatan_extend<mode>xf3_i387"
13862   [(set (match_operand:XF 0 "register_operand" "=f")
13863         (unspec:XF [(float_extend:XF
13864                       (match_operand:MODEF 1 "register_operand" "0"))
13865                     (float_extend:XF
13866                       (match_operand:MODEF 2 "register_operand" "u"))]
13867                    UNSPEC_FPATAN))
13868    (clobber (match_scratch:XF 3 "=2"))]
13869   "TARGET_USE_FANCY_MATH_387
13870    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13871        || TARGET_MIX_SSE_I387)
13872    && flag_unsafe_math_optimizations"
13873   "fpatan"
13874   [(set_attr "type" "fpspc")
13875    (set_attr "mode" "XF")])
13876
13877 (define_expand "atan2xf3"
13878   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13879                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13880                                (match_operand:XF 1 "register_operand" "")]
13881                               UNSPEC_FPATAN))
13882               (clobber (match_scratch:XF 3 ""))])]
13883   "TARGET_USE_FANCY_MATH_387
13884    && flag_unsafe_math_optimizations")
13885
13886 (define_expand "atan2<mode>3"
13887   [(use (match_operand:MODEF 0 "register_operand" ""))
13888    (use (match_operand:MODEF 1 "register_operand" ""))
13889    (use (match_operand:MODEF 2 "register_operand" ""))]
13890   "TARGET_USE_FANCY_MATH_387
13891    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13892        || TARGET_MIX_SSE_I387)
13893    && flag_unsafe_math_optimizations"
13894 {
13895   rtx op0 = gen_reg_rtx (XFmode);
13896
13897   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13898   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13899   DONE;
13900 })
13901
13902 (define_expand "atanxf2"
13903   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13904                    (unspec:XF [(match_dup 2)
13905                                (match_operand:XF 1 "register_operand" "")]
13906                               UNSPEC_FPATAN))
13907               (clobber (match_scratch:XF 3 ""))])]
13908   "TARGET_USE_FANCY_MATH_387
13909    && flag_unsafe_math_optimizations"
13910 {
13911   operands[2] = gen_reg_rtx (XFmode);
13912   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13913 })
13914
13915 (define_expand "atan<mode>2"
13916   [(use (match_operand:MODEF 0 "register_operand" ""))
13917    (use (match_operand:MODEF 1 "register_operand" ""))]
13918   "TARGET_USE_FANCY_MATH_387
13919    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13920        || TARGET_MIX_SSE_I387)
13921    && flag_unsafe_math_optimizations"
13922 {
13923   rtx op0 = gen_reg_rtx (XFmode);
13924
13925   rtx op2 = gen_reg_rtx (<MODE>mode);
13926   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13927
13928   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13929   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13930   DONE;
13931 })
13932
13933 (define_expand "asinxf2"
13934   [(set (match_dup 2)
13935         (mult:XF (match_operand:XF 1 "register_operand" "")
13936                  (match_dup 1)))
13937    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13938    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13939    (parallel [(set (match_operand:XF 0 "register_operand" "")
13940                    (unspec:XF [(match_dup 5) (match_dup 1)]
13941                               UNSPEC_FPATAN))
13942               (clobber (match_scratch:XF 6 ""))])]
13943   "TARGET_USE_FANCY_MATH_387
13944    && flag_unsafe_math_optimizations"
13945 {
13946   int i;
13947
13948   if (optimize_insn_for_size_p ())
13949     FAIL;
13950
13951   for (i = 2; i < 6; i++)
13952     operands[i] = gen_reg_rtx (XFmode);
13953
13954   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13955 })
13956
13957 (define_expand "asin<mode>2"
13958   [(use (match_operand:MODEF 0 "register_operand" ""))
13959    (use (match_operand:MODEF 1 "general_operand" ""))]
13960  "TARGET_USE_FANCY_MATH_387
13961    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13962        || TARGET_MIX_SSE_I387)
13963    && flag_unsafe_math_optimizations"
13964 {
13965   rtx op0 = gen_reg_rtx (XFmode);
13966   rtx op1 = gen_reg_rtx (XFmode);
13967
13968   if (optimize_insn_for_size_p ())
13969     FAIL;
13970
13971   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13972   emit_insn (gen_asinxf2 (op0, op1));
13973   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13974   DONE;
13975 })
13976
13977 (define_expand "acosxf2"
13978   [(set (match_dup 2)
13979         (mult:XF (match_operand:XF 1 "register_operand" "")
13980                  (match_dup 1)))
13981    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13982    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13983    (parallel [(set (match_operand:XF 0 "register_operand" "")
13984                    (unspec:XF [(match_dup 1) (match_dup 5)]
13985                               UNSPEC_FPATAN))
13986               (clobber (match_scratch:XF 6 ""))])]
13987   "TARGET_USE_FANCY_MATH_387
13988    && flag_unsafe_math_optimizations"
13989 {
13990   int i;
13991
13992   if (optimize_insn_for_size_p ())
13993     FAIL;
13994
13995   for (i = 2; i < 6; i++)
13996     operands[i] = gen_reg_rtx (XFmode);
13997
13998   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13999 })
14000
14001 (define_expand "acos<mode>2"
14002   [(use (match_operand:MODEF 0 "register_operand" ""))
14003    (use (match_operand:MODEF 1 "general_operand" ""))]
14004  "TARGET_USE_FANCY_MATH_387
14005    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14006        || TARGET_MIX_SSE_I387)
14007    && flag_unsafe_math_optimizations"
14008 {
14009   rtx op0 = gen_reg_rtx (XFmode);
14010   rtx op1 = gen_reg_rtx (XFmode);
14011
14012   if (optimize_insn_for_size_p ())
14013     FAIL;
14014
14015   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14016   emit_insn (gen_acosxf2 (op0, op1));
14017   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14018   DONE;
14019 })
14020
14021 (define_insn "fyl2xxf3_i387"
14022   [(set (match_operand:XF 0 "register_operand" "=f")
14023         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14024                     (match_operand:XF 2 "register_operand" "u")]
14025                    UNSPEC_FYL2X))
14026    (clobber (match_scratch:XF 3 "=2"))]
14027   "TARGET_USE_FANCY_MATH_387
14028    && flag_unsafe_math_optimizations"
14029   "fyl2x"
14030   [(set_attr "type" "fpspc")
14031    (set_attr "mode" "XF")])
14032
14033 (define_insn "fyl2x_extend<mode>xf3_i387"
14034   [(set (match_operand:XF 0 "register_operand" "=f")
14035         (unspec:XF [(float_extend:XF
14036                       (match_operand:MODEF 1 "register_operand" "0"))
14037                     (match_operand:XF 2 "register_operand" "u")]
14038                    UNSPEC_FYL2X))
14039    (clobber (match_scratch:XF 3 "=2"))]
14040   "TARGET_USE_FANCY_MATH_387
14041    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042        || TARGET_MIX_SSE_I387)
14043    && flag_unsafe_math_optimizations"
14044   "fyl2x"
14045   [(set_attr "type" "fpspc")
14046    (set_attr "mode" "XF")])
14047
14048 (define_expand "logxf2"
14049   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14050                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14051                                (match_dup 2)] UNSPEC_FYL2X))
14052               (clobber (match_scratch:XF 3 ""))])]
14053   "TARGET_USE_FANCY_MATH_387
14054    && flag_unsafe_math_optimizations"
14055 {
14056   operands[2] = gen_reg_rtx (XFmode);
14057   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14058 })
14059
14060 (define_expand "log<mode>2"
14061   [(use (match_operand:MODEF 0 "register_operand" ""))
14062    (use (match_operand:MODEF 1 "register_operand" ""))]
14063   "TARGET_USE_FANCY_MATH_387
14064    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14065        || TARGET_MIX_SSE_I387)
14066    && flag_unsafe_math_optimizations"
14067 {
14068   rtx op0 = gen_reg_rtx (XFmode);
14069
14070   rtx op2 = gen_reg_rtx (XFmode);
14071   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14072
14073   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14074   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14075   DONE;
14076 })
14077
14078 (define_expand "log10xf2"
14079   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14080                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14081                                (match_dup 2)] UNSPEC_FYL2X))
14082               (clobber (match_scratch:XF 3 ""))])]
14083   "TARGET_USE_FANCY_MATH_387
14084    && flag_unsafe_math_optimizations"
14085 {
14086   operands[2] = gen_reg_rtx (XFmode);
14087   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14088 })
14089
14090 (define_expand "log10<mode>2"
14091   [(use (match_operand:MODEF 0 "register_operand" ""))
14092    (use (match_operand:MODEF 1 "register_operand" ""))]
14093   "TARGET_USE_FANCY_MATH_387
14094    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14095        || TARGET_MIX_SSE_I387)
14096    && flag_unsafe_math_optimizations"
14097 {
14098   rtx op0 = gen_reg_rtx (XFmode);
14099
14100   rtx op2 = gen_reg_rtx (XFmode);
14101   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14102
14103   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14104   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14105   DONE;
14106 })
14107
14108 (define_expand "log2xf2"
14109   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14110                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14111                                (match_dup 2)] UNSPEC_FYL2X))
14112               (clobber (match_scratch:XF 3 ""))])]
14113   "TARGET_USE_FANCY_MATH_387
14114    && flag_unsafe_math_optimizations"
14115 {
14116   operands[2] = gen_reg_rtx (XFmode);
14117   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14118 })
14119
14120 (define_expand "log2<mode>2"
14121   [(use (match_operand:MODEF 0 "register_operand" ""))
14122    (use (match_operand:MODEF 1 "register_operand" ""))]
14123   "TARGET_USE_FANCY_MATH_387
14124    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14125        || TARGET_MIX_SSE_I387)
14126    && flag_unsafe_math_optimizations"
14127 {
14128   rtx op0 = gen_reg_rtx (XFmode);
14129
14130   rtx op2 = gen_reg_rtx (XFmode);
14131   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14132
14133   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14134   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14135   DONE;
14136 })
14137
14138 (define_insn "fyl2xp1xf3_i387"
14139   [(set (match_operand:XF 0 "register_operand" "=f")
14140         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14141                     (match_operand:XF 2 "register_operand" "u")]
14142                    UNSPEC_FYL2XP1))
14143    (clobber (match_scratch:XF 3 "=2"))]
14144   "TARGET_USE_FANCY_MATH_387
14145    && flag_unsafe_math_optimizations"
14146   "fyl2xp1"
14147   [(set_attr "type" "fpspc")
14148    (set_attr "mode" "XF")])
14149
14150 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14151   [(set (match_operand:XF 0 "register_operand" "=f")
14152         (unspec:XF [(float_extend:XF
14153                       (match_operand:MODEF 1 "register_operand" "0"))
14154                     (match_operand:XF 2 "register_operand" "u")]
14155                    UNSPEC_FYL2XP1))
14156    (clobber (match_scratch:XF 3 "=2"))]
14157   "TARGET_USE_FANCY_MATH_387
14158    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14159        || TARGET_MIX_SSE_I387)
14160    && flag_unsafe_math_optimizations"
14161   "fyl2xp1"
14162   [(set_attr "type" "fpspc")
14163    (set_attr "mode" "XF")])
14164
14165 (define_expand "log1pxf2"
14166   [(use (match_operand:XF 0 "register_operand" ""))
14167    (use (match_operand:XF 1 "register_operand" ""))]
14168   "TARGET_USE_FANCY_MATH_387
14169    && flag_unsafe_math_optimizations"
14170 {
14171   if (optimize_insn_for_size_p ())
14172     FAIL;
14173
14174   ix86_emit_i387_log1p (operands[0], operands[1]);
14175   DONE;
14176 })
14177
14178 (define_expand "log1p<mode>2"
14179   [(use (match_operand:MODEF 0 "register_operand" ""))
14180    (use (match_operand:MODEF 1 "register_operand" ""))]
14181   "TARGET_USE_FANCY_MATH_387
14182    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14183        || TARGET_MIX_SSE_I387)
14184    && flag_unsafe_math_optimizations"
14185 {
14186   rtx op0;
14187
14188   if (optimize_insn_for_size_p ())
14189     FAIL;
14190
14191   op0 = gen_reg_rtx (XFmode);
14192
14193   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14194
14195   ix86_emit_i387_log1p (op0, operands[1]);
14196   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14197   DONE;
14198 })
14199
14200 (define_insn "fxtractxf3_i387"
14201   [(set (match_operand:XF 0 "register_operand" "=f")
14202         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14203                    UNSPEC_XTRACT_FRACT))
14204    (set (match_operand:XF 1 "register_operand" "=u")
14205         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14206   "TARGET_USE_FANCY_MATH_387
14207    && flag_unsafe_math_optimizations"
14208   "fxtract"
14209   [(set_attr "type" "fpspc")
14210    (set_attr "mode" "XF")])
14211
14212 (define_insn "fxtract_extend<mode>xf3_i387"
14213   [(set (match_operand:XF 0 "register_operand" "=f")
14214         (unspec:XF [(float_extend:XF
14215                       (match_operand:MODEF 2 "register_operand" "0"))]
14216                    UNSPEC_XTRACT_FRACT))
14217    (set (match_operand:XF 1 "register_operand" "=u")
14218         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14219   "TARGET_USE_FANCY_MATH_387
14220    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14221        || TARGET_MIX_SSE_I387)
14222    && flag_unsafe_math_optimizations"
14223   "fxtract"
14224   [(set_attr "type" "fpspc")
14225    (set_attr "mode" "XF")])
14226
14227 (define_expand "logbxf2"
14228   [(parallel [(set (match_dup 2)
14229                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14230                               UNSPEC_XTRACT_FRACT))
14231               (set (match_operand:XF 0 "register_operand" "")
14232                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14233   "TARGET_USE_FANCY_MATH_387
14234    && flag_unsafe_math_optimizations"
14235   "operands[2] = gen_reg_rtx (XFmode);")
14236
14237 (define_expand "logb<mode>2"
14238   [(use (match_operand:MODEF 0 "register_operand" ""))
14239    (use (match_operand:MODEF 1 "register_operand" ""))]
14240   "TARGET_USE_FANCY_MATH_387
14241    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14242        || TARGET_MIX_SSE_I387)
14243    && flag_unsafe_math_optimizations"
14244 {
14245   rtx op0 = gen_reg_rtx (XFmode);
14246   rtx op1 = gen_reg_rtx (XFmode);
14247
14248   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14249   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14250   DONE;
14251 })
14252
14253 (define_expand "ilogbxf2"
14254   [(use (match_operand:SI 0 "register_operand" ""))
14255    (use (match_operand:XF 1 "register_operand" ""))]
14256   "TARGET_USE_FANCY_MATH_387
14257    && flag_unsafe_math_optimizations"
14258 {
14259   rtx op0, op1;
14260
14261   if (optimize_insn_for_size_p ())
14262     FAIL;
14263
14264   op0 = gen_reg_rtx (XFmode);
14265   op1 = gen_reg_rtx (XFmode);
14266
14267   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14268   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14269   DONE;
14270 })
14271
14272 (define_expand "ilogb<mode>2"
14273   [(use (match_operand:SI 0 "register_operand" ""))
14274    (use (match_operand:MODEF 1 "register_operand" ""))]
14275   "TARGET_USE_FANCY_MATH_387
14276    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14277        || TARGET_MIX_SSE_I387)
14278    && flag_unsafe_math_optimizations"
14279 {
14280   rtx op0, op1;
14281
14282   if (optimize_insn_for_size_p ())
14283     FAIL;
14284
14285   op0 = gen_reg_rtx (XFmode);
14286   op1 = gen_reg_rtx (XFmode);
14287
14288   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14289   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14290   DONE;
14291 })
14292
14293 (define_insn "*f2xm1xf2_i387"
14294   [(set (match_operand:XF 0 "register_operand" "=f")
14295         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14296                    UNSPEC_F2XM1))]
14297   "TARGET_USE_FANCY_MATH_387
14298    && flag_unsafe_math_optimizations"
14299   "f2xm1"
14300   [(set_attr "type" "fpspc")
14301    (set_attr "mode" "XF")])
14302
14303 (define_insn "*fscalexf4_i387"
14304   [(set (match_operand:XF 0 "register_operand" "=f")
14305         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14306                     (match_operand:XF 3 "register_operand" "1")]
14307                    UNSPEC_FSCALE_FRACT))
14308    (set (match_operand:XF 1 "register_operand" "=u")
14309         (unspec:XF [(match_dup 2) (match_dup 3)]
14310                    UNSPEC_FSCALE_EXP))]
14311   "TARGET_USE_FANCY_MATH_387
14312    && flag_unsafe_math_optimizations"
14313   "fscale"
14314   [(set_attr "type" "fpspc")
14315    (set_attr "mode" "XF")])
14316
14317 (define_expand "expNcorexf3"
14318   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14319                                (match_operand:XF 2 "register_operand" "")))
14320    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14321    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14322    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14323    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14324    (parallel [(set (match_operand:XF 0 "register_operand" "")
14325                    (unspec:XF [(match_dup 8) (match_dup 4)]
14326                               UNSPEC_FSCALE_FRACT))
14327               (set (match_dup 9)
14328                    (unspec:XF [(match_dup 8) (match_dup 4)]
14329                               UNSPEC_FSCALE_EXP))])]
14330   "TARGET_USE_FANCY_MATH_387
14331    && flag_unsafe_math_optimizations"
14332 {
14333   int i;
14334
14335   if (optimize_insn_for_size_p ())
14336     FAIL;
14337
14338   for (i = 3; i < 10; i++)
14339     operands[i] = gen_reg_rtx (XFmode);
14340
14341   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14342 })
14343
14344 (define_expand "expxf2"
14345   [(use (match_operand:XF 0 "register_operand" ""))
14346    (use (match_operand:XF 1 "register_operand" ""))]
14347   "TARGET_USE_FANCY_MATH_387
14348    && flag_unsafe_math_optimizations"
14349 {
14350   rtx op2;
14351
14352   if (optimize_insn_for_size_p ())
14353     FAIL;
14354
14355   op2 = gen_reg_rtx (XFmode);
14356   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14357
14358   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14359   DONE;
14360 })
14361
14362 (define_expand "exp<mode>2"
14363   [(use (match_operand:MODEF 0 "register_operand" ""))
14364    (use (match_operand:MODEF 1 "general_operand" ""))]
14365  "TARGET_USE_FANCY_MATH_387
14366    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14367        || TARGET_MIX_SSE_I387)
14368    && flag_unsafe_math_optimizations"
14369 {
14370   rtx op0, op1;
14371
14372   if (optimize_insn_for_size_p ())
14373     FAIL;
14374
14375   op0 = gen_reg_rtx (XFmode);
14376   op1 = gen_reg_rtx (XFmode);
14377
14378   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14379   emit_insn (gen_expxf2 (op0, op1));
14380   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14381   DONE;
14382 })
14383
14384 (define_expand "exp10xf2"
14385   [(use (match_operand:XF 0 "register_operand" ""))
14386    (use (match_operand:XF 1 "register_operand" ""))]
14387   "TARGET_USE_FANCY_MATH_387
14388    && flag_unsafe_math_optimizations"
14389 {
14390   rtx op2;
14391
14392   if (optimize_insn_for_size_p ())
14393     FAIL;
14394
14395   op2 = gen_reg_rtx (XFmode);
14396   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14397
14398   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14399   DONE;
14400 })
14401
14402 (define_expand "exp10<mode>2"
14403   [(use (match_operand:MODEF 0 "register_operand" ""))
14404    (use (match_operand:MODEF 1 "general_operand" ""))]
14405  "TARGET_USE_FANCY_MATH_387
14406    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14407        || TARGET_MIX_SSE_I387)
14408    && flag_unsafe_math_optimizations"
14409 {
14410   rtx op0, op1;
14411
14412   if (optimize_insn_for_size_p ())
14413     FAIL;
14414
14415   op0 = gen_reg_rtx (XFmode);
14416   op1 = gen_reg_rtx (XFmode);
14417
14418   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14419   emit_insn (gen_exp10xf2 (op0, op1));
14420   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14421   DONE;
14422 })
14423
14424 (define_expand "exp2xf2"
14425   [(use (match_operand:XF 0 "register_operand" ""))
14426    (use (match_operand:XF 1 "register_operand" ""))]
14427   "TARGET_USE_FANCY_MATH_387
14428    && flag_unsafe_math_optimizations"
14429 {
14430   rtx op2;
14431
14432   if (optimize_insn_for_size_p ())
14433     FAIL;
14434
14435   op2 = gen_reg_rtx (XFmode);
14436   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14437
14438   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14439   DONE;
14440 })
14441
14442 (define_expand "exp2<mode>2"
14443   [(use (match_operand:MODEF 0 "register_operand" ""))
14444    (use (match_operand:MODEF 1 "general_operand" ""))]
14445  "TARGET_USE_FANCY_MATH_387
14446    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14447        || TARGET_MIX_SSE_I387)
14448    && flag_unsafe_math_optimizations"
14449 {
14450   rtx op0, op1;
14451
14452   if (optimize_insn_for_size_p ())
14453     FAIL;
14454
14455   op0 = gen_reg_rtx (XFmode);
14456   op1 = gen_reg_rtx (XFmode);
14457
14458   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14459   emit_insn (gen_exp2xf2 (op0, op1));
14460   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14461   DONE;
14462 })
14463
14464 (define_expand "expm1xf2"
14465   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14466                                (match_dup 2)))
14467    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14468    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14469    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14470    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14471    (parallel [(set (match_dup 7)
14472                    (unspec:XF [(match_dup 6) (match_dup 4)]
14473                               UNSPEC_FSCALE_FRACT))
14474               (set (match_dup 8)
14475                    (unspec:XF [(match_dup 6) (match_dup 4)]
14476                               UNSPEC_FSCALE_EXP))])
14477    (parallel [(set (match_dup 10)
14478                    (unspec:XF [(match_dup 9) (match_dup 8)]
14479                               UNSPEC_FSCALE_FRACT))
14480               (set (match_dup 11)
14481                    (unspec:XF [(match_dup 9) (match_dup 8)]
14482                               UNSPEC_FSCALE_EXP))])
14483    (set (match_dup 12) (minus:XF (match_dup 10)
14484                                  (float_extend:XF (match_dup 13))))
14485    (set (match_operand:XF 0 "register_operand" "")
14486         (plus:XF (match_dup 12) (match_dup 7)))]
14487   "TARGET_USE_FANCY_MATH_387
14488    && flag_unsafe_math_optimizations"
14489 {
14490   int i;
14491
14492   if (optimize_insn_for_size_p ())
14493     FAIL;
14494
14495   for (i = 2; i < 13; i++)
14496     operands[i] = gen_reg_rtx (XFmode);
14497
14498   operands[13]
14499     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14500
14501   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14502 })
14503
14504 (define_expand "expm1<mode>2"
14505   [(use (match_operand:MODEF 0 "register_operand" ""))
14506    (use (match_operand:MODEF 1 "general_operand" ""))]
14507  "TARGET_USE_FANCY_MATH_387
14508    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14509        || TARGET_MIX_SSE_I387)
14510    && flag_unsafe_math_optimizations"
14511 {
14512   rtx op0, op1;
14513
14514   if (optimize_insn_for_size_p ())
14515     FAIL;
14516
14517   op0 = gen_reg_rtx (XFmode);
14518   op1 = gen_reg_rtx (XFmode);
14519
14520   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14521   emit_insn (gen_expm1xf2 (op0, op1));
14522   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14523   DONE;
14524 })
14525
14526 (define_expand "ldexpxf3"
14527   [(set (match_dup 3)
14528         (float:XF (match_operand:SI 2 "register_operand" "")))
14529    (parallel [(set (match_operand:XF 0 " register_operand" "")
14530                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14531                                (match_dup 3)]
14532                               UNSPEC_FSCALE_FRACT))
14533               (set (match_dup 4)
14534                    (unspec:XF [(match_dup 1) (match_dup 3)]
14535                               UNSPEC_FSCALE_EXP))])]
14536   "TARGET_USE_FANCY_MATH_387
14537    && flag_unsafe_math_optimizations"
14538 {
14539   if (optimize_insn_for_size_p ())
14540     FAIL;
14541
14542   operands[3] = gen_reg_rtx (XFmode);
14543   operands[4] = gen_reg_rtx (XFmode);
14544 })
14545
14546 (define_expand "ldexp<mode>3"
14547   [(use (match_operand:MODEF 0 "register_operand" ""))
14548    (use (match_operand:MODEF 1 "general_operand" ""))
14549    (use (match_operand:SI 2 "register_operand" ""))]
14550  "TARGET_USE_FANCY_MATH_387
14551    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14552        || TARGET_MIX_SSE_I387)
14553    && flag_unsafe_math_optimizations"
14554 {
14555   rtx op0, op1;
14556
14557   if (optimize_insn_for_size_p ())
14558     FAIL;
14559
14560   op0 = gen_reg_rtx (XFmode);
14561   op1 = gen_reg_rtx (XFmode);
14562
14563   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14564   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14565   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14566   DONE;
14567 })
14568
14569 (define_expand "scalbxf3"
14570   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14571                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14572                                (match_operand:XF 2 "register_operand" "")]
14573                               UNSPEC_FSCALE_FRACT))
14574               (set (match_dup 3)
14575                    (unspec:XF [(match_dup 1) (match_dup 2)]
14576                               UNSPEC_FSCALE_EXP))])]
14577   "TARGET_USE_FANCY_MATH_387
14578    && flag_unsafe_math_optimizations"
14579 {
14580   if (optimize_insn_for_size_p ())
14581     FAIL;
14582
14583   operands[3] = gen_reg_rtx (XFmode);
14584 })
14585
14586 (define_expand "scalb<mode>3"
14587   [(use (match_operand:MODEF 0 "register_operand" ""))
14588    (use (match_operand:MODEF 1 "general_operand" ""))
14589    (use (match_operand:MODEF 2 "general_operand" ""))]
14590  "TARGET_USE_FANCY_MATH_387
14591    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14592        || TARGET_MIX_SSE_I387)
14593    && flag_unsafe_math_optimizations"
14594 {
14595   rtx op0, op1, op2;
14596
14597   if (optimize_insn_for_size_p ())
14598     FAIL;
14599
14600   op0 = gen_reg_rtx (XFmode);
14601   op1 = gen_reg_rtx (XFmode);
14602   op2 = gen_reg_rtx (XFmode);
14603
14604   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14605   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14606   emit_insn (gen_scalbxf3 (op0, op1, op2));
14607   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14608   DONE;
14609 })
14610
14611 (define_expand "significandxf2"
14612   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14613                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14614                               UNSPEC_XTRACT_FRACT))
14615               (set (match_dup 2)
14616                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14617   "TARGET_USE_FANCY_MATH_387
14618    && flag_unsafe_math_optimizations"
14619   "operands[2] = gen_reg_rtx (XFmode);")
14620
14621 (define_expand "significand<mode>2"
14622   [(use (match_operand:MODEF 0 "register_operand" ""))
14623    (use (match_operand:MODEF 1 "register_operand" ""))]
14624   "TARGET_USE_FANCY_MATH_387
14625    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14626        || TARGET_MIX_SSE_I387)
14627    && flag_unsafe_math_optimizations"
14628 {
14629   rtx op0 = gen_reg_rtx (XFmode);
14630   rtx op1 = gen_reg_rtx (XFmode);
14631
14632   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14633   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14634   DONE;
14635 })
14636 \f
14637
14638 (define_insn "sse4_1_round<mode>2"
14639   [(set (match_operand:MODEF 0 "register_operand" "=x")
14640         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14641                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14642                       UNSPEC_ROUND))]
14643   "TARGET_ROUND"
14644   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14645   [(set_attr "type" "ssecvt")
14646    (set_attr "prefix_extra" "1")
14647    (set_attr "prefix" "maybe_vex")
14648    (set_attr "mode" "<MODE>")])
14649
14650 (define_insn "rintxf2"
14651   [(set (match_operand:XF 0 "register_operand" "=f")
14652         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14653                    UNSPEC_FRNDINT))]
14654   "TARGET_USE_FANCY_MATH_387
14655    && flag_unsafe_math_optimizations"
14656   "frndint"
14657   [(set_attr "type" "fpspc")
14658    (set_attr "mode" "XF")])
14659
14660 (define_expand "rint<mode>2"
14661   [(use (match_operand:MODEF 0 "register_operand" ""))
14662    (use (match_operand:MODEF 1 "register_operand" ""))]
14663   "(TARGET_USE_FANCY_MATH_387
14664     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14665         || TARGET_MIX_SSE_I387)
14666     && flag_unsafe_math_optimizations)
14667    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14668        && !flag_trapping_math)"
14669 {
14670   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14671       && !flag_trapping_math)
14672     {
14673       if (TARGET_ROUND)
14674         emit_insn (gen_sse4_1_round<mode>2
14675                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14676       else if (optimize_insn_for_size_p ())
14677         FAIL;
14678       else
14679         ix86_expand_rint (operands[0], operands[1]);
14680     }
14681   else
14682     {
14683       rtx op0 = gen_reg_rtx (XFmode);
14684       rtx op1 = gen_reg_rtx (XFmode);
14685
14686       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14687       emit_insn (gen_rintxf2 (op0, op1));
14688
14689       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14690     }
14691   DONE;
14692 })
14693
14694 (define_expand "round<mode>2"
14695   [(match_operand:X87MODEF 0 "register_operand" "")
14696    (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14697   "(TARGET_USE_FANCY_MATH_387
14698     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14699         || TARGET_MIX_SSE_I387)
14700     && flag_unsafe_math_optimizations)
14701    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14702        && !flag_trapping_math && !flag_rounding_math)"
14703 {
14704   if (optimize_insn_for_size_p ())
14705     FAIL;
14706
14707   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14708       && !flag_trapping_math && !flag_rounding_math)
14709     {
14710       if (TARGET_ROUND)
14711         {
14712           operands[1] = force_reg (<MODE>mode, operands[1]);
14713           ix86_expand_round_sse4 (operands[0], operands[1]);
14714         }
14715       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14716         ix86_expand_round (operands[0], operands[1]);
14717       else
14718         ix86_expand_rounddf_32 (operands[0], operands[1]);
14719     }
14720   else
14721     {
14722       operands[1] = force_reg (<MODE>mode, operands[1]);
14723       ix86_emit_i387_round (operands[0], operands[1]);
14724     }
14725   DONE;
14726 })
14727
14728 (define_insn_and_split "*fistdi2_1"
14729   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14730         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14731                    UNSPEC_FIST))]
14732   "TARGET_USE_FANCY_MATH_387
14733    && can_create_pseudo_p ()"
14734   "#"
14735   "&& 1"
14736   [(const_int 0)]
14737 {
14738   if (memory_operand (operands[0], VOIDmode))
14739     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14740   else
14741     {
14742       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14743       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14744                                          operands[2]));
14745     }
14746   DONE;
14747 }
14748   [(set_attr "type" "fpspc")
14749    (set_attr "mode" "DI")])
14750
14751 (define_insn "fistdi2"
14752   [(set (match_operand:DI 0 "memory_operand" "=m")
14753         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14754                    UNSPEC_FIST))
14755    (clobber (match_scratch:XF 2 "=&1f"))]
14756   "TARGET_USE_FANCY_MATH_387"
14757   "* return output_fix_trunc (insn, operands, false);"
14758   [(set_attr "type" "fpspc")
14759    (set_attr "mode" "DI")])
14760
14761 (define_insn "fistdi2_with_temp"
14762   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14763         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14764                    UNSPEC_FIST))
14765    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14766    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14767   "TARGET_USE_FANCY_MATH_387"
14768   "#"
14769   [(set_attr "type" "fpspc")
14770    (set_attr "mode" "DI")])
14771
14772 (define_split
14773   [(set (match_operand:DI 0 "register_operand" "")
14774         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14775                    UNSPEC_FIST))
14776    (clobber (match_operand:DI 2 "memory_operand" ""))
14777    (clobber (match_scratch 3 ""))]
14778   "reload_completed"
14779   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14780               (clobber (match_dup 3))])
14781    (set (match_dup 0) (match_dup 2))])
14782
14783 (define_split
14784   [(set (match_operand:DI 0 "memory_operand" "")
14785         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14786                    UNSPEC_FIST))
14787    (clobber (match_operand:DI 2 "memory_operand" ""))
14788    (clobber (match_scratch 3 ""))]
14789   "reload_completed"
14790   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14791               (clobber (match_dup 3))])])
14792
14793 (define_insn_and_split "*fist<mode>2_1"
14794   [(set (match_operand:SWI24 0 "register_operand" "")
14795         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14796                       UNSPEC_FIST))]
14797   "TARGET_USE_FANCY_MATH_387
14798    && can_create_pseudo_p ()"
14799   "#"
14800   "&& 1"
14801   [(const_int 0)]
14802 {
14803   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14804   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14805                                         operands[2]));
14806   DONE;
14807 }
14808   [(set_attr "type" "fpspc")
14809    (set_attr "mode" "<MODE>")])
14810
14811 (define_insn "fist<mode>2"
14812   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14813         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14814                       UNSPEC_FIST))]
14815   "TARGET_USE_FANCY_MATH_387"
14816   "* return output_fix_trunc (insn, operands, false);"
14817   [(set_attr "type" "fpspc")
14818    (set_attr "mode" "<MODE>")])
14819
14820 (define_insn "fist<mode>2_with_temp"
14821   [(set (match_operand:SWI24 0 "register_operand" "=r")
14822         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14823                       UNSPEC_FIST))
14824    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14825   "TARGET_USE_FANCY_MATH_387"
14826   "#"
14827   [(set_attr "type" "fpspc")
14828    (set_attr "mode" "<MODE>")])
14829
14830 (define_split
14831   [(set (match_operand:SWI24 0 "register_operand" "")
14832         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14833                       UNSPEC_FIST))
14834    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14835   "reload_completed"
14836   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14837    (set (match_dup 0) (match_dup 2))])
14838
14839 (define_split
14840   [(set (match_operand:SWI24 0 "memory_operand" "")
14841         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14842                       UNSPEC_FIST))
14843    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14844   "reload_completed"
14845   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14846
14847 (define_expand "lrintxf<mode>2"
14848   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14849      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14850                      UNSPEC_FIST))]
14851   "TARGET_USE_FANCY_MATH_387")
14852
14853 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14854   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14855      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14856                         UNSPEC_FIX_NOTRUNC))]
14857   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14858    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14859
14860 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14861   [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14862    (match_operand:X87MODEF 1 "register_operand" "")]
14863   "(TARGET_USE_FANCY_MATH_387
14864     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14865         || TARGET_MIX_SSE_I387)
14866     && flag_unsafe_math_optimizations)
14867    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14868        && <SWI248x:MODE>mode != HImode 
14869        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14870        && !flag_trapping_math && !flag_rounding_math)"
14871 {
14872   if (optimize_insn_for_size_p ())
14873     FAIL;
14874
14875   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14876       && <SWI248x:MODE>mode != HImode
14877       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14878       && !flag_trapping_math && !flag_rounding_math)
14879     ix86_expand_lround (operands[0], operands[1]);
14880   else
14881     ix86_emit_i387_round (operands[0], operands[1]);
14882   DONE;
14883 })
14884
14885 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14886 (define_insn_and_split "frndintxf2_floor"
14887   [(set (match_operand:XF 0 "register_operand" "")
14888         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14889          UNSPEC_FRNDINT_FLOOR))
14890    (clobber (reg:CC FLAGS_REG))]
14891   "TARGET_USE_FANCY_MATH_387
14892    && flag_unsafe_math_optimizations
14893    && can_create_pseudo_p ()"
14894   "#"
14895   "&& 1"
14896   [(const_int 0)]
14897 {
14898   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14899
14900   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14901   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14902
14903   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14904                                         operands[2], operands[3]));
14905   DONE;
14906 }
14907   [(set_attr "type" "frndint")
14908    (set_attr "i387_cw" "floor")
14909    (set_attr "mode" "XF")])
14910
14911 (define_insn "frndintxf2_floor_i387"
14912   [(set (match_operand:XF 0 "register_operand" "=f")
14913         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14914          UNSPEC_FRNDINT_FLOOR))
14915    (use (match_operand:HI 2 "memory_operand" "m"))
14916    (use (match_operand:HI 3 "memory_operand" "m"))]
14917   "TARGET_USE_FANCY_MATH_387
14918    && flag_unsafe_math_optimizations"
14919   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14920   [(set_attr "type" "frndint")
14921    (set_attr "i387_cw" "floor")
14922    (set_attr "mode" "XF")])
14923
14924 (define_expand "floorxf2"
14925   [(use (match_operand:XF 0 "register_operand" ""))
14926    (use (match_operand:XF 1 "register_operand" ""))]
14927   "TARGET_USE_FANCY_MATH_387
14928    && flag_unsafe_math_optimizations"
14929 {
14930   if (optimize_insn_for_size_p ())
14931     FAIL;
14932   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14933   DONE;
14934 })
14935
14936 (define_expand "floor<mode>2"
14937   [(use (match_operand:MODEF 0 "register_operand" ""))
14938    (use (match_operand:MODEF 1 "register_operand" ""))]
14939   "(TARGET_USE_FANCY_MATH_387
14940     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14941         || TARGET_MIX_SSE_I387)
14942     && flag_unsafe_math_optimizations)
14943    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14944        && !flag_trapping_math)"
14945 {
14946   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14947       && !flag_trapping_math)
14948     {
14949       if (TARGET_ROUND)
14950         emit_insn (gen_sse4_1_round<mode>2
14951                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14952       else if (optimize_insn_for_size_p ())
14953         FAIL;
14954       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14955         ix86_expand_floorceil (operands[0], operands[1], true);
14956       else
14957         ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14958     }
14959   else
14960     {
14961       rtx op0, op1;
14962
14963       if (optimize_insn_for_size_p ())
14964         FAIL;
14965
14966       op0 = gen_reg_rtx (XFmode);
14967       op1 = gen_reg_rtx (XFmode);
14968       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14969       emit_insn (gen_frndintxf2_floor (op0, op1));
14970
14971       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14972     }
14973   DONE;
14974 })
14975
14976 (define_insn_and_split "*fist<mode>2_floor_1"
14977   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14978         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14979                         UNSPEC_FIST_FLOOR))
14980    (clobber (reg:CC FLAGS_REG))]
14981   "TARGET_USE_FANCY_MATH_387
14982    && flag_unsafe_math_optimizations
14983    && can_create_pseudo_p ()"
14984   "#"
14985   "&& 1"
14986   [(const_int 0)]
14987 {
14988   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14989
14990   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14991   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14992   if (memory_operand (operands[0], VOIDmode))
14993     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14994                                       operands[2], operands[3]));
14995   else
14996     {
14997       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14998       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14999                                                   operands[2], operands[3],
15000                                                   operands[4]));
15001     }
15002   DONE;
15003 }
15004   [(set_attr "type" "fistp")
15005    (set_attr "i387_cw" "floor")
15006    (set_attr "mode" "<MODE>")])
15007
15008 (define_insn "fistdi2_floor"
15009   [(set (match_operand:DI 0 "memory_operand" "=m")
15010         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15011                    UNSPEC_FIST_FLOOR))
15012    (use (match_operand:HI 2 "memory_operand" "m"))
15013    (use (match_operand:HI 3 "memory_operand" "m"))
15014    (clobber (match_scratch:XF 4 "=&1f"))]
15015   "TARGET_USE_FANCY_MATH_387
15016    && flag_unsafe_math_optimizations"
15017   "* return output_fix_trunc (insn, operands, false);"
15018   [(set_attr "type" "fistp")
15019    (set_attr "i387_cw" "floor")
15020    (set_attr "mode" "DI")])
15021
15022 (define_insn "fistdi2_floor_with_temp"
15023   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15024         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15025                    UNSPEC_FIST_FLOOR))
15026    (use (match_operand:HI 2 "memory_operand" "m,m"))
15027    (use (match_operand:HI 3 "memory_operand" "m,m"))
15028    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15029    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15030   "TARGET_USE_FANCY_MATH_387
15031    && flag_unsafe_math_optimizations"
15032   "#"
15033   [(set_attr "type" "fistp")
15034    (set_attr "i387_cw" "floor")
15035    (set_attr "mode" "DI")])
15036
15037 (define_split
15038   [(set (match_operand:DI 0 "register_operand" "")
15039         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15040                    UNSPEC_FIST_FLOOR))
15041    (use (match_operand:HI 2 "memory_operand" ""))
15042    (use (match_operand:HI 3 "memory_operand" ""))
15043    (clobber (match_operand:DI 4 "memory_operand" ""))
15044    (clobber (match_scratch 5 ""))]
15045   "reload_completed"
15046   [(parallel [(set (match_dup 4)
15047                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15048               (use (match_dup 2))
15049               (use (match_dup 3))
15050               (clobber (match_dup 5))])
15051    (set (match_dup 0) (match_dup 4))])
15052
15053 (define_split
15054   [(set (match_operand:DI 0 "memory_operand" "")
15055         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15056                    UNSPEC_FIST_FLOOR))
15057    (use (match_operand:HI 2 "memory_operand" ""))
15058    (use (match_operand:HI 3 "memory_operand" ""))
15059    (clobber (match_operand:DI 4 "memory_operand" ""))
15060    (clobber (match_scratch 5 ""))]
15061   "reload_completed"
15062   [(parallel [(set (match_dup 0)
15063                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15064               (use (match_dup 2))
15065               (use (match_dup 3))
15066               (clobber (match_dup 5))])])
15067
15068 (define_insn "fist<mode>2_floor"
15069   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15070         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15071                       UNSPEC_FIST_FLOOR))
15072    (use (match_operand:HI 2 "memory_operand" "m"))
15073    (use (match_operand:HI 3 "memory_operand" "m"))]
15074   "TARGET_USE_FANCY_MATH_387
15075    && flag_unsafe_math_optimizations"
15076   "* return output_fix_trunc (insn, operands, false);"
15077   [(set_attr "type" "fistp")
15078    (set_attr "i387_cw" "floor")
15079    (set_attr "mode" "<MODE>")])
15080
15081 (define_insn "fist<mode>2_floor_with_temp"
15082   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15083         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15084                       UNSPEC_FIST_FLOOR))
15085    (use (match_operand:HI 2 "memory_operand" "m,m"))
15086    (use (match_operand:HI 3 "memory_operand" "m,m"))
15087    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15088   "TARGET_USE_FANCY_MATH_387
15089    && flag_unsafe_math_optimizations"
15090   "#"
15091   [(set_attr "type" "fistp")
15092    (set_attr "i387_cw" "floor")
15093    (set_attr "mode" "<MODE>")])
15094
15095 (define_split
15096   [(set (match_operand:SWI24 0 "register_operand" "")
15097         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15098                       UNSPEC_FIST_FLOOR))
15099    (use (match_operand:HI 2 "memory_operand" ""))
15100    (use (match_operand:HI 3 "memory_operand" ""))
15101    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15102   "reload_completed"
15103   [(parallel [(set (match_dup 4)
15104                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15105               (use (match_dup 2))
15106               (use (match_dup 3))])
15107    (set (match_dup 0) (match_dup 4))])
15108
15109 (define_split
15110   [(set (match_operand:SWI24 0 "memory_operand" "")
15111         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15112                       UNSPEC_FIST_FLOOR))
15113    (use (match_operand:HI 2 "memory_operand" ""))
15114    (use (match_operand:HI 3 "memory_operand" ""))
15115    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15116   "reload_completed"
15117   [(parallel [(set (match_dup 0)
15118                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15119               (use (match_dup 2))
15120               (use (match_dup 3))])])
15121
15122 (define_expand "lfloorxf<mode>2"
15123   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15124                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15125                                    UNSPEC_FIST_FLOOR))
15126               (clobber (reg:CC FLAGS_REG))])]
15127   "TARGET_USE_FANCY_MATH_387
15128    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15129    && flag_unsafe_math_optimizations")
15130
15131 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15132   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15133    (match_operand:MODEF 1 "register_operand" "")]
15134   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15135    && !flag_trapping_math"
15136 {
15137   if (TARGET_64BIT && optimize_insn_for_size_p ())
15138     FAIL;
15139   ix86_expand_lfloorceil (operands[0], operands[1], true);
15140   DONE;
15141 })
15142
15143 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15144 (define_insn_and_split "frndintxf2_ceil"
15145   [(set (match_operand:XF 0 "register_operand" "")
15146         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15147          UNSPEC_FRNDINT_CEIL))
15148    (clobber (reg:CC FLAGS_REG))]
15149   "TARGET_USE_FANCY_MATH_387
15150    && flag_unsafe_math_optimizations
15151    && can_create_pseudo_p ()"
15152   "#"
15153   "&& 1"
15154   [(const_int 0)]
15155 {
15156   ix86_optimize_mode_switching[I387_CEIL] = 1;
15157
15158   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15159   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15160
15161   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15162                                        operands[2], operands[3]));
15163   DONE;
15164 }
15165   [(set_attr "type" "frndint")
15166    (set_attr "i387_cw" "ceil")
15167    (set_attr "mode" "XF")])
15168
15169 (define_insn "frndintxf2_ceil_i387"
15170   [(set (match_operand:XF 0 "register_operand" "=f")
15171         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15172          UNSPEC_FRNDINT_CEIL))
15173    (use (match_operand:HI 2 "memory_operand" "m"))
15174    (use (match_operand:HI 3 "memory_operand" "m"))]
15175   "TARGET_USE_FANCY_MATH_387
15176    && flag_unsafe_math_optimizations"
15177   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15178   [(set_attr "type" "frndint")
15179    (set_attr "i387_cw" "ceil")
15180    (set_attr "mode" "XF")])
15181
15182 (define_expand "ceilxf2"
15183   [(use (match_operand:XF 0 "register_operand" ""))
15184    (use (match_operand:XF 1 "register_operand" ""))]
15185   "TARGET_USE_FANCY_MATH_387
15186    && flag_unsafe_math_optimizations"
15187 {
15188   if (optimize_insn_for_size_p ())
15189     FAIL;
15190   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15191   DONE;
15192 })
15193
15194 (define_expand "ceil<mode>2"
15195   [(use (match_operand:MODEF 0 "register_operand" ""))
15196    (use (match_operand:MODEF 1 "register_operand" ""))]
15197   "(TARGET_USE_FANCY_MATH_387
15198     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15199         || TARGET_MIX_SSE_I387)
15200     && flag_unsafe_math_optimizations)
15201    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15202        && !flag_trapping_math)"
15203 {
15204   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15205       && !flag_trapping_math)
15206     {
15207       if (TARGET_ROUND)
15208         emit_insn (gen_sse4_1_round<mode>2
15209                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15210       else if (optimize_insn_for_size_p ())
15211         FAIL;
15212       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15213         ix86_expand_floorceil (operands[0], operands[1], false);
15214       else
15215         ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15216     }
15217   else
15218     {
15219       rtx op0, op1;
15220
15221       if (optimize_insn_for_size_p ())
15222         FAIL;
15223
15224       op0 = gen_reg_rtx (XFmode);
15225       op1 = gen_reg_rtx (XFmode);
15226       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15227       emit_insn (gen_frndintxf2_ceil (op0, op1));
15228
15229       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15230     }
15231   DONE;
15232 })
15233
15234 (define_insn_and_split "*fist<mode>2_ceil_1"
15235   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15236         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15237                         UNSPEC_FIST_CEIL))
15238    (clobber (reg:CC FLAGS_REG))]
15239   "TARGET_USE_FANCY_MATH_387
15240    && flag_unsafe_math_optimizations
15241    && can_create_pseudo_p ()"
15242   "#"
15243   "&& 1"
15244   [(const_int 0)]
15245 {
15246   ix86_optimize_mode_switching[I387_CEIL] = 1;
15247
15248   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15249   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15250   if (memory_operand (operands[0], VOIDmode))
15251     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15252                                      operands[2], operands[3]));
15253   else
15254     {
15255       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15256       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15257                                                  operands[2], operands[3],
15258                                                  operands[4]));
15259     }
15260   DONE;
15261 }
15262   [(set_attr "type" "fistp")
15263    (set_attr "i387_cw" "ceil")
15264    (set_attr "mode" "<MODE>")])
15265
15266 (define_insn "fistdi2_ceil"
15267   [(set (match_operand:DI 0 "memory_operand" "=m")
15268         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15269                    UNSPEC_FIST_CEIL))
15270    (use (match_operand:HI 2 "memory_operand" "m"))
15271    (use (match_operand:HI 3 "memory_operand" "m"))
15272    (clobber (match_scratch:XF 4 "=&1f"))]
15273   "TARGET_USE_FANCY_MATH_387
15274    && flag_unsafe_math_optimizations"
15275   "* return output_fix_trunc (insn, operands, false);"
15276   [(set_attr "type" "fistp")
15277    (set_attr "i387_cw" "ceil")
15278    (set_attr "mode" "DI")])
15279
15280 (define_insn "fistdi2_ceil_with_temp"
15281   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15282         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15283                    UNSPEC_FIST_CEIL))
15284    (use (match_operand:HI 2 "memory_operand" "m,m"))
15285    (use (match_operand:HI 3 "memory_operand" "m,m"))
15286    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15287    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15288   "TARGET_USE_FANCY_MATH_387
15289    && flag_unsafe_math_optimizations"
15290   "#"
15291   [(set_attr "type" "fistp")
15292    (set_attr "i387_cw" "ceil")
15293    (set_attr "mode" "DI")])
15294
15295 (define_split
15296   [(set (match_operand:DI 0 "register_operand" "")
15297         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15298                    UNSPEC_FIST_CEIL))
15299    (use (match_operand:HI 2 "memory_operand" ""))
15300    (use (match_operand:HI 3 "memory_operand" ""))
15301    (clobber (match_operand:DI 4 "memory_operand" ""))
15302    (clobber (match_scratch 5 ""))]
15303   "reload_completed"
15304   [(parallel [(set (match_dup 4)
15305                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15306               (use (match_dup 2))
15307               (use (match_dup 3))
15308               (clobber (match_dup 5))])
15309    (set (match_dup 0) (match_dup 4))])
15310
15311 (define_split
15312   [(set (match_operand:DI 0 "memory_operand" "")
15313         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15314                    UNSPEC_FIST_CEIL))
15315    (use (match_operand:HI 2 "memory_operand" ""))
15316    (use (match_operand:HI 3 "memory_operand" ""))
15317    (clobber (match_operand:DI 4 "memory_operand" ""))
15318    (clobber (match_scratch 5 ""))]
15319   "reload_completed"
15320   [(parallel [(set (match_dup 0)
15321                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15322               (use (match_dup 2))
15323               (use (match_dup 3))
15324               (clobber (match_dup 5))])])
15325
15326 (define_insn "fist<mode>2_ceil"
15327   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15328         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15329                       UNSPEC_FIST_CEIL))
15330    (use (match_operand:HI 2 "memory_operand" "m"))
15331    (use (match_operand:HI 3 "memory_operand" "m"))]
15332   "TARGET_USE_FANCY_MATH_387
15333    && flag_unsafe_math_optimizations"
15334   "* return output_fix_trunc (insn, operands, false);"
15335   [(set_attr "type" "fistp")
15336    (set_attr "i387_cw" "ceil")
15337    (set_attr "mode" "<MODE>")])
15338
15339 (define_insn "fist<mode>2_ceil_with_temp"
15340   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15341         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15342                       UNSPEC_FIST_CEIL))
15343    (use (match_operand:HI 2 "memory_operand" "m,m"))
15344    (use (match_operand:HI 3 "memory_operand" "m,m"))
15345    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15346   "TARGET_USE_FANCY_MATH_387
15347    && flag_unsafe_math_optimizations"
15348   "#"
15349   [(set_attr "type" "fistp")
15350    (set_attr "i387_cw" "ceil")
15351    (set_attr "mode" "<MODE>")])
15352
15353 (define_split
15354   [(set (match_operand:SWI24 0 "register_operand" "")
15355         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15356                       UNSPEC_FIST_CEIL))
15357    (use (match_operand:HI 2 "memory_operand" ""))
15358    (use (match_operand:HI 3 "memory_operand" ""))
15359    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15360   "reload_completed"
15361   [(parallel [(set (match_dup 4)
15362                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15363               (use (match_dup 2))
15364               (use (match_dup 3))])
15365    (set (match_dup 0) (match_dup 4))])
15366
15367 (define_split
15368   [(set (match_operand:SWI24 0 "memory_operand" "")
15369         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15370                       UNSPEC_FIST_CEIL))
15371    (use (match_operand:HI 2 "memory_operand" ""))
15372    (use (match_operand:HI 3 "memory_operand" ""))
15373    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15374   "reload_completed"
15375   [(parallel [(set (match_dup 0)
15376                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15377               (use (match_dup 2))
15378               (use (match_dup 3))])])
15379
15380 (define_expand "lceilxf<mode>2"
15381   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15382                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15383                                    UNSPEC_FIST_CEIL))
15384               (clobber (reg:CC FLAGS_REG))])]
15385   "TARGET_USE_FANCY_MATH_387
15386    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15387    && flag_unsafe_math_optimizations")
15388
15389 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15390   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15391    (match_operand:MODEF 1 "register_operand" "")]
15392   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15393    && !flag_trapping_math"
15394 {
15395   ix86_expand_lfloorceil (operands[0], operands[1], false);
15396   DONE;
15397 })
15398
15399 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15400 (define_insn_and_split "frndintxf2_trunc"
15401   [(set (match_operand:XF 0 "register_operand" "")
15402         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15403          UNSPEC_FRNDINT_TRUNC))
15404    (clobber (reg:CC FLAGS_REG))]
15405   "TARGET_USE_FANCY_MATH_387
15406    && flag_unsafe_math_optimizations
15407    && can_create_pseudo_p ()"
15408   "#"
15409   "&& 1"
15410   [(const_int 0)]
15411 {
15412   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15413
15414   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15415   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15416
15417   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15418                                         operands[2], operands[3]));
15419   DONE;
15420 }
15421   [(set_attr "type" "frndint")
15422    (set_attr "i387_cw" "trunc")
15423    (set_attr "mode" "XF")])
15424
15425 (define_insn "frndintxf2_trunc_i387"
15426   [(set (match_operand:XF 0 "register_operand" "=f")
15427         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15428          UNSPEC_FRNDINT_TRUNC))
15429    (use (match_operand:HI 2 "memory_operand" "m"))
15430    (use (match_operand:HI 3 "memory_operand" "m"))]
15431   "TARGET_USE_FANCY_MATH_387
15432    && flag_unsafe_math_optimizations"
15433   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15434   [(set_attr "type" "frndint")
15435    (set_attr "i387_cw" "trunc")
15436    (set_attr "mode" "XF")])
15437
15438 (define_expand "btruncxf2"
15439   [(use (match_operand:XF 0 "register_operand" ""))
15440    (use (match_operand:XF 1 "register_operand" ""))]
15441   "TARGET_USE_FANCY_MATH_387
15442    && flag_unsafe_math_optimizations"
15443 {
15444   if (optimize_insn_for_size_p ())
15445     FAIL;
15446   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15447   DONE;
15448 })
15449
15450 (define_expand "btrunc<mode>2"
15451   [(use (match_operand:MODEF 0 "register_operand" ""))
15452    (use (match_operand:MODEF 1 "register_operand" ""))]
15453   "(TARGET_USE_FANCY_MATH_387
15454     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15455         || TARGET_MIX_SSE_I387)
15456     && flag_unsafe_math_optimizations)
15457    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15458        && !flag_trapping_math)"
15459 {
15460   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15461       && !flag_trapping_math)
15462     {
15463       if (TARGET_ROUND)
15464         emit_insn (gen_sse4_1_round<mode>2
15465                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15466       else if (optimize_insn_for_size_p ())
15467         FAIL;
15468       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15469         ix86_expand_trunc (operands[0], operands[1]);
15470       else
15471         ix86_expand_truncdf_32 (operands[0], operands[1]);
15472     }
15473   else
15474     {
15475       rtx op0, op1;
15476
15477       if (optimize_insn_for_size_p ())
15478         FAIL;
15479
15480       op0 = gen_reg_rtx (XFmode);
15481       op1 = gen_reg_rtx (XFmode);
15482       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15483       emit_insn (gen_frndintxf2_trunc (op0, op1));
15484
15485       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15486     }
15487   DONE;
15488 })
15489
15490 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15491 (define_insn_and_split "frndintxf2_mask_pm"
15492   [(set (match_operand:XF 0 "register_operand" "")
15493         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15494          UNSPEC_FRNDINT_MASK_PM))
15495    (clobber (reg:CC FLAGS_REG))]
15496   "TARGET_USE_FANCY_MATH_387
15497    && flag_unsafe_math_optimizations
15498    && can_create_pseudo_p ()"
15499   "#"
15500   "&& 1"
15501   [(const_int 0)]
15502 {
15503   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15504
15505   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15506   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15507
15508   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15509                                           operands[2], operands[3]));
15510   DONE;
15511 }
15512   [(set_attr "type" "frndint")
15513    (set_attr "i387_cw" "mask_pm")
15514    (set_attr "mode" "XF")])
15515
15516 (define_insn "frndintxf2_mask_pm_i387"
15517   [(set (match_operand:XF 0 "register_operand" "=f")
15518         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15519          UNSPEC_FRNDINT_MASK_PM))
15520    (use (match_operand:HI 2 "memory_operand" "m"))
15521    (use (match_operand:HI 3 "memory_operand" "m"))]
15522   "TARGET_USE_FANCY_MATH_387
15523    && flag_unsafe_math_optimizations"
15524   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15525   [(set_attr "type" "frndint")
15526    (set_attr "i387_cw" "mask_pm")
15527    (set_attr "mode" "XF")])
15528
15529 (define_expand "nearbyintxf2"
15530   [(use (match_operand:XF 0 "register_operand" ""))
15531    (use (match_operand:XF 1 "register_operand" ""))]
15532   "TARGET_USE_FANCY_MATH_387
15533    && flag_unsafe_math_optimizations"
15534 {
15535   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15536   DONE;
15537 })
15538
15539 (define_expand "nearbyint<mode>2"
15540   [(use (match_operand:MODEF 0 "register_operand" ""))
15541    (use (match_operand:MODEF 1 "register_operand" ""))]
15542   "TARGET_USE_FANCY_MATH_387
15543    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15544        || TARGET_MIX_SSE_I387)
15545    && flag_unsafe_math_optimizations"
15546 {
15547   rtx op0 = gen_reg_rtx (XFmode);
15548   rtx op1 = gen_reg_rtx (XFmode);
15549
15550   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15551   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15552
15553   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15554   DONE;
15555 })
15556
15557 (define_insn "fxam<mode>2_i387"
15558   [(set (match_operand:HI 0 "register_operand" "=a")
15559         (unspec:HI
15560           [(match_operand:X87MODEF 1 "register_operand" "f")]
15561           UNSPEC_FXAM))]
15562   "TARGET_USE_FANCY_MATH_387"
15563   "fxam\n\tfnstsw\t%0"
15564   [(set_attr "type" "multi")
15565    (set_attr "length" "4")
15566    (set_attr "unit" "i387")
15567    (set_attr "mode" "<MODE>")])
15568
15569 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15570   [(set (match_operand:HI 0 "register_operand" "")
15571         (unspec:HI
15572           [(match_operand:MODEF 1 "memory_operand" "")]
15573           UNSPEC_FXAM_MEM))]
15574   "TARGET_USE_FANCY_MATH_387
15575    && can_create_pseudo_p ()"
15576   "#"
15577   "&& 1"
15578   [(set (match_dup 2)(match_dup 1))
15579    (set (match_dup 0)
15580         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15581 {
15582   operands[2] = gen_reg_rtx (<MODE>mode);
15583
15584   MEM_VOLATILE_P (operands[1]) = 1;
15585 }
15586   [(set_attr "type" "multi")
15587    (set_attr "unit" "i387")
15588    (set_attr "mode" "<MODE>")])
15589
15590 (define_expand "isinfxf2"
15591   [(use (match_operand:SI 0 "register_operand" ""))
15592    (use (match_operand:XF 1 "register_operand" ""))]
15593   "TARGET_USE_FANCY_MATH_387
15594    && TARGET_C99_FUNCTIONS"
15595 {
15596   rtx mask = GEN_INT (0x45);
15597   rtx val = GEN_INT (0x05);
15598
15599   rtx cond;
15600
15601   rtx scratch = gen_reg_rtx (HImode);
15602   rtx res = gen_reg_rtx (QImode);
15603
15604   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15605
15606   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15607   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15608   cond = gen_rtx_fmt_ee (EQ, QImode,
15609                          gen_rtx_REG (CCmode, FLAGS_REG),
15610                          const0_rtx);
15611   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15612   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15613   DONE;
15614 })
15615
15616 (define_expand "isinf<mode>2"
15617   [(use (match_operand:SI 0 "register_operand" ""))
15618    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15619   "TARGET_USE_FANCY_MATH_387
15620    && TARGET_C99_FUNCTIONS
15621    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15622 {
15623   rtx mask = GEN_INT (0x45);
15624   rtx val = GEN_INT (0x05);
15625
15626   rtx cond;
15627
15628   rtx scratch = gen_reg_rtx (HImode);
15629   rtx res = gen_reg_rtx (QImode);
15630
15631   /* Remove excess precision by forcing value through memory. */
15632   if (memory_operand (operands[1], VOIDmode))
15633     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15634   else
15635     {
15636       enum ix86_stack_slot slot = (virtuals_instantiated
15637                                    ? SLOT_TEMP
15638                                    : SLOT_VIRTUAL);
15639       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15640
15641       emit_move_insn (temp, operands[1]);
15642       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15643     }
15644
15645   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15646   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15647   cond = gen_rtx_fmt_ee (EQ, QImode,
15648                          gen_rtx_REG (CCmode, FLAGS_REG),
15649                          const0_rtx);
15650   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15651   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15652   DONE;
15653 })
15654
15655 (define_expand "signbitxf2"
15656   [(use (match_operand:SI 0 "register_operand" ""))
15657    (use (match_operand:XF 1 "register_operand" ""))]
15658   "TARGET_USE_FANCY_MATH_387"
15659 {
15660   rtx scratch = gen_reg_rtx (HImode);
15661
15662   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15663   emit_insn (gen_andsi3 (operands[0],
15664              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15665   DONE;
15666 })
15667
15668 (define_insn "movmsk_df"
15669   [(set (match_operand:SI 0 "register_operand" "=r")
15670         (unspec:SI
15671           [(match_operand:DF 1 "register_operand" "x")]
15672           UNSPEC_MOVMSK))]
15673   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15674   "%vmovmskpd\t{%1, %0|%0, %1}"
15675   [(set_attr "type" "ssemov")
15676    (set_attr "prefix" "maybe_vex")
15677    (set_attr "mode" "DF")])
15678
15679 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15680 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15681 (define_expand "signbitdf2"
15682   [(use (match_operand:SI 0 "register_operand" ""))
15683    (use (match_operand:DF 1 "register_operand" ""))]
15684   "TARGET_USE_FANCY_MATH_387
15685    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15686 {
15687   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15688     {
15689       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15690       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15691     }
15692   else
15693     {
15694       rtx scratch = gen_reg_rtx (HImode);
15695
15696       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15697       emit_insn (gen_andsi3 (operands[0],
15698                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15699     }
15700   DONE;
15701 })
15702
15703 (define_expand "signbitsf2"
15704   [(use (match_operand:SI 0 "register_operand" ""))
15705    (use (match_operand:SF 1 "register_operand" ""))]
15706   "TARGET_USE_FANCY_MATH_387
15707    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15708 {
15709   rtx scratch = gen_reg_rtx (HImode);
15710
15711   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15712   emit_insn (gen_andsi3 (operands[0],
15713              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15714   DONE;
15715 })
15716 \f
15717 ;; Block operation instructions
15718
15719 (define_insn "cld"
15720   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15721   ""
15722   "cld"
15723   [(set_attr "length" "1")
15724    (set_attr "length_immediate" "0")
15725    (set_attr "modrm" "0")])
15726
15727 (define_expand "movmem<mode>"
15728   [(use (match_operand:BLK 0 "memory_operand" ""))
15729    (use (match_operand:BLK 1 "memory_operand" ""))
15730    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15731    (use (match_operand:SWI48 3 "const_int_operand" ""))
15732    (use (match_operand:SI 4 "const_int_operand" ""))
15733    (use (match_operand:SI 5 "const_int_operand" ""))]
15734   ""
15735 {
15736  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15737                          operands[4], operands[5]))
15738    DONE;
15739  else
15740    FAIL;
15741 })
15742
15743 ;; Most CPUs don't like single string operations
15744 ;; Handle this case here to simplify previous expander.
15745
15746 (define_expand "strmov"
15747   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15748    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15749    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15750               (clobber (reg:CC FLAGS_REG))])
15751    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15752               (clobber (reg:CC FLAGS_REG))])]
15753   ""
15754 {
15755   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15756
15757   /* If .md ever supports :P for Pmode, these can be directly
15758      in the pattern above.  */
15759   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15760   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15761
15762   /* Can't use this if the user has appropriated esi or edi.  */
15763   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15764       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15765     {
15766       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15767                                       operands[2], operands[3],
15768                                       operands[5], operands[6]));
15769       DONE;
15770     }
15771
15772   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15773 })
15774
15775 (define_expand "strmov_singleop"
15776   [(parallel [(set (match_operand 1 "memory_operand" "")
15777                    (match_operand 3 "memory_operand" ""))
15778               (set (match_operand 0 "register_operand" "")
15779                    (match_operand 4 "" ""))
15780               (set (match_operand 2 "register_operand" "")
15781                    (match_operand 5 "" ""))])]
15782   ""
15783   "ix86_current_function_needs_cld = 1;")
15784
15785 (define_insn "*strmovdi_rex_1"
15786   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15787         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15788    (set (match_operand:DI 0 "register_operand" "=D")
15789         (plus:DI (match_dup 2)
15790                  (const_int 8)))
15791    (set (match_operand:DI 1 "register_operand" "=S")
15792         (plus:DI (match_dup 3)
15793                  (const_int 8)))]
15794   "TARGET_64BIT
15795    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15796   "movsq"
15797   [(set_attr "type" "str")
15798    (set_attr "memory" "both")
15799    (set_attr "mode" "DI")])
15800
15801 (define_insn "*strmovsi_1"
15802   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15803         (mem:SI (match_operand:P 3 "register_operand" "1")))
15804    (set (match_operand:P 0 "register_operand" "=D")
15805         (plus:P (match_dup 2)
15806                 (const_int 4)))
15807    (set (match_operand:P 1 "register_operand" "=S")
15808         (plus:P (match_dup 3)
15809                 (const_int 4)))]
15810   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15811   "movs{l|d}"
15812   [(set_attr "type" "str")
15813    (set_attr "memory" "both")
15814    (set_attr "mode" "SI")])
15815
15816 (define_insn "*strmovhi_1"
15817   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15818         (mem:HI (match_operand:P 3 "register_operand" "1")))
15819    (set (match_operand:P 0 "register_operand" "=D")
15820         (plus:P (match_dup 2)
15821                 (const_int 2)))
15822    (set (match_operand:P 1 "register_operand" "=S")
15823         (plus:P (match_dup 3)
15824                 (const_int 2)))]
15825   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15826   "movsw"
15827   [(set_attr "type" "str")
15828    (set_attr "memory" "both")
15829    (set_attr "mode" "HI")])
15830
15831 (define_insn "*strmovqi_1"
15832   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15833         (mem:QI (match_operand:P 3 "register_operand" "1")))
15834    (set (match_operand:P 0 "register_operand" "=D")
15835         (plus:P (match_dup 2)
15836                 (const_int 1)))
15837    (set (match_operand:P 1 "register_operand" "=S")
15838         (plus:P (match_dup 3)
15839                 (const_int 1)))]
15840   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15841   "movsb"
15842   [(set_attr "type" "str")
15843    (set_attr "memory" "both")
15844    (set (attr "prefix_rex")
15845         (if_then_else
15846           (match_test "<P:MODE>mode == DImode")
15847           (const_string "0")
15848           (const_string "*")))
15849    (set_attr "mode" "QI")])
15850
15851 (define_expand "rep_mov"
15852   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15853               (set (match_operand 0 "register_operand" "")
15854                    (match_operand 5 "" ""))
15855               (set (match_operand 2 "register_operand" "")
15856                    (match_operand 6 "" ""))
15857               (set (match_operand 1 "memory_operand" "")
15858                    (match_operand 3 "memory_operand" ""))
15859               (use (match_dup 4))])]
15860   ""
15861   "ix86_current_function_needs_cld = 1;")
15862
15863 (define_insn "*rep_movdi_rex64"
15864   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15865    (set (match_operand:DI 0 "register_operand" "=D")
15866         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15867                             (const_int 3))
15868                  (match_operand:DI 3 "register_operand" "0")))
15869    (set (match_operand:DI 1 "register_operand" "=S")
15870         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15871                  (match_operand:DI 4 "register_operand" "1")))
15872    (set (mem:BLK (match_dup 3))
15873         (mem:BLK (match_dup 4)))
15874    (use (match_dup 5))]
15875   "TARGET_64BIT
15876    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15877   "rep{%;} movsq"
15878   [(set_attr "type" "str")
15879    (set_attr "prefix_rep" "1")
15880    (set_attr "memory" "both")
15881    (set_attr "mode" "DI")])
15882
15883 (define_insn "*rep_movsi"
15884   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15885    (set (match_operand:P 0 "register_operand" "=D")
15886         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15887                           (const_int 2))
15888                  (match_operand:P 3 "register_operand" "0")))
15889    (set (match_operand:P 1 "register_operand" "=S")
15890         (plus:P (ashift:P (match_dup 5) (const_int 2))
15891                 (match_operand:P 4 "register_operand" "1")))
15892    (set (mem:BLK (match_dup 3))
15893         (mem:BLK (match_dup 4)))
15894    (use (match_dup 5))]
15895   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15896   "rep{%;} movs{l|d}"
15897   [(set_attr "type" "str")
15898    (set_attr "prefix_rep" "1")
15899    (set_attr "memory" "both")
15900    (set_attr "mode" "SI")])
15901
15902 (define_insn "*rep_movqi"
15903   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15904    (set (match_operand:P 0 "register_operand" "=D")
15905         (plus:P (match_operand:P 3 "register_operand" "0")
15906                 (match_operand:P 5 "register_operand" "2")))
15907    (set (match_operand:P 1 "register_operand" "=S")
15908         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15909    (set (mem:BLK (match_dup 3))
15910         (mem:BLK (match_dup 4)))
15911    (use (match_dup 5))]
15912   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15913   "rep{%;} movsb"
15914   [(set_attr "type" "str")
15915    (set_attr "prefix_rep" "1")
15916    (set_attr "memory" "both")
15917    (set_attr "mode" "QI")])
15918
15919 (define_expand "setmem<mode>"
15920    [(use (match_operand:BLK 0 "memory_operand" ""))
15921     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15922     (use (match_operand:QI 2 "nonmemory_operand" ""))
15923     (use (match_operand 3 "const_int_operand" ""))
15924     (use (match_operand:SI 4 "const_int_operand" ""))
15925     (use (match_operand:SI 5 "const_int_operand" ""))]
15926   ""
15927 {
15928  if (ix86_expand_setmem (operands[0], operands[1],
15929                          operands[2], operands[3],
15930                          operands[4], operands[5]))
15931    DONE;
15932  else
15933    FAIL;
15934 })
15935
15936 ;; Most CPUs don't like single string operations
15937 ;; Handle this case here to simplify previous expander.
15938
15939 (define_expand "strset"
15940   [(set (match_operand 1 "memory_operand" "")
15941         (match_operand 2 "register_operand" ""))
15942    (parallel [(set (match_operand 0 "register_operand" "")
15943                    (match_dup 3))
15944               (clobber (reg:CC FLAGS_REG))])]
15945   ""
15946 {
15947   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15948     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15949
15950   /* If .md ever supports :P for Pmode, this can be directly
15951      in the pattern above.  */
15952   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15953                               GEN_INT (GET_MODE_SIZE (GET_MODE
15954                                                       (operands[2]))));
15955   /* Can't use this if the user has appropriated eax or edi.  */
15956   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15957       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15958     {
15959       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15960                                       operands[3]));
15961       DONE;
15962     }
15963 })
15964
15965 (define_expand "strset_singleop"
15966   [(parallel [(set (match_operand 1 "memory_operand" "")
15967                    (match_operand 2 "register_operand" ""))
15968               (set (match_operand 0 "register_operand" "")
15969                    (match_operand 3 "" ""))])]
15970   ""
15971   "ix86_current_function_needs_cld = 1;")
15972
15973 (define_insn "*strsetdi_rex_1"
15974   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15975         (match_operand:DI 2 "register_operand" "a"))
15976    (set (match_operand:DI 0 "register_operand" "=D")
15977         (plus:DI (match_dup 1)
15978                  (const_int 8)))]
15979   "TARGET_64BIT
15980    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15981   "stosq"
15982   [(set_attr "type" "str")
15983    (set_attr "memory" "store")
15984    (set_attr "mode" "DI")])
15985
15986 (define_insn "*strsetsi_1"
15987   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15988         (match_operand:SI 2 "register_operand" "a"))
15989    (set (match_operand:P 0 "register_operand" "=D")
15990         (plus:P (match_dup 1)
15991                 (const_int 4)))]
15992   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15993   "stos{l|d}"
15994   [(set_attr "type" "str")
15995    (set_attr "memory" "store")
15996    (set_attr "mode" "SI")])
15997
15998 (define_insn "*strsethi_1"
15999   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16000         (match_operand:HI 2 "register_operand" "a"))
16001    (set (match_operand:P 0 "register_operand" "=D")
16002         (plus:P (match_dup 1)
16003                 (const_int 2)))]
16004   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16005   "stosw"
16006   [(set_attr "type" "str")
16007    (set_attr "memory" "store")
16008    (set_attr "mode" "HI")])
16009
16010 (define_insn "*strsetqi_1"
16011   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16012         (match_operand:QI 2 "register_operand" "a"))
16013    (set (match_operand:P 0 "register_operand" "=D")
16014         (plus:P (match_dup 1)
16015                 (const_int 1)))]
16016   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16017   "stosb"
16018   [(set_attr "type" "str")
16019    (set_attr "memory" "store")
16020    (set (attr "prefix_rex")
16021         (if_then_else
16022           (match_test "<P:MODE>mode == DImode")
16023           (const_string "0")
16024           (const_string "*")))
16025    (set_attr "mode" "QI")])
16026
16027 (define_expand "rep_stos"
16028   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16029               (set (match_operand 0 "register_operand" "")
16030                    (match_operand 4 "" ""))
16031               (set (match_operand 2 "memory_operand" "") (const_int 0))
16032               (use (match_operand 3 "register_operand" ""))
16033               (use (match_dup 1))])]
16034   ""
16035   "ix86_current_function_needs_cld = 1;")
16036
16037 (define_insn "*rep_stosdi_rex64"
16038   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16039    (set (match_operand:DI 0 "register_operand" "=D")
16040         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16041                             (const_int 3))
16042                  (match_operand:DI 3 "register_operand" "0")))
16043    (set (mem:BLK (match_dup 3))
16044         (const_int 0))
16045    (use (match_operand:DI 2 "register_operand" "a"))
16046    (use (match_dup 4))]
16047   "TARGET_64BIT
16048    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16049   "rep{%;} stosq"
16050   [(set_attr "type" "str")
16051    (set_attr "prefix_rep" "1")
16052    (set_attr "memory" "store")
16053    (set_attr "mode" "DI")])
16054
16055 (define_insn "*rep_stossi"
16056   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16057    (set (match_operand:P 0 "register_operand" "=D")
16058         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16059                           (const_int 2))
16060                  (match_operand:P 3 "register_operand" "0")))
16061    (set (mem:BLK (match_dup 3))
16062         (const_int 0))
16063    (use (match_operand:SI 2 "register_operand" "a"))
16064    (use (match_dup 4))]
16065   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16066   "rep{%;} stos{l|d}"
16067   [(set_attr "type" "str")
16068    (set_attr "prefix_rep" "1")
16069    (set_attr "memory" "store")
16070    (set_attr "mode" "SI")])
16071
16072 (define_insn "*rep_stosqi"
16073   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16074    (set (match_operand:P 0 "register_operand" "=D")
16075         (plus:P (match_operand:P 3 "register_operand" "0")
16076                 (match_operand:P 4 "register_operand" "1")))
16077    (set (mem:BLK (match_dup 3))
16078         (const_int 0))
16079    (use (match_operand:QI 2 "register_operand" "a"))
16080    (use (match_dup 4))]
16081   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16082   "rep{%;} stosb"
16083   [(set_attr "type" "str")
16084    (set_attr "prefix_rep" "1")
16085    (set_attr "memory" "store")
16086    (set (attr "prefix_rex")
16087         (if_then_else
16088           (match_test "<P:MODE>mode == DImode")
16089           (const_string "0")
16090           (const_string "*")))
16091    (set_attr "mode" "QI")])
16092
16093 (define_expand "cmpstrnsi"
16094   [(set (match_operand:SI 0 "register_operand" "")
16095         (compare:SI (match_operand:BLK 1 "general_operand" "")
16096                     (match_operand:BLK 2 "general_operand" "")))
16097    (use (match_operand 3 "general_operand" ""))
16098    (use (match_operand 4 "immediate_operand" ""))]
16099   ""
16100 {
16101   rtx addr1, addr2, out, outlow, count, countreg, align;
16102
16103   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16104     FAIL;
16105
16106   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16107   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16108     FAIL;
16109
16110   out = operands[0];
16111   if (!REG_P (out))
16112     out = gen_reg_rtx (SImode);
16113
16114   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16115   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16116   if (addr1 != XEXP (operands[1], 0))
16117     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16118   if (addr2 != XEXP (operands[2], 0))
16119     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16120
16121   count = operands[3];
16122   countreg = ix86_zero_extend_to_Pmode (count);
16123
16124   /* %%% Iff we are testing strict equality, we can use known alignment
16125      to good advantage.  This may be possible with combine, particularly
16126      once cc0 is dead.  */
16127   align = operands[4];
16128
16129   if (CONST_INT_P (count))
16130     {
16131       if (INTVAL (count) == 0)
16132         {
16133           emit_move_insn (operands[0], const0_rtx);
16134           DONE;
16135         }
16136       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16137                                      operands[1], operands[2]));
16138     }
16139   else
16140     {
16141       rtx (*gen_cmp) (rtx, rtx);
16142
16143       gen_cmp = (TARGET_64BIT
16144                  ? gen_cmpdi_1 : gen_cmpsi_1);
16145
16146       emit_insn (gen_cmp (countreg, countreg));
16147       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16148                                   operands[1], operands[2]));
16149     }
16150
16151   outlow = gen_lowpart (QImode, out);
16152   emit_insn (gen_cmpintqi (outlow));
16153   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16154
16155   if (operands[0] != out)
16156     emit_move_insn (operands[0], out);
16157
16158   DONE;
16159 })
16160
16161 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16162
16163 (define_expand "cmpintqi"
16164   [(set (match_dup 1)
16165         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16166    (set (match_dup 2)
16167         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16168    (parallel [(set (match_operand:QI 0 "register_operand" "")
16169                    (minus:QI (match_dup 1)
16170                              (match_dup 2)))
16171               (clobber (reg:CC FLAGS_REG))])]
16172   ""
16173 {
16174   operands[1] = gen_reg_rtx (QImode);
16175   operands[2] = gen_reg_rtx (QImode);
16176 })
16177
16178 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16179 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16180
16181 (define_expand "cmpstrnqi_nz_1"
16182   [(parallel [(set (reg:CC FLAGS_REG)
16183                    (compare:CC (match_operand 4 "memory_operand" "")
16184                                (match_operand 5 "memory_operand" "")))
16185               (use (match_operand 2 "register_operand" ""))
16186               (use (match_operand:SI 3 "immediate_operand" ""))
16187               (clobber (match_operand 0 "register_operand" ""))
16188               (clobber (match_operand 1 "register_operand" ""))
16189               (clobber (match_dup 2))])]
16190   ""
16191   "ix86_current_function_needs_cld = 1;")
16192
16193 (define_insn "*cmpstrnqi_nz_1"
16194   [(set (reg:CC FLAGS_REG)
16195         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16196                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16197    (use (match_operand:P 6 "register_operand" "2"))
16198    (use (match_operand:SI 3 "immediate_operand" "i"))
16199    (clobber (match_operand:P 0 "register_operand" "=S"))
16200    (clobber (match_operand:P 1 "register_operand" "=D"))
16201    (clobber (match_operand:P 2 "register_operand" "=c"))]
16202   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16203   "repz{%;} cmpsb"
16204   [(set_attr "type" "str")
16205    (set_attr "mode" "QI")
16206    (set (attr "prefix_rex")
16207         (if_then_else
16208           (match_test "<P:MODE>mode == DImode")
16209           (const_string "0")
16210           (const_string "*")))
16211    (set_attr "prefix_rep" "1")])
16212
16213 ;; The same, but the count is not known to not be zero.
16214
16215 (define_expand "cmpstrnqi_1"
16216   [(parallel [(set (reg:CC FLAGS_REG)
16217                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16218                                      (const_int 0))
16219                   (compare:CC (match_operand 4 "memory_operand" "")
16220                               (match_operand 5 "memory_operand" ""))
16221                   (const_int 0)))
16222               (use (match_operand:SI 3 "immediate_operand" ""))
16223               (use (reg:CC FLAGS_REG))
16224               (clobber (match_operand 0 "register_operand" ""))
16225               (clobber (match_operand 1 "register_operand" ""))
16226               (clobber (match_dup 2))])]
16227   ""
16228   "ix86_current_function_needs_cld = 1;")
16229
16230 (define_insn "*cmpstrnqi_1"
16231   [(set (reg:CC FLAGS_REG)
16232         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16233                              (const_int 0))
16234           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16235                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16236           (const_int 0)))
16237    (use (match_operand:SI 3 "immediate_operand" "i"))
16238    (use (reg:CC FLAGS_REG))
16239    (clobber (match_operand:P 0 "register_operand" "=S"))
16240    (clobber (match_operand:P 1 "register_operand" "=D"))
16241    (clobber (match_operand:P 2 "register_operand" "=c"))]
16242   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16243   "repz{%;} cmpsb"
16244   [(set_attr "type" "str")
16245    (set_attr "mode" "QI")
16246    (set (attr "prefix_rex")
16247         (if_then_else
16248           (match_test "<P:MODE>mode == DImode")
16249           (const_string "0")
16250           (const_string "*")))
16251    (set_attr "prefix_rep" "1")])
16252
16253 (define_expand "strlen<mode>"
16254   [(set (match_operand:P 0 "register_operand" "")
16255         (unspec:P [(match_operand:BLK 1 "general_operand" "")
16256                    (match_operand:QI 2 "immediate_operand" "")
16257                    (match_operand 3 "immediate_operand" "")]
16258                   UNSPEC_SCAS))]
16259   ""
16260 {
16261  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16262    DONE;
16263  else
16264    FAIL;
16265 })
16266
16267 (define_expand "strlenqi_1"
16268   [(parallel [(set (match_operand 0 "register_operand" "")
16269                    (match_operand 2 "" ""))
16270               (clobber (match_operand 1 "register_operand" ""))
16271               (clobber (reg:CC FLAGS_REG))])]
16272   ""
16273   "ix86_current_function_needs_cld = 1;")
16274
16275 (define_insn "*strlenqi_1"
16276   [(set (match_operand:P 0 "register_operand" "=&c")
16277         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16278                    (match_operand:QI 2 "register_operand" "a")
16279                    (match_operand:P 3 "immediate_operand" "i")
16280                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16281    (clobber (match_operand:P 1 "register_operand" "=D"))
16282    (clobber (reg:CC FLAGS_REG))]
16283   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16284   "repnz{%;} scasb"
16285   [(set_attr "type" "str")
16286    (set_attr "mode" "QI")
16287    (set (attr "prefix_rex")
16288         (if_then_else
16289           (match_test "<P:MODE>mode == DImode")
16290           (const_string "0")
16291           (const_string "*")))
16292    (set_attr "prefix_rep" "1")])
16293
16294 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16295 ;; handled in combine, but it is not currently up to the task.
16296 ;; When used for their truth value, the cmpstrn* expanders generate
16297 ;; code like this:
16298 ;;
16299 ;;   repz cmpsb
16300 ;;   seta       %al
16301 ;;   setb       %dl
16302 ;;   cmpb       %al, %dl
16303 ;;   jcc        label
16304 ;;
16305 ;; The intermediate three instructions are unnecessary.
16306
16307 ;; This one handles cmpstrn*_nz_1...
16308 (define_peephole2
16309   [(parallel[
16310      (set (reg:CC FLAGS_REG)
16311           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16312                       (mem:BLK (match_operand 5 "register_operand" ""))))
16313      (use (match_operand 6 "register_operand" ""))
16314      (use (match_operand:SI 3 "immediate_operand" ""))
16315      (clobber (match_operand 0 "register_operand" ""))
16316      (clobber (match_operand 1 "register_operand" ""))
16317      (clobber (match_operand 2 "register_operand" ""))])
16318    (set (match_operand:QI 7 "register_operand" "")
16319         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16320    (set (match_operand:QI 8 "register_operand" "")
16321         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16322    (set (reg FLAGS_REG)
16323         (compare (match_dup 7) (match_dup 8)))
16324   ]
16325   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16326   [(parallel[
16327      (set (reg:CC FLAGS_REG)
16328           (compare:CC (mem:BLK (match_dup 4))
16329                       (mem:BLK (match_dup 5))))
16330      (use (match_dup 6))
16331      (use (match_dup 3))
16332      (clobber (match_dup 0))
16333      (clobber (match_dup 1))
16334      (clobber (match_dup 2))])])
16335
16336 ;; ...and this one handles cmpstrn*_1.
16337 (define_peephole2
16338   [(parallel[
16339      (set (reg:CC FLAGS_REG)
16340           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16341                                (const_int 0))
16342             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16343                         (mem:BLK (match_operand 5 "register_operand" "")))
16344             (const_int 0)))
16345      (use (match_operand:SI 3 "immediate_operand" ""))
16346      (use (reg:CC FLAGS_REG))
16347      (clobber (match_operand 0 "register_operand" ""))
16348      (clobber (match_operand 1 "register_operand" ""))
16349      (clobber (match_operand 2 "register_operand" ""))])
16350    (set (match_operand:QI 7 "register_operand" "")
16351         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16352    (set (match_operand:QI 8 "register_operand" "")
16353         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16354    (set (reg FLAGS_REG)
16355         (compare (match_dup 7) (match_dup 8)))
16356   ]
16357   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16358   [(parallel[
16359      (set (reg:CC FLAGS_REG)
16360           (if_then_else:CC (ne (match_dup 6)
16361                                (const_int 0))
16362             (compare:CC (mem:BLK (match_dup 4))
16363                         (mem:BLK (match_dup 5)))
16364             (const_int 0)))
16365      (use (match_dup 3))
16366      (use (reg:CC FLAGS_REG))
16367      (clobber (match_dup 0))
16368      (clobber (match_dup 1))
16369      (clobber (match_dup 2))])])
16370 \f
16371 ;; Conditional move instructions.
16372
16373 (define_expand "mov<mode>cc"
16374   [(set (match_operand:SWIM 0 "register_operand" "")
16375         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16376                            (match_operand:SWIM 2 "<general_operand>" "")
16377                            (match_operand:SWIM 3 "<general_operand>" "")))]
16378   ""
16379   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16380
16381 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16382 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16383 ;; So just document what we're doing explicitly.
16384
16385 (define_expand "x86_mov<mode>cc_0_m1"
16386   [(parallel
16387     [(set (match_operand:SWI48 0 "register_operand" "")
16388           (if_then_else:SWI48
16389             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16390              [(match_operand 1 "flags_reg_operand" "")
16391               (const_int 0)])
16392             (const_int -1)
16393             (const_int 0)))
16394      (clobber (reg:CC FLAGS_REG))])])
16395
16396 (define_insn "*x86_mov<mode>cc_0_m1"
16397   [(set (match_operand:SWI48 0 "register_operand" "=r")
16398         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16399                              [(reg FLAGS_REG) (const_int 0)])
16400           (const_int -1)
16401           (const_int 0)))
16402    (clobber (reg:CC FLAGS_REG))]
16403   ""
16404   "sbb{<imodesuffix>}\t%0, %0"
16405   ; Since we don't have the proper number of operands for an alu insn,
16406   ; fill in all the blanks.
16407   [(set_attr "type" "alu")
16408    (set_attr "use_carry" "1")
16409    (set_attr "pent_pair" "pu")
16410    (set_attr "memory" "none")
16411    (set_attr "imm_disp" "false")
16412    (set_attr "mode" "<MODE>")
16413    (set_attr "length_immediate" "0")])
16414
16415 (define_insn "*x86_mov<mode>cc_0_m1_se"
16416   [(set (match_operand:SWI48 0 "register_operand" "=r")
16417         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16418                              [(reg FLAGS_REG) (const_int 0)])
16419                             (const_int 1)
16420                             (const_int 0)))
16421    (clobber (reg:CC FLAGS_REG))]
16422   ""
16423   "sbb{<imodesuffix>}\t%0, %0"
16424   [(set_attr "type" "alu")
16425    (set_attr "use_carry" "1")
16426    (set_attr "pent_pair" "pu")
16427    (set_attr "memory" "none")
16428    (set_attr "imm_disp" "false")
16429    (set_attr "mode" "<MODE>")
16430    (set_attr "length_immediate" "0")])
16431
16432 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16433   [(set (match_operand:SWI48 0 "register_operand" "=r")
16434         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16435                     [(reg FLAGS_REG) (const_int 0)])))]
16436   ""
16437   "sbb{<imodesuffix>}\t%0, %0"
16438   [(set_attr "type" "alu")
16439    (set_attr "use_carry" "1")
16440    (set_attr "pent_pair" "pu")
16441    (set_attr "memory" "none")
16442    (set_attr "imm_disp" "false")
16443    (set_attr "mode" "<MODE>")
16444    (set_attr "length_immediate" "0")])
16445
16446 (define_insn "*mov<mode>cc_noc"
16447   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16448         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16449                                [(reg FLAGS_REG) (const_int 0)])
16450           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16451           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16452   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16453   "@
16454    cmov%O2%C1\t{%2, %0|%0, %2}
16455    cmov%O2%c1\t{%3, %0|%0, %3}"
16456   [(set_attr "type" "icmov")
16457    (set_attr "mode" "<MODE>")])
16458
16459 (define_insn_and_split "*movqicc_noc"
16460   [(set (match_operand:QI 0 "register_operand" "=r,r")
16461         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16462                            [(match_operand 4 "flags_reg_operand" "")
16463                             (const_int 0)])
16464                       (match_operand:QI 2 "register_operand" "r,0")
16465                       (match_operand:QI 3 "register_operand" "0,r")))]
16466   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16467   "#"
16468   "&& reload_completed"
16469   [(set (match_dup 0)
16470         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16471                       (match_dup 2)
16472                       (match_dup 3)))]
16473   "operands[0] = gen_lowpart (SImode, operands[0]);
16474    operands[2] = gen_lowpart (SImode, operands[2]);
16475    operands[3] = gen_lowpart (SImode, operands[3]);"
16476   [(set_attr "type" "icmov")
16477    (set_attr "mode" "SI")])
16478
16479 (define_expand "mov<mode>cc"
16480   [(set (match_operand:X87MODEF 0 "register_operand" "")
16481         (if_then_else:X87MODEF
16482           (match_operand 1 "ix86_fp_comparison_operator" "")
16483           (match_operand:X87MODEF 2 "register_operand" "")
16484           (match_operand:X87MODEF 3 "register_operand" "")))]
16485   "(TARGET_80387 && TARGET_CMOVE)
16486    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16487   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16488
16489 (define_insn "*movxfcc_1"
16490   [(set (match_operand:XF 0 "register_operand" "=f,f")
16491         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16492                                 [(reg FLAGS_REG) (const_int 0)])
16493                       (match_operand:XF 2 "register_operand" "f,0")
16494                       (match_operand:XF 3 "register_operand" "0,f")))]
16495   "TARGET_80387 && TARGET_CMOVE"
16496   "@
16497    fcmov%F1\t{%2, %0|%0, %2}
16498    fcmov%f1\t{%3, %0|%0, %3}"
16499   [(set_attr "type" "fcmov")
16500    (set_attr "mode" "XF")])
16501
16502 (define_insn "*movdfcc_1_rex64"
16503   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16504         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16505                                 [(reg FLAGS_REG) (const_int 0)])
16506                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16507                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16508   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16509    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16510   "@
16511    fcmov%F1\t{%2, %0|%0, %2}
16512    fcmov%f1\t{%3, %0|%0, %3}
16513    cmov%O2%C1\t{%2, %0|%0, %2}
16514    cmov%O2%c1\t{%3, %0|%0, %3}"
16515   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16516    (set_attr "mode" "DF,DF,DI,DI")])
16517
16518 (define_insn "*movdfcc_1"
16519   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16520         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16521                                 [(reg FLAGS_REG) (const_int 0)])
16522                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16523                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16524   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16525    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16526   "@
16527    fcmov%F1\t{%2, %0|%0, %2}
16528    fcmov%f1\t{%3, %0|%0, %3}
16529    #
16530    #"
16531   [(set_attr "type" "fcmov,fcmov,multi,multi")
16532    (set_attr "mode" "DF,DF,DI,DI")])
16533
16534 (define_split
16535   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16536         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16537                                 [(match_operand 4 "flags_reg_operand" "")
16538                                  (const_int 0)])
16539                       (match_operand:DF 2 "nonimmediate_operand" "")
16540                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16541   "!TARGET_64BIT && reload_completed"
16542   [(set (match_dup 2)
16543         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16544                       (match_dup 5)
16545                       (match_dup 6)))
16546    (set (match_dup 3)
16547         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16548                       (match_dup 7)
16549                       (match_dup 8)))]
16550 {
16551   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16552   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16553 })
16554
16555 (define_insn "*movsfcc_1_387"
16556   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16557         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16558                                 [(reg FLAGS_REG) (const_int 0)])
16559                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16560                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16561   "TARGET_80387 && TARGET_CMOVE
16562    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16563   "@
16564    fcmov%F1\t{%2, %0|%0, %2}
16565    fcmov%f1\t{%3, %0|%0, %3}
16566    cmov%O2%C1\t{%2, %0|%0, %2}
16567    cmov%O2%c1\t{%3, %0|%0, %3}"
16568   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16569    (set_attr "mode" "SF,SF,SI,SI")])
16570
16571 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16572 ;; the scalar versions to have only XMM registers as operands.
16573
16574 ;; XOP conditional move
16575 (define_insn "*xop_pcmov_<mode>"
16576   [(set (match_operand:MODEF 0 "register_operand" "=x")
16577         (if_then_else:MODEF
16578           (match_operand:MODEF 1 "register_operand" "x")
16579           (match_operand:MODEF 2 "register_operand" "x")
16580           (match_operand:MODEF 3 "register_operand" "x")))]
16581   "TARGET_XOP"
16582   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16583   [(set_attr "type" "sse4arg")])
16584
16585 ;; These versions of the min/max patterns are intentionally ignorant of
16586 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16587 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16588 ;; are undefined in this condition, we're certain this is correct.
16589
16590 (define_insn "<code><mode>3"
16591   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16592         (smaxmin:MODEF
16593           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16594           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16595   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16596   "@
16597    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16598    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16599   [(set_attr "isa" "noavx,avx")
16600    (set_attr "prefix" "orig,vex")
16601    (set_attr "type" "sseadd")
16602    (set_attr "mode" "<MODE>")])
16603
16604 ;; These versions of the min/max patterns implement exactly the operations
16605 ;;   min = (op1 < op2 ? op1 : op2)
16606 ;;   max = (!(op1 < op2) ? op1 : op2)
16607 ;; Their operands are not commutative, and thus they may be used in the
16608 ;; presence of -0.0 and NaN.
16609
16610 (define_insn "*ieee_smin<mode>3"
16611   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16612         (unspec:MODEF
16613           [(match_operand:MODEF 1 "register_operand" "0,x")
16614            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16615          UNSPEC_IEEE_MIN))]
16616   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16617   "@
16618    min<ssemodesuffix>\t{%2, %0|%0, %2}
16619    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16620   [(set_attr "isa" "noavx,avx")
16621    (set_attr "prefix" "orig,vex")
16622    (set_attr "type" "sseadd")
16623    (set_attr "mode" "<MODE>")])
16624
16625 (define_insn "*ieee_smax<mode>3"
16626   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16627         (unspec:MODEF
16628           [(match_operand:MODEF 1 "register_operand" "0,x")
16629            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16630          UNSPEC_IEEE_MAX))]
16631   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16632   "@
16633    max<ssemodesuffix>\t{%2, %0|%0, %2}
16634    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16635   [(set_attr "isa" "noavx,avx")
16636    (set_attr "prefix" "orig,vex")
16637    (set_attr "type" "sseadd")
16638    (set_attr "mode" "<MODE>")])
16639
16640 ;; Make two stack loads independent:
16641 ;;   fld aa              fld aa
16642 ;;   fld %st(0)     ->   fld bb
16643 ;;   fmul bb             fmul %st(1), %st
16644 ;;
16645 ;; Actually we only match the last two instructions for simplicity.
16646 (define_peephole2
16647   [(set (match_operand 0 "fp_register_operand" "")
16648         (match_operand 1 "fp_register_operand" ""))
16649    (set (match_dup 0)
16650         (match_operator 2 "binary_fp_operator"
16651            [(match_dup 0)
16652             (match_operand 3 "memory_operand" "")]))]
16653   "REGNO (operands[0]) != REGNO (operands[1])"
16654   [(set (match_dup 0) (match_dup 3))
16655    (set (match_dup 0) (match_dup 4))]
16656
16657   ;; The % modifier is not operational anymore in peephole2's, so we have to
16658   ;; swap the operands manually in the case of addition and multiplication.
16659 {
16660   rtx op0, op1;
16661
16662   if (COMMUTATIVE_ARITH_P (operands[2]))
16663     op0 = operands[0], op1 = operands[1];
16664   else
16665     op0 = operands[1], op1 = operands[0];
16666
16667   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16668                                 GET_MODE (operands[2]),
16669                                 op0, op1);
16670 })
16671
16672 ;; Conditional addition patterns
16673 (define_expand "add<mode>cc"
16674   [(match_operand:SWI 0 "register_operand" "")
16675    (match_operand 1 "ordered_comparison_operator" "")
16676    (match_operand:SWI 2 "register_operand" "")
16677    (match_operand:SWI 3 "const_int_operand" "")]
16678   ""
16679   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16680 \f
16681 ;; Misc patterns (?)
16682
16683 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16684 ;; Otherwise there will be nothing to keep
16685 ;;
16686 ;; [(set (reg ebp) (reg esp))]
16687 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16688 ;;  (clobber (eflags)]
16689 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16690 ;;
16691 ;; in proper program order.
16692
16693 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16694   [(set (match_operand:P 0 "register_operand" "=r,r")
16695         (plus:P (match_operand:P 1 "register_operand" "0,r")
16696                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16697    (clobber (reg:CC FLAGS_REG))
16698    (clobber (mem:BLK (scratch)))]
16699   ""
16700 {
16701   switch (get_attr_type (insn))
16702     {
16703     case TYPE_IMOV:
16704       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16705
16706     case TYPE_ALU:
16707       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16708       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16709         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16710
16711       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16712
16713     default:
16714       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16715       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16716     }
16717 }
16718   [(set (attr "type")
16719         (cond [(and (eq_attr "alternative" "0")
16720                     (not (match_test "TARGET_OPT_AGU")))
16721                  (const_string "alu")
16722                (match_operand:<MODE> 2 "const0_operand" "")
16723                  (const_string "imov")
16724               ]
16725               (const_string "lea")))
16726    (set (attr "length_immediate")
16727         (cond [(eq_attr "type" "imov")
16728                  (const_string "0")
16729                (and (eq_attr "type" "alu")
16730                     (match_operand 2 "const128_operand" ""))
16731                  (const_string "1")
16732               ]
16733               (const_string "*")))
16734    (set_attr "mode" "<MODE>")])
16735
16736 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16737   [(set (match_operand:P 0 "register_operand" "=r")
16738         (minus:P (match_operand:P 1 "register_operand" "0")
16739                  (match_operand:P 2 "register_operand" "r")))
16740    (clobber (reg:CC FLAGS_REG))
16741    (clobber (mem:BLK (scratch)))]
16742   ""
16743   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16744   [(set_attr "type" "alu")
16745    (set_attr "mode" "<MODE>")])
16746
16747 (define_insn "allocate_stack_worker_probe_<mode>"
16748   [(set (match_operand:P 0 "register_operand" "=a")
16749         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16750                             UNSPECV_STACK_PROBE))
16751    (clobber (reg:CC FLAGS_REG))]
16752   "ix86_target_stack_probe ()"
16753   "call\t___chkstk_ms"
16754   [(set_attr "type" "multi")
16755    (set_attr "length" "5")])
16756
16757 (define_expand "allocate_stack"
16758   [(match_operand 0 "register_operand" "")
16759    (match_operand 1 "general_operand" "")]
16760   "ix86_target_stack_probe ()"
16761 {
16762   rtx x;
16763
16764 #ifndef CHECK_STACK_LIMIT
16765 #define CHECK_STACK_LIMIT 0
16766 #endif
16767
16768   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16769       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16770     {
16771       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16772                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16773       if (x != stack_pointer_rtx)
16774         emit_move_insn (stack_pointer_rtx, x);
16775     }
16776   else
16777     {
16778       x = copy_to_mode_reg (Pmode, operands[1]);
16779       if (TARGET_64BIT)
16780         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16781       else
16782         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16783       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16784                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16785       if (x != stack_pointer_rtx)
16786         emit_move_insn (stack_pointer_rtx, x);
16787     }
16788
16789   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16790   DONE;
16791 })
16792
16793 ;; Use IOR for stack probes, this is shorter.
16794 (define_expand "probe_stack"
16795   [(match_operand 0 "memory_operand" "")]
16796   ""
16797 {
16798   rtx (*gen_ior3) (rtx, rtx, rtx);
16799
16800   gen_ior3 = (GET_MODE (operands[0]) == DImode
16801               ? gen_iordi3 : gen_iorsi3);
16802
16803   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16804   DONE;
16805 })
16806
16807 (define_insn "adjust_stack_and_probe<mode>"
16808   [(set (match_operand:P 0 "register_operand" "=r")
16809         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16810                             UNSPECV_PROBE_STACK_RANGE))
16811    (set (reg:P SP_REG)
16812         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16813    (clobber (reg:CC FLAGS_REG))
16814    (clobber (mem:BLK (scratch)))]
16815   ""
16816   "* return output_adjust_stack_and_probe (operands[0]);"
16817   [(set_attr "type" "multi")])
16818
16819 (define_insn "probe_stack_range<mode>"
16820   [(set (match_operand:P 0 "register_operand" "=r")
16821         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16822                             (match_operand:P 2 "const_int_operand" "n")]
16823                             UNSPECV_PROBE_STACK_RANGE))
16824    (clobber (reg:CC FLAGS_REG))]
16825   ""
16826   "* return output_probe_stack_range (operands[0], operands[2]);"
16827   [(set_attr "type" "multi")])
16828
16829 (define_expand "builtin_setjmp_receiver"
16830   [(label_ref (match_operand 0 "" ""))]
16831   "!TARGET_64BIT && flag_pic"
16832 {
16833 #if TARGET_MACHO
16834   if (TARGET_MACHO)
16835     {
16836       rtx xops[3];
16837       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16838       rtx label_rtx = gen_label_rtx ();
16839       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16840       xops[0] = xops[1] = picreg;
16841       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16842       ix86_expand_binary_operator (MINUS, SImode, xops);
16843     }
16844   else
16845 #endif
16846     emit_insn (gen_set_got (pic_offset_table_rtx));
16847   DONE;
16848 })
16849 \f
16850 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16851
16852 (define_split
16853   [(set (match_operand 0 "register_operand" "")
16854         (match_operator 3 "promotable_binary_operator"
16855            [(match_operand 1 "register_operand" "")
16856             (match_operand 2 "aligned_operand" "")]))
16857    (clobber (reg:CC FLAGS_REG))]
16858   "! TARGET_PARTIAL_REG_STALL && reload_completed
16859    && ((GET_MODE (operands[0]) == HImode
16860         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16861             /* ??? next two lines just !satisfies_constraint_K (...) */
16862             || !CONST_INT_P (operands[2])
16863             || satisfies_constraint_K (operands[2])))
16864        || (GET_MODE (operands[0]) == QImode
16865            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16866   [(parallel [(set (match_dup 0)
16867                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16868               (clobber (reg:CC FLAGS_REG))])]
16869 {
16870   operands[0] = gen_lowpart (SImode, operands[0]);
16871   operands[1] = gen_lowpart (SImode, operands[1]);
16872   if (GET_CODE (operands[3]) != ASHIFT)
16873     operands[2] = gen_lowpart (SImode, operands[2]);
16874   PUT_MODE (operands[3], SImode);
16875 })
16876
16877 ; Promote the QImode tests, as i386 has encoding of the AND
16878 ; instruction with 32-bit sign-extended immediate and thus the
16879 ; instruction size is unchanged, except in the %eax case for
16880 ; which it is increased by one byte, hence the ! optimize_size.
16881 (define_split
16882   [(set (match_operand 0 "flags_reg_operand" "")
16883         (match_operator 2 "compare_operator"
16884           [(and (match_operand 3 "aligned_operand" "")
16885                 (match_operand 4 "const_int_operand" ""))
16886            (const_int 0)]))
16887    (set (match_operand 1 "register_operand" "")
16888         (and (match_dup 3) (match_dup 4)))]
16889   "! TARGET_PARTIAL_REG_STALL && reload_completed
16890    && optimize_insn_for_speed_p ()
16891    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16892        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16893    /* Ensure that the operand will remain sign-extended immediate.  */
16894    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16895   [(parallel [(set (match_dup 0)
16896                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16897                                     (const_int 0)]))
16898               (set (match_dup 1)
16899                    (and:SI (match_dup 3) (match_dup 4)))])]
16900 {
16901   operands[4]
16902     = gen_int_mode (INTVAL (operands[4])
16903                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16904   operands[1] = gen_lowpart (SImode, operands[1]);
16905   operands[3] = gen_lowpart (SImode, operands[3]);
16906 })
16907
16908 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16909 ; the TEST instruction with 32-bit sign-extended immediate and thus
16910 ; the instruction size would at least double, which is not what we
16911 ; want even with ! optimize_size.
16912 (define_split
16913   [(set (match_operand 0 "flags_reg_operand" "")
16914         (match_operator 1 "compare_operator"
16915           [(and (match_operand:HI 2 "aligned_operand" "")
16916                 (match_operand:HI 3 "const_int_operand" ""))
16917            (const_int 0)]))]
16918   "! TARGET_PARTIAL_REG_STALL && reload_completed
16919    && ! TARGET_FAST_PREFIX
16920    && optimize_insn_for_speed_p ()
16921    /* Ensure that the operand will remain sign-extended immediate.  */
16922    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16923   [(set (match_dup 0)
16924         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16925                          (const_int 0)]))]
16926 {
16927   operands[3]
16928     = gen_int_mode (INTVAL (operands[3])
16929                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16930   operands[2] = gen_lowpart (SImode, operands[2]);
16931 })
16932
16933 (define_split
16934   [(set (match_operand 0 "register_operand" "")
16935         (neg (match_operand 1 "register_operand" "")))
16936    (clobber (reg:CC FLAGS_REG))]
16937   "! TARGET_PARTIAL_REG_STALL && reload_completed
16938    && (GET_MODE (operands[0]) == HImode
16939        || (GET_MODE (operands[0]) == QImode
16940            && (TARGET_PROMOTE_QImode
16941                || optimize_insn_for_size_p ())))"
16942   [(parallel [(set (match_dup 0)
16943                    (neg:SI (match_dup 1)))
16944               (clobber (reg:CC FLAGS_REG))])]
16945 {
16946   operands[0] = gen_lowpart (SImode, operands[0]);
16947   operands[1] = gen_lowpart (SImode, operands[1]);
16948 })
16949
16950 (define_split
16951   [(set (match_operand 0 "register_operand" "")
16952         (not (match_operand 1 "register_operand" "")))]
16953   "! TARGET_PARTIAL_REG_STALL && reload_completed
16954    && (GET_MODE (operands[0]) == HImode
16955        || (GET_MODE (operands[0]) == QImode
16956            && (TARGET_PROMOTE_QImode
16957                || optimize_insn_for_size_p ())))"
16958   [(set (match_dup 0)
16959         (not:SI (match_dup 1)))]
16960 {
16961   operands[0] = gen_lowpart (SImode, operands[0]);
16962   operands[1] = gen_lowpart (SImode, operands[1]);
16963 })
16964
16965 (define_split
16966   [(set (match_operand 0 "register_operand" "")
16967         (if_then_else (match_operator 1 "ordered_comparison_operator"
16968                                 [(reg FLAGS_REG) (const_int 0)])
16969                       (match_operand 2 "register_operand" "")
16970                       (match_operand 3 "register_operand" "")))]
16971   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16972    && (GET_MODE (operands[0]) == HImode
16973        || (GET_MODE (operands[0]) == QImode
16974            && (TARGET_PROMOTE_QImode
16975                || optimize_insn_for_size_p ())))"
16976   [(set (match_dup 0)
16977         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16978 {
16979   operands[0] = gen_lowpart (SImode, operands[0]);
16980   operands[2] = gen_lowpart (SImode, operands[2]);
16981   operands[3] = gen_lowpart (SImode, operands[3]);
16982 })
16983 \f
16984 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16985 ;; transform a complex memory operation into two memory to register operations.
16986
16987 ;; Don't push memory operands
16988 (define_peephole2
16989   [(set (match_operand:SWI 0 "push_operand" "")
16990         (match_operand:SWI 1 "memory_operand" ""))
16991    (match_scratch:SWI 2 "<r>")]
16992   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16993    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16994   [(set (match_dup 2) (match_dup 1))
16995    (set (match_dup 0) (match_dup 2))])
16996
16997 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16998 ;; SImode pushes.
16999 (define_peephole2
17000   [(set (match_operand:SF 0 "push_operand" "")
17001         (match_operand:SF 1 "memory_operand" ""))
17002    (match_scratch:SF 2 "r")]
17003   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17004    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17005   [(set (match_dup 2) (match_dup 1))
17006    (set (match_dup 0) (match_dup 2))])
17007
17008 ;; Don't move an immediate directly to memory when the instruction
17009 ;; gets too big.
17010 (define_peephole2
17011   [(match_scratch:SWI124 1 "<r>")
17012    (set (match_operand:SWI124 0 "memory_operand" "")
17013         (const_int 0))]
17014   "optimize_insn_for_speed_p ()
17015    && !TARGET_USE_MOV0
17016    && TARGET_SPLIT_LONG_MOVES
17017    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17018    && peep2_regno_dead_p (0, FLAGS_REG)"
17019   [(parallel [(set (match_dup 2) (const_int 0))
17020               (clobber (reg:CC FLAGS_REG))])
17021    (set (match_dup 0) (match_dup 1))]
17022   "operands[2] = gen_lowpart (SImode, operands[1]);")
17023
17024 (define_peephole2
17025   [(match_scratch:SWI124 2 "<r>")
17026    (set (match_operand:SWI124 0 "memory_operand" "")
17027         (match_operand:SWI124 1 "immediate_operand" ""))]
17028   "optimize_insn_for_speed_p ()
17029    && TARGET_SPLIT_LONG_MOVES
17030    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17031   [(set (match_dup 2) (match_dup 1))
17032    (set (match_dup 0) (match_dup 2))])
17033
17034 ;; Don't compare memory with zero, load and use a test instead.
17035 (define_peephole2
17036   [(set (match_operand 0 "flags_reg_operand" "")
17037         (match_operator 1 "compare_operator"
17038           [(match_operand:SI 2 "memory_operand" "")
17039            (const_int 0)]))
17040    (match_scratch:SI 3 "r")]
17041   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17042   [(set (match_dup 3) (match_dup 2))
17043    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17044
17045 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17046 ;; Don't split NOTs with a displacement operand, because resulting XOR
17047 ;; will not be pairable anyway.
17048 ;;
17049 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17050 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17051 ;; so this split helps here as well.
17052 ;;
17053 ;; Note: Can't do this as a regular split because we can't get proper
17054 ;; lifetime information then.
17055
17056 (define_peephole2
17057   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17058         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17059   "optimize_insn_for_speed_p ()
17060    && ((TARGET_NOT_UNPAIRABLE
17061         && (!MEM_P (operands[0])
17062             || !memory_displacement_operand (operands[0], <MODE>mode)))
17063        || (TARGET_NOT_VECTORMODE
17064            && long_memory_operand (operands[0], <MODE>mode)))
17065    && peep2_regno_dead_p (0, FLAGS_REG)"
17066   [(parallel [(set (match_dup 0)
17067                    (xor:SWI124 (match_dup 1) (const_int -1)))
17068               (clobber (reg:CC FLAGS_REG))])])
17069
17070 ;; Non pairable "test imm, reg" instructions can be translated to
17071 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17072 ;; byte opcode instead of two, have a short form for byte operands),
17073 ;; so do it for other CPUs as well.  Given that the value was dead,
17074 ;; this should not create any new dependencies.  Pass on the sub-word
17075 ;; versions if we're concerned about partial register stalls.
17076
17077 (define_peephole2
17078   [(set (match_operand 0 "flags_reg_operand" "")
17079         (match_operator 1 "compare_operator"
17080           [(and:SI (match_operand:SI 2 "register_operand" "")
17081                    (match_operand:SI 3 "immediate_operand" ""))
17082            (const_int 0)]))]
17083   "ix86_match_ccmode (insn, CCNOmode)
17084    && (true_regnum (operands[2]) != AX_REG
17085        || satisfies_constraint_K (operands[3]))
17086    && peep2_reg_dead_p (1, operands[2])"
17087   [(parallel
17088      [(set (match_dup 0)
17089            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17090                             (const_int 0)]))
17091       (set (match_dup 2)
17092            (and:SI (match_dup 2) (match_dup 3)))])])
17093
17094 ;; We don't need to handle HImode case, because it will be promoted to SImode
17095 ;; on ! TARGET_PARTIAL_REG_STALL
17096
17097 (define_peephole2
17098   [(set (match_operand 0 "flags_reg_operand" "")
17099         (match_operator 1 "compare_operator"
17100           [(and:QI (match_operand:QI 2 "register_operand" "")
17101                    (match_operand:QI 3 "immediate_operand" ""))
17102            (const_int 0)]))]
17103   "! TARGET_PARTIAL_REG_STALL
17104    && ix86_match_ccmode (insn, CCNOmode)
17105    && true_regnum (operands[2]) != AX_REG
17106    && peep2_reg_dead_p (1, operands[2])"
17107   [(parallel
17108      [(set (match_dup 0)
17109            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17110                             (const_int 0)]))
17111       (set (match_dup 2)
17112            (and:QI (match_dup 2) (match_dup 3)))])])
17113
17114 (define_peephole2
17115   [(set (match_operand 0 "flags_reg_operand" "")
17116         (match_operator 1 "compare_operator"
17117           [(and:SI
17118              (zero_extract:SI
17119                (match_operand 2 "ext_register_operand" "")
17120                (const_int 8)
17121                (const_int 8))
17122              (match_operand 3 "const_int_operand" ""))
17123            (const_int 0)]))]
17124   "! TARGET_PARTIAL_REG_STALL
17125    && ix86_match_ccmode (insn, CCNOmode)
17126    && true_regnum (operands[2]) != AX_REG
17127    && peep2_reg_dead_p (1, operands[2])"
17128   [(parallel [(set (match_dup 0)
17129                    (match_op_dup 1
17130                      [(and:SI
17131                         (zero_extract:SI
17132                           (match_dup 2)
17133                           (const_int 8)
17134                           (const_int 8))
17135                         (match_dup 3))
17136                       (const_int 0)]))
17137               (set (zero_extract:SI (match_dup 2)
17138                                     (const_int 8)
17139                                     (const_int 8))
17140                    (and:SI
17141                      (zero_extract:SI
17142                        (match_dup 2)
17143                        (const_int 8)
17144                        (const_int 8))
17145                      (match_dup 3)))])])
17146
17147 ;; Don't do logical operations with memory inputs.
17148 (define_peephole2
17149   [(match_scratch:SI 2 "r")
17150    (parallel [(set (match_operand:SI 0 "register_operand" "")
17151                    (match_operator:SI 3 "arith_or_logical_operator"
17152                      [(match_dup 0)
17153                       (match_operand:SI 1 "memory_operand" "")]))
17154               (clobber (reg:CC FLAGS_REG))])]
17155   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17156   [(set (match_dup 2) (match_dup 1))
17157    (parallel [(set (match_dup 0)
17158                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17159               (clobber (reg:CC FLAGS_REG))])])
17160
17161 (define_peephole2
17162   [(match_scratch:SI 2 "r")
17163    (parallel [(set (match_operand:SI 0 "register_operand" "")
17164                    (match_operator:SI 3 "arith_or_logical_operator"
17165                      [(match_operand:SI 1 "memory_operand" "")
17166                       (match_dup 0)]))
17167               (clobber (reg:CC FLAGS_REG))])]
17168   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17169   [(set (match_dup 2) (match_dup 1))
17170    (parallel [(set (match_dup 0)
17171                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17172               (clobber (reg:CC FLAGS_REG))])])
17173
17174 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17175 ;; refers to the destination of the load!
17176
17177 (define_peephole2
17178   [(set (match_operand:SI 0 "register_operand" "")
17179         (match_operand:SI 1 "register_operand" ""))
17180    (parallel [(set (match_dup 0)
17181                    (match_operator:SI 3 "commutative_operator"
17182                      [(match_dup 0)
17183                       (match_operand:SI 2 "memory_operand" "")]))
17184               (clobber (reg:CC FLAGS_REG))])]
17185   "REGNO (operands[0]) != REGNO (operands[1])
17186    && GENERAL_REGNO_P (REGNO (operands[0]))
17187    && GENERAL_REGNO_P (REGNO (operands[1]))"
17188   [(set (match_dup 0) (match_dup 4))
17189    (parallel [(set (match_dup 0)
17190                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17191               (clobber (reg:CC FLAGS_REG))])]
17192   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17193
17194 (define_peephole2
17195   [(set (match_operand 0 "register_operand" "")
17196         (match_operand 1 "register_operand" ""))
17197    (set (match_dup 0)
17198                    (match_operator 3 "commutative_operator"
17199                      [(match_dup 0)
17200                       (match_operand 2 "memory_operand" "")]))]
17201   "REGNO (operands[0]) != REGNO (operands[1])
17202    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17203        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17204   [(set (match_dup 0) (match_dup 2))
17205    (set (match_dup 0)
17206         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17207
17208 ; Don't do logical operations with memory outputs
17209 ;
17210 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17211 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17212 ; the same decoder scheduling characteristics as the original.
17213
17214 (define_peephole2
17215   [(match_scratch:SI 2 "r")
17216    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17217                    (match_operator:SI 3 "arith_or_logical_operator"
17218                      [(match_dup 0)
17219                       (match_operand:SI 1 "nonmemory_operand" "")]))
17220               (clobber (reg:CC FLAGS_REG))])]
17221   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17222    /* Do not split stack checking probes.  */
17223    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17224   [(set (match_dup 2) (match_dup 0))
17225    (parallel [(set (match_dup 2)
17226                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17227               (clobber (reg:CC FLAGS_REG))])
17228    (set (match_dup 0) (match_dup 2))])
17229
17230 (define_peephole2
17231   [(match_scratch:SI 2 "r")
17232    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17233                    (match_operator:SI 3 "arith_or_logical_operator"
17234                      [(match_operand:SI 1 "nonmemory_operand" "")
17235                       (match_dup 0)]))
17236               (clobber (reg:CC FLAGS_REG))])]
17237   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17238    /* Do not split stack checking probes.  */
17239    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17240   [(set (match_dup 2) (match_dup 0))
17241    (parallel [(set (match_dup 2)
17242                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17243               (clobber (reg:CC FLAGS_REG))])
17244    (set (match_dup 0) (match_dup 2))])
17245
17246 ;; Attempt to use arith or logical operations with memory outputs with
17247 ;; setting of flags.
17248 (define_peephole2
17249   [(set (match_operand:SWI 0 "register_operand" "")
17250         (match_operand:SWI 1 "memory_operand" ""))
17251    (parallel [(set (match_dup 0)
17252                    (match_operator:SWI 3 "plusminuslogic_operator"
17253                      [(match_dup 0)
17254                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17255               (clobber (reg:CC FLAGS_REG))])
17256    (set (match_dup 1) (match_dup 0))
17257    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17258   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17259    && peep2_reg_dead_p (4, operands[0])
17260    && !reg_overlap_mentioned_p (operands[0], operands[1])
17261    && ix86_match_ccmode (peep2_next_insn (3),
17262                          (GET_CODE (operands[3]) == PLUS
17263                           || GET_CODE (operands[3]) == MINUS)
17264                          ? CCGOCmode : CCNOmode)"
17265   [(parallel [(set (match_dup 4) (match_dup 5))
17266               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17267                                                   (match_dup 2)]))])]
17268 {
17269   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17270   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17271                                 copy_rtx (operands[1]),
17272                                 copy_rtx (operands[2]));
17273   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17274                                  operands[5], const0_rtx);
17275 })
17276
17277 (define_peephole2
17278   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17279                    (match_operator:SWI 2 "plusminuslogic_operator"
17280                      [(match_dup 0)
17281                       (match_operand:SWI 1 "memory_operand" "")]))
17282               (clobber (reg:CC FLAGS_REG))])
17283    (set (match_dup 1) (match_dup 0))
17284    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17285   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17286    && GET_CODE (operands[2]) != MINUS
17287    && peep2_reg_dead_p (3, operands[0])
17288    && !reg_overlap_mentioned_p (operands[0], operands[1])
17289    && ix86_match_ccmode (peep2_next_insn (2),
17290                          GET_CODE (operands[2]) == PLUS
17291                          ? CCGOCmode : CCNOmode)"
17292   [(parallel [(set (match_dup 3) (match_dup 4))
17293               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17294                                                   (match_dup 0)]))])]
17295 {
17296   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17297   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17298                                 copy_rtx (operands[1]),
17299                                 copy_rtx (operands[0]));
17300   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17301                                  operands[4], const0_rtx);
17302 })
17303
17304 (define_peephole2
17305   [(set (match_operand:SWI12 0 "register_operand" "")
17306         (match_operand:SWI12 1 "memory_operand" ""))
17307    (parallel [(set (match_operand:SI 4 "register_operand" "")
17308                    (match_operator:SI 3 "plusminuslogic_operator"
17309                      [(match_dup 4)
17310                       (match_operand:SI 2 "nonmemory_operand" "")]))
17311               (clobber (reg:CC FLAGS_REG))])
17312    (set (match_dup 1) (match_dup 0))
17313    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17314   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17315    && REG_P (operands[0]) && REG_P (operands[4])
17316    && REGNO (operands[0]) == REGNO (operands[4])
17317    && peep2_reg_dead_p (4, operands[0])
17318    && !reg_overlap_mentioned_p (operands[0], operands[1])
17319    && ix86_match_ccmode (peep2_next_insn (3),
17320                          (GET_CODE (operands[3]) == PLUS
17321                           || GET_CODE (operands[3]) == MINUS)
17322                          ? CCGOCmode : CCNOmode)"
17323   [(parallel [(set (match_dup 4) (match_dup 5))
17324               (set (match_dup 1) (match_dup 6))])]
17325 {
17326   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17327   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17328   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17329                                 copy_rtx (operands[1]), operands[2]);
17330   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17331                                  operands[5], const0_rtx);
17332   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17333                                 copy_rtx (operands[1]),
17334                                 copy_rtx (operands[2]));
17335 })
17336
17337 ;; Attempt to always use XOR for zeroing registers.
17338 (define_peephole2
17339   [(set (match_operand 0 "register_operand" "")
17340         (match_operand 1 "const0_operand" ""))]
17341   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17342    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17343    && GENERAL_REG_P (operands[0])
17344    && peep2_regno_dead_p (0, FLAGS_REG)"
17345   [(parallel [(set (match_dup 0) (const_int 0))
17346               (clobber (reg:CC FLAGS_REG))])]
17347   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17348
17349 (define_peephole2
17350   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17351         (const_int 0))]
17352   "(GET_MODE (operands[0]) == QImode
17353     || GET_MODE (operands[0]) == HImode)
17354    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17355    && peep2_regno_dead_p (0, FLAGS_REG)"
17356   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17357               (clobber (reg:CC FLAGS_REG))])])
17358
17359 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17360 (define_peephole2
17361   [(set (match_operand:SWI248 0 "register_operand" "")
17362         (const_int -1))]
17363   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17364    && peep2_regno_dead_p (0, FLAGS_REG)"
17365   [(parallel [(set (match_dup 0) (const_int -1))
17366               (clobber (reg:CC FLAGS_REG))])]
17367 {
17368   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17369     operands[0] = gen_lowpart (SImode, operands[0]);
17370 })
17371
17372 ;; Attempt to convert simple lea to add/shift.
17373 ;; These can be created by move expanders.
17374
17375 (define_peephole2
17376   [(set (match_operand:SWI48 0 "register_operand" "")
17377         (plus:SWI48 (match_dup 0)
17378                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17379   "peep2_regno_dead_p (0, FLAGS_REG)"
17380   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17381               (clobber (reg:CC FLAGS_REG))])])
17382
17383 (define_peephole2
17384   [(set (match_operand:SI 0 "register_operand" "")
17385         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17386                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17387   "TARGET_64BIT
17388    && peep2_regno_dead_p (0, FLAGS_REG)
17389    && REGNO (operands[0]) == REGNO (operands[1])"
17390   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17391               (clobber (reg:CC FLAGS_REG))])]
17392   "operands[2] = gen_lowpart (SImode, operands[2]);")
17393
17394 (define_peephole2
17395   [(set (match_operand:SWI48 0 "register_operand" "")
17396         (mult:SWI48 (match_dup 0)
17397                     (match_operand:SWI48 1 "const_int_operand" "")))]
17398   "exact_log2 (INTVAL (operands[1])) >= 0
17399    && peep2_regno_dead_p (0, FLAGS_REG)"
17400   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17401               (clobber (reg:CC FLAGS_REG))])]
17402   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17403
17404 (define_peephole2
17405   [(set (match_operand:SI 0 "register_operand" "")
17406         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17407                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17408   "TARGET_64BIT
17409    && exact_log2 (INTVAL (operands[2])) >= 0
17410    && REGNO (operands[0]) == REGNO (operands[1])
17411    && peep2_regno_dead_p (0, FLAGS_REG)"
17412   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17413               (clobber (reg:CC FLAGS_REG))])]
17414   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17415
17416 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17417 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17418 ;; On many CPUs it is also faster, since special hardware to avoid esp
17419 ;; dependencies is present.
17420
17421 ;; While some of these conversions may be done using splitters, we use
17422 ;; peepholes in order to allow combine_stack_adjustments pass to see
17423 ;; nonobfuscated RTL.
17424
17425 ;; Convert prologue esp subtractions to push.
17426 ;; We need register to push.  In order to keep verify_flow_info happy we have
17427 ;; two choices
17428 ;; - use scratch and clobber it in order to avoid dependencies
17429 ;; - use already live register
17430 ;; We can't use the second way right now, since there is no reliable way how to
17431 ;; verify that given register is live.  First choice will also most likely in
17432 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17433 ;; call clobbered registers are dead.  We may want to use base pointer as an
17434 ;; alternative when no register is available later.
17435
17436 (define_peephole2
17437   [(match_scratch:P 1 "r")
17438    (parallel [(set (reg:P SP_REG)
17439                    (plus:P (reg:P SP_REG)
17440                            (match_operand:P 0 "const_int_operand" "")))
17441               (clobber (reg:CC FLAGS_REG))
17442               (clobber (mem:BLK (scratch)))])]
17443   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17444    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17445   [(clobber (match_dup 1))
17446    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17447               (clobber (mem:BLK (scratch)))])])
17448
17449 (define_peephole2
17450   [(match_scratch:P 1 "r")
17451    (parallel [(set (reg:P SP_REG)
17452                    (plus:P (reg:P SP_REG)
17453                            (match_operand:P 0 "const_int_operand" "")))
17454               (clobber (reg:CC FLAGS_REG))
17455               (clobber (mem:BLK (scratch)))])]
17456   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17457    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17458   [(clobber (match_dup 1))
17459    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17460    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17461               (clobber (mem:BLK (scratch)))])])
17462
17463 ;; Convert esp subtractions to push.
17464 (define_peephole2
17465   [(match_scratch:P 1 "r")
17466    (parallel [(set (reg:P SP_REG)
17467                    (plus:P (reg:P SP_REG)
17468                            (match_operand:P 0 "const_int_operand" "")))
17469               (clobber (reg:CC FLAGS_REG))])]
17470   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17471    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17472   [(clobber (match_dup 1))
17473    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17474
17475 (define_peephole2
17476   [(match_scratch:P 1 "r")
17477    (parallel [(set (reg:P SP_REG)
17478                    (plus:P (reg:P SP_REG)
17479                            (match_operand:P 0 "const_int_operand" "")))
17480               (clobber (reg:CC FLAGS_REG))])]
17481   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17482    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17483   [(clobber (match_dup 1))
17484    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17485    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17486
17487 ;; Convert epilogue deallocator to pop.
17488 (define_peephole2
17489   [(match_scratch:P 1 "r")
17490    (parallel [(set (reg:P SP_REG)
17491                    (plus:P (reg:P SP_REG)
17492                            (match_operand:P 0 "const_int_operand" "")))
17493               (clobber (reg:CC FLAGS_REG))
17494               (clobber (mem:BLK (scratch)))])]
17495   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17496    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17497   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17498               (clobber (mem:BLK (scratch)))])])
17499
17500 ;; Two pops case is tricky, since pop causes dependency
17501 ;; on destination register.  We use two registers if available.
17502 (define_peephole2
17503   [(match_scratch:P 1 "r")
17504    (match_scratch:P 2 "r")
17505    (parallel [(set (reg:P SP_REG)
17506                    (plus:P (reg:P SP_REG)
17507                            (match_operand:P 0 "const_int_operand" "")))
17508               (clobber (reg:CC FLAGS_REG))
17509               (clobber (mem:BLK (scratch)))])]
17510   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17511    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17512   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17513               (clobber (mem:BLK (scratch)))])
17514    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17515
17516 (define_peephole2
17517   [(match_scratch:P 1 "r")
17518    (parallel [(set (reg:P SP_REG)
17519                    (plus:P (reg:P SP_REG)
17520                            (match_operand:P 0 "const_int_operand" "")))
17521               (clobber (reg:CC FLAGS_REG))
17522               (clobber (mem:BLK (scratch)))])]
17523   "optimize_insn_for_size_p ()
17524    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17525   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17526               (clobber (mem:BLK (scratch)))])
17527    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17528
17529 ;; Convert esp additions to pop.
17530 (define_peephole2
17531   [(match_scratch:P 1 "r")
17532    (parallel [(set (reg:P SP_REG)
17533                    (plus:P (reg:P SP_REG)
17534                            (match_operand:P 0 "const_int_operand" "")))
17535               (clobber (reg:CC FLAGS_REG))])]
17536   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17537   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17538
17539 ;; Two pops case is tricky, since pop causes dependency
17540 ;; on destination register.  We use two registers if available.
17541 (define_peephole2
17542   [(match_scratch:P 1 "r")
17543    (match_scratch:P 2 "r")
17544    (parallel [(set (reg:P SP_REG)
17545                    (plus:P (reg:P SP_REG)
17546                            (match_operand:P 0 "const_int_operand" "")))
17547               (clobber (reg:CC FLAGS_REG))])]
17548   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17549   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17550    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17551
17552 (define_peephole2
17553   [(match_scratch:P 1 "r")
17554    (parallel [(set (reg:P SP_REG)
17555                    (plus:P (reg:P SP_REG)
17556                            (match_operand:P 0 "const_int_operand" "")))
17557               (clobber (reg:CC FLAGS_REG))])]
17558   "optimize_insn_for_size_p ()
17559    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17560   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17561    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17562 \f
17563 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17564 ;; required and register dies.  Similarly for 128 to -128.
17565 (define_peephole2
17566   [(set (match_operand 0 "flags_reg_operand" "")
17567         (match_operator 1 "compare_operator"
17568           [(match_operand 2 "register_operand" "")
17569            (match_operand 3 "const_int_operand" "")]))]
17570   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17571      && incdec_operand (operands[3], GET_MODE (operands[3])))
17572     || (!TARGET_FUSE_CMP_AND_BRANCH
17573         && INTVAL (operands[3]) == 128))
17574    && ix86_match_ccmode (insn, CCGCmode)
17575    && peep2_reg_dead_p (1, operands[2])"
17576   [(parallel [(set (match_dup 0)
17577                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17578               (clobber (match_dup 2))])])
17579 \f
17580 ;; Convert imul by three, five and nine into lea
17581 (define_peephole2
17582   [(parallel
17583     [(set (match_operand:SWI48 0 "register_operand" "")
17584           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17585                       (match_operand:SWI48 2 "const359_operand" "")))
17586      (clobber (reg:CC FLAGS_REG))])]
17587   "!TARGET_PARTIAL_REG_STALL
17588    || <MODE>mode == SImode
17589    || optimize_function_for_size_p (cfun)"
17590   [(set (match_dup 0)
17591         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17592                     (match_dup 1)))]
17593   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17594
17595 (define_peephole2
17596   [(parallel
17597     [(set (match_operand:SWI48 0 "register_operand" "")
17598           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17599                       (match_operand:SWI48 2 "const359_operand" "")))
17600      (clobber (reg:CC FLAGS_REG))])]
17601   "optimize_insn_for_speed_p ()
17602    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17603   [(set (match_dup 0) (match_dup 1))
17604    (set (match_dup 0)
17605         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17606                     (match_dup 0)))]
17607   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17608
17609 ;; imul $32bit_imm, mem, reg is vector decoded, while
17610 ;; imul $32bit_imm, reg, reg is direct decoded.
17611 (define_peephole2
17612   [(match_scratch:SWI48 3 "r")
17613    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17614                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17615                                (match_operand:SWI48 2 "immediate_operand" "")))
17616               (clobber (reg:CC FLAGS_REG))])]
17617   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17618    && !satisfies_constraint_K (operands[2])"
17619   [(set (match_dup 3) (match_dup 1))
17620    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17621               (clobber (reg:CC FLAGS_REG))])])
17622
17623 (define_peephole2
17624   [(match_scratch:SI 3 "r")
17625    (parallel [(set (match_operand:DI 0 "register_operand" "")
17626                    (zero_extend:DI
17627                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17628                               (match_operand:SI 2 "immediate_operand" ""))))
17629               (clobber (reg:CC FLAGS_REG))])]
17630   "TARGET_64BIT
17631    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17632    && !satisfies_constraint_K (operands[2])"
17633   [(set (match_dup 3) (match_dup 1))
17634    (parallel [(set (match_dup 0)
17635                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17636               (clobber (reg:CC FLAGS_REG))])])
17637
17638 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17639 ;; Convert it into imul reg, reg
17640 ;; It would be better to force assembler to encode instruction using long
17641 ;; immediate, but there is apparently no way to do so.
17642 (define_peephole2
17643   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17644                    (mult:SWI248
17645                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17646                     (match_operand:SWI248 2 "const_int_operand" "")))
17647               (clobber (reg:CC FLAGS_REG))])
17648    (match_scratch:SWI248 3 "r")]
17649   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17650    && satisfies_constraint_K (operands[2])"
17651   [(set (match_dup 3) (match_dup 2))
17652    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17653               (clobber (reg:CC FLAGS_REG))])]
17654 {
17655   if (!rtx_equal_p (operands[0], operands[1]))
17656     emit_move_insn (operands[0], operands[1]);
17657 })
17658
17659 ;; After splitting up read-modify operations, array accesses with memory
17660 ;; operands might end up in form:
17661 ;;  sall    $2, %eax
17662 ;;  movl    4(%esp), %edx
17663 ;;  addl    %edx, %eax
17664 ;; instead of pre-splitting:
17665 ;;  sall    $2, %eax
17666 ;;  addl    4(%esp), %eax
17667 ;; Turn it into:
17668 ;;  movl    4(%esp), %edx
17669 ;;  leal    (%edx,%eax,4), %eax
17670
17671 (define_peephole2
17672   [(match_scratch:P 5 "r")
17673    (parallel [(set (match_operand 0 "register_operand" "")
17674                    (ashift (match_operand 1 "register_operand" "")
17675                            (match_operand 2 "const_int_operand" "")))
17676                (clobber (reg:CC FLAGS_REG))])
17677    (parallel [(set (match_operand 3 "register_operand" "")
17678                    (plus (match_dup 0)
17679                          (match_operand 4 "x86_64_general_operand" "")))
17680                    (clobber (reg:CC FLAGS_REG))])]
17681   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17682    /* Validate MODE for lea.  */
17683    && ((!TARGET_PARTIAL_REG_STALL
17684         && (GET_MODE (operands[0]) == QImode
17685             || GET_MODE (operands[0]) == HImode))
17686        || GET_MODE (operands[0]) == SImode
17687        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17688    && (rtx_equal_p (operands[0], operands[3])
17689        || peep2_reg_dead_p (2, operands[0]))
17690    /* We reorder load and the shift.  */
17691    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17692   [(set (match_dup 5) (match_dup 4))
17693    (set (match_dup 0) (match_dup 1))]
17694 {
17695   enum machine_mode op1mode = GET_MODE (operands[1]);
17696   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17697   int scale = 1 << INTVAL (operands[2]);
17698   rtx index = gen_lowpart (Pmode, operands[1]);
17699   rtx base = gen_lowpart (Pmode, operands[5]);
17700   rtx dest = gen_lowpart (mode, operands[3]);
17701
17702   operands[1] = gen_rtx_PLUS (Pmode, base,
17703                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17704   operands[5] = base;
17705   if (mode != Pmode)
17706     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17707   if (op1mode != Pmode)
17708     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17709   operands[0] = dest;
17710 })
17711 \f
17712 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17713 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17714 ;; caught for use by garbage collectors and the like.  Using an insn that
17715 ;; maps to SIGILL makes it more likely the program will rightfully die.
17716 ;; Keeping with tradition, "6" is in honor of #UD.
17717 (define_insn "trap"
17718   [(trap_if (const_int 1) (const_int 6))]
17719   ""
17720   { return ASM_SHORT "0x0b0f"; }
17721   [(set_attr "length" "2")])
17722
17723 (define_expand "prefetch"
17724   [(prefetch (match_operand 0 "address_operand" "")
17725              (match_operand:SI 1 "const_int_operand" "")
17726              (match_operand:SI 2 "const_int_operand" ""))]
17727   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17728 {
17729   int rw = INTVAL (operands[1]);
17730   int locality = INTVAL (operands[2]);
17731
17732   gcc_assert (rw == 0 || rw == 1);
17733   gcc_assert (locality >= 0 && locality <= 3);
17734   gcc_assert (GET_MODE (operands[0]) == Pmode
17735               || GET_MODE (operands[0]) == VOIDmode);
17736
17737   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17738      supported by SSE counterpart or the SSE prefetch is not available
17739      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17740      of locality.  */
17741   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17742     operands[2] = GEN_INT (3);
17743   else
17744     operands[1] = const0_rtx;
17745 })
17746
17747 (define_insn "*prefetch_sse_<mode>"
17748   [(prefetch (match_operand:P 0 "address_operand" "p")
17749              (const_int 0)
17750              (match_operand:SI 1 "const_int_operand" ""))]
17751   "TARGET_PREFETCH_SSE"
17752 {
17753   static const char * const patterns[4] = {
17754    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17755   };
17756
17757   int locality = INTVAL (operands[1]);
17758   gcc_assert (locality >= 0 && locality <= 3);
17759
17760   return patterns[locality];
17761 }
17762   [(set_attr "type" "sse")
17763    (set_attr "atom_sse_attr" "prefetch")
17764    (set (attr "length_address")
17765         (symbol_ref "memory_address_length (operands[0])"))
17766    (set_attr "memory" "none")])
17767
17768 (define_insn "*prefetch_3dnow_<mode>"
17769   [(prefetch (match_operand:P 0 "address_operand" "p")
17770              (match_operand:SI 1 "const_int_operand" "n")
17771              (const_int 3))]
17772   "TARGET_3DNOW"
17773 {
17774   if (INTVAL (operands[1]) == 0)
17775     return "prefetch\t%a0";
17776   else
17777     return "prefetchw\t%a0";
17778 }
17779   [(set_attr "type" "mmx")
17780    (set (attr "length_address")
17781         (symbol_ref "memory_address_length (operands[0])"))
17782    (set_attr "memory" "none")])
17783
17784 (define_expand "stack_protect_set"
17785   [(match_operand 0 "memory_operand" "")
17786    (match_operand 1 "memory_operand" "")]
17787   ""
17788 {
17789   rtx (*insn)(rtx, rtx);
17790
17791 #ifdef TARGET_THREAD_SSP_OFFSET
17792   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17793   insn = (TARGET_LP64
17794           ? gen_stack_tls_protect_set_di
17795           : gen_stack_tls_protect_set_si);
17796 #else
17797   insn = (TARGET_LP64
17798           ? gen_stack_protect_set_di
17799           : gen_stack_protect_set_si);
17800 #endif
17801
17802   emit_insn (insn (operands[0], operands[1]));
17803   DONE;
17804 })
17805
17806 (define_insn "stack_protect_set_<mode>"
17807   [(set (match_operand:PTR 0 "memory_operand" "=m")
17808         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17809                     UNSPEC_SP_SET))
17810    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17811    (clobber (reg:CC FLAGS_REG))]
17812   ""
17813   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17814   [(set_attr "type" "multi")])
17815
17816 (define_insn "stack_tls_protect_set_<mode>"
17817   [(set (match_operand:PTR 0 "memory_operand" "=m")
17818         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17819                     UNSPEC_SP_TLS_SET))
17820    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17821    (clobber (reg:CC FLAGS_REG))]
17822   ""
17823   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17824   [(set_attr "type" "multi")])
17825
17826 (define_expand "stack_protect_test"
17827   [(match_operand 0 "memory_operand" "")
17828    (match_operand 1 "memory_operand" "")
17829    (match_operand 2 "" "")]
17830   ""
17831 {
17832   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17833
17834   rtx (*insn)(rtx, rtx, rtx);
17835
17836 #ifdef TARGET_THREAD_SSP_OFFSET
17837   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17838   insn = (TARGET_LP64
17839           ? gen_stack_tls_protect_test_di
17840           : gen_stack_tls_protect_test_si);
17841 #else
17842   insn = (TARGET_LP64
17843           ? gen_stack_protect_test_di
17844           : gen_stack_protect_test_si);
17845 #endif
17846
17847   emit_insn (insn (flags, operands[0], operands[1]));
17848
17849   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17850                                   flags, const0_rtx, operands[2]));
17851   DONE;
17852 })
17853
17854 (define_insn "stack_protect_test_<mode>"
17855   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17856         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17857                      (match_operand:PTR 2 "memory_operand" "m")]
17858                     UNSPEC_SP_TEST))
17859    (clobber (match_scratch:PTR 3 "=&r"))]
17860   ""
17861   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17862   [(set_attr "type" "multi")])
17863
17864 (define_insn "stack_tls_protect_test_<mode>"
17865   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17866         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17867                      (match_operand:PTR 2 "const_int_operand" "i")]
17868                     UNSPEC_SP_TLS_TEST))
17869    (clobber (match_scratch:PTR 3 "=r"))]
17870   ""
17871   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17872   [(set_attr "type" "multi")])
17873
17874 (define_insn "sse4_2_crc32<mode>"
17875   [(set (match_operand:SI 0 "register_operand" "=r")
17876         (unspec:SI
17877           [(match_operand:SI 1 "register_operand" "0")
17878            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17879           UNSPEC_CRC32))]
17880   "TARGET_SSE4_2 || TARGET_CRC32"
17881   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17882   [(set_attr "type" "sselog1")
17883    (set_attr "prefix_rep" "1")
17884    (set_attr "prefix_extra" "1")
17885    (set (attr "prefix_data16")
17886      (if_then_else (match_operand:HI 2 "" "")
17887        (const_string "1")
17888        (const_string "*")))
17889    (set (attr "prefix_rex")
17890      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17891        (const_string "1")
17892        (const_string "*")))
17893    (set_attr "mode" "SI")])
17894
17895 (define_insn "sse4_2_crc32di"
17896   [(set (match_operand:DI 0 "register_operand" "=r")
17897         (unspec:DI
17898           [(match_operand:DI 1 "register_operand" "0")
17899            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17900           UNSPEC_CRC32))]
17901   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17902   "crc32{q}\t{%2, %0|%0, %2}"
17903   [(set_attr "type" "sselog1")
17904    (set_attr "prefix_rep" "1")
17905    (set_attr "prefix_extra" "1")
17906    (set_attr "mode" "DI")])
17907
17908 (define_expand "rdpmc"
17909   [(match_operand:DI 0 "register_operand" "")
17910    (match_operand:SI 1 "register_operand" "")]
17911   ""
17912 {
17913   rtx reg = gen_reg_rtx (DImode);
17914   rtx si;
17915
17916   /* Force operand 1 into ECX.  */
17917   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17918   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17919   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17920                                 UNSPECV_RDPMC);
17921
17922   if (TARGET_64BIT)
17923     {
17924       rtvec vec = rtvec_alloc (2);
17925       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17926       rtx upper = gen_reg_rtx (DImode);
17927       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17928                                         gen_rtvec (1, const0_rtx),
17929                                         UNSPECV_RDPMC);
17930       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17931       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17932       emit_insn (load);
17933       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17934                                    NULL, 1, OPTAB_DIRECT);
17935       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17936                                  OPTAB_DIRECT);
17937     }
17938   else
17939     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17940   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17941   DONE;
17942 })
17943
17944 (define_insn "*rdpmc"
17945   [(set (match_operand:DI 0 "register_operand" "=A")
17946         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17947                             UNSPECV_RDPMC))]
17948   "!TARGET_64BIT"
17949   "rdpmc"
17950   [(set_attr "type" "other")
17951    (set_attr "length" "2")])
17952
17953 (define_insn "*rdpmc_rex64"
17954   [(set (match_operand:DI 0 "register_operand" "=a")
17955         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17956                             UNSPECV_RDPMC))
17957   (set (match_operand:DI 1 "register_operand" "=d")
17958        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17959   "TARGET_64BIT"
17960   "rdpmc"
17961   [(set_attr "type" "other")
17962    (set_attr "length" "2")])
17963
17964 (define_expand "rdtsc"
17965   [(set (match_operand:DI 0 "register_operand" "")
17966         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17967   ""
17968 {
17969   if (TARGET_64BIT)
17970     {
17971       rtvec vec = rtvec_alloc (2);
17972       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17973       rtx upper = gen_reg_rtx (DImode);
17974       rtx lower = gen_reg_rtx (DImode);
17975       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17976                                          gen_rtvec (1, const0_rtx),
17977                                          UNSPECV_RDTSC);
17978       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17979       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17980       emit_insn (load);
17981       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17982                                    NULL, 1, OPTAB_DIRECT);
17983       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17984                                    OPTAB_DIRECT);
17985       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17986       DONE;
17987     }
17988 })
17989
17990 (define_insn "*rdtsc"
17991   [(set (match_operand:DI 0 "register_operand" "=A")
17992         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17993   "!TARGET_64BIT"
17994   "rdtsc"
17995   [(set_attr "type" "other")
17996    (set_attr "length" "2")])
17997
17998 (define_insn "*rdtsc_rex64"
17999   [(set (match_operand:DI 0 "register_operand" "=a")
18000         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18001    (set (match_operand:DI 1 "register_operand" "=d")
18002         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18003   "TARGET_64BIT"
18004   "rdtsc"
18005   [(set_attr "type" "other")
18006    (set_attr "length" "2")])
18007
18008 (define_expand "rdtscp"
18009   [(match_operand:DI 0 "register_operand" "")
18010    (match_operand:SI 1 "memory_operand" "")]
18011   ""
18012 {
18013   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18014                                     gen_rtvec (1, const0_rtx),
18015                                     UNSPECV_RDTSCP);
18016   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18017                                     gen_rtvec (1, const0_rtx),
18018                                     UNSPECV_RDTSCP);
18019   rtx reg = gen_reg_rtx (DImode);
18020   rtx tmp = gen_reg_rtx (SImode);
18021
18022   if (TARGET_64BIT)
18023     {
18024       rtvec vec = rtvec_alloc (3);
18025       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18026       rtx upper = gen_reg_rtx (DImode);
18027       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18028       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18029       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18030       emit_insn (load);
18031       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18032                                    NULL, 1, OPTAB_DIRECT);
18033       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18034                                  OPTAB_DIRECT);
18035     }
18036   else
18037     {
18038       rtvec vec = rtvec_alloc (2);
18039       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18040       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18041       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18042       emit_insn (load);
18043     }
18044   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18045   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18046   DONE;
18047 })
18048
18049 (define_insn "*rdtscp"
18050   [(set (match_operand:DI 0 "register_operand" "=A")
18051         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18052    (set (match_operand:SI 1 "register_operand" "=c")
18053         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18054   "!TARGET_64BIT"
18055   "rdtscp"
18056   [(set_attr "type" "other")
18057    (set_attr "length" "3")])
18058
18059 (define_insn "*rdtscp_rex64"
18060   [(set (match_operand:DI 0 "register_operand" "=a")
18061         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18062    (set (match_operand:DI 1 "register_operand" "=d")
18063         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18064    (set (match_operand:SI 2 "register_operand" "=c")
18065         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18066   "TARGET_64BIT"
18067   "rdtscp"
18068   [(set_attr "type" "other")
18069    (set_attr "length" "3")])
18070
18071 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18072 ;;
18073 ;; LWP instructions
18074 ;;
18075 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18076
18077 (define_expand "lwp_llwpcb"
18078   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18079                     UNSPECV_LLWP_INTRINSIC)]
18080   "TARGET_LWP")
18081
18082 (define_insn "*lwp_llwpcb<mode>1"
18083   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18084                     UNSPECV_LLWP_INTRINSIC)]
18085   "TARGET_LWP"
18086   "llwpcb\t%0"
18087   [(set_attr "type" "lwp")
18088    (set_attr "mode" "<MODE>")
18089    (set_attr "length" "5")])
18090
18091 (define_expand "lwp_slwpcb"
18092   [(set (match_operand 0 "register_operand" "=r")
18093         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18094   "TARGET_LWP"
18095 {
18096   rtx (*insn)(rtx);
18097
18098   insn = (TARGET_64BIT
18099           ? gen_lwp_slwpcbdi
18100           : gen_lwp_slwpcbsi);
18101
18102   emit_insn (insn (operands[0]));
18103   DONE;
18104 })
18105
18106 (define_insn "lwp_slwpcb<mode>"
18107   [(set (match_operand:P 0 "register_operand" "=r")
18108         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18109   "TARGET_LWP"
18110   "slwpcb\t%0"
18111   [(set_attr "type" "lwp")
18112    (set_attr "mode" "<MODE>")
18113    (set_attr "length" "5")])
18114
18115 (define_expand "lwp_lwpval<mode>3"
18116   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18117                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18118                      (match_operand:SI 3 "const_int_operand" "i")]
18119                     UNSPECV_LWPVAL_INTRINSIC)]
18120   "TARGET_LWP"
18121   ;; Avoid unused variable warning.
18122   "(void) operands[0];")
18123
18124 (define_insn "*lwp_lwpval<mode>3_1"
18125   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18126                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18127                      (match_operand:SI 2 "const_int_operand" "i")]
18128                     UNSPECV_LWPVAL_INTRINSIC)]
18129   "TARGET_LWP"
18130   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18131   [(set_attr "type" "lwp")
18132    (set_attr "mode" "<MODE>")
18133    (set (attr "length")
18134         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18135
18136 (define_expand "lwp_lwpins<mode>3"
18137   [(set (reg:CCC FLAGS_REG)
18138         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18139                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18140                               (match_operand:SI 3 "const_int_operand" "i")]
18141                              UNSPECV_LWPINS_INTRINSIC))
18142    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18143         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18144   "TARGET_LWP")
18145
18146 (define_insn "*lwp_lwpins<mode>3_1"
18147   [(set (reg:CCC FLAGS_REG)
18148         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18149                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18150                               (match_operand:SI 2 "const_int_operand" "i")]
18151                              UNSPECV_LWPINS_INTRINSIC))]
18152   "TARGET_LWP"
18153   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18154   [(set_attr "type" "lwp")
18155    (set_attr "mode" "<MODE>")
18156    (set (attr "length")
18157         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18158
18159 (define_insn "rdfsbase<mode>"
18160   [(set (match_operand:SWI48 0 "register_operand" "=r")
18161         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18162   "TARGET_64BIT && TARGET_FSGSBASE"
18163   "rdfsbase %0"
18164   [(set_attr "type" "other")
18165    (set_attr "prefix_extra" "2")])
18166
18167 (define_insn "rdgsbase<mode>"
18168   [(set (match_operand:SWI48 0 "register_operand" "=r")
18169         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18170   "TARGET_64BIT && TARGET_FSGSBASE"
18171   "rdgsbase %0"
18172   [(set_attr "type" "other")
18173    (set_attr "prefix_extra" "2")])
18174
18175 (define_insn "wrfsbase<mode>"
18176   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18177                     UNSPECV_WRFSBASE)]
18178   "TARGET_64BIT && TARGET_FSGSBASE"
18179   "wrfsbase %0"
18180   [(set_attr "type" "other")
18181    (set_attr "prefix_extra" "2")])
18182
18183 (define_insn "wrgsbase<mode>"
18184   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18185                     UNSPECV_WRGSBASE)]
18186   "TARGET_64BIT && TARGET_FSGSBASE"
18187   "wrgsbase %0"
18188   [(set_attr "type" "other")
18189    (set_attr "prefix_extra" "2")])
18190
18191 (define_insn "rdrand<mode>_1"
18192   [(set (match_operand:SWI248 0 "register_operand" "=r")
18193         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18194    (set (reg:CCC FLAGS_REG)
18195         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18196   "TARGET_RDRND"
18197   "rdrand\t%0"
18198   [(set_attr "type" "other")
18199    (set_attr "prefix_extra" "1")])
18200
18201 (define_expand "pause"
18202   [(set (match_dup 0)
18203         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18204   ""
18205 {
18206   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18207   MEM_VOLATILE_P (operands[0]) = 1;
18208 })
18209
18210 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18211 ;; They have the same encoding.
18212 (define_insn "*pause"
18213   [(set (match_operand:BLK 0 "" "")
18214         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18215   ""
18216   "rep; nop"
18217   [(set_attr "length" "2")
18218    (set_attr "memory" "unknown")])
18219
18220 (include "mmx.md")
18221 (include "sse.md")
18222 (include "sync.md")