OSDN Git Service

35273d95683ede4c02419edafb7aa2bed4778df0
[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" "p") 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" "p")))]
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   if (crtl->args.pops_args)
11740     {
11741       rtx popc = GEN_INT (crtl->args.pops_args);
11742       emit_jump_insn (gen_simple_return_pop_internal (popc));
11743       DONE;
11744     }
11745 })
11746
11747 ;; We need to disable this for TARGET_SEH, as otherwise
11748 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11749 ;; the maximum size of prologue in unwind information.
11750
11751 (define_expand "simple_return"
11752   [(simple_return)]
11753   "!TARGET_SEH"
11754 {
11755   if (crtl->args.pops_args)
11756     {
11757       rtx popc = GEN_INT (crtl->args.pops_args);
11758       emit_jump_insn (gen_simple_return_pop_internal (popc));
11759       DONE;
11760     }
11761 })
11762
11763 (define_insn "simple_return_internal"
11764   [(simple_return)]
11765   "reload_completed"
11766   "ret"
11767   [(set_attr "length" "1")
11768    (set_attr "atom_unit" "jeu")
11769    (set_attr "length_immediate" "0")
11770    (set_attr "modrm" "0")])
11771
11772 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11773 ;; instruction Athlon and K8 have.
11774
11775 (define_insn "simple_return_internal_long"
11776   [(simple_return)
11777    (unspec [(const_int 0)] UNSPEC_REP)]
11778   "reload_completed"
11779   "rep\;ret"
11780   [(set_attr "length" "2")
11781    (set_attr "atom_unit" "jeu")
11782    (set_attr "length_immediate" "0")
11783    (set_attr "prefix_rep" "1")
11784    (set_attr "modrm" "0")])
11785
11786 (define_insn "simple_return_pop_internal"
11787   [(simple_return)
11788    (use (match_operand:SI 0 "const_int_operand" ""))]
11789   "reload_completed"
11790   "ret\t%0"
11791   [(set_attr "length" "3")
11792    (set_attr "atom_unit" "jeu")
11793    (set_attr "length_immediate" "2")
11794    (set_attr "modrm" "0")])
11795
11796 (define_insn "simple_return_indirect_internal"
11797   [(simple_return)
11798    (use (match_operand:SI 0 "register_operand" "r"))]
11799   "reload_completed"
11800   "jmp\t%A0"
11801   [(set_attr "type" "ibr")
11802    (set_attr "length_immediate" "0")])
11803
11804 (define_insn "nop"
11805   [(const_int 0)]
11806   ""
11807   "nop"
11808   [(set_attr "length" "1")
11809    (set_attr "length_immediate" "0")
11810    (set_attr "modrm" "0")])
11811
11812 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11813 (define_insn "nops"
11814   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11815                     UNSPECV_NOPS)]
11816   "reload_completed"
11817 {
11818   int num = INTVAL (operands[0]);
11819
11820   gcc_assert (num >= 1 && num <= 8);
11821
11822   while (num--)
11823     fputs ("\tnop\n", asm_out_file);
11824
11825   return "";
11826 }
11827   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11828    (set_attr "length_immediate" "0")
11829    (set_attr "modrm" "0")])
11830
11831 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11832 ;; branch prediction penalty for the third jump in a 16-byte
11833 ;; block on K8.
11834
11835 (define_insn "pad"
11836   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11837   ""
11838 {
11839 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11840   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11841 #else
11842   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11843      The align insn is used to avoid 3 jump instructions in the row to improve
11844      branch prediction and the benefits hardly outweigh the cost of extra 8
11845      nops on the average inserted by full alignment pseudo operation.  */
11846 #endif
11847   return "";
11848 }
11849   [(set_attr "length" "16")])
11850
11851 (define_expand "prologue"
11852   [(const_int 0)]
11853   ""
11854   "ix86_expand_prologue (); DONE;")
11855
11856 (define_insn "set_got"
11857   [(set (match_operand:SI 0 "register_operand" "=r")
11858         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11859    (clobber (reg:CC FLAGS_REG))]
11860   "!TARGET_64BIT"
11861   "* return output_set_got (operands[0], NULL_RTX);"
11862   [(set_attr "type" "multi")
11863    (set_attr "length" "12")])
11864
11865 (define_insn "set_got_labelled"
11866   [(set (match_operand:SI 0 "register_operand" "=r")
11867         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11868          UNSPEC_SET_GOT))
11869    (clobber (reg:CC FLAGS_REG))]
11870   "!TARGET_64BIT"
11871   "* return output_set_got (operands[0], operands[1]);"
11872   [(set_attr "type" "multi")
11873    (set_attr "length" "12")])
11874
11875 (define_insn "set_got_rex64"
11876   [(set (match_operand:DI 0 "register_operand" "=r")
11877         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11878   "TARGET_64BIT"
11879   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11880   [(set_attr "type" "lea")
11881    (set_attr "length_address" "4")
11882    (set_attr "mode" "DI")])
11883
11884 (define_insn "set_rip_rex64"
11885   [(set (match_operand:DI 0 "register_operand" "=r")
11886         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11887   "TARGET_64BIT"
11888   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11889   [(set_attr "type" "lea")
11890    (set_attr "length_address" "4")
11891    (set_attr "mode" "DI")])
11892
11893 (define_insn "set_got_offset_rex64"
11894   [(set (match_operand:DI 0 "register_operand" "=r")
11895         (unspec:DI
11896           [(label_ref (match_operand 1 "" ""))]
11897           UNSPEC_SET_GOT_OFFSET))]
11898   "TARGET_LP64"
11899   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11900   [(set_attr "type" "imov")
11901    (set_attr "length_immediate" "0")
11902    (set_attr "length_address" "8")
11903    (set_attr "mode" "DI")])
11904
11905 (define_expand "epilogue"
11906   [(const_int 0)]
11907   ""
11908   "ix86_expand_epilogue (1); DONE;")
11909
11910 (define_expand "sibcall_epilogue"
11911   [(const_int 0)]
11912   ""
11913   "ix86_expand_epilogue (0); DONE;")
11914
11915 (define_expand "eh_return"
11916   [(use (match_operand 0 "register_operand" ""))]
11917   ""
11918 {
11919   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11920
11921   /* Tricky bit: we write the address of the handler to which we will
11922      be returning into someone else's stack frame, one word below the
11923      stack address we wish to restore.  */
11924   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11925   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11926   tmp = gen_rtx_MEM (Pmode, tmp);
11927   emit_move_insn (tmp, ra);
11928
11929   emit_jump_insn (gen_eh_return_internal ());
11930   emit_barrier ();
11931   DONE;
11932 })
11933
11934 (define_insn_and_split "eh_return_internal"
11935   [(eh_return)]
11936   ""
11937   "#"
11938   "epilogue_completed"
11939   [(const_int 0)]
11940   "ix86_expand_epilogue (2); DONE;")
11941
11942 (define_insn "leave"
11943   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11944    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11945    (clobber (mem:BLK (scratch)))]
11946   "!TARGET_64BIT"
11947   "leave"
11948   [(set_attr "type" "leave")])
11949
11950 (define_insn "leave_rex64"
11951   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11952    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11953    (clobber (mem:BLK (scratch)))]
11954   "TARGET_64BIT"
11955   "leave"
11956   [(set_attr "type" "leave")])
11957 \f
11958 ;; Handle -fsplit-stack.
11959
11960 (define_expand "split_stack_prologue"
11961   [(const_int 0)]
11962   ""
11963 {
11964   ix86_expand_split_stack_prologue ();
11965   DONE;
11966 })
11967
11968 ;; In order to support the call/return predictor, we use a return
11969 ;; instruction which the middle-end doesn't see.
11970 (define_insn "split_stack_return"
11971   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11972                      UNSPECV_SPLIT_STACK_RETURN)]
11973   ""
11974 {
11975   if (operands[0] == const0_rtx)
11976     return "ret";
11977   else
11978     return "ret\t%0";
11979 }
11980   [(set_attr "atom_unit" "jeu")
11981    (set_attr "modrm" "0")
11982    (set (attr "length")
11983         (if_then_else (match_operand:SI 0 "const0_operand" "")
11984                       (const_int 1)
11985                       (const_int 3)))
11986    (set (attr "length_immediate")
11987         (if_then_else (match_operand:SI 0 "const0_operand" "")
11988                       (const_int 0)
11989                       (const_int 2)))])
11990
11991 ;; If there are operand 0 bytes available on the stack, jump to
11992 ;; operand 1.
11993
11994 (define_expand "split_stack_space_check"
11995   [(set (pc) (if_then_else
11996               (ltu (minus (reg SP_REG)
11997                           (match_operand 0 "register_operand" ""))
11998                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11999               (label_ref (match_operand 1 "" ""))
12000               (pc)))]
12001   ""
12002 {
12003   rtx reg, size, limit;
12004
12005   reg = gen_reg_rtx (Pmode);
12006   size = force_reg (Pmode, operands[0]);
12007   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12008   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12009                           UNSPEC_STACK_CHECK);
12010   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12011   ix86_expand_branch (GEU, reg, limit, operands[1]);
12012
12013   DONE;
12014 })
12015 \f
12016 ;; Bit manipulation instructions.
12017
12018 (define_expand "ffs<mode>2"
12019   [(set (match_dup 2) (const_int -1))
12020    (parallel [(set (reg:CCZ FLAGS_REG)
12021                    (compare:CCZ
12022                      (match_operand:SWI48 1 "nonimmediate_operand" "")
12023                      (const_int 0)))
12024               (set (match_operand:SWI48 0 "register_operand" "")
12025                    (ctz:SWI48 (match_dup 1)))])
12026    (set (match_dup 0) (if_then_else:SWI48
12027                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12028                         (match_dup 2)
12029                         (match_dup 0)))
12030    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12031               (clobber (reg:CC FLAGS_REG))])]
12032   ""
12033 {
12034   if (<MODE>mode == SImode && !TARGET_CMOVE)
12035     {
12036       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12037       DONE;
12038     }
12039   operands[2] = gen_reg_rtx (<MODE>mode);
12040 })
12041
12042 (define_insn_and_split "ffssi2_no_cmove"
12043   [(set (match_operand:SI 0 "register_operand" "=r")
12044         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12045    (clobber (match_scratch:SI 2 "=&q"))
12046    (clobber (reg:CC FLAGS_REG))]
12047   "!TARGET_CMOVE"
12048   "#"
12049   "&& reload_completed"
12050   [(parallel [(set (reg:CCZ FLAGS_REG)
12051                    (compare:CCZ (match_dup 1) (const_int 0)))
12052               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12053    (set (strict_low_part (match_dup 3))
12054         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12055    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12056               (clobber (reg:CC FLAGS_REG))])
12057    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12058               (clobber (reg:CC FLAGS_REG))])
12059    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12060               (clobber (reg:CC FLAGS_REG))])]
12061 {
12062   operands[3] = gen_lowpart (QImode, operands[2]);
12063   ix86_expand_clear (operands[2]);
12064 })
12065
12066 (define_insn "*ffs<mode>_1"
12067   [(set (reg:CCZ FLAGS_REG)
12068         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12069                      (const_int 0)))
12070    (set (match_operand:SWI48 0 "register_operand" "=r")
12071         (ctz:SWI48 (match_dup 1)))]
12072   ""
12073   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12074   [(set_attr "type" "alu1")
12075    (set_attr "prefix_0f" "1")
12076    (set_attr "mode" "<MODE>")])
12077
12078 (define_insn "ctz<mode>2"
12079   [(set (match_operand:SWI248 0 "register_operand" "=r")
12080         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12081    (clobber (reg:CC FLAGS_REG))]
12082   ""
12083 {
12084   if (TARGET_BMI)
12085     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12086   else
12087     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12088 }
12089   [(set_attr "type" "alu1")
12090    (set_attr "prefix_0f" "1")
12091    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12092    (set_attr "mode" "<MODE>")])
12093
12094 (define_expand "clz<mode>2"
12095   [(parallel
12096      [(set (match_operand:SWI248 0 "register_operand" "")
12097            (minus:SWI248
12098              (match_dup 2)
12099              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12100       (clobber (reg:CC FLAGS_REG))])
12101    (parallel
12102      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12103       (clobber (reg:CC FLAGS_REG))])]
12104   ""
12105 {
12106   if (TARGET_LZCNT)
12107     {
12108       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12109       DONE;
12110     }
12111   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12112 })
12113
12114 (define_insn "clz<mode>2_lzcnt"
12115   [(set (match_operand:SWI248 0 "register_operand" "=r")
12116         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12117    (clobber (reg:CC FLAGS_REG))]
12118   "TARGET_LZCNT"
12119   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12120   [(set_attr "prefix_rep" "1")
12121    (set_attr "type" "bitmanip")
12122    (set_attr "mode" "<MODE>")])
12123
12124 ;; BMI instructions.
12125 (define_insn "*bmi_andn_<mode>"
12126   [(set (match_operand:SWI48 0 "register_operand" "=r")
12127         (and:SWI48
12128           (not:SWI48
12129             (match_operand:SWI48 1 "register_operand" "r"))
12130             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12131    (clobber (reg:CC FLAGS_REG))]
12132   "TARGET_BMI"
12133   "andn\t{%2, %1, %0|%0, %1, %2}"
12134   [(set_attr "type" "bitmanip")
12135    (set_attr "mode" "<MODE>")])
12136
12137 (define_insn "bmi_bextr_<mode>"
12138   [(set (match_operand:SWI48 0 "register_operand" "=r")
12139         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12140                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12141                        UNSPEC_BEXTR))
12142    (clobber (reg:CC FLAGS_REG))]
12143   "TARGET_BMI"
12144   "bextr\t{%2, %1, %0|%0, %1, %2}"
12145   [(set_attr "type" "bitmanip")
12146    (set_attr "mode" "<MODE>")])
12147
12148 (define_insn "*bmi_blsi_<mode>"
12149   [(set (match_operand:SWI48 0 "register_operand" "=r")
12150         (and:SWI48
12151           (neg:SWI48
12152             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12153           (match_dup 1)))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "TARGET_BMI"
12156   "blsi\t{%1, %0|%0, %1}"
12157   [(set_attr "type" "bitmanip")
12158    (set_attr "mode" "<MODE>")])
12159
12160 (define_insn "*bmi_blsmsk_<mode>"
12161   [(set (match_operand:SWI48 0 "register_operand" "=r")
12162         (xor:SWI48
12163           (plus:SWI48
12164             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12165             (const_int -1))
12166           (match_dup 1)))
12167    (clobber (reg:CC FLAGS_REG))]
12168   "TARGET_BMI"
12169   "blsmsk\t{%1, %0|%0, %1}"
12170   [(set_attr "type" "bitmanip")
12171    (set_attr "mode" "<MODE>")])
12172
12173 (define_insn "*bmi_blsr_<mode>"
12174   [(set (match_operand:SWI48 0 "register_operand" "=r")
12175         (and:SWI48
12176           (plus:SWI48
12177             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12178             (const_int -1))
12179           (match_dup 1)))
12180    (clobber (reg:CC FLAGS_REG))]
12181    "TARGET_BMI"
12182    "blsr\t{%1, %0|%0, %1}"
12183   [(set_attr "type" "bitmanip")
12184    (set_attr "mode" "<MODE>")])
12185
12186 ;; BMI2 instructions.
12187 (define_insn "bmi2_bzhi_<mode>3"
12188   [(set (match_operand:SWI48 0 "register_operand" "=r")
12189         (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12190                    (lshiftrt:SWI48 (const_int -1)
12191                                    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12192    (clobber (reg:CC FLAGS_REG))]
12193   "TARGET_BMI2"
12194   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12195   [(set_attr "type" "bitmanip")
12196    (set_attr "prefix" "vex")
12197    (set_attr "mode" "<MODE>")])
12198
12199 (define_insn "bmi2_pdep_<mode>3"
12200   [(set (match_operand:SWI48 0 "register_operand" "=r")
12201         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12202                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12203                        UNSPEC_PDEP))]
12204   "TARGET_BMI2"
12205   "pdep\t{%2, %1, %0|%0, %1, %2}"
12206   [(set_attr "type" "bitmanip")
12207    (set_attr "prefix" "vex")
12208    (set_attr "mode" "<MODE>")])
12209
12210 (define_insn "bmi2_pext_<mode>3"
12211   [(set (match_operand:SWI48 0 "register_operand" "=r")
12212         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12213                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12214                        UNSPEC_PEXT))]
12215   "TARGET_BMI2"
12216   "pext\t{%2, %1, %0|%0, %1, %2}"
12217   [(set_attr "type" "bitmanip")
12218    (set_attr "prefix" "vex")
12219    (set_attr "mode" "<MODE>")])
12220
12221 ;; TBM instructions.
12222 (define_insn "tbm_bextri_<mode>"
12223   [(set (match_operand:SWI48 0 "register_operand" "=r")
12224         (zero_extract:SWI48
12225           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12226           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12227           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12228    (clobber (reg:CC FLAGS_REG))]
12229    "TARGET_TBM"
12230 {
12231   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12232   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12233 }
12234   [(set_attr "type" "bitmanip")
12235    (set_attr "mode" "<MODE>")])
12236
12237 (define_insn "*tbm_blcfill_<mode>"
12238   [(set (match_operand:SWI48 0 "register_operand" "=r")
12239         (and:SWI48
12240           (plus:SWI48
12241             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12242             (const_int 1))
12243           (match_dup 1)))
12244    (clobber (reg:CC FLAGS_REG))]
12245    "TARGET_TBM"
12246    "blcfill\t{%1, %0|%0, %1}"
12247   [(set_attr "type" "bitmanip")
12248    (set_attr "mode" "<MODE>")])
12249
12250 (define_insn "*tbm_blci_<mode>"
12251   [(set (match_operand:SWI48 0 "register_operand" "=r")
12252         (ior:SWI48
12253           (not:SWI48
12254             (plus:SWI48
12255               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12256               (const_int 1)))
12257           (match_dup 1)))
12258    (clobber (reg:CC FLAGS_REG))]
12259    "TARGET_TBM"
12260    "blci\t{%1, %0|%0, %1}"
12261   [(set_attr "type" "bitmanip")
12262    (set_attr "mode" "<MODE>")])
12263
12264 (define_insn "*tbm_blcic_<mode>"
12265   [(set (match_operand:SWI48 0 "register_operand" "=r")
12266         (and:SWI48
12267           (plus:SWI48
12268             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12269             (const_int 1))
12270           (not:SWI48
12271             (match_dup 1))))
12272    (clobber (reg:CC FLAGS_REG))]
12273    "TARGET_TBM"
12274    "blcic\t{%1, %0|%0, %1}"
12275   [(set_attr "type" "bitmanip")
12276    (set_attr "mode" "<MODE>")])
12277
12278 (define_insn "*tbm_blcmsk_<mode>"
12279   [(set (match_operand:SWI48 0 "register_operand" "=r")
12280         (xor:SWI48
12281           (plus:SWI48
12282             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12283             (const_int 1))
12284           (match_dup 1)))
12285    (clobber (reg:CC FLAGS_REG))]
12286    "TARGET_TBM"
12287    "blcmsk\t{%1, %0|%0, %1}"
12288   [(set_attr "type" "bitmanip")
12289    (set_attr "mode" "<MODE>")])
12290
12291 (define_insn "*tbm_blcs_<mode>"
12292   [(set (match_operand:SWI48 0 "register_operand" "=r")
12293         (ior:SWI48
12294           (plus:SWI48
12295             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12296             (const_int 1))
12297           (match_dup 1)))
12298    (clobber (reg:CC FLAGS_REG))]
12299    "TARGET_TBM"
12300    "blcs\t{%1, %0|%0, %1}"
12301   [(set_attr "type" "bitmanip")
12302    (set_attr "mode" "<MODE>")])
12303
12304 (define_insn "*tbm_blsfill_<mode>"
12305   [(set (match_operand:SWI48 0 "register_operand" "=r")
12306         (ior:SWI48
12307           (plus:SWI48
12308             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12309             (const_int -1))
12310           (match_dup 1)))
12311    (clobber (reg:CC FLAGS_REG))]
12312    "TARGET_TBM"
12313    "blsfill\t{%1, %0|%0, %1}"
12314   [(set_attr "type" "bitmanip")
12315    (set_attr "mode" "<MODE>")])
12316
12317 (define_insn "*tbm_blsic_<mode>"
12318   [(set (match_operand:SWI48 0 "register_operand" "=r")
12319         (ior:SWI48
12320           (plus:SWI48
12321             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12322             (const_int -1))
12323           (not:SWI48
12324             (match_dup 1))))
12325    (clobber (reg:CC FLAGS_REG))]
12326    "TARGET_TBM"
12327    "blsic\t{%1, %0|%0, %1}"
12328   [(set_attr "type" "bitmanip")
12329    (set_attr "mode" "<MODE>")])
12330
12331 (define_insn "*tbm_t1mskc_<mode>"
12332   [(set (match_operand:SWI48 0 "register_operand" "=r")
12333         (ior:SWI48
12334           (plus:SWI48
12335             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12336             (const_int 1))
12337           (not:SWI48
12338             (match_dup 1))))
12339    (clobber (reg:CC FLAGS_REG))]
12340    "TARGET_TBM"
12341    "t1mskc\t{%1, %0|%0, %1}"
12342   [(set_attr "type" "bitmanip")
12343    (set_attr "mode" "<MODE>")])
12344
12345 (define_insn "*tbm_tzmsk_<mode>"
12346   [(set (match_operand:SWI48 0 "register_operand" "=r")
12347         (and:SWI48
12348           (plus:SWI48
12349             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12350             (const_int -1))
12351           (not:SWI48
12352             (match_dup 1))))
12353    (clobber (reg:CC FLAGS_REG))]
12354    "TARGET_TBM"
12355    "tzmsk\t{%1, %0|%0, %1}"
12356   [(set_attr "type" "bitmanip")
12357    (set_attr "mode" "<MODE>")])
12358
12359 (define_insn "bsr_rex64"
12360   [(set (match_operand:DI 0 "register_operand" "=r")
12361         (minus:DI (const_int 63)
12362                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12363    (clobber (reg:CC FLAGS_REG))]
12364   "TARGET_64BIT"
12365   "bsr{q}\t{%1, %0|%0, %1}"
12366   [(set_attr "type" "alu1")
12367    (set_attr "prefix_0f" "1")
12368    (set_attr "mode" "DI")])
12369
12370 (define_insn "bsr"
12371   [(set (match_operand:SI 0 "register_operand" "=r")
12372         (minus:SI (const_int 31)
12373                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12374    (clobber (reg:CC FLAGS_REG))]
12375   ""
12376   "bsr{l}\t{%1, %0|%0, %1}"
12377   [(set_attr "type" "alu1")
12378    (set_attr "prefix_0f" "1")
12379    (set_attr "mode" "SI")])
12380
12381 (define_insn "*bsrhi"
12382   [(set (match_operand:HI 0 "register_operand" "=r")
12383         (minus:HI (const_int 15)
12384                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12385    (clobber (reg:CC FLAGS_REG))]
12386   ""
12387   "bsr{w}\t{%1, %0|%0, %1}"
12388   [(set_attr "type" "alu1")
12389    (set_attr "prefix_0f" "1")
12390    (set_attr "mode" "HI")])
12391
12392 (define_insn "popcount<mode>2"
12393   [(set (match_operand:SWI248 0 "register_operand" "=r")
12394         (popcount:SWI248
12395           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12396    (clobber (reg:CC FLAGS_REG))]
12397   "TARGET_POPCNT"
12398 {
12399 #if TARGET_MACHO
12400   return "popcnt\t{%1, %0|%0, %1}";
12401 #else
12402   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12403 #endif
12404 }
12405   [(set_attr "prefix_rep" "1")
12406    (set_attr "type" "bitmanip")
12407    (set_attr "mode" "<MODE>")])
12408
12409 (define_insn "*popcount<mode>2_cmp"
12410   [(set (reg FLAGS_REG)
12411         (compare
12412           (popcount:SWI248
12413             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12414           (const_int 0)))
12415    (set (match_operand:SWI248 0 "register_operand" "=r")
12416         (popcount:SWI248 (match_dup 1)))]
12417   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12418 {
12419 #if TARGET_MACHO
12420   return "popcnt\t{%1, %0|%0, %1}";
12421 #else
12422   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12423 #endif
12424 }
12425   [(set_attr "prefix_rep" "1")
12426    (set_attr "type" "bitmanip")
12427    (set_attr "mode" "<MODE>")])
12428
12429 (define_insn "*popcountsi2_cmp_zext"
12430   [(set (reg FLAGS_REG)
12431         (compare
12432           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12433           (const_int 0)))
12434    (set (match_operand:DI 0 "register_operand" "=r")
12435         (zero_extend:DI(popcount:SI (match_dup 1))))]
12436   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12437 {
12438 #if TARGET_MACHO
12439   return "popcnt\t{%1, %0|%0, %1}";
12440 #else
12441   return "popcnt{l}\t{%1, %0|%0, %1}";
12442 #endif
12443 }
12444   [(set_attr "prefix_rep" "1")
12445    (set_attr "type" "bitmanip")
12446    (set_attr "mode" "SI")])
12447
12448 (define_expand "bswap<mode>2"
12449   [(set (match_operand:SWI48 0 "register_operand" "")
12450         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12451   ""
12452 {
12453   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12454     {
12455       rtx x = operands[0];
12456
12457       emit_move_insn (x, operands[1]);
12458       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12459       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12460       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12461       DONE;
12462     }
12463 })
12464
12465 (define_insn "*bswap<mode>2_movbe"
12466   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12467         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12468   "TARGET_MOVBE
12469    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12470   "@
12471     bswap\t%0
12472     movbe\t{%1, %0|%0, %1}
12473     movbe\t{%1, %0|%0, %1}"
12474   [(set_attr "type" "bitmanip,imov,imov")
12475    (set_attr "modrm" "0,1,1")
12476    (set_attr "prefix_0f" "*,1,1")
12477    (set_attr "prefix_extra" "*,1,1")
12478    (set_attr "mode" "<MODE>")])
12479
12480 (define_insn "*bswap<mode>2_1"
12481   [(set (match_operand:SWI48 0 "register_operand" "=r")
12482         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12483   "TARGET_BSWAP"
12484   "bswap\t%0"
12485   [(set_attr "type" "bitmanip")
12486    (set_attr "modrm" "0")
12487    (set_attr "mode" "<MODE>")])
12488
12489 (define_insn "*bswaphi_lowpart_1"
12490   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12491         (bswap:HI (match_dup 0)))
12492    (clobber (reg:CC FLAGS_REG))]
12493   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12494   "@
12495     xchg{b}\t{%h0, %b0|%b0, %h0}
12496     rol{w}\t{$8, %0|%0, 8}"
12497   [(set_attr "length" "2,4")
12498    (set_attr "mode" "QI,HI")])
12499
12500 (define_insn "bswaphi_lowpart"
12501   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12502         (bswap:HI (match_dup 0)))
12503    (clobber (reg:CC FLAGS_REG))]
12504   ""
12505   "rol{w}\t{$8, %0|%0, 8}"
12506   [(set_attr "length" "4")
12507    (set_attr "mode" "HI")])
12508
12509 (define_expand "paritydi2"
12510   [(set (match_operand:DI 0 "register_operand" "")
12511         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12512   "! TARGET_POPCNT"
12513 {
12514   rtx scratch = gen_reg_rtx (QImode);
12515   rtx cond;
12516
12517   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12518                                 NULL_RTX, operands[1]));
12519
12520   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12521                          gen_rtx_REG (CCmode, FLAGS_REG),
12522                          const0_rtx);
12523   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12524
12525   if (TARGET_64BIT)
12526     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12527   else
12528     {
12529       rtx tmp = gen_reg_rtx (SImode);
12530
12531       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12532       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12533     }
12534   DONE;
12535 })
12536
12537 (define_expand "paritysi2"
12538   [(set (match_operand:SI 0 "register_operand" "")
12539         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12540   "! TARGET_POPCNT"
12541 {
12542   rtx scratch = gen_reg_rtx (QImode);
12543   rtx cond;
12544
12545   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12546
12547   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12548                          gen_rtx_REG (CCmode, FLAGS_REG),
12549                          const0_rtx);
12550   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12551
12552   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12553   DONE;
12554 })
12555
12556 (define_insn_and_split "paritydi2_cmp"
12557   [(set (reg:CC FLAGS_REG)
12558         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12559                    UNSPEC_PARITY))
12560    (clobber (match_scratch:DI 0 "=r"))
12561    (clobber (match_scratch:SI 1 "=&r"))
12562    (clobber (match_scratch:HI 2 "=Q"))]
12563   "! TARGET_POPCNT"
12564   "#"
12565   "&& reload_completed"
12566   [(parallel
12567      [(set (match_dup 1)
12568            (xor:SI (match_dup 1) (match_dup 4)))
12569       (clobber (reg:CC FLAGS_REG))])
12570    (parallel
12571      [(set (reg:CC FLAGS_REG)
12572            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12573       (clobber (match_dup 1))
12574       (clobber (match_dup 2))])]
12575 {
12576   operands[4] = gen_lowpart (SImode, operands[3]);
12577
12578   if (TARGET_64BIT)
12579     {
12580       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12581       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12582     }
12583   else
12584     operands[1] = gen_highpart (SImode, operands[3]);
12585 })
12586
12587 (define_insn_and_split "paritysi2_cmp"
12588   [(set (reg:CC FLAGS_REG)
12589         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12590                    UNSPEC_PARITY))
12591    (clobber (match_scratch:SI 0 "=r"))
12592    (clobber (match_scratch:HI 1 "=&Q"))]
12593   "! TARGET_POPCNT"
12594   "#"
12595   "&& reload_completed"
12596   [(parallel
12597      [(set (match_dup 1)
12598            (xor:HI (match_dup 1) (match_dup 3)))
12599       (clobber (reg:CC FLAGS_REG))])
12600    (parallel
12601      [(set (reg:CC FLAGS_REG)
12602            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12603       (clobber (match_dup 1))])]
12604 {
12605   operands[3] = gen_lowpart (HImode, operands[2]);
12606
12607   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12608   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12609 })
12610
12611 (define_insn "*parityhi2_cmp"
12612   [(set (reg:CC FLAGS_REG)
12613         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12614                    UNSPEC_PARITY))
12615    (clobber (match_scratch:HI 0 "=Q"))]
12616   "! TARGET_POPCNT"
12617   "xor{b}\t{%h0, %b0|%b0, %h0}"
12618   [(set_attr "length" "2")
12619    (set_attr "mode" "HI")])
12620
12621 \f
12622 ;; Thread-local storage patterns for ELF.
12623 ;;
12624 ;; Note that these code sequences must appear exactly as shown
12625 ;; in order to allow linker relaxation.
12626
12627 (define_insn "*tls_global_dynamic_32_gnu"
12628   [(set (match_operand:SI 0 "register_operand" "=a")
12629         (unspec:SI
12630          [(match_operand:SI 1 "register_operand" "b")
12631           (match_operand:SI 2 "tls_symbolic_operand" "")
12632           (match_operand:SI 3 "constant_call_address_operand" "z")]
12633          UNSPEC_TLS_GD))
12634    (clobber (match_scratch:SI 4 "=d"))
12635    (clobber (match_scratch:SI 5 "=c"))
12636    (clobber (reg:CC FLAGS_REG))]
12637   "!TARGET_64BIT && TARGET_GNU_TLS"
12638 {
12639   output_asm_insn
12640     ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12641   if (TARGET_SUN_TLS)
12642 #ifdef HAVE_AS_IX86_TLSGDPLT
12643     return "call\t%a2@tlsgdplt";
12644 #else
12645     return "call\t%p3@plt";
12646 #endif
12647   return "call\t%P3";
12648 }
12649   [(set_attr "type" "multi")
12650    (set_attr "length" "12")])
12651
12652 (define_expand "tls_global_dynamic_32"
12653   [(parallel
12654     [(set (match_operand:SI 0 "register_operand" "")
12655           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12656                       (match_operand:SI 1 "tls_symbolic_operand" "")
12657                       (match_operand:SI 3 "constant_call_address_operand" "")]
12658                      UNSPEC_TLS_GD))
12659      (clobber (match_scratch:SI 4 ""))
12660      (clobber (match_scratch:SI 5 ""))
12661      (clobber (reg:CC FLAGS_REG))])])
12662
12663 (define_insn "*tls_global_dynamic_64"
12664   [(set (match_operand:DI 0 "register_operand" "=a")
12665         (call:DI
12666          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12667          (match_operand:DI 3 "" "")))
12668    (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12669               UNSPEC_TLS_GD)]
12670   "TARGET_64BIT"
12671 {
12672   if (!TARGET_X32)
12673     fputs (ASM_BYTE "0x66\n", asm_out_file);
12674   output_asm_insn
12675     ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12676   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12677   fputs ("\trex64\n", asm_out_file);
12678   if (TARGET_SUN_TLS)
12679     return "call\t%p2@plt";
12680   return "call\t%P2";
12681 }
12682   [(set_attr "type" "multi")
12683    (set (attr "length")
12684         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12685
12686 (define_expand "tls_global_dynamic_64"
12687   [(parallel
12688     [(set (match_operand:DI 0 "register_operand" "")
12689           (call:DI
12690            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12691            (const_int 0)))
12692      (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12693                 UNSPEC_TLS_GD)])])
12694
12695 (define_insn "*tls_local_dynamic_base_32_gnu"
12696   [(set (match_operand:SI 0 "register_operand" "=a")
12697         (unspec:SI
12698          [(match_operand:SI 1 "register_operand" "b")
12699           (match_operand:SI 2 "constant_call_address_operand" "z")]
12700          UNSPEC_TLS_LD_BASE))
12701    (clobber (match_scratch:SI 3 "=d"))
12702    (clobber (match_scratch:SI 4 "=c"))
12703    (clobber (reg:CC FLAGS_REG))]
12704   "!TARGET_64BIT && TARGET_GNU_TLS"
12705 {
12706   output_asm_insn
12707     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12708   if (TARGET_SUN_TLS)
12709 #ifdef HAVE_AS_IX86_TLSLDMPLT
12710     return "call\t%&@tlsldmplt";
12711 #else
12712     return "call\t%p2@plt";
12713 #endif
12714   return "call\t%P2";
12715 }
12716   [(set_attr "type" "multi")
12717    (set_attr "length" "11")])
12718
12719 (define_expand "tls_local_dynamic_base_32"
12720   [(parallel
12721      [(set (match_operand:SI 0 "register_operand" "")
12722            (unspec:SI
12723             [(match_operand:SI 1 "register_operand" "")
12724              (match_operand:SI 2 "constant_call_address_operand" "")]
12725             UNSPEC_TLS_LD_BASE))
12726       (clobber (match_scratch:SI 3 ""))
12727       (clobber (match_scratch:SI 4 ""))
12728       (clobber (reg:CC FLAGS_REG))])])
12729
12730 (define_insn "*tls_local_dynamic_base_64"
12731   [(set (match_operand:DI 0 "register_operand" "=a")
12732         (call:DI
12733          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12734          (match_operand:DI 2 "" "")))
12735    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12736   "TARGET_64BIT"
12737 {
12738   output_asm_insn
12739     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12740   if (TARGET_SUN_TLS)
12741     return "call\t%p1@plt";
12742   return "call\t%P1";
12743 }
12744   [(set_attr "type" "multi")
12745    (set_attr "length" "12")])
12746
12747 (define_expand "tls_local_dynamic_base_64"
12748   [(parallel
12749      [(set (match_operand:DI 0 "register_operand" "")
12750            (call:DI
12751             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12752             (const_int 0)))
12753       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12754
12755 ;; Local dynamic of a single variable is a lose.  Show combine how
12756 ;; to convert that back to global dynamic.
12757
12758 (define_insn_and_split "*tls_local_dynamic_32_once"
12759   [(set (match_operand:SI 0 "register_operand" "=a")
12760         (plus:SI
12761          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12762                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12763                     UNSPEC_TLS_LD_BASE)
12764          (const:SI (unspec:SI
12765                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12766                     UNSPEC_DTPOFF))))
12767    (clobber (match_scratch:SI 4 "=d"))
12768    (clobber (match_scratch:SI 5 "=c"))
12769    (clobber (reg:CC FLAGS_REG))]
12770   ""
12771   "#"
12772   ""
12773   [(parallel
12774      [(set (match_dup 0)
12775            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12776                       UNSPEC_TLS_GD))
12777       (clobber (match_dup 4))
12778       (clobber (match_dup 5))
12779       (clobber (reg:CC FLAGS_REG))])])
12780
12781 ;; Segment register for the thread base ptr load
12782 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12783
12784 ;; Load and add the thread base pointer from %<tp_seg>:0.
12785 (define_insn "*load_tp_x32"
12786   [(set (match_operand:SI 0 "register_operand" "=r")
12787         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12788   "TARGET_X32"
12789   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12790   [(set_attr "type" "imov")
12791    (set_attr "modrm" "0")
12792    (set_attr "length" "7")
12793    (set_attr "memory" "load")
12794    (set_attr "imm_disp" "false")])
12795
12796 (define_insn "*load_tp_x32_zext"
12797   [(set (match_operand:DI 0 "register_operand" "=r")
12798         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12799   "TARGET_X32"
12800   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12801   [(set_attr "type" "imov")
12802    (set_attr "modrm" "0")
12803    (set_attr "length" "7")
12804    (set_attr "memory" "load")
12805    (set_attr "imm_disp" "false")])
12806
12807 (define_insn "*load_tp_<mode>"
12808   [(set (match_operand:P 0 "register_operand" "=r")
12809         (unspec:P [(const_int 0)] UNSPEC_TP))]
12810   "!TARGET_X32"
12811   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12812   [(set_attr "type" "imov")
12813    (set_attr "modrm" "0")
12814    (set_attr "length" "7")
12815    (set_attr "memory" "load")
12816    (set_attr "imm_disp" "false")])
12817
12818 (define_insn "*add_tp_x32"
12819   [(set (match_operand:SI 0 "register_operand" "=r")
12820         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12821                  (match_operand:SI 1 "register_operand" "0")))
12822    (clobber (reg:CC FLAGS_REG))]
12823   "TARGET_X32"
12824   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12825   [(set_attr "type" "alu")
12826    (set_attr "modrm" "0")
12827    (set_attr "length" "7")
12828    (set_attr "memory" "load")
12829    (set_attr "imm_disp" "false")])
12830
12831 (define_insn "*add_tp_x32_zext"
12832   [(set (match_operand:DI 0 "register_operand" "=r")
12833         (zero_extend:DI
12834           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12835                    (match_operand:SI 1 "register_operand" "0"))))
12836    (clobber (reg:CC FLAGS_REG))]
12837   "TARGET_X32"
12838   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12839   [(set_attr "type" "alu")
12840    (set_attr "modrm" "0")
12841    (set_attr "length" "7")
12842    (set_attr "memory" "load")
12843    (set_attr "imm_disp" "false")])
12844
12845 (define_insn "*add_tp_<mode>"
12846   [(set (match_operand:P 0 "register_operand" "=r")
12847         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12848                 (match_operand:P 1 "register_operand" "0")))
12849    (clobber (reg:CC FLAGS_REG))]
12850   "!TARGET_X32"
12851   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12852   [(set_attr "type" "alu")
12853    (set_attr "modrm" "0")
12854    (set_attr "length" "7")
12855    (set_attr "memory" "load")
12856    (set_attr "imm_disp" "false")])
12857
12858 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12859 ;; %rax as destination of the initial executable code sequence.
12860 (define_insn "tls_initial_exec_64_sun"
12861   [(set (match_operand:DI 0 "register_operand" "=a")
12862         (unspec:DI
12863          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12864          UNSPEC_TLS_IE_SUN))
12865    (clobber (reg:CC FLAGS_REG))]
12866   "TARGET_64BIT && TARGET_SUN_TLS"
12867 {
12868   output_asm_insn
12869     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12870   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12871 }
12872   [(set_attr "type" "multi")])
12873
12874 ;; GNU2 TLS patterns can be split.
12875
12876 (define_expand "tls_dynamic_gnu2_32"
12877   [(set (match_dup 3)
12878         (plus:SI (match_operand:SI 2 "register_operand" "")
12879                  (const:SI
12880                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12881                              UNSPEC_TLSDESC))))
12882    (parallel
12883     [(set (match_operand:SI 0 "register_operand" "")
12884           (unspec:SI [(match_dup 1) (match_dup 3)
12885                       (match_dup 2) (reg:SI SP_REG)]
12886                       UNSPEC_TLSDESC))
12887      (clobber (reg:CC FLAGS_REG))])]
12888   "!TARGET_64BIT && TARGET_GNU2_TLS"
12889 {
12890   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12891   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12892 })
12893
12894 (define_insn "*tls_dynamic_gnu2_lea_32"
12895   [(set (match_operand:SI 0 "register_operand" "=r")
12896         (plus:SI (match_operand:SI 1 "register_operand" "b")
12897                  (const:SI
12898                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12899                               UNSPEC_TLSDESC))))]
12900   "!TARGET_64BIT && TARGET_GNU2_TLS"
12901   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12902   [(set_attr "type" "lea")
12903    (set_attr "mode" "SI")
12904    (set_attr "length" "6")
12905    (set_attr "length_address" "4")])
12906
12907 (define_insn "*tls_dynamic_gnu2_call_32"
12908   [(set (match_operand:SI 0 "register_operand" "=a")
12909         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12910                     (match_operand:SI 2 "register_operand" "0")
12911                     ;; we have to make sure %ebx still points to the GOT
12912                     (match_operand:SI 3 "register_operand" "b")
12913                     (reg:SI SP_REG)]
12914                    UNSPEC_TLSDESC))
12915    (clobber (reg:CC FLAGS_REG))]
12916   "!TARGET_64BIT && TARGET_GNU2_TLS"
12917   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12918   [(set_attr "type" "call")
12919    (set_attr "length" "2")
12920    (set_attr "length_address" "0")])
12921
12922 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12923   [(set (match_operand:SI 0 "register_operand" "=&a")
12924         (plus:SI
12925          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12926                      (match_operand:SI 4 "" "")
12927                      (match_operand:SI 2 "register_operand" "b")
12928                      (reg:SI SP_REG)]
12929                     UNSPEC_TLSDESC)
12930          (const:SI (unspec:SI
12931                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12932                     UNSPEC_DTPOFF))))
12933    (clobber (reg:CC FLAGS_REG))]
12934   "!TARGET_64BIT && TARGET_GNU2_TLS"
12935   "#"
12936   ""
12937   [(set (match_dup 0) (match_dup 5))]
12938 {
12939   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12940   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12941 })
12942
12943 (define_expand "tls_dynamic_gnu2_64"
12944   [(set (match_dup 2)
12945         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12946                    UNSPEC_TLSDESC))
12947    (parallel
12948     [(set (match_operand:DI 0 "register_operand" "")
12949           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12950                      UNSPEC_TLSDESC))
12951      (clobber (reg:CC FLAGS_REG))])]
12952   "TARGET_64BIT && TARGET_GNU2_TLS"
12953 {
12954   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12955   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12956 })
12957
12958 (define_insn "*tls_dynamic_gnu2_lea_64"
12959   [(set (match_operand:DI 0 "register_operand" "=r")
12960         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12961                    UNSPEC_TLSDESC))]
12962   "TARGET_64BIT && TARGET_GNU2_TLS"
12963   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12964   [(set_attr "type" "lea")
12965    (set_attr "mode" "DI")
12966    (set_attr "length" "7")
12967    (set_attr "length_address" "4")])
12968
12969 (define_insn "*tls_dynamic_gnu2_call_64"
12970   [(set (match_operand:DI 0 "register_operand" "=a")
12971         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12972                     (match_operand:DI 2 "register_operand" "0")
12973                     (reg:DI SP_REG)]
12974                    UNSPEC_TLSDESC))
12975    (clobber (reg:CC FLAGS_REG))]
12976   "TARGET_64BIT && TARGET_GNU2_TLS"
12977   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12978   [(set_attr "type" "call")
12979    (set_attr "length" "2")
12980    (set_attr "length_address" "0")])
12981
12982 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12983   [(set (match_operand:DI 0 "register_operand" "=&a")
12984         (plus:DI
12985          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12986                      (match_operand:DI 3 "" "")
12987                      (reg:DI SP_REG)]
12988                     UNSPEC_TLSDESC)
12989          (const:DI (unspec:DI
12990                     [(match_operand 1 "tls_symbolic_operand" "")]
12991                     UNSPEC_DTPOFF))))
12992    (clobber (reg:CC FLAGS_REG))]
12993   "TARGET_64BIT && TARGET_GNU2_TLS"
12994   "#"
12995   ""
12996   [(set (match_dup 0) (match_dup 4))]
12997 {
12998   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12999   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13000 })
13001 \f
13002 ;; These patterns match the binary 387 instructions for addM3, subM3,
13003 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13004 ;; SFmode.  The first is the normal insn, the second the same insn but
13005 ;; with one operand a conversion, and the third the same insn but with
13006 ;; the other operand a conversion.  The conversion may be SFmode or
13007 ;; SImode if the target mode DFmode, but only SImode if the target mode
13008 ;; is SFmode.
13009
13010 ;; Gcc is slightly more smart about handling normal two address instructions
13011 ;; so use special patterns for add and mull.
13012
13013 (define_insn "*fop_<mode>_comm_mixed"
13014   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13015         (match_operator:MODEF 3 "binary_fp_operator"
13016           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13017            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13018   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13019    && COMMUTATIVE_ARITH_P (operands[3])
13020    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13021   "* return output_387_binary_op (insn, operands);"
13022   [(set (attr "type")
13023         (if_then_else (eq_attr "alternative" "1,2")
13024            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13025               (const_string "ssemul")
13026               (const_string "sseadd"))
13027            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13028               (const_string "fmul")
13029               (const_string "fop"))))
13030    (set_attr "isa" "*,noavx,avx")
13031    (set_attr "prefix" "orig,orig,vex")
13032    (set_attr "mode" "<MODE>")])
13033
13034 (define_insn "*fop_<mode>_comm_sse"
13035   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13036         (match_operator:MODEF 3 "binary_fp_operator"
13037           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13038            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13039   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13040    && COMMUTATIVE_ARITH_P (operands[3])
13041    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13042   "* return output_387_binary_op (insn, operands);"
13043   [(set (attr "type")
13044         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13045            (const_string "ssemul")
13046            (const_string "sseadd")))
13047    (set_attr "isa" "noavx,avx")
13048    (set_attr "prefix" "orig,vex")
13049    (set_attr "mode" "<MODE>")])
13050
13051 (define_insn "*fop_<mode>_comm_i387"
13052   [(set (match_operand:MODEF 0 "register_operand" "=f")
13053         (match_operator:MODEF 3 "binary_fp_operator"
13054           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13055            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13056   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13057    && COMMUTATIVE_ARITH_P (operands[3])
13058    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13059   "* return output_387_binary_op (insn, operands);"
13060   [(set (attr "type")
13061         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13062            (const_string "fmul")
13063            (const_string "fop")))
13064    (set_attr "mode" "<MODE>")])
13065
13066 (define_insn "*fop_<mode>_1_mixed"
13067   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13068         (match_operator:MODEF 3 "binary_fp_operator"
13069           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13070            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13071   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13072    && !COMMUTATIVE_ARITH_P (operands[3])
13073    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13074   "* return output_387_binary_op (insn, operands);"
13075   [(set (attr "type")
13076         (cond [(and (eq_attr "alternative" "2,3")
13077                     (match_operand:MODEF 3 "mult_operator" ""))
13078                  (const_string "ssemul")
13079                (and (eq_attr "alternative" "2,3")
13080                     (match_operand:MODEF 3 "div_operator" ""))
13081                  (const_string "ssediv")
13082                (eq_attr "alternative" "2,3")
13083                  (const_string "sseadd")
13084                (match_operand:MODEF 3 "mult_operator" "")
13085                  (const_string "fmul")
13086                (match_operand:MODEF 3 "div_operator" "")
13087                  (const_string "fdiv")
13088               ]
13089               (const_string "fop")))
13090    (set_attr "isa" "*,*,noavx,avx")
13091    (set_attr "prefix" "orig,orig,orig,vex")
13092    (set_attr "mode" "<MODE>")])
13093
13094 (define_insn "*rcpsf2_sse"
13095   [(set (match_operand:SF 0 "register_operand" "=x")
13096         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13097                    UNSPEC_RCP))]
13098   "TARGET_SSE_MATH"
13099   "%vrcpss\t{%1, %d0|%d0, %1}"
13100   [(set_attr "type" "sse")
13101    (set_attr "atom_sse_attr" "rcp")
13102    (set_attr "prefix" "maybe_vex")
13103    (set_attr "mode" "SF")])
13104
13105 (define_insn "*fop_<mode>_1_sse"
13106   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13107         (match_operator:MODEF 3 "binary_fp_operator"
13108           [(match_operand:MODEF 1 "register_operand" "0,x")
13109            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13110   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13111    && !COMMUTATIVE_ARITH_P (operands[3])"
13112   "* return output_387_binary_op (insn, operands);"
13113   [(set (attr "type")
13114         (cond [(match_operand:MODEF 3 "mult_operator" "")
13115                  (const_string "ssemul")
13116                (match_operand:MODEF 3 "div_operator" "")
13117                  (const_string "ssediv")
13118               ]
13119               (const_string "sseadd")))
13120    (set_attr "isa" "noavx,avx")
13121    (set_attr "prefix" "orig,vex")
13122    (set_attr "mode" "<MODE>")])
13123
13124 ;; This pattern is not fully shadowed by the pattern above.
13125 (define_insn "*fop_<mode>_1_i387"
13126   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13127         (match_operator:MODEF 3 "binary_fp_operator"
13128           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13129            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13130   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13131    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13132    && !COMMUTATIVE_ARITH_P (operands[3])
13133    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13134   "* return output_387_binary_op (insn, operands);"
13135   [(set (attr "type")
13136         (cond [(match_operand:MODEF 3 "mult_operator" "")
13137                  (const_string "fmul")
13138                (match_operand:MODEF 3 "div_operator" "")
13139                  (const_string "fdiv")
13140               ]
13141               (const_string "fop")))
13142    (set_attr "mode" "<MODE>")])
13143
13144 ;; ??? Add SSE splitters for these!
13145 (define_insn "*fop_<MODEF:mode>_2_i387"
13146   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13147         (match_operator:MODEF 3 "binary_fp_operator"
13148           [(float:MODEF
13149              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13150            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13151   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13152    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13153    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13154   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13155   [(set (attr "type")
13156         (cond [(match_operand:MODEF 3 "mult_operator" "")
13157                  (const_string "fmul")
13158                (match_operand:MODEF 3 "div_operator" "")
13159                  (const_string "fdiv")
13160               ]
13161               (const_string "fop")))
13162    (set_attr "fp_int_src" "true")
13163    (set_attr "mode" "<SWI24:MODE>")])
13164
13165 (define_insn "*fop_<MODEF:mode>_3_i387"
13166   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13167         (match_operator:MODEF 3 "binary_fp_operator"
13168           [(match_operand:MODEF 1 "register_operand" "0,0")
13169            (float:MODEF
13170              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13171   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13172    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13173    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13174   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13175   [(set (attr "type")
13176         (cond [(match_operand:MODEF 3 "mult_operator" "")
13177                  (const_string "fmul")
13178                (match_operand:MODEF 3 "div_operator" "")
13179                  (const_string "fdiv")
13180               ]
13181               (const_string "fop")))
13182    (set_attr "fp_int_src" "true")
13183    (set_attr "mode" "<MODE>")])
13184
13185 (define_insn "*fop_df_4_i387"
13186   [(set (match_operand:DF 0 "register_operand" "=f,f")
13187         (match_operator:DF 3 "binary_fp_operator"
13188            [(float_extend:DF
13189              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13190             (match_operand:DF 2 "register_operand" "0,f")]))]
13191   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13192    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13193    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13194   "* return output_387_binary_op (insn, operands);"
13195   [(set (attr "type")
13196         (cond [(match_operand:DF 3 "mult_operator" "")
13197                  (const_string "fmul")
13198                (match_operand:DF 3 "div_operator" "")
13199                  (const_string "fdiv")
13200               ]
13201               (const_string "fop")))
13202    (set_attr "mode" "SF")])
13203
13204 (define_insn "*fop_df_5_i387"
13205   [(set (match_operand:DF 0 "register_operand" "=f,f")
13206         (match_operator:DF 3 "binary_fp_operator"
13207           [(match_operand:DF 1 "register_operand" "0,f")
13208            (float_extend:DF
13209             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13210   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13211    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13212   "* return output_387_binary_op (insn, operands);"
13213   [(set (attr "type")
13214         (cond [(match_operand:DF 3 "mult_operator" "")
13215                  (const_string "fmul")
13216                (match_operand:DF 3 "div_operator" "")
13217                  (const_string "fdiv")
13218               ]
13219               (const_string "fop")))
13220    (set_attr "mode" "SF")])
13221
13222 (define_insn "*fop_df_6_i387"
13223   [(set (match_operand:DF 0 "register_operand" "=f,f")
13224         (match_operator:DF 3 "binary_fp_operator"
13225           [(float_extend:DF
13226             (match_operand:SF 1 "register_operand" "0,f"))
13227            (float_extend:DF
13228             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13229   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13230    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13231   "* return output_387_binary_op (insn, operands);"
13232   [(set (attr "type")
13233         (cond [(match_operand:DF 3 "mult_operator" "")
13234                  (const_string "fmul")
13235                (match_operand:DF 3 "div_operator" "")
13236                  (const_string "fdiv")
13237               ]
13238               (const_string "fop")))
13239    (set_attr "mode" "SF")])
13240
13241 (define_insn "*fop_xf_comm_i387"
13242   [(set (match_operand:XF 0 "register_operand" "=f")
13243         (match_operator:XF 3 "binary_fp_operator"
13244                         [(match_operand:XF 1 "register_operand" "%0")
13245                          (match_operand:XF 2 "register_operand" "f")]))]
13246   "TARGET_80387
13247    && COMMUTATIVE_ARITH_P (operands[3])"
13248   "* return output_387_binary_op (insn, operands);"
13249   [(set (attr "type")
13250         (if_then_else (match_operand:XF 3 "mult_operator" "")
13251            (const_string "fmul")
13252            (const_string "fop")))
13253    (set_attr "mode" "XF")])
13254
13255 (define_insn "*fop_xf_1_i387"
13256   [(set (match_operand:XF 0 "register_operand" "=f,f")
13257         (match_operator:XF 3 "binary_fp_operator"
13258                         [(match_operand:XF 1 "register_operand" "0,f")
13259                          (match_operand:XF 2 "register_operand" "f,0")]))]
13260   "TARGET_80387
13261    && !COMMUTATIVE_ARITH_P (operands[3])"
13262   "* return output_387_binary_op (insn, operands);"
13263   [(set (attr "type")
13264         (cond [(match_operand:XF 3 "mult_operator" "")
13265                  (const_string "fmul")
13266                (match_operand:XF 3 "div_operator" "")
13267                  (const_string "fdiv")
13268               ]
13269               (const_string "fop")))
13270    (set_attr "mode" "XF")])
13271
13272 (define_insn "*fop_xf_2_i387"
13273   [(set (match_operand:XF 0 "register_operand" "=f,f")
13274         (match_operator:XF 3 "binary_fp_operator"
13275           [(float:XF
13276              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13277            (match_operand:XF 2 "register_operand" "0,0")]))]
13278   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13279   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13280   [(set (attr "type")
13281         (cond [(match_operand:XF 3 "mult_operator" "")
13282                  (const_string "fmul")
13283                (match_operand:XF 3 "div_operator" "")
13284                  (const_string "fdiv")
13285               ]
13286               (const_string "fop")))
13287    (set_attr "fp_int_src" "true")
13288    (set_attr "mode" "<MODE>")])
13289
13290 (define_insn "*fop_xf_3_i387"
13291   [(set (match_operand:XF 0 "register_operand" "=f,f")
13292         (match_operator:XF 3 "binary_fp_operator"
13293           [(match_operand:XF 1 "register_operand" "0,0")
13294            (float:XF
13295              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13296   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13297   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13298   [(set (attr "type")
13299         (cond [(match_operand:XF 3 "mult_operator" "")
13300                  (const_string "fmul")
13301                (match_operand:XF 3 "div_operator" "")
13302                  (const_string "fdiv")
13303               ]
13304               (const_string "fop")))
13305    (set_attr "fp_int_src" "true")
13306    (set_attr "mode" "<MODE>")])
13307
13308 (define_insn "*fop_xf_4_i387"
13309   [(set (match_operand:XF 0 "register_operand" "=f,f")
13310         (match_operator:XF 3 "binary_fp_operator"
13311            [(float_extend:XF
13312               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13313             (match_operand:XF 2 "register_operand" "0,f")]))]
13314   "TARGET_80387"
13315   "* return output_387_binary_op (insn, operands);"
13316   [(set (attr "type")
13317         (cond [(match_operand:XF 3 "mult_operator" "")
13318                  (const_string "fmul")
13319                (match_operand:XF 3 "div_operator" "")
13320                  (const_string "fdiv")
13321               ]
13322               (const_string "fop")))
13323    (set_attr "mode" "<MODE>")])
13324
13325 (define_insn "*fop_xf_5_i387"
13326   [(set (match_operand:XF 0 "register_operand" "=f,f")
13327         (match_operator:XF 3 "binary_fp_operator"
13328           [(match_operand:XF 1 "register_operand" "0,f")
13329            (float_extend:XF
13330              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13331   "TARGET_80387"
13332   "* return output_387_binary_op (insn, operands);"
13333   [(set (attr "type")
13334         (cond [(match_operand:XF 3 "mult_operator" "")
13335                  (const_string "fmul")
13336                (match_operand:XF 3 "div_operator" "")
13337                  (const_string "fdiv")
13338               ]
13339               (const_string "fop")))
13340    (set_attr "mode" "<MODE>")])
13341
13342 (define_insn "*fop_xf_6_i387"
13343   [(set (match_operand:XF 0 "register_operand" "=f,f")
13344         (match_operator:XF 3 "binary_fp_operator"
13345           [(float_extend:XF
13346              (match_operand:MODEF 1 "register_operand" "0,f"))
13347            (float_extend:XF
13348              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13349   "TARGET_80387"
13350   "* return output_387_binary_op (insn, operands);"
13351   [(set (attr "type")
13352         (cond [(match_operand:XF 3 "mult_operator" "")
13353                  (const_string "fmul")
13354                (match_operand:XF 3 "div_operator" "")
13355                  (const_string "fdiv")
13356               ]
13357               (const_string "fop")))
13358    (set_attr "mode" "<MODE>")])
13359
13360 (define_split
13361   [(set (match_operand 0 "register_operand" "")
13362         (match_operator 3 "binary_fp_operator"
13363            [(float (match_operand:SWI24 1 "register_operand" ""))
13364             (match_operand 2 "register_operand" "")]))]
13365   "reload_completed
13366    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13367    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13368   [(const_int 0)]
13369 {
13370   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13371   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13372   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13373                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13374                                           GET_MODE (operands[3]),
13375                                           operands[4],
13376                                           operands[2])));
13377   ix86_free_from_memory (GET_MODE (operands[1]));
13378   DONE;
13379 })
13380
13381 (define_split
13382   [(set (match_operand 0 "register_operand" "")
13383         (match_operator 3 "binary_fp_operator"
13384            [(match_operand 1 "register_operand" "")
13385             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13386   "reload_completed
13387    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13388    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13389   [(const_int 0)]
13390 {
13391   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13392   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13393   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13394                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13395                                           GET_MODE (operands[3]),
13396                                           operands[1],
13397                                           operands[4])));
13398   ix86_free_from_memory (GET_MODE (operands[2]));
13399   DONE;
13400 })
13401 \f
13402 ;; FPU special functions.
13403
13404 ;; This pattern implements a no-op XFmode truncation for
13405 ;; all fancy i386 XFmode math functions.
13406
13407 (define_insn "truncxf<mode>2_i387_noop_unspec"
13408   [(set (match_operand:MODEF 0 "register_operand" "=f")
13409         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13410         UNSPEC_TRUNC_NOOP))]
13411   "TARGET_USE_FANCY_MATH_387"
13412   "* return output_387_reg_move (insn, operands);"
13413   [(set_attr "type" "fmov")
13414    (set_attr "mode" "<MODE>")])
13415
13416 (define_insn "sqrtxf2"
13417   [(set (match_operand:XF 0 "register_operand" "=f")
13418         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13419   "TARGET_USE_FANCY_MATH_387"
13420   "fsqrt"
13421   [(set_attr "type" "fpspc")
13422    (set_attr "mode" "XF")
13423    (set_attr "athlon_decode" "direct")
13424    (set_attr "amdfam10_decode" "direct")
13425    (set_attr "bdver1_decode" "direct")])
13426
13427 (define_insn "sqrt_extend<mode>xf2_i387"
13428   [(set (match_operand:XF 0 "register_operand" "=f")
13429         (sqrt:XF
13430           (float_extend:XF
13431             (match_operand:MODEF 1 "register_operand" "0"))))]
13432   "TARGET_USE_FANCY_MATH_387"
13433   "fsqrt"
13434   [(set_attr "type" "fpspc")
13435    (set_attr "mode" "XF")
13436    (set_attr "athlon_decode" "direct")
13437    (set_attr "amdfam10_decode" "direct")
13438    (set_attr "bdver1_decode" "direct")])
13439
13440 (define_insn "*rsqrtsf2_sse"
13441   [(set (match_operand:SF 0 "register_operand" "=x")
13442         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13443                    UNSPEC_RSQRT))]
13444   "TARGET_SSE_MATH"
13445   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13446   [(set_attr "type" "sse")
13447    (set_attr "atom_sse_attr" "rcp")
13448    (set_attr "prefix" "maybe_vex")
13449    (set_attr "mode" "SF")])
13450
13451 (define_expand "rsqrtsf2"
13452   [(set (match_operand:SF 0 "register_operand" "")
13453         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13454                    UNSPEC_RSQRT))]
13455   "TARGET_SSE_MATH"
13456 {
13457   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13458   DONE;
13459 })
13460
13461 (define_insn "*sqrt<mode>2_sse"
13462   [(set (match_operand:MODEF 0 "register_operand" "=x")
13463         (sqrt:MODEF
13464           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13465   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13466   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13467   [(set_attr "type" "sse")
13468    (set_attr "atom_sse_attr" "sqrt")
13469    (set_attr "prefix" "maybe_vex")
13470    (set_attr "mode" "<MODE>")
13471    (set_attr "athlon_decode" "*")
13472    (set_attr "amdfam10_decode" "*")
13473    (set_attr "bdver1_decode" "*")])
13474
13475 (define_expand "sqrt<mode>2"
13476   [(set (match_operand:MODEF 0 "register_operand" "")
13477         (sqrt:MODEF
13478           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13479   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13480    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13481 {
13482   if (<MODE>mode == SFmode
13483       && TARGET_SSE_MATH
13484       && TARGET_RECIP_SQRT
13485       && !optimize_function_for_size_p (cfun)
13486       && flag_finite_math_only && !flag_trapping_math
13487       && flag_unsafe_math_optimizations)
13488     {
13489       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13490       DONE;
13491     }
13492
13493   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13494     {
13495       rtx op0 = gen_reg_rtx (XFmode);
13496       rtx op1 = force_reg (<MODE>mode, operands[1]);
13497
13498       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13499       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13500       DONE;
13501    }
13502 })
13503
13504 (define_insn "fpremxf4_i387"
13505   [(set (match_operand:XF 0 "register_operand" "=f")
13506         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13507                     (match_operand:XF 3 "register_operand" "1")]
13508                    UNSPEC_FPREM_F))
13509    (set (match_operand:XF 1 "register_operand" "=u")
13510         (unspec:XF [(match_dup 2) (match_dup 3)]
13511                    UNSPEC_FPREM_U))
13512    (set (reg:CCFP FPSR_REG)
13513         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13514                      UNSPEC_C2_FLAG))]
13515   "TARGET_USE_FANCY_MATH_387"
13516   "fprem"
13517   [(set_attr "type" "fpspc")
13518    (set_attr "mode" "XF")])
13519
13520 (define_expand "fmodxf3"
13521   [(use (match_operand:XF 0 "register_operand" ""))
13522    (use (match_operand:XF 1 "general_operand" ""))
13523    (use (match_operand:XF 2 "general_operand" ""))]
13524   "TARGET_USE_FANCY_MATH_387"
13525 {
13526   rtx label = gen_label_rtx ();
13527
13528   rtx op1 = gen_reg_rtx (XFmode);
13529   rtx op2 = gen_reg_rtx (XFmode);
13530
13531   emit_move_insn (op2, operands[2]);
13532   emit_move_insn (op1, operands[1]);
13533
13534   emit_label (label);
13535   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13536   ix86_emit_fp_unordered_jump (label);
13537   LABEL_NUSES (label) = 1;
13538
13539   emit_move_insn (operands[0], op1);
13540   DONE;
13541 })
13542
13543 (define_expand "fmod<mode>3"
13544   [(use (match_operand:MODEF 0 "register_operand" ""))
13545    (use (match_operand:MODEF 1 "general_operand" ""))
13546    (use (match_operand:MODEF 2 "general_operand" ""))]
13547   "TARGET_USE_FANCY_MATH_387"
13548 {
13549   rtx (*gen_truncxf) (rtx, rtx);
13550
13551   rtx label = gen_label_rtx ();
13552
13553   rtx op1 = gen_reg_rtx (XFmode);
13554   rtx op2 = gen_reg_rtx (XFmode);
13555
13556   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13557   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13558
13559   emit_label (label);
13560   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13561   ix86_emit_fp_unordered_jump (label);
13562   LABEL_NUSES (label) = 1;
13563
13564   /* Truncate the result properly for strict SSE math.  */
13565   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13566       && !TARGET_MIX_SSE_I387)
13567     gen_truncxf = gen_truncxf<mode>2;
13568   else
13569     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13570
13571   emit_insn (gen_truncxf (operands[0], op1));
13572   DONE;
13573 })
13574
13575 (define_insn "fprem1xf4_i387"
13576   [(set (match_operand:XF 0 "register_operand" "=f")
13577         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13578                     (match_operand:XF 3 "register_operand" "1")]
13579                    UNSPEC_FPREM1_F))
13580    (set (match_operand:XF 1 "register_operand" "=u")
13581         (unspec:XF [(match_dup 2) (match_dup 3)]
13582                    UNSPEC_FPREM1_U))
13583    (set (reg:CCFP FPSR_REG)
13584         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13585                      UNSPEC_C2_FLAG))]
13586   "TARGET_USE_FANCY_MATH_387"
13587   "fprem1"
13588   [(set_attr "type" "fpspc")
13589    (set_attr "mode" "XF")])
13590
13591 (define_expand "remainderxf3"
13592   [(use (match_operand:XF 0 "register_operand" ""))
13593    (use (match_operand:XF 1 "general_operand" ""))
13594    (use (match_operand:XF 2 "general_operand" ""))]
13595   "TARGET_USE_FANCY_MATH_387"
13596 {
13597   rtx label = gen_label_rtx ();
13598
13599   rtx op1 = gen_reg_rtx (XFmode);
13600   rtx op2 = gen_reg_rtx (XFmode);
13601
13602   emit_move_insn (op2, operands[2]);
13603   emit_move_insn (op1, operands[1]);
13604
13605   emit_label (label);
13606   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13607   ix86_emit_fp_unordered_jump (label);
13608   LABEL_NUSES (label) = 1;
13609
13610   emit_move_insn (operands[0], op1);
13611   DONE;
13612 })
13613
13614 (define_expand "remainder<mode>3"
13615   [(use (match_operand:MODEF 0 "register_operand" ""))
13616    (use (match_operand:MODEF 1 "general_operand" ""))
13617    (use (match_operand:MODEF 2 "general_operand" ""))]
13618   "TARGET_USE_FANCY_MATH_387"
13619 {
13620   rtx (*gen_truncxf) (rtx, rtx);
13621
13622   rtx label = gen_label_rtx ();
13623
13624   rtx op1 = gen_reg_rtx (XFmode);
13625   rtx op2 = gen_reg_rtx (XFmode);
13626
13627   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13628   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13629
13630   emit_label (label);
13631
13632   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13633   ix86_emit_fp_unordered_jump (label);
13634   LABEL_NUSES (label) = 1;
13635
13636   /* Truncate the result properly for strict SSE math.  */
13637   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13638       && !TARGET_MIX_SSE_I387)
13639     gen_truncxf = gen_truncxf<mode>2;
13640   else
13641     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13642
13643   emit_insn (gen_truncxf (operands[0], op1));
13644   DONE;
13645 })
13646
13647 (define_insn "*sinxf2_i387"
13648   [(set (match_operand:XF 0 "register_operand" "=f")
13649         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13650   "TARGET_USE_FANCY_MATH_387
13651    && flag_unsafe_math_optimizations"
13652   "fsin"
13653   [(set_attr "type" "fpspc")
13654    (set_attr "mode" "XF")])
13655
13656 (define_insn "*sin_extend<mode>xf2_i387"
13657   [(set (match_operand:XF 0 "register_operand" "=f")
13658         (unspec:XF [(float_extend:XF
13659                       (match_operand:MODEF 1 "register_operand" "0"))]
13660                    UNSPEC_SIN))]
13661   "TARGET_USE_FANCY_MATH_387
13662    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13663        || TARGET_MIX_SSE_I387)
13664    && flag_unsafe_math_optimizations"
13665   "fsin"
13666   [(set_attr "type" "fpspc")
13667    (set_attr "mode" "XF")])
13668
13669 (define_insn "*cosxf2_i387"
13670   [(set (match_operand:XF 0 "register_operand" "=f")
13671         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13672   "TARGET_USE_FANCY_MATH_387
13673    && flag_unsafe_math_optimizations"
13674   "fcos"
13675   [(set_attr "type" "fpspc")
13676    (set_attr "mode" "XF")])
13677
13678 (define_insn "*cos_extend<mode>xf2_i387"
13679   [(set (match_operand:XF 0 "register_operand" "=f")
13680         (unspec:XF [(float_extend:XF
13681                       (match_operand:MODEF 1 "register_operand" "0"))]
13682                    UNSPEC_COS))]
13683   "TARGET_USE_FANCY_MATH_387
13684    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13685        || TARGET_MIX_SSE_I387)
13686    && flag_unsafe_math_optimizations"
13687   "fcos"
13688   [(set_attr "type" "fpspc")
13689    (set_attr "mode" "XF")])
13690
13691 ;; When sincos pattern is defined, sin and cos builtin functions will be
13692 ;; expanded to sincos pattern with one of its outputs left unused.
13693 ;; CSE pass will figure out if two sincos patterns can be combined,
13694 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13695 ;; depending on the unused output.
13696
13697 (define_insn "sincosxf3"
13698   [(set (match_operand:XF 0 "register_operand" "=f")
13699         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13700                    UNSPEC_SINCOS_COS))
13701    (set (match_operand:XF 1 "register_operand" "=u")
13702         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13703   "TARGET_USE_FANCY_MATH_387
13704    && flag_unsafe_math_optimizations"
13705   "fsincos"
13706   [(set_attr "type" "fpspc")
13707    (set_attr "mode" "XF")])
13708
13709 (define_split
13710   [(set (match_operand:XF 0 "register_operand" "")
13711         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13712                    UNSPEC_SINCOS_COS))
13713    (set (match_operand:XF 1 "register_operand" "")
13714         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13715   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13716    && can_create_pseudo_p ()"
13717   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13718
13719 (define_split
13720   [(set (match_operand:XF 0 "register_operand" "")
13721         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13722                    UNSPEC_SINCOS_COS))
13723    (set (match_operand:XF 1 "register_operand" "")
13724         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13725   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13726    && can_create_pseudo_p ()"
13727   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13728
13729 (define_insn "sincos_extend<mode>xf3_i387"
13730   [(set (match_operand:XF 0 "register_operand" "=f")
13731         (unspec:XF [(float_extend:XF
13732                       (match_operand:MODEF 2 "register_operand" "0"))]
13733                    UNSPEC_SINCOS_COS))
13734    (set (match_operand:XF 1 "register_operand" "=u")
13735         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13736   "TARGET_USE_FANCY_MATH_387
13737    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13738        || TARGET_MIX_SSE_I387)
13739    && flag_unsafe_math_optimizations"
13740   "fsincos"
13741   [(set_attr "type" "fpspc")
13742    (set_attr "mode" "XF")])
13743
13744 (define_split
13745   [(set (match_operand:XF 0 "register_operand" "")
13746         (unspec:XF [(float_extend:XF
13747                       (match_operand:MODEF 2 "register_operand" ""))]
13748                    UNSPEC_SINCOS_COS))
13749    (set (match_operand:XF 1 "register_operand" "")
13750         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13751   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13752    && can_create_pseudo_p ()"
13753   [(set (match_dup 1)
13754         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13755
13756 (define_split
13757   [(set (match_operand:XF 0 "register_operand" "")
13758         (unspec:XF [(float_extend:XF
13759                       (match_operand:MODEF 2 "register_operand" ""))]
13760                    UNSPEC_SINCOS_COS))
13761    (set (match_operand:XF 1 "register_operand" "")
13762         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13763   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13764    && can_create_pseudo_p ()"
13765   [(set (match_dup 0)
13766         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13767
13768 (define_expand "sincos<mode>3"
13769   [(use (match_operand:MODEF 0 "register_operand" ""))
13770    (use (match_operand:MODEF 1 "register_operand" ""))
13771    (use (match_operand:MODEF 2 "register_operand" ""))]
13772   "TARGET_USE_FANCY_MATH_387
13773    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13774        || TARGET_MIX_SSE_I387)
13775    && flag_unsafe_math_optimizations"
13776 {
13777   rtx op0 = gen_reg_rtx (XFmode);
13778   rtx op1 = gen_reg_rtx (XFmode);
13779
13780   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13781   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13782   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13783   DONE;
13784 })
13785
13786 (define_insn "fptanxf4_i387"
13787   [(set (match_operand:XF 0 "register_operand" "=f")
13788         (match_operand:XF 3 "const_double_operand" "F"))
13789    (set (match_operand:XF 1 "register_operand" "=u")
13790         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13791                    UNSPEC_TAN))]
13792   "TARGET_USE_FANCY_MATH_387
13793    && flag_unsafe_math_optimizations
13794    && standard_80387_constant_p (operands[3]) == 2"
13795   "fptan"
13796   [(set_attr "type" "fpspc")
13797    (set_attr "mode" "XF")])
13798
13799 (define_insn "fptan_extend<mode>xf4_i387"
13800   [(set (match_operand:MODEF 0 "register_operand" "=f")
13801         (match_operand:MODEF 3 "const_double_operand" "F"))
13802    (set (match_operand:XF 1 "register_operand" "=u")
13803         (unspec:XF [(float_extend:XF
13804                       (match_operand:MODEF 2 "register_operand" "0"))]
13805                    UNSPEC_TAN))]
13806   "TARGET_USE_FANCY_MATH_387
13807    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13808        || TARGET_MIX_SSE_I387)
13809    && flag_unsafe_math_optimizations
13810    && standard_80387_constant_p (operands[3]) == 2"
13811   "fptan"
13812   [(set_attr "type" "fpspc")
13813    (set_attr "mode" "XF")])
13814
13815 (define_expand "tanxf2"
13816   [(use (match_operand:XF 0 "register_operand" ""))
13817    (use (match_operand:XF 1 "register_operand" ""))]
13818   "TARGET_USE_FANCY_MATH_387
13819    && flag_unsafe_math_optimizations"
13820 {
13821   rtx one = gen_reg_rtx (XFmode);
13822   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13823
13824   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13825   DONE;
13826 })
13827
13828 (define_expand "tan<mode>2"
13829   [(use (match_operand:MODEF 0 "register_operand" ""))
13830    (use (match_operand:MODEF 1 "register_operand" ""))]
13831   "TARGET_USE_FANCY_MATH_387
13832    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13833        || TARGET_MIX_SSE_I387)
13834    && flag_unsafe_math_optimizations"
13835 {
13836   rtx op0 = gen_reg_rtx (XFmode);
13837
13838   rtx one = gen_reg_rtx (<MODE>mode);
13839   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13840
13841   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13842                                              operands[1], op2));
13843   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13844   DONE;
13845 })
13846
13847 (define_insn "*fpatanxf3_i387"
13848   [(set (match_operand:XF 0 "register_operand" "=f")
13849         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13850                     (match_operand:XF 2 "register_operand" "u")]
13851                    UNSPEC_FPATAN))
13852    (clobber (match_scratch:XF 3 "=2"))]
13853   "TARGET_USE_FANCY_MATH_387
13854    && flag_unsafe_math_optimizations"
13855   "fpatan"
13856   [(set_attr "type" "fpspc")
13857    (set_attr "mode" "XF")])
13858
13859 (define_insn "fpatan_extend<mode>xf3_i387"
13860   [(set (match_operand:XF 0 "register_operand" "=f")
13861         (unspec:XF [(float_extend:XF
13862                       (match_operand:MODEF 1 "register_operand" "0"))
13863                     (float_extend:XF
13864                       (match_operand:MODEF 2 "register_operand" "u"))]
13865                    UNSPEC_FPATAN))
13866    (clobber (match_scratch:XF 3 "=2"))]
13867   "TARGET_USE_FANCY_MATH_387
13868    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13869        || TARGET_MIX_SSE_I387)
13870    && flag_unsafe_math_optimizations"
13871   "fpatan"
13872   [(set_attr "type" "fpspc")
13873    (set_attr "mode" "XF")])
13874
13875 (define_expand "atan2xf3"
13876   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13877                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13878                                (match_operand:XF 1 "register_operand" "")]
13879                               UNSPEC_FPATAN))
13880               (clobber (match_scratch:XF 3 ""))])]
13881   "TARGET_USE_FANCY_MATH_387
13882    && flag_unsafe_math_optimizations")
13883
13884 (define_expand "atan2<mode>3"
13885   [(use (match_operand:MODEF 0 "register_operand" ""))
13886    (use (match_operand:MODEF 1 "register_operand" ""))
13887    (use (match_operand:MODEF 2 "register_operand" ""))]
13888   "TARGET_USE_FANCY_MATH_387
13889    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13890        || TARGET_MIX_SSE_I387)
13891    && flag_unsafe_math_optimizations"
13892 {
13893   rtx op0 = gen_reg_rtx (XFmode);
13894
13895   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13896   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13897   DONE;
13898 })
13899
13900 (define_expand "atanxf2"
13901   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13902                    (unspec:XF [(match_dup 2)
13903                                (match_operand:XF 1 "register_operand" "")]
13904                               UNSPEC_FPATAN))
13905               (clobber (match_scratch:XF 3 ""))])]
13906   "TARGET_USE_FANCY_MATH_387
13907    && flag_unsafe_math_optimizations"
13908 {
13909   operands[2] = gen_reg_rtx (XFmode);
13910   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13911 })
13912
13913 (define_expand "atan<mode>2"
13914   [(use (match_operand:MODEF 0 "register_operand" ""))
13915    (use (match_operand:MODEF 1 "register_operand" ""))]
13916   "TARGET_USE_FANCY_MATH_387
13917    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13918        || TARGET_MIX_SSE_I387)
13919    && flag_unsafe_math_optimizations"
13920 {
13921   rtx op0 = gen_reg_rtx (XFmode);
13922
13923   rtx op2 = gen_reg_rtx (<MODE>mode);
13924   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13925
13926   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13927   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13928   DONE;
13929 })
13930
13931 (define_expand "asinxf2"
13932   [(set (match_dup 2)
13933         (mult:XF (match_operand:XF 1 "register_operand" "")
13934                  (match_dup 1)))
13935    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13936    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13937    (parallel [(set (match_operand:XF 0 "register_operand" "")
13938                    (unspec:XF [(match_dup 5) (match_dup 1)]
13939                               UNSPEC_FPATAN))
13940               (clobber (match_scratch:XF 6 ""))])]
13941   "TARGET_USE_FANCY_MATH_387
13942    && flag_unsafe_math_optimizations"
13943 {
13944   int i;
13945
13946   if (optimize_insn_for_size_p ())
13947     FAIL;
13948
13949   for (i = 2; i < 6; i++)
13950     operands[i] = gen_reg_rtx (XFmode);
13951
13952   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13953 })
13954
13955 (define_expand "asin<mode>2"
13956   [(use (match_operand:MODEF 0 "register_operand" ""))
13957    (use (match_operand:MODEF 1 "general_operand" ""))]
13958  "TARGET_USE_FANCY_MATH_387
13959    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13960        || TARGET_MIX_SSE_I387)
13961    && flag_unsafe_math_optimizations"
13962 {
13963   rtx op0 = gen_reg_rtx (XFmode);
13964   rtx op1 = gen_reg_rtx (XFmode);
13965
13966   if (optimize_insn_for_size_p ())
13967     FAIL;
13968
13969   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13970   emit_insn (gen_asinxf2 (op0, op1));
13971   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13972   DONE;
13973 })
13974
13975 (define_expand "acosxf2"
13976   [(set (match_dup 2)
13977         (mult:XF (match_operand:XF 1 "register_operand" "")
13978                  (match_dup 1)))
13979    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13980    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13981    (parallel [(set (match_operand:XF 0 "register_operand" "")
13982                    (unspec:XF [(match_dup 1) (match_dup 5)]
13983                               UNSPEC_FPATAN))
13984               (clobber (match_scratch:XF 6 ""))])]
13985   "TARGET_USE_FANCY_MATH_387
13986    && flag_unsafe_math_optimizations"
13987 {
13988   int i;
13989
13990   if (optimize_insn_for_size_p ())
13991     FAIL;
13992
13993   for (i = 2; i < 6; i++)
13994     operands[i] = gen_reg_rtx (XFmode);
13995
13996   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13997 })
13998
13999 (define_expand "acos<mode>2"
14000   [(use (match_operand:MODEF 0 "register_operand" ""))
14001    (use (match_operand:MODEF 1 "general_operand" ""))]
14002  "TARGET_USE_FANCY_MATH_387
14003    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14004        || TARGET_MIX_SSE_I387)
14005    && flag_unsafe_math_optimizations"
14006 {
14007   rtx op0 = gen_reg_rtx (XFmode);
14008   rtx op1 = gen_reg_rtx (XFmode);
14009
14010   if (optimize_insn_for_size_p ())
14011     FAIL;
14012
14013   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14014   emit_insn (gen_acosxf2 (op0, op1));
14015   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14016   DONE;
14017 })
14018
14019 (define_insn "fyl2xxf3_i387"
14020   [(set (match_operand:XF 0 "register_operand" "=f")
14021         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14022                     (match_operand:XF 2 "register_operand" "u")]
14023                    UNSPEC_FYL2X))
14024    (clobber (match_scratch:XF 3 "=2"))]
14025   "TARGET_USE_FANCY_MATH_387
14026    && flag_unsafe_math_optimizations"
14027   "fyl2x"
14028   [(set_attr "type" "fpspc")
14029    (set_attr "mode" "XF")])
14030
14031 (define_insn "fyl2x_extend<mode>xf3_i387"
14032   [(set (match_operand:XF 0 "register_operand" "=f")
14033         (unspec:XF [(float_extend:XF
14034                       (match_operand:MODEF 1 "register_operand" "0"))
14035                     (match_operand:XF 2 "register_operand" "u")]
14036                    UNSPEC_FYL2X))
14037    (clobber (match_scratch:XF 3 "=2"))]
14038   "TARGET_USE_FANCY_MATH_387
14039    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14040        || TARGET_MIX_SSE_I387)
14041    && flag_unsafe_math_optimizations"
14042   "fyl2x"
14043   [(set_attr "type" "fpspc")
14044    (set_attr "mode" "XF")])
14045
14046 (define_expand "logxf2"
14047   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14048                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14049                                (match_dup 2)] UNSPEC_FYL2X))
14050               (clobber (match_scratch:XF 3 ""))])]
14051   "TARGET_USE_FANCY_MATH_387
14052    && flag_unsafe_math_optimizations"
14053 {
14054   operands[2] = gen_reg_rtx (XFmode);
14055   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14056 })
14057
14058 (define_expand "log<mode>2"
14059   [(use (match_operand:MODEF 0 "register_operand" ""))
14060    (use (match_operand:MODEF 1 "register_operand" ""))]
14061   "TARGET_USE_FANCY_MATH_387
14062    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14063        || TARGET_MIX_SSE_I387)
14064    && flag_unsafe_math_optimizations"
14065 {
14066   rtx op0 = gen_reg_rtx (XFmode);
14067
14068   rtx op2 = gen_reg_rtx (XFmode);
14069   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14070
14071   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14072   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14073   DONE;
14074 })
14075
14076 (define_expand "log10xf2"
14077   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14078                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14079                                (match_dup 2)] UNSPEC_FYL2X))
14080               (clobber (match_scratch:XF 3 ""))])]
14081   "TARGET_USE_FANCY_MATH_387
14082    && flag_unsafe_math_optimizations"
14083 {
14084   operands[2] = gen_reg_rtx (XFmode);
14085   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14086 })
14087
14088 (define_expand "log10<mode>2"
14089   [(use (match_operand:MODEF 0 "register_operand" ""))
14090    (use (match_operand:MODEF 1 "register_operand" ""))]
14091   "TARGET_USE_FANCY_MATH_387
14092    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14093        || TARGET_MIX_SSE_I387)
14094    && flag_unsafe_math_optimizations"
14095 {
14096   rtx op0 = gen_reg_rtx (XFmode);
14097
14098   rtx op2 = gen_reg_rtx (XFmode);
14099   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14100
14101   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14102   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14103   DONE;
14104 })
14105
14106 (define_expand "log2xf2"
14107   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14108                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14109                                (match_dup 2)] UNSPEC_FYL2X))
14110               (clobber (match_scratch:XF 3 ""))])]
14111   "TARGET_USE_FANCY_MATH_387
14112    && flag_unsafe_math_optimizations"
14113 {
14114   operands[2] = gen_reg_rtx (XFmode);
14115   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14116 })
14117
14118 (define_expand "log2<mode>2"
14119   [(use (match_operand:MODEF 0 "register_operand" ""))
14120    (use (match_operand:MODEF 1 "register_operand" ""))]
14121   "TARGET_USE_FANCY_MATH_387
14122    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14123        || TARGET_MIX_SSE_I387)
14124    && flag_unsafe_math_optimizations"
14125 {
14126   rtx op0 = gen_reg_rtx (XFmode);
14127
14128   rtx op2 = gen_reg_rtx (XFmode);
14129   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14130
14131   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14132   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14133   DONE;
14134 })
14135
14136 (define_insn "fyl2xp1xf3_i387"
14137   [(set (match_operand:XF 0 "register_operand" "=f")
14138         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14139                     (match_operand:XF 2 "register_operand" "u")]
14140                    UNSPEC_FYL2XP1))
14141    (clobber (match_scratch:XF 3 "=2"))]
14142   "TARGET_USE_FANCY_MATH_387
14143    && flag_unsafe_math_optimizations"
14144   "fyl2xp1"
14145   [(set_attr "type" "fpspc")
14146    (set_attr "mode" "XF")])
14147
14148 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14149   [(set (match_operand:XF 0 "register_operand" "=f")
14150         (unspec:XF [(float_extend:XF
14151                       (match_operand:MODEF 1 "register_operand" "0"))
14152                     (match_operand:XF 2 "register_operand" "u")]
14153                    UNSPEC_FYL2XP1))
14154    (clobber (match_scratch:XF 3 "=2"))]
14155   "TARGET_USE_FANCY_MATH_387
14156    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14157        || TARGET_MIX_SSE_I387)
14158    && flag_unsafe_math_optimizations"
14159   "fyl2xp1"
14160   [(set_attr "type" "fpspc")
14161    (set_attr "mode" "XF")])
14162
14163 (define_expand "log1pxf2"
14164   [(use (match_operand:XF 0 "register_operand" ""))
14165    (use (match_operand:XF 1 "register_operand" ""))]
14166   "TARGET_USE_FANCY_MATH_387
14167    && flag_unsafe_math_optimizations"
14168 {
14169   if (optimize_insn_for_size_p ())
14170     FAIL;
14171
14172   ix86_emit_i387_log1p (operands[0], operands[1]);
14173   DONE;
14174 })
14175
14176 (define_expand "log1p<mode>2"
14177   [(use (match_operand:MODEF 0 "register_operand" ""))
14178    (use (match_operand:MODEF 1 "register_operand" ""))]
14179   "TARGET_USE_FANCY_MATH_387
14180    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14181        || TARGET_MIX_SSE_I387)
14182    && flag_unsafe_math_optimizations"
14183 {
14184   rtx op0;
14185
14186   if (optimize_insn_for_size_p ())
14187     FAIL;
14188
14189   op0 = gen_reg_rtx (XFmode);
14190
14191   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14192
14193   ix86_emit_i387_log1p (op0, operands[1]);
14194   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14195   DONE;
14196 })
14197
14198 (define_insn "fxtractxf3_i387"
14199   [(set (match_operand:XF 0 "register_operand" "=f")
14200         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14201                    UNSPEC_XTRACT_FRACT))
14202    (set (match_operand:XF 1 "register_operand" "=u")
14203         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14204   "TARGET_USE_FANCY_MATH_387
14205    && flag_unsafe_math_optimizations"
14206   "fxtract"
14207   [(set_attr "type" "fpspc")
14208    (set_attr "mode" "XF")])
14209
14210 (define_insn "fxtract_extend<mode>xf3_i387"
14211   [(set (match_operand:XF 0 "register_operand" "=f")
14212         (unspec:XF [(float_extend:XF
14213                       (match_operand:MODEF 2 "register_operand" "0"))]
14214                    UNSPEC_XTRACT_FRACT))
14215    (set (match_operand:XF 1 "register_operand" "=u")
14216         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14217   "TARGET_USE_FANCY_MATH_387
14218    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14219        || TARGET_MIX_SSE_I387)
14220    && flag_unsafe_math_optimizations"
14221   "fxtract"
14222   [(set_attr "type" "fpspc")
14223    (set_attr "mode" "XF")])
14224
14225 (define_expand "logbxf2"
14226   [(parallel [(set (match_dup 2)
14227                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14228                               UNSPEC_XTRACT_FRACT))
14229               (set (match_operand:XF 0 "register_operand" "")
14230                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14231   "TARGET_USE_FANCY_MATH_387
14232    && flag_unsafe_math_optimizations"
14233   "operands[2] = gen_reg_rtx (XFmode);")
14234
14235 (define_expand "logb<mode>2"
14236   [(use (match_operand:MODEF 0 "register_operand" ""))
14237    (use (match_operand:MODEF 1 "register_operand" ""))]
14238   "TARGET_USE_FANCY_MATH_387
14239    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14240        || TARGET_MIX_SSE_I387)
14241    && flag_unsafe_math_optimizations"
14242 {
14243   rtx op0 = gen_reg_rtx (XFmode);
14244   rtx op1 = gen_reg_rtx (XFmode);
14245
14246   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14247   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14248   DONE;
14249 })
14250
14251 (define_expand "ilogbxf2"
14252   [(use (match_operand:SI 0 "register_operand" ""))
14253    (use (match_operand:XF 1 "register_operand" ""))]
14254   "TARGET_USE_FANCY_MATH_387
14255    && flag_unsafe_math_optimizations"
14256 {
14257   rtx op0, op1;
14258
14259   if (optimize_insn_for_size_p ())
14260     FAIL;
14261
14262   op0 = gen_reg_rtx (XFmode);
14263   op1 = gen_reg_rtx (XFmode);
14264
14265   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14266   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14267   DONE;
14268 })
14269
14270 (define_expand "ilogb<mode>2"
14271   [(use (match_operand:SI 0 "register_operand" ""))
14272    (use (match_operand:MODEF 1 "register_operand" ""))]
14273   "TARGET_USE_FANCY_MATH_387
14274    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14275        || TARGET_MIX_SSE_I387)
14276    && flag_unsafe_math_optimizations"
14277 {
14278   rtx op0, op1;
14279
14280   if (optimize_insn_for_size_p ())
14281     FAIL;
14282
14283   op0 = gen_reg_rtx (XFmode);
14284   op1 = gen_reg_rtx (XFmode);
14285
14286   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14287   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14288   DONE;
14289 })
14290
14291 (define_insn "*f2xm1xf2_i387"
14292   [(set (match_operand:XF 0 "register_operand" "=f")
14293         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14294                    UNSPEC_F2XM1))]
14295   "TARGET_USE_FANCY_MATH_387
14296    && flag_unsafe_math_optimizations"
14297   "f2xm1"
14298   [(set_attr "type" "fpspc")
14299    (set_attr "mode" "XF")])
14300
14301 (define_insn "*fscalexf4_i387"
14302   [(set (match_operand:XF 0 "register_operand" "=f")
14303         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14304                     (match_operand:XF 3 "register_operand" "1")]
14305                    UNSPEC_FSCALE_FRACT))
14306    (set (match_operand:XF 1 "register_operand" "=u")
14307         (unspec:XF [(match_dup 2) (match_dup 3)]
14308                    UNSPEC_FSCALE_EXP))]
14309   "TARGET_USE_FANCY_MATH_387
14310    && flag_unsafe_math_optimizations"
14311   "fscale"
14312   [(set_attr "type" "fpspc")
14313    (set_attr "mode" "XF")])
14314
14315 (define_expand "expNcorexf3"
14316   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14317                                (match_operand:XF 2 "register_operand" "")))
14318    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14319    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14320    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14321    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14322    (parallel [(set (match_operand:XF 0 "register_operand" "")
14323                    (unspec:XF [(match_dup 8) (match_dup 4)]
14324                               UNSPEC_FSCALE_FRACT))
14325               (set (match_dup 9)
14326                    (unspec:XF [(match_dup 8) (match_dup 4)]
14327                               UNSPEC_FSCALE_EXP))])]
14328   "TARGET_USE_FANCY_MATH_387
14329    && flag_unsafe_math_optimizations"
14330 {
14331   int i;
14332
14333   if (optimize_insn_for_size_p ())
14334     FAIL;
14335
14336   for (i = 3; i < 10; i++)
14337     operands[i] = gen_reg_rtx (XFmode);
14338
14339   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14340 })
14341
14342 (define_expand "expxf2"
14343   [(use (match_operand:XF 0 "register_operand" ""))
14344    (use (match_operand:XF 1 "register_operand" ""))]
14345   "TARGET_USE_FANCY_MATH_387
14346    && flag_unsafe_math_optimizations"
14347 {
14348   rtx op2;
14349
14350   if (optimize_insn_for_size_p ())
14351     FAIL;
14352
14353   op2 = gen_reg_rtx (XFmode);
14354   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14355
14356   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14357   DONE;
14358 })
14359
14360 (define_expand "exp<mode>2"
14361   [(use (match_operand:MODEF 0 "register_operand" ""))
14362    (use (match_operand:MODEF 1 "general_operand" ""))]
14363  "TARGET_USE_FANCY_MATH_387
14364    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14365        || TARGET_MIX_SSE_I387)
14366    && flag_unsafe_math_optimizations"
14367 {
14368   rtx op0, op1;
14369
14370   if (optimize_insn_for_size_p ())
14371     FAIL;
14372
14373   op0 = gen_reg_rtx (XFmode);
14374   op1 = gen_reg_rtx (XFmode);
14375
14376   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14377   emit_insn (gen_expxf2 (op0, op1));
14378   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14379   DONE;
14380 })
14381
14382 (define_expand "exp10xf2"
14383   [(use (match_operand:XF 0 "register_operand" ""))
14384    (use (match_operand:XF 1 "register_operand" ""))]
14385   "TARGET_USE_FANCY_MATH_387
14386    && flag_unsafe_math_optimizations"
14387 {
14388   rtx op2;
14389
14390   if (optimize_insn_for_size_p ())
14391     FAIL;
14392
14393   op2 = gen_reg_rtx (XFmode);
14394   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14395
14396   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14397   DONE;
14398 })
14399
14400 (define_expand "exp10<mode>2"
14401   [(use (match_operand:MODEF 0 "register_operand" ""))
14402    (use (match_operand:MODEF 1 "general_operand" ""))]
14403  "TARGET_USE_FANCY_MATH_387
14404    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14405        || TARGET_MIX_SSE_I387)
14406    && flag_unsafe_math_optimizations"
14407 {
14408   rtx op0, op1;
14409
14410   if (optimize_insn_for_size_p ())
14411     FAIL;
14412
14413   op0 = gen_reg_rtx (XFmode);
14414   op1 = gen_reg_rtx (XFmode);
14415
14416   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14417   emit_insn (gen_exp10xf2 (op0, op1));
14418   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14419   DONE;
14420 })
14421
14422 (define_expand "exp2xf2"
14423   [(use (match_operand:XF 0 "register_operand" ""))
14424    (use (match_operand:XF 1 "register_operand" ""))]
14425   "TARGET_USE_FANCY_MATH_387
14426    && flag_unsafe_math_optimizations"
14427 {
14428   rtx op2;
14429
14430   if (optimize_insn_for_size_p ())
14431     FAIL;
14432
14433   op2 = gen_reg_rtx (XFmode);
14434   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14435
14436   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14437   DONE;
14438 })
14439
14440 (define_expand "exp2<mode>2"
14441   [(use (match_operand:MODEF 0 "register_operand" ""))
14442    (use (match_operand:MODEF 1 "general_operand" ""))]
14443  "TARGET_USE_FANCY_MATH_387
14444    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14445        || TARGET_MIX_SSE_I387)
14446    && flag_unsafe_math_optimizations"
14447 {
14448   rtx op0, op1;
14449
14450   if (optimize_insn_for_size_p ())
14451     FAIL;
14452
14453   op0 = gen_reg_rtx (XFmode);
14454   op1 = gen_reg_rtx (XFmode);
14455
14456   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14457   emit_insn (gen_exp2xf2 (op0, op1));
14458   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14459   DONE;
14460 })
14461
14462 (define_expand "expm1xf2"
14463   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14464                                (match_dup 2)))
14465    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14466    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14467    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14468    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14469    (parallel [(set (match_dup 7)
14470                    (unspec:XF [(match_dup 6) (match_dup 4)]
14471                               UNSPEC_FSCALE_FRACT))
14472               (set (match_dup 8)
14473                    (unspec:XF [(match_dup 6) (match_dup 4)]
14474                               UNSPEC_FSCALE_EXP))])
14475    (parallel [(set (match_dup 10)
14476                    (unspec:XF [(match_dup 9) (match_dup 8)]
14477                               UNSPEC_FSCALE_FRACT))
14478               (set (match_dup 11)
14479                    (unspec:XF [(match_dup 9) (match_dup 8)]
14480                               UNSPEC_FSCALE_EXP))])
14481    (set (match_dup 12) (minus:XF (match_dup 10)
14482                                  (float_extend:XF (match_dup 13))))
14483    (set (match_operand:XF 0 "register_operand" "")
14484         (plus:XF (match_dup 12) (match_dup 7)))]
14485   "TARGET_USE_FANCY_MATH_387
14486    && flag_unsafe_math_optimizations"
14487 {
14488   int i;
14489
14490   if (optimize_insn_for_size_p ())
14491     FAIL;
14492
14493   for (i = 2; i < 13; i++)
14494     operands[i] = gen_reg_rtx (XFmode);
14495
14496   operands[13]
14497     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14498
14499   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14500 })
14501
14502 (define_expand "expm1<mode>2"
14503   [(use (match_operand:MODEF 0 "register_operand" ""))
14504    (use (match_operand:MODEF 1 "general_operand" ""))]
14505  "TARGET_USE_FANCY_MATH_387
14506    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14507        || TARGET_MIX_SSE_I387)
14508    && flag_unsafe_math_optimizations"
14509 {
14510   rtx op0, op1;
14511
14512   if (optimize_insn_for_size_p ())
14513     FAIL;
14514
14515   op0 = gen_reg_rtx (XFmode);
14516   op1 = gen_reg_rtx (XFmode);
14517
14518   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14519   emit_insn (gen_expm1xf2 (op0, op1));
14520   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14521   DONE;
14522 })
14523
14524 (define_expand "ldexpxf3"
14525   [(set (match_dup 3)
14526         (float:XF (match_operand:SI 2 "register_operand" "")))
14527    (parallel [(set (match_operand:XF 0 " register_operand" "")
14528                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14529                                (match_dup 3)]
14530                               UNSPEC_FSCALE_FRACT))
14531               (set (match_dup 4)
14532                    (unspec:XF [(match_dup 1) (match_dup 3)]
14533                               UNSPEC_FSCALE_EXP))])]
14534   "TARGET_USE_FANCY_MATH_387
14535    && flag_unsafe_math_optimizations"
14536 {
14537   if (optimize_insn_for_size_p ())
14538     FAIL;
14539
14540   operands[3] = gen_reg_rtx (XFmode);
14541   operands[4] = gen_reg_rtx (XFmode);
14542 })
14543
14544 (define_expand "ldexp<mode>3"
14545   [(use (match_operand:MODEF 0 "register_operand" ""))
14546    (use (match_operand:MODEF 1 "general_operand" ""))
14547    (use (match_operand:SI 2 "register_operand" ""))]
14548  "TARGET_USE_FANCY_MATH_387
14549    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14550        || TARGET_MIX_SSE_I387)
14551    && flag_unsafe_math_optimizations"
14552 {
14553   rtx op0, op1;
14554
14555   if (optimize_insn_for_size_p ())
14556     FAIL;
14557
14558   op0 = gen_reg_rtx (XFmode);
14559   op1 = gen_reg_rtx (XFmode);
14560
14561   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14562   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14563   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14564   DONE;
14565 })
14566
14567 (define_expand "scalbxf3"
14568   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14569                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14570                                (match_operand:XF 2 "register_operand" "")]
14571                               UNSPEC_FSCALE_FRACT))
14572               (set (match_dup 3)
14573                    (unspec:XF [(match_dup 1) (match_dup 2)]
14574                               UNSPEC_FSCALE_EXP))])]
14575   "TARGET_USE_FANCY_MATH_387
14576    && flag_unsafe_math_optimizations"
14577 {
14578   if (optimize_insn_for_size_p ())
14579     FAIL;
14580
14581   operands[3] = gen_reg_rtx (XFmode);
14582 })
14583
14584 (define_expand "scalb<mode>3"
14585   [(use (match_operand:MODEF 0 "register_operand" ""))
14586    (use (match_operand:MODEF 1 "general_operand" ""))
14587    (use (match_operand:MODEF 2 "general_operand" ""))]
14588  "TARGET_USE_FANCY_MATH_387
14589    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14590        || TARGET_MIX_SSE_I387)
14591    && flag_unsafe_math_optimizations"
14592 {
14593   rtx op0, op1, op2;
14594
14595   if (optimize_insn_for_size_p ())
14596     FAIL;
14597
14598   op0 = gen_reg_rtx (XFmode);
14599   op1 = gen_reg_rtx (XFmode);
14600   op2 = gen_reg_rtx (XFmode);
14601
14602   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14603   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14604   emit_insn (gen_scalbxf3 (op0, op1, op2));
14605   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14606   DONE;
14607 })
14608
14609 (define_expand "significandxf2"
14610   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14611                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14612                               UNSPEC_XTRACT_FRACT))
14613               (set (match_dup 2)
14614                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14615   "TARGET_USE_FANCY_MATH_387
14616    && flag_unsafe_math_optimizations"
14617   "operands[2] = gen_reg_rtx (XFmode);")
14618
14619 (define_expand "significand<mode>2"
14620   [(use (match_operand:MODEF 0 "register_operand" ""))
14621    (use (match_operand:MODEF 1 "register_operand" ""))]
14622   "TARGET_USE_FANCY_MATH_387
14623    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14624        || TARGET_MIX_SSE_I387)
14625    && flag_unsafe_math_optimizations"
14626 {
14627   rtx op0 = gen_reg_rtx (XFmode);
14628   rtx op1 = gen_reg_rtx (XFmode);
14629
14630   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14631   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14632   DONE;
14633 })
14634 \f
14635
14636 (define_insn "sse4_1_round<mode>2"
14637   [(set (match_operand:MODEF 0 "register_operand" "=x")
14638         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14639                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14640                       UNSPEC_ROUND))]
14641   "TARGET_ROUND"
14642   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14643   [(set_attr "type" "ssecvt")
14644    (set_attr "prefix_extra" "1")
14645    (set_attr "prefix" "maybe_vex")
14646    (set_attr "mode" "<MODE>")])
14647
14648 (define_insn "rintxf2"
14649   [(set (match_operand:XF 0 "register_operand" "=f")
14650         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14651                    UNSPEC_FRNDINT))]
14652   "TARGET_USE_FANCY_MATH_387
14653    && flag_unsafe_math_optimizations"
14654   "frndint"
14655   [(set_attr "type" "fpspc")
14656    (set_attr "mode" "XF")])
14657
14658 (define_expand "rint<mode>2"
14659   [(use (match_operand:MODEF 0 "register_operand" ""))
14660    (use (match_operand:MODEF 1 "register_operand" ""))]
14661   "(TARGET_USE_FANCY_MATH_387
14662     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14663         || TARGET_MIX_SSE_I387)
14664     && flag_unsafe_math_optimizations)
14665    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14666        && !flag_trapping_math)"
14667 {
14668   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14669       && !flag_trapping_math)
14670     {
14671       if (TARGET_ROUND)
14672         emit_insn (gen_sse4_1_round<mode>2
14673                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14674       else if (optimize_insn_for_size_p ())
14675         FAIL;
14676       else
14677         ix86_expand_rint (operands[0], operands[1]);
14678     }
14679   else
14680     {
14681       rtx op0 = gen_reg_rtx (XFmode);
14682       rtx op1 = gen_reg_rtx (XFmode);
14683
14684       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14685       emit_insn (gen_rintxf2 (op0, op1));
14686
14687       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14688     }
14689   DONE;
14690 })
14691
14692 (define_expand "round<mode>2"
14693   [(match_operand:X87MODEF 0 "register_operand" "")
14694    (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14695   "(TARGET_USE_FANCY_MATH_387
14696     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14697         || TARGET_MIX_SSE_I387)
14698     && flag_unsafe_math_optimizations)
14699    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14700        && !flag_trapping_math && !flag_rounding_math)"
14701 {
14702   if (optimize_insn_for_size_p ())
14703     FAIL;
14704
14705   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14706       && !flag_trapping_math && !flag_rounding_math)
14707     {
14708       if (TARGET_ROUND)
14709         {
14710           operands[1] = force_reg (<MODE>mode, operands[1]);
14711           ix86_expand_round_sse4 (operands[0], operands[1]);
14712         }
14713       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14714         ix86_expand_round (operands[0], operands[1]);
14715       else
14716         ix86_expand_rounddf_32 (operands[0], operands[1]);
14717     }
14718   else
14719     {
14720       operands[1] = force_reg (<MODE>mode, operands[1]);
14721       ix86_emit_i387_round (operands[0], operands[1]);
14722     }
14723   DONE;
14724 })
14725
14726 (define_insn_and_split "*fistdi2_1"
14727   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14728         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14729                    UNSPEC_FIST))]
14730   "TARGET_USE_FANCY_MATH_387
14731    && can_create_pseudo_p ()"
14732   "#"
14733   "&& 1"
14734   [(const_int 0)]
14735 {
14736   if (memory_operand (operands[0], VOIDmode))
14737     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14738   else
14739     {
14740       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14741       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14742                                          operands[2]));
14743     }
14744   DONE;
14745 }
14746   [(set_attr "type" "fpspc")
14747    (set_attr "mode" "DI")])
14748
14749 (define_insn "fistdi2"
14750   [(set (match_operand:DI 0 "memory_operand" "=m")
14751         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14752                    UNSPEC_FIST))
14753    (clobber (match_scratch:XF 2 "=&1f"))]
14754   "TARGET_USE_FANCY_MATH_387"
14755   "* return output_fix_trunc (insn, operands, false);"
14756   [(set_attr "type" "fpspc")
14757    (set_attr "mode" "DI")])
14758
14759 (define_insn "fistdi2_with_temp"
14760   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14761         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14762                    UNSPEC_FIST))
14763    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14764    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14765   "TARGET_USE_FANCY_MATH_387"
14766   "#"
14767   [(set_attr "type" "fpspc")
14768    (set_attr "mode" "DI")])
14769
14770 (define_split
14771   [(set (match_operand:DI 0 "register_operand" "")
14772         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14773                    UNSPEC_FIST))
14774    (clobber (match_operand:DI 2 "memory_operand" ""))
14775    (clobber (match_scratch 3 ""))]
14776   "reload_completed"
14777   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14778               (clobber (match_dup 3))])
14779    (set (match_dup 0) (match_dup 2))])
14780
14781 (define_split
14782   [(set (match_operand:DI 0 "memory_operand" "")
14783         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14784                    UNSPEC_FIST))
14785    (clobber (match_operand:DI 2 "memory_operand" ""))
14786    (clobber (match_scratch 3 ""))]
14787   "reload_completed"
14788   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14789               (clobber (match_dup 3))])])
14790
14791 (define_insn_and_split "*fist<mode>2_1"
14792   [(set (match_operand:SWI24 0 "register_operand" "")
14793         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14794                       UNSPEC_FIST))]
14795   "TARGET_USE_FANCY_MATH_387
14796    && can_create_pseudo_p ()"
14797   "#"
14798   "&& 1"
14799   [(const_int 0)]
14800 {
14801   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14802   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14803                                         operands[2]));
14804   DONE;
14805 }
14806   [(set_attr "type" "fpspc")
14807    (set_attr "mode" "<MODE>")])
14808
14809 (define_insn "fist<mode>2"
14810   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14811         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14812                       UNSPEC_FIST))]
14813   "TARGET_USE_FANCY_MATH_387"
14814   "* return output_fix_trunc (insn, operands, false);"
14815   [(set_attr "type" "fpspc")
14816    (set_attr "mode" "<MODE>")])
14817
14818 (define_insn "fist<mode>2_with_temp"
14819   [(set (match_operand:SWI24 0 "register_operand" "=r")
14820         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14821                       UNSPEC_FIST))
14822    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14823   "TARGET_USE_FANCY_MATH_387"
14824   "#"
14825   [(set_attr "type" "fpspc")
14826    (set_attr "mode" "<MODE>")])
14827
14828 (define_split
14829   [(set (match_operand:SWI24 0 "register_operand" "")
14830         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14831                       UNSPEC_FIST))
14832    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14833   "reload_completed"
14834   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14835    (set (match_dup 0) (match_dup 2))])
14836
14837 (define_split
14838   [(set (match_operand:SWI24 0 "memory_operand" "")
14839         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14840                       UNSPEC_FIST))
14841    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14842   "reload_completed"
14843   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14844
14845 (define_expand "lrintxf<mode>2"
14846   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14847      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14848                      UNSPEC_FIST))]
14849   "TARGET_USE_FANCY_MATH_387")
14850
14851 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14852   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14853      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14854                         UNSPEC_FIX_NOTRUNC))]
14855   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14856    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14857
14858 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14859   [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14860    (match_operand:X87MODEF 1 "register_operand" "")]
14861   "(TARGET_USE_FANCY_MATH_387
14862     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14863         || TARGET_MIX_SSE_I387)
14864     && flag_unsafe_math_optimizations)
14865    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14866        && <SWI248x:MODE>mode != HImode 
14867        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14868        && !flag_trapping_math && !flag_rounding_math)"
14869 {
14870   if (optimize_insn_for_size_p ())
14871     FAIL;
14872
14873   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14874       && <SWI248x:MODE>mode != HImode
14875       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14876       && !flag_trapping_math && !flag_rounding_math)
14877     ix86_expand_lround (operands[0], operands[1]);
14878   else
14879     ix86_emit_i387_round (operands[0], operands[1]);
14880   DONE;
14881 })
14882
14883 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14884 (define_insn_and_split "frndintxf2_floor"
14885   [(set (match_operand:XF 0 "register_operand" "")
14886         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14887          UNSPEC_FRNDINT_FLOOR))
14888    (clobber (reg:CC FLAGS_REG))]
14889   "TARGET_USE_FANCY_MATH_387
14890    && flag_unsafe_math_optimizations
14891    && can_create_pseudo_p ()"
14892   "#"
14893   "&& 1"
14894   [(const_int 0)]
14895 {
14896   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14897
14898   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14899   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14900
14901   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14902                                         operands[2], operands[3]));
14903   DONE;
14904 }
14905   [(set_attr "type" "frndint")
14906    (set_attr "i387_cw" "floor")
14907    (set_attr "mode" "XF")])
14908
14909 (define_insn "frndintxf2_floor_i387"
14910   [(set (match_operand:XF 0 "register_operand" "=f")
14911         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14912          UNSPEC_FRNDINT_FLOOR))
14913    (use (match_operand:HI 2 "memory_operand" "m"))
14914    (use (match_operand:HI 3 "memory_operand" "m"))]
14915   "TARGET_USE_FANCY_MATH_387
14916    && flag_unsafe_math_optimizations"
14917   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14918   [(set_attr "type" "frndint")
14919    (set_attr "i387_cw" "floor")
14920    (set_attr "mode" "XF")])
14921
14922 (define_expand "floorxf2"
14923   [(use (match_operand:XF 0 "register_operand" ""))
14924    (use (match_operand:XF 1 "register_operand" ""))]
14925   "TARGET_USE_FANCY_MATH_387
14926    && flag_unsafe_math_optimizations"
14927 {
14928   if (optimize_insn_for_size_p ())
14929     FAIL;
14930   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14931   DONE;
14932 })
14933
14934 (define_expand "floor<mode>2"
14935   [(use (match_operand:MODEF 0 "register_operand" ""))
14936    (use (match_operand:MODEF 1 "register_operand" ""))]
14937   "(TARGET_USE_FANCY_MATH_387
14938     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14939         || TARGET_MIX_SSE_I387)
14940     && flag_unsafe_math_optimizations)
14941    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14942        && !flag_trapping_math)"
14943 {
14944   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14945       && !flag_trapping_math)
14946     {
14947       if (TARGET_ROUND)
14948         emit_insn (gen_sse4_1_round<mode>2
14949                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14950       else if (optimize_insn_for_size_p ())
14951         FAIL;
14952       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14953         ix86_expand_floorceil (operands[0], operands[1], true);
14954       else
14955         ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14956     }
14957   else
14958     {
14959       rtx op0, op1;
14960
14961       if (optimize_insn_for_size_p ())
14962         FAIL;
14963
14964       op0 = gen_reg_rtx (XFmode);
14965       op1 = gen_reg_rtx (XFmode);
14966       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14967       emit_insn (gen_frndintxf2_floor (op0, op1));
14968
14969       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14970     }
14971   DONE;
14972 })
14973
14974 (define_insn_and_split "*fist<mode>2_floor_1"
14975   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14976         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14977                         UNSPEC_FIST_FLOOR))
14978    (clobber (reg:CC FLAGS_REG))]
14979   "TARGET_USE_FANCY_MATH_387
14980    && flag_unsafe_math_optimizations
14981    && can_create_pseudo_p ()"
14982   "#"
14983   "&& 1"
14984   [(const_int 0)]
14985 {
14986   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14987
14988   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14989   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14990   if (memory_operand (operands[0], VOIDmode))
14991     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14992                                       operands[2], operands[3]));
14993   else
14994     {
14995       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14996       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14997                                                   operands[2], operands[3],
14998                                                   operands[4]));
14999     }
15000   DONE;
15001 }
15002   [(set_attr "type" "fistp")
15003    (set_attr "i387_cw" "floor")
15004    (set_attr "mode" "<MODE>")])
15005
15006 (define_insn "fistdi2_floor"
15007   [(set (match_operand:DI 0 "memory_operand" "=m")
15008         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15009                    UNSPEC_FIST_FLOOR))
15010    (use (match_operand:HI 2 "memory_operand" "m"))
15011    (use (match_operand:HI 3 "memory_operand" "m"))
15012    (clobber (match_scratch:XF 4 "=&1f"))]
15013   "TARGET_USE_FANCY_MATH_387
15014    && flag_unsafe_math_optimizations"
15015   "* return output_fix_trunc (insn, operands, false);"
15016   [(set_attr "type" "fistp")
15017    (set_attr "i387_cw" "floor")
15018    (set_attr "mode" "DI")])
15019
15020 (define_insn "fistdi2_floor_with_temp"
15021   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15022         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15023                    UNSPEC_FIST_FLOOR))
15024    (use (match_operand:HI 2 "memory_operand" "m,m"))
15025    (use (match_operand:HI 3 "memory_operand" "m,m"))
15026    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15027    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15028   "TARGET_USE_FANCY_MATH_387
15029    && flag_unsafe_math_optimizations"
15030   "#"
15031   [(set_attr "type" "fistp")
15032    (set_attr "i387_cw" "floor")
15033    (set_attr "mode" "DI")])
15034
15035 (define_split
15036   [(set (match_operand:DI 0 "register_operand" "")
15037         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15038                    UNSPEC_FIST_FLOOR))
15039    (use (match_operand:HI 2 "memory_operand" ""))
15040    (use (match_operand:HI 3 "memory_operand" ""))
15041    (clobber (match_operand:DI 4 "memory_operand" ""))
15042    (clobber (match_scratch 5 ""))]
15043   "reload_completed"
15044   [(parallel [(set (match_dup 4)
15045                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15046               (use (match_dup 2))
15047               (use (match_dup 3))
15048               (clobber (match_dup 5))])
15049    (set (match_dup 0) (match_dup 4))])
15050
15051 (define_split
15052   [(set (match_operand:DI 0 "memory_operand" "")
15053         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15054                    UNSPEC_FIST_FLOOR))
15055    (use (match_operand:HI 2 "memory_operand" ""))
15056    (use (match_operand:HI 3 "memory_operand" ""))
15057    (clobber (match_operand:DI 4 "memory_operand" ""))
15058    (clobber (match_scratch 5 ""))]
15059   "reload_completed"
15060   [(parallel [(set (match_dup 0)
15061                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15062               (use (match_dup 2))
15063               (use (match_dup 3))
15064               (clobber (match_dup 5))])])
15065
15066 (define_insn "fist<mode>2_floor"
15067   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15068         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15069                       UNSPEC_FIST_FLOOR))
15070    (use (match_operand:HI 2 "memory_operand" "m"))
15071    (use (match_operand:HI 3 "memory_operand" "m"))]
15072   "TARGET_USE_FANCY_MATH_387
15073    && flag_unsafe_math_optimizations"
15074   "* return output_fix_trunc (insn, operands, false);"
15075   [(set_attr "type" "fistp")
15076    (set_attr "i387_cw" "floor")
15077    (set_attr "mode" "<MODE>")])
15078
15079 (define_insn "fist<mode>2_floor_with_temp"
15080   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15081         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15082                       UNSPEC_FIST_FLOOR))
15083    (use (match_operand:HI 2 "memory_operand" "m,m"))
15084    (use (match_operand:HI 3 "memory_operand" "m,m"))
15085    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15086   "TARGET_USE_FANCY_MATH_387
15087    && flag_unsafe_math_optimizations"
15088   "#"
15089   [(set_attr "type" "fistp")
15090    (set_attr "i387_cw" "floor")
15091    (set_attr "mode" "<MODE>")])
15092
15093 (define_split
15094   [(set (match_operand:SWI24 0 "register_operand" "")
15095         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15096                       UNSPEC_FIST_FLOOR))
15097    (use (match_operand:HI 2 "memory_operand" ""))
15098    (use (match_operand:HI 3 "memory_operand" ""))
15099    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15100   "reload_completed"
15101   [(parallel [(set (match_dup 4)
15102                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15103               (use (match_dup 2))
15104               (use (match_dup 3))])
15105    (set (match_dup 0) (match_dup 4))])
15106
15107 (define_split
15108   [(set (match_operand:SWI24 0 "memory_operand" "")
15109         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15110                       UNSPEC_FIST_FLOOR))
15111    (use (match_operand:HI 2 "memory_operand" ""))
15112    (use (match_operand:HI 3 "memory_operand" ""))
15113    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15114   "reload_completed"
15115   [(parallel [(set (match_dup 0)
15116                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15117               (use (match_dup 2))
15118               (use (match_dup 3))])])
15119
15120 (define_expand "lfloorxf<mode>2"
15121   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15122                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15123                                    UNSPEC_FIST_FLOOR))
15124               (clobber (reg:CC FLAGS_REG))])]
15125   "TARGET_USE_FANCY_MATH_387
15126    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15127    && flag_unsafe_math_optimizations")
15128
15129 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15130   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15131    (match_operand:MODEF 1 "register_operand" "")]
15132   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15133    && !flag_trapping_math"
15134 {
15135   if (TARGET_64BIT && optimize_insn_for_size_p ())
15136     FAIL;
15137   ix86_expand_lfloorceil (operands[0], operands[1], true);
15138   DONE;
15139 })
15140
15141 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15142 (define_insn_and_split "frndintxf2_ceil"
15143   [(set (match_operand:XF 0 "register_operand" "")
15144         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15145          UNSPEC_FRNDINT_CEIL))
15146    (clobber (reg:CC FLAGS_REG))]
15147   "TARGET_USE_FANCY_MATH_387
15148    && flag_unsafe_math_optimizations
15149    && can_create_pseudo_p ()"
15150   "#"
15151   "&& 1"
15152   [(const_int 0)]
15153 {
15154   ix86_optimize_mode_switching[I387_CEIL] = 1;
15155
15156   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15157   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15158
15159   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15160                                        operands[2], operands[3]));
15161   DONE;
15162 }
15163   [(set_attr "type" "frndint")
15164    (set_attr "i387_cw" "ceil")
15165    (set_attr "mode" "XF")])
15166
15167 (define_insn "frndintxf2_ceil_i387"
15168   [(set (match_operand:XF 0 "register_operand" "=f")
15169         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15170          UNSPEC_FRNDINT_CEIL))
15171    (use (match_operand:HI 2 "memory_operand" "m"))
15172    (use (match_operand:HI 3 "memory_operand" "m"))]
15173   "TARGET_USE_FANCY_MATH_387
15174    && flag_unsafe_math_optimizations"
15175   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15176   [(set_attr "type" "frndint")
15177    (set_attr "i387_cw" "ceil")
15178    (set_attr "mode" "XF")])
15179
15180 (define_expand "ceilxf2"
15181   [(use (match_operand:XF 0 "register_operand" ""))
15182    (use (match_operand:XF 1 "register_operand" ""))]
15183   "TARGET_USE_FANCY_MATH_387
15184    && flag_unsafe_math_optimizations"
15185 {
15186   if (optimize_insn_for_size_p ())
15187     FAIL;
15188   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15189   DONE;
15190 })
15191
15192 (define_expand "ceil<mode>2"
15193   [(use (match_operand:MODEF 0 "register_operand" ""))
15194    (use (match_operand:MODEF 1 "register_operand" ""))]
15195   "(TARGET_USE_FANCY_MATH_387
15196     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15197         || TARGET_MIX_SSE_I387)
15198     && flag_unsafe_math_optimizations)
15199    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15200        && !flag_trapping_math)"
15201 {
15202   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15203       && !flag_trapping_math)
15204     {
15205       if (TARGET_ROUND)
15206         emit_insn (gen_sse4_1_round<mode>2
15207                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15208       else if (optimize_insn_for_size_p ())
15209         FAIL;
15210       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15211         ix86_expand_floorceil (operands[0], operands[1], false);
15212       else
15213         ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15214     }
15215   else
15216     {
15217       rtx op0, op1;
15218
15219       if (optimize_insn_for_size_p ())
15220         FAIL;
15221
15222       op0 = gen_reg_rtx (XFmode);
15223       op1 = gen_reg_rtx (XFmode);
15224       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15225       emit_insn (gen_frndintxf2_ceil (op0, op1));
15226
15227       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15228     }
15229   DONE;
15230 })
15231
15232 (define_insn_and_split "*fist<mode>2_ceil_1"
15233   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15234         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15235                         UNSPEC_FIST_CEIL))
15236    (clobber (reg:CC FLAGS_REG))]
15237   "TARGET_USE_FANCY_MATH_387
15238    && flag_unsafe_math_optimizations
15239    && can_create_pseudo_p ()"
15240   "#"
15241   "&& 1"
15242   [(const_int 0)]
15243 {
15244   ix86_optimize_mode_switching[I387_CEIL] = 1;
15245
15246   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15247   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15248   if (memory_operand (operands[0], VOIDmode))
15249     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15250                                      operands[2], operands[3]));
15251   else
15252     {
15253       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15254       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15255                                                  operands[2], operands[3],
15256                                                  operands[4]));
15257     }
15258   DONE;
15259 }
15260   [(set_attr "type" "fistp")
15261    (set_attr "i387_cw" "ceil")
15262    (set_attr "mode" "<MODE>")])
15263
15264 (define_insn "fistdi2_ceil"
15265   [(set (match_operand:DI 0 "memory_operand" "=m")
15266         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15267                    UNSPEC_FIST_CEIL))
15268    (use (match_operand:HI 2 "memory_operand" "m"))
15269    (use (match_operand:HI 3 "memory_operand" "m"))
15270    (clobber (match_scratch:XF 4 "=&1f"))]
15271   "TARGET_USE_FANCY_MATH_387
15272    && flag_unsafe_math_optimizations"
15273   "* return output_fix_trunc (insn, operands, false);"
15274   [(set_attr "type" "fistp")
15275    (set_attr "i387_cw" "ceil")
15276    (set_attr "mode" "DI")])
15277
15278 (define_insn "fistdi2_ceil_with_temp"
15279   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15280         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15281                    UNSPEC_FIST_CEIL))
15282    (use (match_operand:HI 2 "memory_operand" "m,m"))
15283    (use (match_operand:HI 3 "memory_operand" "m,m"))
15284    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15285    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15286   "TARGET_USE_FANCY_MATH_387
15287    && flag_unsafe_math_optimizations"
15288   "#"
15289   [(set_attr "type" "fistp")
15290    (set_attr "i387_cw" "ceil")
15291    (set_attr "mode" "DI")])
15292
15293 (define_split
15294   [(set (match_operand:DI 0 "register_operand" "")
15295         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15296                    UNSPEC_FIST_CEIL))
15297    (use (match_operand:HI 2 "memory_operand" ""))
15298    (use (match_operand:HI 3 "memory_operand" ""))
15299    (clobber (match_operand:DI 4 "memory_operand" ""))
15300    (clobber (match_scratch 5 ""))]
15301   "reload_completed"
15302   [(parallel [(set (match_dup 4)
15303                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15304               (use (match_dup 2))
15305               (use (match_dup 3))
15306               (clobber (match_dup 5))])
15307    (set (match_dup 0) (match_dup 4))])
15308
15309 (define_split
15310   [(set (match_operand:DI 0 "memory_operand" "")
15311         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15312                    UNSPEC_FIST_CEIL))
15313    (use (match_operand:HI 2 "memory_operand" ""))
15314    (use (match_operand:HI 3 "memory_operand" ""))
15315    (clobber (match_operand:DI 4 "memory_operand" ""))
15316    (clobber (match_scratch 5 ""))]
15317   "reload_completed"
15318   [(parallel [(set (match_dup 0)
15319                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15320               (use (match_dup 2))
15321               (use (match_dup 3))
15322               (clobber (match_dup 5))])])
15323
15324 (define_insn "fist<mode>2_ceil"
15325   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15326         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15327                       UNSPEC_FIST_CEIL))
15328    (use (match_operand:HI 2 "memory_operand" "m"))
15329    (use (match_operand:HI 3 "memory_operand" "m"))]
15330   "TARGET_USE_FANCY_MATH_387
15331    && flag_unsafe_math_optimizations"
15332   "* return output_fix_trunc (insn, operands, false);"
15333   [(set_attr "type" "fistp")
15334    (set_attr "i387_cw" "ceil")
15335    (set_attr "mode" "<MODE>")])
15336
15337 (define_insn "fist<mode>2_ceil_with_temp"
15338   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15339         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15340                       UNSPEC_FIST_CEIL))
15341    (use (match_operand:HI 2 "memory_operand" "m,m"))
15342    (use (match_operand:HI 3 "memory_operand" "m,m"))
15343    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15344   "TARGET_USE_FANCY_MATH_387
15345    && flag_unsafe_math_optimizations"
15346   "#"
15347   [(set_attr "type" "fistp")
15348    (set_attr "i387_cw" "ceil")
15349    (set_attr "mode" "<MODE>")])
15350
15351 (define_split
15352   [(set (match_operand:SWI24 0 "register_operand" "")
15353         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15354                       UNSPEC_FIST_CEIL))
15355    (use (match_operand:HI 2 "memory_operand" ""))
15356    (use (match_operand:HI 3 "memory_operand" ""))
15357    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15358   "reload_completed"
15359   [(parallel [(set (match_dup 4)
15360                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15361               (use (match_dup 2))
15362               (use (match_dup 3))])
15363    (set (match_dup 0) (match_dup 4))])
15364
15365 (define_split
15366   [(set (match_operand:SWI24 0 "memory_operand" "")
15367         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15368                       UNSPEC_FIST_CEIL))
15369    (use (match_operand:HI 2 "memory_operand" ""))
15370    (use (match_operand:HI 3 "memory_operand" ""))
15371    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15372   "reload_completed"
15373   [(parallel [(set (match_dup 0)
15374                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15375               (use (match_dup 2))
15376               (use (match_dup 3))])])
15377
15378 (define_expand "lceilxf<mode>2"
15379   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15380                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15381                                    UNSPEC_FIST_CEIL))
15382               (clobber (reg:CC FLAGS_REG))])]
15383   "TARGET_USE_FANCY_MATH_387
15384    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15385    && flag_unsafe_math_optimizations")
15386
15387 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15388   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15389    (match_operand:MODEF 1 "register_operand" "")]
15390   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15391    && !flag_trapping_math"
15392 {
15393   ix86_expand_lfloorceil (operands[0], operands[1], false);
15394   DONE;
15395 })
15396
15397 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15398 (define_insn_and_split "frndintxf2_trunc"
15399   [(set (match_operand:XF 0 "register_operand" "")
15400         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15401          UNSPEC_FRNDINT_TRUNC))
15402    (clobber (reg:CC FLAGS_REG))]
15403   "TARGET_USE_FANCY_MATH_387
15404    && flag_unsafe_math_optimizations
15405    && can_create_pseudo_p ()"
15406   "#"
15407   "&& 1"
15408   [(const_int 0)]
15409 {
15410   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15411
15412   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15413   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15414
15415   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15416                                         operands[2], operands[3]));
15417   DONE;
15418 }
15419   [(set_attr "type" "frndint")
15420    (set_attr "i387_cw" "trunc")
15421    (set_attr "mode" "XF")])
15422
15423 (define_insn "frndintxf2_trunc_i387"
15424   [(set (match_operand:XF 0 "register_operand" "=f")
15425         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15426          UNSPEC_FRNDINT_TRUNC))
15427    (use (match_operand:HI 2 "memory_operand" "m"))
15428    (use (match_operand:HI 3 "memory_operand" "m"))]
15429   "TARGET_USE_FANCY_MATH_387
15430    && flag_unsafe_math_optimizations"
15431   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15432   [(set_attr "type" "frndint")
15433    (set_attr "i387_cw" "trunc")
15434    (set_attr "mode" "XF")])
15435
15436 (define_expand "btruncxf2"
15437   [(use (match_operand:XF 0 "register_operand" ""))
15438    (use (match_operand:XF 1 "register_operand" ""))]
15439   "TARGET_USE_FANCY_MATH_387
15440    && flag_unsafe_math_optimizations"
15441 {
15442   if (optimize_insn_for_size_p ())
15443     FAIL;
15444   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15445   DONE;
15446 })
15447
15448 (define_expand "btrunc<mode>2"
15449   [(use (match_operand:MODEF 0 "register_operand" ""))
15450    (use (match_operand:MODEF 1 "register_operand" ""))]
15451   "(TARGET_USE_FANCY_MATH_387
15452     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15453         || TARGET_MIX_SSE_I387)
15454     && flag_unsafe_math_optimizations)
15455    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15456        && !flag_trapping_math)"
15457 {
15458   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15459       && !flag_trapping_math)
15460     {
15461       if (TARGET_ROUND)
15462         emit_insn (gen_sse4_1_round<mode>2
15463                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15464       else if (optimize_insn_for_size_p ())
15465         FAIL;
15466       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15467         ix86_expand_trunc (operands[0], operands[1]);
15468       else
15469         ix86_expand_truncdf_32 (operands[0], operands[1]);
15470     }
15471   else
15472     {
15473       rtx op0, op1;
15474
15475       if (optimize_insn_for_size_p ())
15476         FAIL;
15477
15478       op0 = gen_reg_rtx (XFmode);
15479       op1 = gen_reg_rtx (XFmode);
15480       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15481       emit_insn (gen_frndintxf2_trunc (op0, op1));
15482
15483       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15484     }
15485   DONE;
15486 })
15487
15488 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15489 (define_insn_and_split "frndintxf2_mask_pm"
15490   [(set (match_operand:XF 0 "register_operand" "")
15491         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15492          UNSPEC_FRNDINT_MASK_PM))
15493    (clobber (reg:CC FLAGS_REG))]
15494   "TARGET_USE_FANCY_MATH_387
15495    && flag_unsafe_math_optimizations
15496    && can_create_pseudo_p ()"
15497   "#"
15498   "&& 1"
15499   [(const_int 0)]
15500 {
15501   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15502
15503   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15504   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15505
15506   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15507                                           operands[2], operands[3]));
15508   DONE;
15509 }
15510   [(set_attr "type" "frndint")
15511    (set_attr "i387_cw" "mask_pm")
15512    (set_attr "mode" "XF")])
15513
15514 (define_insn "frndintxf2_mask_pm_i387"
15515   [(set (match_operand:XF 0 "register_operand" "=f")
15516         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15517          UNSPEC_FRNDINT_MASK_PM))
15518    (use (match_operand:HI 2 "memory_operand" "m"))
15519    (use (match_operand:HI 3 "memory_operand" "m"))]
15520   "TARGET_USE_FANCY_MATH_387
15521    && flag_unsafe_math_optimizations"
15522   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15523   [(set_attr "type" "frndint")
15524    (set_attr "i387_cw" "mask_pm")
15525    (set_attr "mode" "XF")])
15526
15527 (define_expand "nearbyintxf2"
15528   [(use (match_operand:XF 0 "register_operand" ""))
15529    (use (match_operand:XF 1 "register_operand" ""))]
15530   "TARGET_USE_FANCY_MATH_387
15531    && flag_unsafe_math_optimizations"
15532 {
15533   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15534   DONE;
15535 })
15536
15537 (define_expand "nearbyint<mode>2"
15538   [(use (match_operand:MODEF 0 "register_operand" ""))
15539    (use (match_operand:MODEF 1 "register_operand" ""))]
15540   "TARGET_USE_FANCY_MATH_387
15541    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15542        || TARGET_MIX_SSE_I387)
15543    && flag_unsafe_math_optimizations"
15544 {
15545   rtx op0 = gen_reg_rtx (XFmode);
15546   rtx op1 = gen_reg_rtx (XFmode);
15547
15548   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15549   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15550
15551   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15552   DONE;
15553 })
15554
15555 (define_insn "fxam<mode>2_i387"
15556   [(set (match_operand:HI 0 "register_operand" "=a")
15557         (unspec:HI
15558           [(match_operand:X87MODEF 1 "register_operand" "f")]
15559           UNSPEC_FXAM))]
15560   "TARGET_USE_FANCY_MATH_387"
15561   "fxam\n\tfnstsw\t%0"
15562   [(set_attr "type" "multi")
15563    (set_attr "length" "4")
15564    (set_attr "unit" "i387")
15565    (set_attr "mode" "<MODE>")])
15566
15567 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15568   [(set (match_operand:HI 0 "register_operand" "")
15569         (unspec:HI
15570           [(match_operand:MODEF 1 "memory_operand" "")]
15571           UNSPEC_FXAM_MEM))]
15572   "TARGET_USE_FANCY_MATH_387
15573    && can_create_pseudo_p ()"
15574   "#"
15575   "&& 1"
15576   [(set (match_dup 2)(match_dup 1))
15577    (set (match_dup 0)
15578         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15579 {
15580   operands[2] = gen_reg_rtx (<MODE>mode);
15581
15582   MEM_VOLATILE_P (operands[1]) = 1;
15583 }
15584   [(set_attr "type" "multi")
15585    (set_attr "unit" "i387")
15586    (set_attr "mode" "<MODE>")])
15587
15588 (define_expand "isinfxf2"
15589   [(use (match_operand:SI 0 "register_operand" ""))
15590    (use (match_operand:XF 1 "register_operand" ""))]
15591   "TARGET_USE_FANCY_MATH_387
15592    && TARGET_C99_FUNCTIONS"
15593 {
15594   rtx mask = GEN_INT (0x45);
15595   rtx val = GEN_INT (0x05);
15596
15597   rtx cond;
15598
15599   rtx scratch = gen_reg_rtx (HImode);
15600   rtx res = gen_reg_rtx (QImode);
15601
15602   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15603
15604   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15605   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15606   cond = gen_rtx_fmt_ee (EQ, QImode,
15607                          gen_rtx_REG (CCmode, FLAGS_REG),
15608                          const0_rtx);
15609   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15610   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15611   DONE;
15612 })
15613
15614 (define_expand "isinf<mode>2"
15615   [(use (match_operand:SI 0 "register_operand" ""))
15616    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15617   "TARGET_USE_FANCY_MATH_387
15618    && TARGET_C99_FUNCTIONS
15619    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15620 {
15621   rtx mask = GEN_INT (0x45);
15622   rtx val = GEN_INT (0x05);
15623
15624   rtx cond;
15625
15626   rtx scratch = gen_reg_rtx (HImode);
15627   rtx res = gen_reg_rtx (QImode);
15628
15629   /* Remove excess precision by forcing value through memory. */
15630   if (memory_operand (operands[1], VOIDmode))
15631     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15632   else
15633     {
15634       enum ix86_stack_slot slot = (virtuals_instantiated
15635                                    ? SLOT_TEMP
15636                                    : SLOT_VIRTUAL);
15637       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15638
15639       emit_move_insn (temp, operands[1]);
15640       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15641     }
15642
15643   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15644   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15645   cond = gen_rtx_fmt_ee (EQ, QImode,
15646                          gen_rtx_REG (CCmode, FLAGS_REG),
15647                          const0_rtx);
15648   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15649   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15650   DONE;
15651 })
15652
15653 (define_expand "signbitxf2"
15654   [(use (match_operand:SI 0 "register_operand" ""))
15655    (use (match_operand:XF 1 "register_operand" ""))]
15656   "TARGET_USE_FANCY_MATH_387"
15657 {
15658   rtx scratch = gen_reg_rtx (HImode);
15659
15660   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15661   emit_insn (gen_andsi3 (operands[0],
15662              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15663   DONE;
15664 })
15665
15666 (define_insn "movmsk_df"
15667   [(set (match_operand:SI 0 "register_operand" "=r")
15668         (unspec:SI
15669           [(match_operand:DF 1 "register_operand" "x")]
15670           UNSPEC_MOVMSK))]
15671   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15672   "%vmovmskpd\t{%1, %0|%0, %1}"
15673   [(set_attr "type" "ssemov")
15674    (set_attr "prefix" "maybe_vex")
15675    (set_attr "mode" "DF")])
15676
15677 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15678 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15679 (define_expand "signbitdf2"
15680   [(use (match_operand:SI 0 "register_operand" ""))
15681    (use (match_operand:DF 1 "register_operand" ""))]
15682   "TARGET_USE_FANCY_MATH_387
15683    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15684 {
15685   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15686     {
15687       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15688       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15689     }
15690   else
15691     {
15692       rtx scratch = gen_reg_rtx (HImode);
15693
15694       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15695       emit_insn (gen_andsi3 (operands[0],
15696                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15697     }
15698   DONE;
15699 })
15700
15701 (define_expand "signbitsf2"
15702   [(use (match_operand:SI 0 "register_operand" ""))
15703    (use (match_operand:SF 1 "register_operand" ""))]
15704   "TARGET_USE_FANCY_MATH_387
15705    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15706 {
15707   rtx scratch = gen_reg_rtx (HImode);
15708
15709   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15710   emit_insn (gen_andsi3 (operands[0],
15711              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15712   DONE;
15713 })
15714 \f
15715 ;; Block operation instructions
15716
15717 (define_insn "cld"
15718   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15719   ""
15720   "cld"
15721   [(set_attr "length" "1")
15722    (set_attr "length_immediate" "0")
15723    (set_attr "modrm" "0")])
15724
15725 (define_expand "movmem<mode>"
15726   [(use (match_operand:BLK 0 "memory_operand" ""))
15727    (use (match_operand:BLK 1 "memory_operand" ""))
15728    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15729    (use (match_operand:SWI48 3 "const_int_operand" ""))
15730    (use (match_operand:SI 4 "const_int_operand" ""))
15731    (use (match_operand:SI 5 "const_int_operand" ""))]
15732   ""
15733 {
15734  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15735                          operands[4], operands[5]))
15736    DONE;
15737  else
15738    FAIL;
15739 })
15740
15741 ;; Most CPUs don't like single string operations
15742 ;; Handle this case here to simplify previous expander.
15743
15744 (define_expand "strmov"
15745   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15746    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15747    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15748               (clobber (reg:CC FLAGS_REG))])
15749    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15750               (clobber (reg:CC FLAGS_REG))])]
15751   ""
15752 {
15753   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15754
15755   /* If .md ever supports :P for Pmode, these can be directly
15756      in the pattern above.  */
15757   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15758   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15759
15760   /* Can't use this if the user has appropriated esi or edi.  */
15761   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15762       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15763     {
15764       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15765                                       operands[2], operands[3],
15766                                       operands[5], operands[6]));
15767       DONE;
15768     }
15769
15770   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15771 })
15772
15773 (define_expand "strmov_singleop"
15774   [(parallel [(set (match_operand 1 "memory_operand" "")
15775                    (match_operand 3 "memory_operand" ""))
15776               (set (match_operand 0 "register_operand" "")
15777                    (match_operand 4 "" ""))
15778               (set (match_operand 2 "register_operand" "")
15779                    (match_operand 5 "" ""))])]
15780   ""
15781   "ix86_current_function_needs_cld = 1;")
15782
15783 (define_insn "*strmovdi_rex_1"
15784   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15785         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15786    (set (match_operand:DI 0 "register_operand" "=D")
15787         (plus:DI (match_dup 2)
15788                  (const_int 8)))
15789    (set (match_operand:DI 1 "register_operand" "=S")
15790         (plus:DI (match_dup 3)
15791                  (const_int 8)))]
15792   "TARGET_64BIT
15793    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15794   "movsq"
15795   [(set_attr "type" "str")
15796    (set_attr "memory" "both")
15797    (set_attr "mode" "DI")])
15798
15799 (define_insn "*strmovsi_1"
15800   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15801         (mem:SI (match_operand:P 3 "register_operand" "1")))
15802    (set (match_operand:P 0 "register_operand" "=D")
15803         (plus:P (match_dup 2)
15804                 (const_int 4)))
15805    (set (match_operand:P 1 "register_operand" "=S")
15806         (plus:P (match_dup 3)
15807                 (const_int 4)))]
15808   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15809   "movs{l|d}"
15810   [(set_attr "type" "str")
15811    (set_attr "memory" "both")
15812    (set_attr "mode" "SI")])
15813
15814 (define_insn "*strmovhi_1"
15815   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15816         (mem:HI (match_operand:P 3 "register_operand" "1")))
15817    (set (match_operand:P 0 "register_operand" "=D")
15818         (plus:P (match_dup 2)
15819                 (const_int 2)))
15820    (set (match_operand:P 1 "register_operand" "=S")
15821         (plus:P (match_dup 3)
15822                 (const_int 2)))]
15823   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15824   "movsw"
15825   [(set_attr "type" "str")
15826    (set_attr "memory" "both")
15827    (set_attr "mode" "HI")])
15828
15829 (define_insn "*strmovqi_1"
15830   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15831         (mem:QI (match_operand:P 3 "register_operand" "1")))
15832    (set (match_operand:P 0 "register_operand" "=D")
15833         (plus:P (match_dup 2)
15834                 (const_int 1)))
15835    (set (match_operand:P 1 "register_operand" "=S")
15836         (plus:P (match_dup 3)
15837                 (const_int 1)))]
15838   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15839   "movsb"
15840   [(set_attr "type" "str")
15841    (set_attr "memory" "both")
15842    (set (attr "prefix_rex")
15843         (if_then_else
15844           (match_test "<P:MODE>mode == DImode")
15845           (const_string "0")
15846           (const_string "*")))
15847    (set_attr "mode" "QI")])
15848
15849 (define_expand "rep_mov"
15850   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15851               (set (match_operand 0 "register_operand" "")
15852                    (match_operand 5 "" ""))
15853               (set (match_operand 2 "register_operand" "")
15854                    (match_operand 6 "" ""))
15855               (set (match_operand 1 "memory_operand" "")
15856                    (match_operand 3 "memory_operand" ""))
15857               (use (match_dup 4))])]
15858   ""
15859   "ix86_current_function_needs_cld = 1;")
15860
15861 (define_insn "*rep_movdi_rex64"
15862   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15863    (set (match_operand:DI 0 "register_operand" "=D")
15864         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15865                             (const_int 3))
15866                  (match_operand:DI 3 "register_operand" "0")))
15867    (set (match_operand:DI 1 "register_operand" "=S")
15868         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15869                  (match_operand:DI 4 "register_operand" "1")))
15870    (set (mem:BLK (match_dup 3))
15871         (mem:BLK (match_dup 4)))
15872    (use (match_dup 5))]
15873   "TARGET_64BIT
15874    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15875   "rep{%;} movsq"
15876   [(set_attr "type" "str")
15877    (set_attr "prefix_rep" "1")
15878    (set_attr "memory" "both")
15879    (set_attr "mode" "DI")])
15880
15881 (define_insn "*rep_movsi"
15882   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15883    (set (match_operand:P 0 "register_operand" "=D")
15884         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15885                           (const_int 2))
15886                  (match_operand:P 3 "register_operand" "0")))
15887    (set (match_operand:P 1 "register_operand" "=S")
15888         (plus:P (ashift:P (match_dup 5) (const_int 2))
15889                 (match_operand:P 4 "register_operand" "1")))
15890    (set (mem:BLK (match_dup 3))
15891         (mem:BLK (match_dup 4)))
15892    (use (match_dup 5))]
15893   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15894   "rep{%;} movs{l|d}"
15895   [(set_attr "type" "str")
15896    (set_attr "prefix_rep" "1")
15897    (set_attr "memory" "both")
15898    (set_attr "mode" "SI")])
15899
15900 (define_insn "*rep_movqi"
15901   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15902    (set (match_operand:P 0 "register_operand" "=D")
15903         (plus:P (match_operand:P 3 "register_operand" "0")
15904                 (match_operand:P 5 "register_operand" "2")))
15905    (set (match_operand:P 1 "register_operand" "=S")
15906         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15907    (set (mem:BLK (match_dup 3))
15908         (mem:BLK (match_dup 4)))
15909    (use (match_dup 5))]
15910   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15911   "rep{%;} movsb"
15912   [(set_attr "type" "str")
15913    (set_attr "prefix_rep" "1")
15914    (set_attr "memory" "both")
15915    (set_attr "mode" "QI")])
15916
15917 (define_expand "setmem<mode>"
15918    [(use (match_operand:BLK 0 "memory_operand" ""))
15919     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15920     (use (match_operand:QI 2 "nonmemory_operand" ""))
15921     (use (match_operand 3 "const_int_operand" ""))
15922     (use (match_operand:SI 4 "const_int_operand" ""))
15923     (use (match_operand:SI 5 "const_int_operand" ""))]
15924   ""
15925 {
15926  if (ix86_expand_setmem (operands[0], operands[1],
15927                          operands[2], operands[3],
15928                          operands[4], operands[5]))
15929    DONE;
15930  else
15931    FAIL;
15932 })
15933
15934 ;; Most CPUs don't like single string operations
15935 ;; Handle this case here to simplify previous expander.
15936
15937 (define_expand "strset"
15938   [(set (match_operand 1 "memory_operand" "")
15939         (match_operand 2 "register_operand" ""))
15940    (parallel [(set (match_operand 0 "register_operand" "")
15941                    (match_dup 3))
15942               (clobber (reg:CC FLAGS_REG))])]
15943   ""
15944 {
15945   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15946     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15947
15948   /* If .md ever supports :P for Pmode, this can be directly
15949      in the pattern above.  */
15950   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15951                               GEN_INT (GET_MODE_SIZE (GET_MODE
15952                                                       (operands[2]))));
15953   /* Can't use this if the user has appropriated eax or edi.  */
15954   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15955       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15956     {
15957       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15958                                       operands[3]));
15959       DONE;
15960     }
15961 })
15962
15963 (define_expand "strset_singleop"
15964   [(parallel [(set (match_operand 1 "memory_operand" "")
15965                    (match_operand 2 "register_operand" ""))
15966               (set (match_operand 0 "register_operand" "")
15967                    (match_operand 3 "" ""))])]
15968   ""
15969   "ix86_current_function_needs_cld = 1;")
15970
15971 (define_insn "*strsetdi_rex_1"
15972   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15973         (match_operand:DI 2 "register_operand" "a"))
15974    (set (match_operand:DI 0 "register_operand" "=D")
15975         (plus:DI (match_dup 1)
15976                  (const_int 8)))]
15977   "TARGET_64BIT
15978    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15979   "stosq"
15980   [(set_attr "type" "str")
15981    (set_attr "memory" "store")
15982    (set_attr "mode" "DI")])
15983
15984 (define_insn "*strsetsi_1"
15985   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15986         (match_operand:SI 2 "register_operand" "a"))
15987    (set (match_operand:P 0 "register_operand" "=D")
15988         (plus:P (match_dup 1)
15989                 (const_int 4)))]
15990   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15991   "stos{l|d}"
15992   [(set_attr "type" "str")
15993    (set_attr "memory" "store")
15994    (set_attr "mode" "SI")])
15995
15996 (define_insn "*strsethi_1"
15997   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15998         (match_operand:HI 2 "register_operand" "a"))
15999    (set (match_operand:P 0 "register_operand" "=D")
16000         (plus:P (match_dup 1)
16001                 (const_int 2)))]
16002   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16003   "stosw"
16004   [(set_attr "type" "str")
16005    (set_attr "memory" "store")
16006    (set_attr "mode" "HI")])
16007
16008 (define_insn "*strsetqi_1"
16009   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16010         (match_operand:QI 2 "register_operand" "a"))
16011    (set (match_operand:P 0 "register_operand" "=D")
16012         (plus:P (match_dup 1)
16013                 (const_int 1)))]
16014   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16015   "stosb"
16016   [(set_attr "type" "str")
16017    (set_attr "memory" "store")
16018    (set (attr "prefix_rex")
16019         (if_then_else
16020           (match_test "<P:MODE>mode == DImode")
16021           (const_string "0")
16022           (const_string "*")))
16023    (set_attr "mode" "QI")])
16024
16025 (define_expand "rep_stos"
16026   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16027               (set (match_operand 0 "register_operand" "")
16028                    (match_operand 4 "" ""))
16029               (set (match_operand 2 "memory_operand" "") (const_int 0))
16030               (use (match_operand 3 "register_operand" ""))
16031               (use (match_dup 1))])]
16032   ""
16033   "ix86_current_function_needs_cld = 1;")
16034
16035 (define_insn "*rep_stosdi_rex64"
16036   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16037    (set (match_operand:DI 0 "register_operand" "=D")
16038         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16039                             (const_int 3))
16040                  (match_operand:DI 3 "register_operand" "0")))
16041    (set (mem:BLK (match_dup 3))
16042         (const_int 0))
16043    (use (match_operand:DI 2 "register_operand" "a"))
16044    (use (match_dup 4))]
16045   "TARGET_64BIT
16046    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16047   "rep{%;} stosq"
16048   [(set_attr "type" "str")
16049    (set_attr "prefix_rep" "1")
16050    (set_attr "memory" "store")
16051    (set_attr "mode" "DI")])
16052
16053 (define_insn "*rep_stossi"
16054   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16055    (set (match_operand:P 0 "register_operand" "=D")
16056         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16057                           (const_int 2))
16058                  (match_operand:P 3 "register_operand" "0")))
16059    (set (mem:BLK (match_dup 3))
16060         (const_int 0))
16061    (use (match_operand:SI 2 "register_operand" "a"))
16062    (use (match_dup 4))]
16063   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16064   "rep{%;} stos{l|d}"
16065   [(set_attr "type" "str")
16066    (set_attr "prefix_rep" "1")
16067    (set_attr "memory" "store")
16068    (set_attr "mode" "SI")])
16069
16070 (define_insn "*rep_stosqi"
16071   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16072    (set (match_operand:P 0 "register_operand" "=D")
16073         (plus:P (match_operand:P 3 "register_operand" "0")
16074                 (match_operand:P 4 "register_operand" "1")))
16075    (set (mem:BLK (match_dup 3))
16076         (const_int 0))
16077    (use (match_operand:QI 2 "register_operand" "a"))
16078    (use (match_dup 4))]
16079   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16080   "rep{%;} stosb"
16081   [(set_attr "type" "str")
16082    (set_attr "prefix_rep" "1")
16083    (set_attr "memory" "store")
16084    (set (attr "prefix_rex")
16085         (if_then_else
16086           (match_test "<P:MODE>mode == DImode")
16087           (const_string "0")
16088           (const_string "*")))
16089    (set_attr "mode" "QI")])
16090
16091 (define_expand "cmpstrnsi"
16092   [(set (match_operand:SI 0 "register_operand" "")
16093         (compare:SI (match_operand:BLK 1 "general_operand" "")
16094                     (match_operand:BLK 2 "general_operand" "")))
16095    (use (match_operand 3 "general_operand" ""))
16096    (use (match_operand 4 "immediate_operand" ""))]
16097   ""
16098 {
16099   rtx addr1, addr2, out, outlow, count, countreg, align;
16100
16101   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16102     FAIL;
16103
16104   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16105   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16106     FAIL;
16107
16108   out = operands[0];
16109   if (!REG_P (out))
16110     out = gen_reg_rtx (SImode);
16111
16112   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16113   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16114   if (addr1 != XEXP (operands[1], 0))
16115     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16116   if (addr2 != XEXP (operands[2], 0))
16117     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16118
16119   count = operands[3];
16120   countreg = ix86_zero_extend_to_Pmode (count);
16121
16122   /* %%% Iff we are testing strict equality, we can use known alignment
16123      to good advantage.  This may be possible with combine, particularly
16124      once cc0 is dead.  */
16125   align = operands[4];
16126
16127   if (CONST_INT_P (count))
16128     {
16129       if (INTVAL (count) == 0)
16130         {
16131           emit_move_insn (operands[0], const0_rtx);
16132           DONE;
16133         }
16134       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16135                                      operands[1], operands[2]));
16136     }
16137   else
16138     {
16139       rtx (*gen_cmp) (rtx, rtx);
16140
16141       gen_cmp = (TARGET_64BIT
16142                  ? gen_cmpdi_1 : gen_cmpsi_1);
16143
16144       emit_insn (gen_cmp (countreg, countreg));
16145       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16146                                   operands[1], operands[2]));
16147     }
16148
16149   outlow = gen_lowpart (QImode, out);
16150   emit_insn (gen_cmpintqi (outlow));
16151   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16152
16153   if (operands[0] != out)
16154     emit_move_insn (operands[0], out);
16155
16156   DONE;
16157 })
16158
16159 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16160
16161 (define_expand "cmpintqi"
16162   [(set (match_dup 1)
16163         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16164    (set (match_dup 2)
16165         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16166    (parallel [(set (match_operand:QI 0 "register_operand" "")
16167                    (minus:QI (match_dup 1)
16168                              (match_dup 2)))
16169               (clobber (reg:CC FLAGS_REG))])]
16170   ""
16171 {
16172   operands[1] = gen_reg_rtx (QImode);
16173   operands[2] = gen_reg_rtx (QImode);
16174 })
16175
16176 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16177 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16178
16179 (define_expand "cmpstrnqi_nz_1"
16180   [(parallel [(set (reg:CC FLAGS_REG)
16181                    (compare:CC (match_operand 4 "memory_operand" "")
16182                                (match_operand 5 "memory_operand" "")))
16183               (use (match_operand 2 "register_operand" ""))
16184               (use (match_operand:SI 3 "immediate_operand" ""))
16185               (clobber (match_operand 0 "register_operand" ""))
16186               (clobber (match_operand 1 "register_operand" ""))
16187               (clobber (match_dup 2))])]
16188   ""
16189   "ix86_current_function_needs_cld = 1;")
16190
16191 (define_insn "*cmpstrnqi_nz_1"
16192   [(set (reg:CC FLAGS_REG)
16193         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16194                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16195    (use (match_operand:P 6 "register_operand" "2"))
16196    (use (match_operand:SI 3 "immediate_operand" "i"))
16197    (clobber (match_operand:P 0 "register_operand" "=S"))
16198    (clobber (match_operand:P 1 "register_operand" "=D"))
16199    (clobber (match_operand:P 2 "register_operand" "=c"))]
16200   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16201   "repz{%;} cmpsb"
16202   [(set_attr "type" "str")
16203    (set_attr "mode" "QI")
16204    (set (attr "prefix_rex")
16205         (if_then_else
16206           (match_test "<P:MODE>mode == DImode")
16207           (const_string "0")
16208           (const_string "*")))
16209    (set_attr "prefix_rep" "1")])
16210
16211 ;; The same, but the count is not known to not be zero.
16212
16213 (define_expand "cmpstrnqi_1"
16214   [(parallel [(set (reg:CC FLAGS_REG)
16215                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16216                                      (const_int 0))
16217                   (compare:CC (match_operand 4 "memory_operand" "")
16218                               (match_operand 5 "memory_operand" ""))
16219                   (const_int 0)))
16220               (use (match_operand:SI 3 "immediate_operand" ""))
16221               (use (reg:CC FLAGS_REG))
16222               (clobber (match_operand 0 "register_operand" ""))
16223               (clobber (match_operand 1 "register_operand" ""))
16224               (clobber (match_dup 2))])]
16225   ""
16226   "ix86_current_function_needs_cld = 1;")
16227
16228 (define_insn "*cmpstrnqi_1"
16229   [(set (reg:CC FLAGS_REG)
16230         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16231                              (const_int 0))
16232           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16233                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16234           (const_int 0)))
16235    (use (match_operand:SI 3 "immediate_operand" "i"))
16236    (use (reg:CC FLAGS_REG))
16237    (clobber (match_operand:P 0 "register_operand" "=S"))
16238    (clobber (match_operand:P 1 "register_operand" "=D"))
16239    (clobber (match_operand:P 2 "register_operand" "=c"))]
16240   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16241   "repz{%;} cmpsb"
16242   [(set_attr "type" "str")
16243    (set_attr "mode" "QI")
16244    (set (attr "prefix_rex")
16245         (if_then_else
16246           (match_test "<P:MODE>mode == DImode")
16247           (const_string "0")
16248           (const_string "*")))
16249    (set_attr "prefix_rep" "1")])
16250
16251 (define_expand "strlen<mode>"
16252   [(set (match_operand:P 0 "register_operand" "")
16253         (unspec:P [(match_operand:BLK 1 "general_operand" "")
16254                    (match_operand:QI 2 "immediate_operand" "")
16255                    (match_operand 3 "immediate_operand" "")]
16256                   UNSPEC_SCAS))]
16257   ""
16258 {
16259  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16260    DONE;
16261  else
16262    FAIL;
16263 })
16264
16265 (define_expand "strlenqi_1"
16266   [(parallel [(set (match_operand 0 "register_operand" "")
16267                    (match_operand 2 "" ""))
16268               (clobber (match_operand 1 "register_operand" ""))
16269               (clobber (reg:CC FLAGS_REG))])]
16270   ""
16271   "ix86_current_function_needs_cld = 1;")
16272
16273 (define_insn "*strlenqi_1"
16274   [(set (match_operand:P 0 "register_operand" "=&c")
16275         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16276                    (match_operand:QI 2 "register_operand" "a")
16277                    (match_operand:P 3 "immediate_operand" "i")
16278                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16279    (clobber (match_operand:P 1 "register_operand" "=D"))
16280    (clobber (reg:CC FLAGS_REG))]
16281   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16282   "repnz{%;} scasb"
16283   [(set_attr "type" "str")
16284    (set_attr "mode" "QI")
16285    (set (attr "prefix_rex")
16286         (if_then_else
16287           (match_test "<P:MODE>mode == DImode")
16288           (const_string "0")
16289           (const_string "*")))
16290    (set_attr "prefix_rep" "1")])
16291
16292 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16293 ;; handled in combine, but it is not currently up to the task.
16294 ;; When used for their truth value, the cmpstrn* expanders generate
16295 ;; code like this:
16296 ;;
16297 ;;   repz cmpsb
16298 ;;   seta       %al
16299 ;;   setb       %dl
16300 ;;   cmpb       %al, %dl
16301 ;;   jcc        label
16302 ;;
16303 ;; The intermediate three instructions are unnecessary.
16304
16305 ;; This one handles cmpstrn*_nz_1...
16306 (define_peephole2
16307   [(parallel[
16308      (set (reg:CC FLAGS_REG)
16309           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16310                       (mem:BLK (match_operand 5 "register_operand" ""))))
16311      (use (match_operand 6 "register_operand" ""))
16312      (use (match_operand:SI 3 "immediate_operand" ""))
16313      (clobber (match_operand 0 "register_operand" ""))
16314      (clobber (match_operand 1 "register_operand" ""))
16315      (clobber (match_operand 2 "register_operand" ""))])
16316    (set (match_operand:QI 7 "register_operand" "")
16317         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16318    (set (match_operand:QI 8 "register_operand" "")
16319         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16320    (set (reg FLAGS_REG)
16321         (compare (match_dup 7) (match_dup 8)))
16322   ]
16323   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16324   [(parallel[
16325      (set (reg:CC FLAGS_REG)
16326           (compare:CC (mem:BLK (match_dup 4))
16327                       (mem:BLK (match_dup 5))))
16328      (use (match_dup 6))
16329      (use (match_dup 3))
16330      (clobber (match_dup 0))
16331      (clobber (match_dup 1))
16332      (clobber (match_dup 2))])])
16333
16334 ;; ...and this one handles cmpstrn*_1.
16335 (define_peephole2
16336   [(parallel[
16337      (set (reg:CC FLAGS_REG)
16338           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16339                                (const_int 0))
16340             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16341                         (mem:BLK (match_operand 5 "register_operand" "")))
16342             (const_int 0)))
16343      (use (match_operand:SI 3 "immediate_operand" ""))
16344      (use (reg:CC FLAGS_REG))
16345      (clobber (match_operand 0 "register_operand" ""))
16346      (clobber (match_operand 1 "register_operand" ""))
16347      (clobber (match_operand 2 "register_operand" ""))])
16348    (set (match_operand:QI 7 "register_operand" "")
16349         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16350    (set (match_operand:QI 8 "register_operand" "")
16351         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16352    (set (reg FLAGS_REG)
16353         (compare (match_dup 7) (match_dup 8)))
16354   ]
16355   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16356   [(parallel[
16357      (set (reg:CC FLAGS_REG)
16358           (if_then_else:CC (ne (match_dup 6)
16359                                (const_int 0))
16360             (compare:CC (mem:BLK (match_dup 4))
16361                         (mem:BLK (match_dup 5)))
16362             (const_int 0)))
16363      (use (match_dup 3))
16364      (use (reg:CC FLAGS_REG))
16365      (clobber (match_dup 0))
16366      (clobber (match_dup 1))
16367      (clobber (match_dup 2))])])
16368 \f
16369 ;; Conditional move instructions.
16370
16371 (define_expand "mov<mode>cc"
16372   [(set (match_operand:SWIM 0 "register_operand" "")
16373         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16374                            (match_operand:SWIM 2 "<general_operand>" "")
16375                            (match_operand:SWIM 3 "<general_operand>" "")))]
16376   ""
16377   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16378
16379 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16380 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16381 ;; So just document what we're doing explicitly.
16382
16383 (define_expand "x86_mov<mode>cc_0_m1"
16384   [(parallel
16385     [(set (match_operand:SWI48 0 "register_operand" "")
16386           (if_then_else:SWI48
16387             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16388              [(match_operand 1 "flags_reg_operand" "")
16389               (const_int 0)])
16390             (const_int -1)
16391             (const_int 0)))
16392      (clobber (reg:CC FLAGS_REG))])])
16393
16394 (define_insn "*x86_mov<mode>cc_0_m1"
16395   [(set (match_operand:SWI48 0 "register_operand" "=r")
16396         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16397                              [(reg FLAGS_REG) (const_int 0)])
16398           (const_int -1)
16399           (const_int 0)))
16400    (clobber (reg:CC FLAGS_REG))]
16401   ""
16402   "sbb{<imodesuffix>}\t%0, %0"
16403   ; Since we don't have the proper number of operands for an alu insn,
16404   ; fill in all the blanks.
16405   [(set_attr "type" "alu")
16406    (set_attr "use_carry" "1")
16407    (set_attr "pent_pair" "pu")
16408    (set_attr "memory" "none")
16409    (set_attr "imm_disp" "false")
16410    (set_attr "mode" "<MODE>")
16411    (set_attr "length_immediate" "0")])
16412
16413 (define_insn "*x86_mov<mode>cc_0_m1_se"
16414   [(set (match_operand:SWI48 0 "register_operand" "=r")
16415         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16416                              [(reg FLAGS_REG) (const_int 0)])
16417                             (const_int 1)
16418                             (const_int 0)))
16419    (clobber (reg:CC FLAGS_REG))]
16420   ""
16421   "sbb{<imodesuffix>}\t%0, %0"
16422   [(set_attr "type" "alu")
16423    (set_attr "use_carry" "1")
16424    (set_attr "pent_pair" "pu")
16425    (set_attr "memory" "none")
16426    (set_attr "imm_disp" "false")
16427    (set_attr "mode" "<MODE>")
16428    (set_attr "length_immediate" "0")])
16429
16430 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16431   [(set (match_operand:SWI48 0 "register_operand" "=r")
16432         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16433                     [(reg FLAGS_REG) (const_int 0)])))]
16434   ""
16435   "sbb{<imodesuffix>}\t%0, %0"
16436   [(set_attr "type" "alu")
16437    (set_attr "use_carry" "1")
16438    (set_attr "pent_pair" "pu")
16439    (set_attr "memory" "none")
16440    (set_attr "imm_disp" "false")
16441    (set_attr "mode" "<MODE>")
16442    (set_attr "length_immediate" "0")])
16443
16444 (define_insn "*mov<mode>cc_noc"
16445   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16446         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16447                                [(reg FLAGS_REG) (const_int 0)])
16448           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16449           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16450   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16451   "@
16452    cmov%O2%C1\t{%2, %0|%0, %2}
16453    cmov%O2%c1\t{%3, %0|%0, %3}"
16454   [(set_attr "type" "icmov")
16455    (set_attr "mode" "<MODE>")])
16456
16457 (define_insn_and_split "*movqicc_noc"
16458   [(set (match_operand:QI 0 "register_operand" "=r,r")
16459         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16460                            [(match_operand 4 "flags_reg_operand" "")
16461                             (const_int 0)])
16462                       (match_operand:QI 2 "register_operand" "r,0")
16463                       (match_operand:QI 3 "register_operand" "0,r")))]
16464   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16465   "#"
16466   "&& reload_completed"
16467   [(set (match_dup 0)
16468         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16469                       (match_dup 2)
16470                       (match_dup 3)))]
16471   "operands[0] = gen_lowpart (SImode, operands[0]);
16472    operands[2] = gen_lowpart (SImode, operands[2]);
16473    operands[3] = gen_lowpart (SImode, operands[3]);"
16474   [(set_attr "type" "icmov")
16475    (set_attr "mode" "SI")])
16476
16477 (define_expand "mov<mode>cc"
16478   [(set (match_operand:X87MODEF 0 "register_operand" "")
16479         (if_then_else:X87MODEF
16480           (match_operand 1 "ix86_fp_comparison_operator" "")
16481           (match_operand:X87MODEF 2 "register_operand" "")
16482           (match_operand:X87MODEF 3 "register_operand" "")))]
16483   "(TARGET_80387 && TARGET_CMOVE)
16484    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16485   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16486
16487 (define_insn "*movxfcc_1"
16488   [(set (match_operand:XF 0 "register_operand" "=f,f")
16489         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16490                                 [(reg FLAGS_REG) (const_int 0)])
16491                       (match_operand:XF 2 "register_operand" "f,0")
16492                       (match_operand:XF 3 "register_operand" "0,f")))]
16493   "TARGET_80387 && TARGET_CMOVE"
16494   "@
16495    fcmov%F1\t{%2, %0|%0, %2}
16496    fcmov%f1\t{%3, %0|%0, %3}"
16497   [(set_attr "type" "fcmov")
16498    (set_attr "mode" "XF")])
16499
16500 (define_insn "*movdfcc_1_rex64"
16501   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16502         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16503                                 [(reg FLAGS_REG) (const_int 0)])
16504                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16505                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16506   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16507    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16508   "@
16509    fcmov%F1\t{%2, %0|%0, %2}
16510    fcmov%f1\t{%3, %0|%0, %3}
16511    cmov%O2%C1\t{%2, %0|%0, %2}
16512    cmov%O2%c1\t{%3, %0|%0, %3}"
16513   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16514    (set_attr "mode" "DF,DF,DI,DI")])
16515
16516 (define_insn "*movdfcc_1"
16517   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16518         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16519                                 [(reg FLAGS_REG) (const_int 0)])
16520                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16521                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16522   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16523    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16524   "@
16525    fcmov%F1\t{%2, %0|%0, %2}
16526    fcmov%f1\t{%3, %0|%0, %3}
16527    #
16528    #"
16529   [(set_attr "type" "fcmov,fcmov,multi,multi")
16530    (set_attr "mode" "DF,DF,DI,DI")])
16531
16532 (define_split
16533   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16534         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16535                                 [(match_operand 4 "flags_reg_operand" "")
16536                                  (const_int 0)])
16537                       (match_operand:DF 2 "nonimmediate_operand" "")
16538                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16539   "!TARGET_64BIT && reload_completed"
16540   [(set (match_dup 2)
16541         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16542                       (match_dup 5)
16543                       (match_dup 6)))
16544    (set (match_dup 3)
16545         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16546                       (match_dup 7)
16547                       (match_dup 8)))]
16548 {
16549   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16550   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16551 })
16552
16553 (define_insn "*movsfcc_1_387"
16554   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16555         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16556                                 [(reg FLAGS_REG) (const_int 0)])
16557                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16558                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16559   "TARGET_80387 && TARGET_CMOVE
16560    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16561   "@
16562    fcmov%F1\t{%2, %0|%0, %2}
16563    fcmov%f1\t{%3, %0|%0, %3}
16564    cmov%O2%C1\t{%2, %0|%0, %2}
16565    cmov%O2%c1\t{%3, %0|%0, %3}"
16566   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16567    (set_attr "mode" "SF,SF,SI,SI")])
16568
16569 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16570 ;; the scalar versions to have only XMM registers as operands.
16571
16572 ;; XOP conditional move
16573 (define_insn "*xop_pcmov_<mode>"
16574   [(set (match_operand:MODEF 0 "register_operand" "=x")
16575         (if_then_else:MODEF
16576           (match_operand:MODEF 1 "register_operand" "x")
16577           (match_operand:MODEF 2 "register_operand" "x")
16578           (match_operand:MODEF 3 "register_operand" "x")))]
16579   "TARGET_XOP"
16580   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16581   [(set_attr "type" "sse4arg")])
16582
16583 ;; These versions of the min/max patterns are intentionally ignorant of
16584 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16585 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16586 ;; are undefined in this condition, we're certain this is correct.
16587
16588 (define_insn "<code><mode>3"
16589   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16590         (smaxmin:MODEF
16591           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16592           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16593   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16594   "@
16595    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16596    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16597   [(set_attr "isa" "noavx,avx")
16598    (set_attr "prefix" "orig,vex")
16599    (set_attr "type" "sseadd")
16600    (set_attr "mode" "<MODE>")])
16601
16602 ;; These versions of the min/max patterns implement exactly the operations
16603 ;;   min = (op1 < op2 ? op1 : op2)
16604 ;;   max = (!(op1 < op2) ? op1 : op2)
16605 ;; Their operands are not commutative, and thus they may be used in the
16606 ;; presence of -0.0 and NaN.
16607
16608 (define_insn "*ieee_smin<mode>3"
16609   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16610         (unspec:MODEF
16611           [(match_operand:MODEF 1 "register_operand" "0,x")
16612            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16613          UNSPEC_IEEE_MIN))]
16614   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16615   "@
16616    min<ssemodesuffix>\t{%2, %0|%0, %2}
16617    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16618   [(set_attr "isa" "noavx,avx")
16619    (set_attr "prefix" "orig,vex")
16620    (set_attr "type" "sseadd")
16621    (set_attr "mode" "<MODE>")])
16622
16623 (define_insn "*ieee_smax<mode>3"
16624   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16625         (unspec:MODEF
16626           [(match_operand:MODEF 1 "register_operand" "0,x")
16627            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16628          UNSPEC_IEEE_MAX))]
16629   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16630   "@
16631    max<ssemodesuffix>\t{%2, %0|%0, %2}
16632    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16633   [(set_attr "isa" "noavx,avx")
16634    (set_attr "prefix" "orig,vex")
16635    (set_attr "type" "sseadd")
16636    (set_attr "mode" "<MODE>")])
16637
16638 ;; Make two stack loads independent:
16639 ;;   fld aa              fld aa
16640 ;;   fld %st(0)     ->   fld bb
16641 ;;   fmul bb             fmul %st(1), %st
16642 ;;
16643 ;; Actually we only match the last two instructions for simplicity.
16644 (define_peephole2
16645   [(set (match_operand 0 "fp_register_operand" "")
16646         (match_operand 1 "fp_register_operand" ""))
16647    (set (match_dup 0)
16648         (match_operator 2 "binary_fp_operator"
16649            [(match_dup 0)
16650             (match_operand 3 "memory_operand" "")]))]
16651   "REGNO (operands[0]) != REGNO (operands[1])"
16652   [(set (match_dup 0) (match_dup 3))
16653    (set (match_dup 0) (match_dup 4))]
16654
16655   ;; The % modifier is not operational anymore in peephole2's, so we have to
16656   ;; swap the operands manually in the case of addition and multiplication.
16657 {
16658   rtx op0, op1;
16659
16660   if (COMMUTATIVE_ARITH_P (operands[2]))
16661     op0 = operands[0], op1 = operands[1];
16662   else
16663     op0 = operands[1], op1 = operands[0];
16664
16665   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16666                                 GET_MODE (operands[2]),
16667                                 op0, op1);
16668 })
16669
16670 ;; Conditional addition patterns
16671 (define_expand "add<mode>cc"
16672   [(match_operand:SWI 0 "register_operand" "")
16673    (match_operand 1 "ordered_comparison_operator" "")
16674    (match_operand:SWI 2 "register_operand" "")
16675    (match_operand:SWI 3 "const_int_operand" "")]
16676   ""
16677   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16678 \f
16679 ;; Misc patterns (?)
16680
16681 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16682 ;; Otherwise there will be nothing to keep
16683 ;;
16684 ;; [(set (reg ebp) (reg esp))]
16685 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16686 ;;  (clobber (eflags)]
16687 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16688 ;;
16689 ;; in proper program order.
16690
16691 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16692   [(set (match_operand:P 0 "register_operand" "=r,r")
16693         (plus:P (match_operand:P 1 "register_operand" "0,r")
16694                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16695    (clobber (reg:CC FLAGS_REG))
16696    (clobber (mem:BLK (scratch)))]
16697   ""
16698 {
16699   switch (get_attr_type (insn))
16700     {
16701     case TYPE_IMOV:
16702       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16703
16704     case TYPE_ALU:
16705       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16706       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16707         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16708
16709       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16710
16711     default:
16712       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16713       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16714     }
16715 }
16716   [(set (attr "type")
16717         (cond [(and (eq_attr "alternative" "0")
16718                     (not (match_test "TARGET_OPT_AGU")))
16719                  (const_string "alu")
16720                (match_operand:<MODE> 2 "const0_operand" "")
16721                  (const_string "imov")
16722               ]
16723               (const_string "lea")))
16724    (set (attr "length_immediate")
16725         (cond [(eq_attr "type" "imov")
16726                  (const_string "0")
16727                (and (eq_attr "type" "alu")
16728                     (match_operand 2 "const128_operand" ""))
16729                  (const_string "1")
16730               ]
16731               (const_string "*")))
16732    (set_attr "mode" "<MODE>")])
16733
16734 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16735   [(set (match_operand:P 0 "register_operand" "=r")
16736         (minus:P (match_operand:P 1 "register_operand" "0")
16737                  (match_operand:P 2 "register_operand" "r")))
16738    (clobber (reg:CC FLAGS_REG))
16739    (clobber (mem:BLK (scratch)))]
16740   ""
16741   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16742   [(set_attr "type" "alu")
16743    (set_attr "mode" "<MODE>")])
16744
16745 (define_insn "allocate_stack_worker_probe_<mode>"
16746   [(set (match_operand:P 0 "register_operand" "=a")
16747         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16748                             UNSPECV_STACK_PROBE))
16749    (clobber (reg:CC FLAGS_REG))]
16750   "ix86_target_stack_probe ()"
16751   "call\t___chkstk_ms"
16752   [(set_attr "type" "multi")
16753    (set_attr "length" "5")])
16754
16755 (define_expand "allocate_stack"
16756   [(match_operand 0 "register_operand" "")
16757    (match_operand 1 "general_operand" "")]
16758   "ix86_target_stack_probe ()"
16759 {
16760   rtx x;
16761
16762 #ifndef CHECK_STACK_LIMIT
16763 #define CHECK_STACK_LIMIT 0
16764 #endif
16765
16766   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16767       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16768     {
16769       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16770                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16771       if (x != stack_pointer_rtx)
16772         emit_move_insn (stack_pointer_rtx, x);
16773     }
16774   else
16775     {
16776       x = copy_to_mode_reg (Pmode, operands[1]);
16777       if (TARGET_64BIT)
16778         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16779       else
16780         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16781       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16782                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16783       if (x != stack_pointer_rtx)
16784         emit_move_insn (stack_pointer_rtx, x);
16785     }
16786
16787   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16788   DONE;
16789 })
16790
16791 ;; Use IOR for stack probes, this is shorter.
16792 (define_expand "probe_stack"
16793   [(match_operand 0 "memory_operand" "")]
16794   ""
16795 {
16796   rtx (*gen_ior3) (rtx, rtx, rtx);
16797
16798   gen_ior3 = (GET_MODE (operands[0]) == DImode
16799               ? gen_iordi3 : gen_iorsi3);
16800
16801   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16802   DONE;
16803 })
16804
16805 (define_insn "adjust_stack_and_probe<mode>"
16806   [(set (match_operand:P 0 "register_operand" "=r")
16807         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16808                             UNSPECV_PROBE_STACK_RANGE))
16809    (set (reg:P SP_REG)
16810         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16811    (clobber (reg:CC FLAGS_REG))
16812    (clobber (mem:BLK (scratch)))]
16813   ""
16814   "* return output_adjust_stack_and_probe (operands[0]);"
16815   [(set_attr "type" "multi")])
16816
16817 (define_insn "probe_stack_range<mode>"
16818   [(set (match_operand:P 0 "register_operand" "=r")
16819         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16820                             (match_operand:P 2 "const_int_operand" "n")]
16821                             UNSPECV_PROBE_STACK_RANGE))
16822    (clobber (reg:CC FLAGS_REG))]
16823   ""
16824   "* return output_probe_stack_range (operands[0], operands[2]);"
16825   [(set_attr "type" "multi")])
16826
16827 (define_expand "builtin_setjmp_receiver"
16828   [(label_ref (match_operand 0 "" ""))]
16829   "!TARGET_64BIT && flag_pic"
16830 {
16831 #if TARGET_MACHO
16832   if (TARGET_MACHO)
16833     {
16834       rtx xops[3];
16835       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16836       rtx label_rtx = gen_label_rtx ();
16837       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16838       xops[0] = xops[1] = picreg;
16839       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16840       ix86_expand_binary_operator (MINUS, SImode, xops);
16841     }
16842   else
16843 #endif
16844     emit_insn (gen_set_got (pic_offset_table_rtx));
16845   DONE;
16846 })
16847 \f
16848 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16849
16850 (define_split
16851   [(set (match_operand 0 "register_operand" "")
16852         (match_operator 3 "promotable_binary_operator"
16853            [(match_operand 1 "register_operand" "")
16854             (match_operand 2 "aligned_operand" "")]))
16855    (clobber (reg:CC FLAGS_REG))]
16856   "! TARGET_PARTIAL_REG_STALL && reload_completed
16857    && ((GET_MODE (operands[0]) == HImode
16858         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16859             /* ??? next two lines just !satisfies_constraint_K (...) */
16860             || !CONST_INT_P (operands[2])
16861             || satisfies_constraint_K (operands[2])))
16862        || (GET_MODE (operands[0]) == QImode
16863            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16864   [(parallel [(set (match_dup 0)
16865                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16866               (clobber (reg:CC FLAGS_REG))])]
16867 {
16868   operands[0] = gen_lowpart (SImode, operands[0]);
16869   operands[1] = gen_lowpart (SImode, operands[1]);
16870   if (GET_CODE (operands[3]) != ASHIFT)
16871     operands[2] = gen_lowpart (SImode, operands[2]);
16872   PUT_MODE (operands[3], SImode);
16873 })
16874
16875 ; Promote the QImode tests, as i386 has encoding of the AND
16876 ; instruction with 32-bit sign-extended immediate and thus the
16877 ; instruction size is unchanged, except in the %eax case for
16878 ; which it is increased by one byte, hence the ! optimize_size.
16879 (define_split
16880   [(set (match_operand 0 "flags_reg_operand" "")
16881         (match_operator 2 "compare_operator"
16882           [(and (match_operand 3 "aligned_operand" "")
16883                 (match_operand 4 "const_int_operand" ""))
16884            (const_int 0)]))
16885    (set (match_operand 1 "register_operand" "")
16886         (and (match_dup 3) (match_dup 4)))]
16887   "! TARGET_PARTIAL_REG_STALL && reload_completed
16888    && optimize_insn_for_speed_p ()
16889    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16890        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16891    /* Ensure that the operand will remain sign-extended immediate.  */
16892    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16893   [(parallel [(set (match_dup 0)
16894                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16895                                     (const_int 0)]))
16896               (set (match_dup 1)
16897                    (and:SI (match_dup 3) (match_dup 4)))])]
16898 {
16899   operands[4]
16900     = gen_int_mode (INTVAL (operands[4])
16901                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16902   operands[1] = gen_lowpart (SImode, operands[1]);
16903   operands[3] = gen_lowpart (SImode, operands[3]);
16904 })
16905
16906 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16907 ; the TEST instruction with 32-bit sign-extended immediate and thus
16908 ; the instruction size would at least double, which is not what we
16909 ; want even with ! optimize_size.
16910 (define_split
16911   [(set (match_operand 0 "flags_reg_operand" "")
16912         (match_operator 1 "compare_operator"
16913           [(and (match_operand:HI 2 "aligned_operand" "")
16914                 (match_operand:HI 3 "const_int_operand" ""))
16915            (const_int 0)]))]
16916   "! TARGET_PARTIAL_REG_STALL && reload_completed
16917    && ! TARGET_FAST_PREFIX
16918    && optimize_insn_for_speed_p ()
16919    /* Ensure that the operand will remain sign-extended immediate.  */
16920    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16921   [(set (match_dup 0)
16922         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16923                          (const_int 0)]))]
16924 {
16925   operands[3]
16926     = gen_int_mode (INTVAL (operands[3])
16927                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16928   operands[2] = gen_lowpart (SImode, operands[2]);
16929 })
16930
16931 (define_split
16932   [(set (match_operand 0 "register_operand" "")
16933         (neg (match_operand 1 "register_operand" "")))
16934    (clobber (reg:CC FLAGS_REG))]
16935   "! TARGET_PARTIAL_REG_STALL && reload_completed
16936    && (GET_MODE (operands[0]) == HImode
16937        || (GET_MODE (operands[0]) == QImode
16938            && (TARGET_PROMOTE_QImode
16939                || optimize_insn_for_size_p ())))"
16940   [(parallel [(set (match_dup 0)
16941                    (neg:SI (match_dup 1)))
16942               (clobber (reg:CC FLAGS_REG))])]
16943 {
16944   operands[0] = gen_lowpart (SImode, operands[0]);
16945   operands[1] = gen_lowpart (SImode, operands[1]);
16946 })
16947
16948 (define_split
16949   [(set (match_operand 0 "register_operand" "")
16950         (not (match_operand 1 "register_operand" "")))]
16951   "! TARGET_PARTIAL_REG_STALL && reload_completed
16952    && (GET_MODE (operands[0]) == HImode
16953        || (GET_MODE (operands[0]) == QImode
16954            && (TARGET_PROMOTE_QImode
16955                || optimize_insn_for_size_p ())))"
16956   [(set (match_dup 0)
16957         (not:SI (match_dup 1)))]
16958 {
16959   operands[0] = gen_lowpart (SImode, operands[0]);
16960   operands[1] = gen_lowpart (SImode, operands[1]);
16961 })
16962
16963 (define_split
16964   [(set (match_operand 0 "register_operand" "")
16965         (if_then_else (match_operator 1 "ordered_comparison_operator"
16966                                 [(reg FLAGS_REG) (const_int 0)])
16967                       (match_operand 2 "register_operand" "")
16968                       (match_operand 3 "register_operand" "")))]
16969   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16970    && (GET_MODE (operands[0]) == HImode
16971        || (GET_MODE (operands[0]) == QImode
16972            && (TARGET_PROMOTE_QImode
16973                || optimize_insn_for_size_p ())))"
16974   [(set (match_dup 0)
16975         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16976 {
16977   operands[0] = gen_lowpart (SImode, operands[0]);
16978   operands[2] = gen_lowpart (SImode, operands[2]);
16979   operands[3] = gen_lowpart (SImode, operands[3]);
16980 })
16981 \f
16982 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16983 ;; transform a complex memory operation into two memory to register operations.
16984
16985 ;; Don't push memory operands
16986 (define_peephole2
16987   [(set (match_operand:SWI 0 "push_operand" "")
16988         (match_operand:SWI 1 "memory_operand" ""))
16989    (match_scratch:SWI 2 "<r>")]
16990   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16991    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16992   [(set (match_dup 2) (match_dup 1))
16993    (set (match_dup 0) (match_dup 2))])
16994
16995 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16996 ;; SImode pushes.
16997 (define_peephole2
16998   [(set (match_operand:SF 0 "push_operand" "")
16999         (match_operand:SF 1 "memory_operand" ""))
17000    (match_scratch:SF 2 "r")]
17001   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17002    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17003   [(set (match_dup 2) (match_dup 1))
17004    (set (match_dup 0) (match_dup 2))])
17005
17006 ;; Don't move an immediate directly to memory when the instruction
17007 ;; gets too big.
17008 (define_peephole2
17009   [(match_scratch:SWI124 1 "<r>")
17010    (set (match_operand:SWI124 0 "memory_operand" "")
17011         (const_int 0))]
17012   "optimize_insn_for_speed_p ()
17013    && !TARGET_USE_MOV0
17014    && TARGET_SPLIT_LONG_MOVES
17015    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17016    && peep2_regno_dead_p (0, FLAGS_REG)"
17017   [(parallel [(set (match_dup 2) (const_int 0))
17018               (clobber (reg:CC FLAGS_REG))])
17019    (set (match_dup 0) (match_dup 1))]
17020   "operands[2] = gen_lowpart (SImode, operands[1]);")
17021
17022 (define_peephole2
17023   [(match_scratch:SWI124 2 "<r>")
17024    (set (match_operand:SWI124 0 "memory_operand" "")
17025         (match_operand:SWI124 1 "immediate_operand" ""))]
17026   "optimize_insn_for_speed_p ()
17027    && TARGET_SPLIT_LONG_MOVES
17028    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17029   [(set (match_dup 2) (match_dup 1))
17030    (set (match_dup 0) (match_dup 2))])
17031
17032 ;; Don't compare memory with zero, load and use a test instead.
17033 (define_peephole2
17034   [(set (match_operand 0 "flags_reg_operand" "")
17035         (match_operator 1 "compare_operator"
17036           [(match_operand:SI 2 "memory_operand" "")
17037            (const_int 0)]))
17038    (match_scratch:SI 3 "r")]
17039   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17040   [(set (match_dup 3) (match_dup 2))
17041    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17042
17043 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17044 ;; Don't split NOTs with a displacement operand, because resulting XOR
17045 ;; will not be pairable anyway.
17046 ;;
17047 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17048 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17049 ;; so this split helps here as well.
17050 ;;
17051 ;; Note: Can't do this as a regular split because we can't get proper
17052 ;; lifetime information then.
17053
17054 (define_peephole2
17055   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17056         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17057   "optimize_insn_for_speed_p ()
17058    && ((TARGET_NOT_UNPAIRABLE
17059         && (!MEM_P (operands[0])
17060             || !memory_displacement_operand (operands[0], <MODE>mode)))
17061        || (TARGET_NOT_VECTORMODE
17062            && long_memory_operand (operands[0], <MODE>mode)))
17063    && peep2_regno_dead_p (0, FLAGS_REG)"
17064   [(parallel [(set (match_dup 0)
17065                    (xor:SWI124 (match_dup 1) (const_int -1)))
17066               (clobber (reg:CC FLAGS_REG))])])
17067
17068 ;; Non pairable "test imm, reg" instructions can be translated to
17069 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17070 ;; byte opcode instead of two, have a short form for byte operands),
17071 ;; so do it for other CPUs as well.  Given that the value was dead,
17072 ;; this should not create any new dependencies.  Pass on the sub-word
17073 ;; versions if we're concerned about partial register stalls.
17074
17075 (define_peephole2
17076   [(set (match_operand 0 "flags_reg_operand" "")
17077         (match_operator 1 "compare_operator"
17078           [(and:SI (match_operand:SI 2 "register_operand" "")
17079                    (match_operand:SI 3 "immediate_operand" ""))
17080            (const_int 0)]))]
17081   "ix86_match_ccmode (insn, CCNOmode)
17082    && (true_regnum (operands[2]) != AX_REG
17083        || satisfies_constraint_K (operands[3]))
17084    && peep2_reg_dead_p (1, operands[2])"
17085   [(parallel
17086      [(set (match_dup 0)
17087            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17088                             (const_int 0)]))
17089       (set (match_dup 2)
17090            (and:SI (match_dup 2) (match_dup 3)))])])
17091
17092 ;; We don't need to handle HImode case, because it will be promoted to SImode
17093 ;; on ! TARGET_PARTIAL_REG_STALL
17094
17095 (define_peephole2
17096   [(set (match_operand 0 "flags_reg_operand" "")
17097         (match_operator 1 "compare_operator"
17098           [(and:QI (match_operand:QI 2 "register_operand" "")
17099                    (match_operand:QI 3 "immediate_operand" ""))
17100            (const_int 0)]))]
17101   "! TARGET_PARTIAL_REG_STALL
17102    && ix86_match_ccmode (insn, CCNOmode)
17103    && true_regnum (operands[2]) != AX_REG
17104    && peep2_reg_dead_p (1, operands[2])"
17105   [(parallel
17106      [(set (match_dup 0)
17107            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17108                             (const_int 0)]))
17109       (set (match_dup 2)
17110            (and:QI (match_dup 2) (match_dup 3)))])])
17111
17112 (define_peephole2
17113   [(set (match_operand 0 "flags_reg_operand" "")
17114         (match_operator 1 "compare_operator"
17115           [(and:SI
17116              (zero_extract:SI
17117                (match_operand 2 "ext_register_operand" "")
17118                (const_int 8)
17119                (const_int 8))
17120              (match_operand 3 "const_int_operand" ""))
17121            (const_int 0)]))]
17122   "! TARGET_PARTIAL_REG_STALL
17123    && ix86_match_ccmode (insn, CCNOmode)
17124    && true_regnum (operands[2]) != AX_REG
17125    && peep2_reg_dead_p (1, operands[2])"
17126   [(parallel [(set (match_dup 0)
17127                    (match_op_dup 1
17128                      [(and:SI
17129                         (zero_extract:SI
17130                           (match_dup 2)
17131                           (const_int 8)
17132                           (const_int 8))
17133                         (match_dup 3))
17134                       (const_int 0)]))
17135               (set (zero_extract:SI (match_dup 2)
17136                                     (const_int 8)
17137                                     (const_int 8))
17138                    (and:SI
17139                      (zero_extract:SI
17140                        (match_dup 2)
17141                        (const_int 8)
17142                        (const_int 8))
17143                      (match_dup 3)))])])
17144
17145 ;; Don't do logical operations with memory inputs.
17146 (define_peephole2
17147   [(match_scratch:SI 2 "r")
17148    (parallel [(set (match_operand:SI 0 "register_operand" "")
17149                    (match_operator:SI 3 "arith_or_logical_operator"
17150                      [(match_dup 0)
17151                       (match_operand:SI 1 "memory_operand" "")]))
17152               (clobber (reg:CC FLAGS_REG))])]
17153   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17154   [(set (match_dup 2) (match_dup 1))
17155    (parallel [(set (match_dup 0)
17156                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17157               (clobber (reg:CC FLAGS_REG))])])
17158
17159 (define_peephole2
17160   [(match_scratch:SI 2 "r")
17161    (parallel [(set (match_operand:SI 0 "register_operand" "")
17162                    (match_operator:SI 3 "arith_or_logical_operator"
17163                      [(match_operand:SI 1 "memory_operand" "")
17164                       (match_dup 0)]))
17165               (clobber (reg:CC FLAGS_REG))])]
17166   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17167   [(set (match_dup 2) (match_dup 1))
17168    (parallel [(set (match_dup 0)
17169                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17170               (clobber (reg:CC FLAGS_REG))])])
17171
17172 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17173 ;; refers to the destination of the load!
17174
17175 (define_peephole2
17176   [(set (match_operand:SI 0 "register_operand" "")
17177         (match_operand:SI 1 "register_operand" ""))
17178    (parallel [(set (match_dup 0)
17179                    (match_operator:SI 3 "commutative_operator"
17180                      [(match_dup 0)
17181                       (match_operand:SI 2 "memory_operand" "")]))
17182               (clobber (reg:CC FLAGS_REG))])]
17183   "REGNO (operands[0]) != REGNO (operands[1])
17184    && GENERAL_REGNO_P (REGNO (operands[0]))
17185    && GENERAL_REGNO_P (REGNO (operands[1]))"
17186   [(set (match_dup 0) (match_dup 4))
17187    (parallel [(set (match_dup 0)
17188                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17189               (clobber (reg:CC FLAGS_REG))])]
17190   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17191
17192 (define_peephole2
17193   [(set (match_operand 0 "register_operand" "")
17194         (match_operand 1 "register_operand" ""))
17195    (set (match_dup 0)
17196                    (match_operator 3 "commutative_operator"
17197                      [(match_dup 0)
17198                       (match_operand 2 "memory_operand" "")]))]
17199   "REGNO (operands[0]) != REGNO (operands[1])
17200    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17201        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17202   [(set (match_dup 0) (match_dup 2))
17203    (set (match_dup 0)
17204         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17205
17206 ; Don't do logical operations with memory outputs
17207 ;
17208 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17209 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17210 ; the same decoder scheduling characteristics as the original.
17211
17212 (define_peephole2
17213   [(match_scratch:SI 2 "r")
17214    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17215                    (match_operator:SI 3 "arith_or_logical_operator"
17216                      [(match_dup 0)
17217                       (match_operand:SI 1 "nonmemory_operand" "")]))
17218               (clobber (reg:CC FLAGS_REG))])]
17219   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17220    /* Do not split stack checking probes.  */
17221    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17222   [(set (match_dup 2) (match_dup 0))
17223    (parallel [(set (match_dup 2)
17224                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17225               (clobber (reg:CC FLAGS_REG))])
17226    (set (match_dup 0) (match_dup 2))])
17227
17228 (define_peephole2
17229   [(match_scratch:SI 2 "r")
17230    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17231                    (match_operator:SI 3 "arith_or_logical_operator"
17232                      [(match_operand:SI 1 "nonmemory_operand" "")
17233                       (match_dup 0)]))
17234               (clobber (reg:CC FLAGS_REG))])]
17235   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17236    /* Do not split stack checking probes.  */
17237    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17238   [(set (match_dup 2) (match_dup 0))
17239    (parallel [(set (match_dup 2)
17240                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17241               (clobber (reg:CC FLAGS_REG))])
17242    (set (match_dup 0) (match_dup 2))])
17243
17244 ;; Attempt to use arith or logical operations with memory outputs with
17245 ;; setting of flags.
17246 (define_peephole2
17247   [(set (match_operand:SWI 0 "register_operand" "")
17248         (match_operand:SWI 1 "memory_operand" ""))
17249    (parallel [(set (match_dup 0)
17250                    (match_operator:SWI 3 "plusminuslogic_operator"
17251                      [(match_dup 0)
17252                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17253               (clobber (reg:CC FLAGS_REG))])
17254    (set (match_dup 1) (match_dup 0))
17255    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17256   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17257    && peep2_reg_dead_p (4, operands[0])
17258    && !reg_overlap_mentioned_p (operands[0], operands[1])
17259    && ix86_match_ccmode (peep2_next_insn (3),
17260                          (GET_CODE (operands[3]) == PLUS
17261                           || GET_CODE (operands[3]) == MINUS)
17262                          ? CCGOCmode : CCNOmode)"
17263   [(parallel [(set (match_dup 4) (match_dup 5))
17264               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17265                                                   (match_dup 2)]))])]
17266 {
17267   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17268   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17269                                 copy_rtx (operands[1]),
17270                                 copy_rtx (operands[2]));
17271   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17272                                  operands[5], const0_rtx);
17273 })
17274
17275 (define_peephole2
17276   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17277                    (match_operator:SWI 2 "plusminuslogic_operator"
17278                      [(match_dup 0)
17279                       (match_operand:SWI 1 "memory_operand" "")]))
17280               (clobber (reg:CC FLAGS_REG))])
17281    (set (match_dup 1) (match_dup 0))
17282    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17283   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17284    && GET_CODE (operands[2]) != MINUS
17285    && peep2_reg_dead_p (3, operands[0])
17286    && !reg_overlap_mentioned_p (operands[0], operands[1])
17287    && ix86_match_ccmode (peep2_next_insn (2),
17288                          GET_CODE (operands[2]) == PLUS
17289                          ? CCGOCmode : CCNOmode)"
17290   [(parallel [(set (match_dup 3) (match_dup 4))
17291               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17292                                                   (match_dup 0)]))])]
17293 {
17294   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17295   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17296                                 copy_rtx (operands[1]),
17297                                 copy_rtx (operands[0]));
17298   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17299                                  operands[4], const0_rtx);
17300 })
17301
17302 (define_peephole2
17303   [(set (match_operand:SWI12 0 "register_operand" "")
17304         (match_operand:SWI12 1 "memory_operand" ""))
17305    (parallel [(set (match_operand:SI 4 "register_operand" "")
17306                    (match_operator:SI 3 "plusminuslogic_operator"
17307                      [(match_dup 4)
17308                       (match_operand:SI 2 "nonmemory_operand" "")]))
17309               (clobber (reg:CC FLAGS_REG))])
17310    (set (match_dup 1) (match_dup 0))
17311    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17312   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17313    && REG_P (operands[0]) && REG_P (operands[4])
17314    && REGNO (operands[0]) == REGNO (operands[4])
17315    && peep2_reg_dead_p (4, operands[0])
17316    && !reg_overlap_mentioned_p (operands[0], operands[1])
17317    && ix86_match_ccmode (peep2_next_insn (3),
17318                          (GET_CODE (operands[3]) == PLUS
17319                           || GET_CODE (operands[3]) == MINUS)
17320                          ? CCGOCmode : CCNOmode)"
17321   [(parallel [(set (match_dup 4) (match_dup 5))
17322               (set (match_dup 1) (match_dup 6))])]
17323 {
17324   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17325   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17326   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17327                                 copy_rtx (operands[1]), operands[2]);
17328   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17329                                  operands[5], const0_rtx);
17330   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17331                                 copy_rtx (operands[1]),
17332                                 copy_rtx (operands[2]));
17333 })
17334
17335 ;; Attempt to always use XOR for zeroing registers.
17336 (define_peephole2
17337   [(set (match_operand 0 "register_operand" "")
17338         (match_operand 1 "const0_operand" ""))]
17339   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17340    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17341    && GENERAL_REG_P (operands[0])
17342    && peep2_regno_dead_p (0, FLAGS_REG)"
17343   [(parallel [(set (match_dup 0) (const_int 0))
17344               (clobber (reg:CC FLAGS_REG))])]
17345   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17346
17347 (define_peephole2
17348   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17349         (const_int 0))]
17350   "(GET_MODE (operands[0]) == QImode
17351     || GET_MODE (operands[0]) == HImode)
17352    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17353    && peep2_regno_dead_p (0, FLAGS_REG)"
17354   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17355               (clobber (reg:CC FLAGS_REG))])])
17356
17357 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17358 (define_peephole2
17359   [(set (match_operand:SWI248 0 "register_operand" "")
17360         (const_int -1))]
17361   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17362    && peep2_regno_dead_p (0, FLAGS_REG)"
17363   [(parallel [(set (match_dup 0) (const_int -1))
17364               (clobber (reg:CC FLAGS_REG))])]
17365 {
17366   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17367     operands[0] = gen_lowpart (SImode, operands[0]);
17368 })
17369
17370 ;; Attempt to convert simple lea to add/shift.
17371 ;; These can be created by move expanders.
17372
17373 (define_peephole2
17374   [(set (match_operand:SWI48 0 "register_operand" "")
17375         (plus:SWI48 (match_dup 0)
17376                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17377   "peep2_regno_dead_p (0, FLAGS_REG)"
17378   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17379               (clobber (reg:CC FLAGS_REG))])])
17380
17381 (define_peephole2
17382   [(set (match_operand:SI 0 "register_operand" "")
17383         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17384                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17385   "TARGET_64BIT
17386    && peep2_regno_dead_p (0, FLAGS_REG)
17387    && REGNO (operands[0]) == REGNO (operands[1])"
17388   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17389               (clobber (reg:CC FLAGS_REG))])]
17390   "operands[2] = gen_lowpart (SImode, operands[2]);")
17391
17392 (define_peephole2
17393   [(set (match_operand:SWI48 0 "register_operand" "")
17394         (mult:SWI48 (match_dup 0)
17395                     (match_operand:SWI48 1 "const_int_operand" "")))]
17396   "exact_log2 (INTVAL (operands[1])) >= 0
17397    && peep2_regno_dead_p (0, FLAGS_REG)"
17398   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17399               (clobber (reg:CC FLAGS_REG))])]
17400   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17401
17402 (define_peephole2
17403   [(set (match_operand:SI 0 "register_operand" "")
17404         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17405                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17406   "TARGET_64BIT
17407    && exact_log2 (INTVAL (operands[2])) >= 0
17408    && REGNO (operands[0]) == REGNO (operands[1])
17409    && peep2_regno_dead_p (0, FLAGS_REG)"
17410   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17411               (clobber (reg:CC FLAGS_REG))])]
17412   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17413
17414 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17415 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17416 ;; On many CPUs it is also faster, since special hardware to avoid esp
17417 ;; dependencies is present.
17418
17419 ;; While some of these conversions may be done using splitters, we use
17420 ;; peepholes in order to allow combine_stack_adjustments pass to see
17421 ;; nonobfuscated RTL.
17422
17423 ;; Convert prologue esp subtractions to push.
17424 ;; We need register to push.  In order to keep verify_flow_info happy we have
17425 ;; two choices
17426 ;; - use scratch and clobber it in order to avoid dependencies
17427 ;; - use already live register
17428 ;; We can't use the second way right now, since there is no reliable way how to
17429 ;; verify that given register is live.  First choice will also most likely in
17430 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17431 ;; call clobbered registers are dead.  We may want to use base pointer as an
17432 ;; alternative when no register is available later.
17433
17434 (define_peephole2
17435   [(match_scratch:P 1 "r")
17436    (parallel [(set (reg:P SP_REG)
17437                    (plus:P (reg:P SP_REG)
17438                            (match_operand:P 0 "const_int_operand" "")))
17439               (clobber (reg:CC FLAGS_REG))
17440               (clobber (mem:BLK (scratch)))])]
17441   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17442    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17443   [(clobber (match_dup 1))
17444    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17445               (clobber (mem:BLK (scratch)))])])
17446
17447 (define_peephole2
17448   [(match_scratch:P 1 "r")
17449    (parallel [(set (reg:P SP_REG)
17450                    (plus:P (reg:P SP_REG)
17451                            (match_operand:P 0 "const_int_operand" "")))
17452               (clobber (reg:CC FLAGS_REG))
17453               (clobber (mem:BLK (scratch)))])]
17454   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17455    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17456   [(clobber (match_dup 1))
17457    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17458    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17459               (clobber (mem:BLK (scratch)))])])
17460
17461 ;; Convert esp subtractions to push.
17462 (define_peephole2
17463   [(match_scratch:P 1 "r")
17464    (parallel [(set (reg:P SP_REG)
17465                    (plus:P (reg:P SP_REG)
17466                            (match_operand:P 0 "const_int_operand" "")))
17467               (clobber (reg:CC FLAGS_REG))])]
17468   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17469    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17470   [(clobber (match_dup 1))
17471    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17472
17473 (define_peephole2
17474   [(match_scratch:P 1 "r")
17475    (parallel [(set (reg:P SP_REG)
17476                    (plus:P (reg:P SP_REG)
17477                            (match_operand:P 0 "const_int_operand" "")))
17478               (clobber (reg:CC FLAGS_REG))])]
17479   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17480    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17481   [(clobber (match_dup 1))
17482    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17483    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17484
17485 ;; Convert epilogue deallocator to pop.
17486 (define_peephole2
17487   [(match_scratch:P 1 "r")
17488    (parallel [(set (reg:P SP_REG)
17489                    (plus:P (reg:P SP_REG)
17490                            (match_operand:P 0 "const_int_operand" "")))
17491               (clobber (reg:CC FLAGS_REG))
17492               (clobber (mem:BLK (scratch)))])]
17493   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17494    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17495   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17496               (clobber (mem:BLK (scratch)))])])
17497
17498 ;; Two pops case is tricky, since pop causes dependency
17499 ;; on destination register.  We use two registers if available.
17500 (define_peephole2
17501   [(match_scratch:P 1 "r")
17502    (match_scratch:P 2 "r")
17503    (parallel [(set (reg:P SP_REG)
17504                    (plus:P (reg:P SP_REG)
17505                            (match_operand:P 0 "const_int_operand" "")))
17506               (clobber (reg:CC FLAGS_REG))
17507               (clobber (mem:BLK (scratch)))])]
17508   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17509    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17510   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17511               (clobber (mem:BLK (scratch)))])
17512    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17513
17514 (define_peephole2
17515   [(match_scratch:P 1 "r")
17516    (parallel [(set (reg:P SP_REG)
17517                    (plus:P (reg:P SP_REG)
17518                            (match_operand:P 0 "const_int_operand" "")))
17519               (clobber (reg:CC FLAGS_REG))
17520               (clobber (mem:BLK (scratch)))])]
17521   "optimize_insn_for_size_p ()
17522    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17523   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17524               (clobber (mem:BLK (scratch)))])
17525    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17526
17527 ;; Convert esp additions to pop.
17528 (define_peephole2
17529   [(match_scratch:P 1 "r")
17530    (parallel [(set (reg:P SP_REG)
17531                    (plus:P (reg:P SP_REG)
17532                            (match_operand:P 0 "const_int_operand" "")))
17533               (clobber (reg:CC FLAGS_REG))])]
17534   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17535   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17536
17537 ;; Two pops case is tricky, since pop causes dependency
17538 ;; on destination register.  We use two registers if available.
17539 (define_peephole2
17540   [(match_scratch:P 1 "r")
17541    (match_scratch:P 2 "r")
17542    (parallel [(set (reg:P SP_REG)
17543                    (plus:P (reg:P SP_REG)
17544                            (match_operand:P 0 "const_int_operand" "")))
17545               (clobber (reg:CC FLAGS_REG))])]
17546   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17547   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17548    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17549
17550 (define_peephole2
17551   [(match_scratch:P 1 "r")
17552    (parallel [(set (reg:P SP_REG)
17553                    (plus:P (reg:P SP_REG)
17554                            (match_operand:P 0 "const_int_operand" "")))
17555               (clobber (reg:CC FLAGS_REG))])]
17556   "optimize_insn_for_size_p ()
17557    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17558   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17559    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17560 \f
17561 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17562 ;; required and register dies.  Similarly for 128 to -128.
17563 (define_peephole2
17564   [(set (match_operand 0 "flags_reg_operand" "")
17565         (match_operator 1 "compare_operator"
17566           [(match_operand 2 "register_operand" "")
17567            (match_operand 3 "const_int_operand" "")]))]
17568   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17569      && incdec_operand (operands[3], GET_MODE (operands[3])))
17570     || (!TARGET_FUSE_CMP_AND_BRANCH
17571         && INTVAL (operands[3]) == 128))
17572    && ix86_match_ccmode (insn, CCGCmode)
17573    && peep2_reg_dead_p (1, operands[2])"
17574   [(parallel [(set (match_dup 0)
17575                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17576               (clobber (match_dup 2))])])
17577 \f
17578 ;; Convert imul by three, five and nine into lea
17579 (define_peephole2
17580   [(parallel
17581     [(set (match_operand:SWI48 0 "register_operand" "")
17582           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17583                       (match_operand:SWI48 2 "const359_operand" "")))
17584      (clobber (reg:CC FLAGS_REG))])]
17585   "!TARGET_PARTIAL_REG_STALL
17586    || <MODE>mode == SImode
17587    || optimize_function_for_size_p (cfun)"
17588   [(set (match_dup 0)
17589         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17590                     (match_dup 1)))]
17591   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17592
17593 (define_peephole2
17594   [(parallel
17595     [(set (match_operand:SWI48 0 "register_operand" "")
17596           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17597                       (match_operand:SWI48 2 "const359_operand" "")))
17598      (clobber (reg:CC FLAGS_REG))])]
17599   "optimize_insn_for_speed_p ()
17600    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17601   [(set (match_dup 0) (match_dup 1))
17602    (set (match_dup 0)
17603         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17604                     (match_dup 0)))]
17605   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17606
17607 ;; imul $32bit_imm, mem, reg is vector decoded, while
17608 ;; imul $32bit_imm, reg, reg is direct decoded.
17609 (define_peephole2
17610   [(match_scratch:SWI48 3 "r")
17611    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17612                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17613                                (match_operand:SWI48 2 "immediate_operand" "")))
17614               (clobber (reg:CC FLAGS_REG))])]
17615   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17616    && !satisfies_constraint_K (operands[2])"
17617   [(set (match_dup 3) (match_dup 1))
17618    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17619               (clobber (reg:CC FLAGS_REG))])])
17620
17621 (define_peephole2
17622   [(match_scratch:SI 3 "r")
17623    (parallel [(set (match_operand:DI 0 "register_operand" "")
17624                    (zero_extend:DI
17625                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17626                               (match_operand:SI 2 "immediate_operand" ""))))
17627               (clobber (reg:CC FLAGS_REG))])]
17628   "TARGET_64BIT
17629    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17630    && !satisfies_constraint_K (operands[2])"
17631   [(set (match_dup 3) (match_dup 1))
17632    (parallel [(set (match_dup 0)
17633                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17634               (clobber (reg:CC FLAGS_REG))])])
17635
17636 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17637 ;; Convert it into imul reg, reg
17638 ;; It would be better to force assembler to encode instruction using long
17639 ;; immediate, but there is apparently no way to do so.
17640 (define_peephole2
17641   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17642                    (mult:SWI248
17643                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17644                     (match_operand:SWI248 2 "const_int_operand" "")))
17645               (clobber (reg:CC FLAGS_REG))])
17646    (match_scratch:SWI248 3 "r")]
17647   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17648    && satisfies_constraint_K (operands[2])"
17649   [(set (match_dup 3) (match_dup 2))
17650    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17651               (clobber (reg:CC FLAGS_REG))])]
17652 {
17653   if (!rtx_equal_p (operands[0], operands[1]))
17654     emit_move_insn (operands[0], operands[1]);
17655 })
17656
17657 ;; After splitting up read-modify operations, array accesses with memory
17658 ;; operands might end up in form:
17659 ;;  sall    $2, %eax
17660 ;;  movl    4(%esp), %edx
17661 ;;  addl    %edx, %eax
17662 ;; instead of pre-splitting:
17663 ;;  sall    $2, %eax
17664 ;;  addl    4(%esp), %eax
17665 ;; Turn it into:
17666 ;;  movl    4(%esp), %edx
17667 ;;  leal    (%edx,%eax,4), %eax
17668
17669 (define_peephole2
17670   [(match_scratch:P 5 "r")
17671    (parallel [(set (match_operand 0 "register_operand" "")
17672                    (ashift (match_operand 1 "register_operand" "")
17673                            (match_operand 2 "const_int_operand" "")))
17674                (clobber (reg:CC FLAGS_REG))])
17675    (parallel [(set (match_operand 3 "register_operand" "")
17676                    (plus (match_dup 0)
17677                          (match_operand 4 "x86_64_general_operand" "")))
17678                    (clobber (reg:CC FLAGS_REG))])]
17679   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17680    /* Validate MODE for lea.  */
17681    && ((!TARGET_PARTIAL_REG_STALL
17682         && (GET_MODE (operands[0]) == QImode
17683             || GET_MODE (operands[0]) == HImode))
17684        || GET_MODE (operands[0]) == SImode
17685        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17686    && (rtx_equal_p (operands[0], operands[3])
17687        || peep2_reg_dead_p (2, operands[0]))
17688    /* We reorder load and the shift.  */
17689    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17690   [(set (match_dup 5) (match_dup 4))
17691    (set (match_dup 0) (match_dup 1))]
17692 {
17693   enum machine_mode op1mode = GET_MODE (operands[1]);
17694   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17695   int scale = 1 << INTVAL (operands[2]);
17696   rtx index = gen_lowpart (Pmode, operands[1]);
17697   rtx base = gen_lowpart (Pmode, operands[5]);
17698   rtx dest = gen_lowpart (mode, operands[3]);
17699
17700   operands[1] = gen_rtx_PLUS (Pmode, base,
17701                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17702   operands[5] = base;
17703   if (mode != Pmode)
17704     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17705   if (op1mode != Pmode)
17706     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17707   operands[0] = dest;
17708 })
17709 \f
17710 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17711 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17712 ;; caught for use by garbage collectors and the like.  Using an insn that
17713 ;; maps to SIGILL makes it more likely the program will rightfully die.
17714 ;; Keeping with tradition, "6" is in honor of #UD.
17715 (define_insn "trap"
17716   [(trap_if (const_int 1) (const_int 6))]
17717   ""
17718   { return ASM_SHORT "0x0b0f"; }
17719   [(set_attr "length" "2")])
17720
17721 (define_expand "prefetch"
17722   [(prefetch (match_operand 0 "address_operand" "")
17723              (match_operand:SI 1 "const_int_operand" "")
17724              (match_operand:SI 2 "const_int_operand" ""))]
17725   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17726 {
17727   int rw = INTVAL (operands[1]);
17728   int locality = INTVAL (operands[2]);
17729
17730   gcc_assert (rw == 0 || rw == 1);
17731   gcc_assert (locality >= 0 && locality <= 3);
17732   gcc_assert (GET_MODE (operands[0]) == Pmode
17733               || GET_MODE (operands[0]) == VOIDmode);
17734
17735   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17736      supported by SSE counterpart or the SSE prefetch is not available
17737      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17738      of locality.  */
17739   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17740     operands[2] = GEN_INT (3);
17741   else
17742     operands[1] = const0_rtx;
17743 })
17744
17745 (define_insn "*prefetch_sse_<mode>"
17746   [(prefetch (match_operand:P 0 "address_operand" "p")
17747              (const_int 0)
17748              (match_operand:SI 1 "const_int_operand" ""))]
17749   "TARGET_PREFETCH_SSE"
17750 {
17751   static const char * const patterns[4] = {
17752    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17753   };
17754
17755   int locality = INTVAL (operands[1]);
17756   gcc_assert (locality >= 0 && locality <= 3);
17757
17758   return patterns[locality];
17759 }
17760   [(set_attr "type" "sse")
17761    (set_attr "atom_sse_attr" "prefetch")
17762    (set (attr "length_address")
17763         (symbol_ref "memory_address_length (operands[0])"))
17764    (set_attr "memory" "none")])
17765
17766 (define_insn "*prefetch_3dnow_<mode>"
17767   [(prefetch (match_operand:P 0 "address_operand" "p")
17768              (match_operand:SI 1 "const_int_operand" "n")
17769              (const_int 3))]
17770   "TARGET_3DNOW"
17771 {
17772   if (INTVAL (operands[1]) == 0)
17773     return "prefetch\t%a0";
17774   else
17775     return "prefetchw\t%a0";
17776 }
17777   [(set_attr "type" "mmx")
17778    (set (attr "length_address")
17779         (symbol_ref "memory_address_length (operands[0])"))
17780    (set_attr "memory" "none")])
17781
17782 (define_expand "stack_protect_set"
17783   [(match_operand 0 "memory_operand" "")
17784    (match_operand 1 "memory_operand" "")]
17785   ""
17786 {
17787   rtx (*insn)(rtx, rtx);
17788
17789 #ifdef TARGET_THREAD_SSP_OFFSET
17790   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17791   insn = (TARGET_LP64
17792           ? gen_stack_tls_protect_set_di
17793           : gen_stack_tls_protect_set_si);
17794 #else
17795   insn = (TARGET_LP64
17796           ? gen_stack_protect_set_di
17797           : gen_stack_protect_set_si);
17798 #endif
17799
17800   emit_insn (insn (operands[0], operands[1]));
17801   DONE;
17802 })
17803
17804 (define_insn "stack_protect_set_<mode>"
17805   [(set (match_operand:PTR 0 "memory_operand" "=m")
17806         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17807                     UNSPEC_SP_SET))
17808    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17809    (clobber (reg:CC FLAGS_REG))]
17810   ""
17811   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17812   [(set_attr "type" "multi")])
17813
17814 (define_insn "stack_tls_protect_set_<mode>"
17815   [(set (match_operand:PTR 0 "memory_operand" "=m")
17816         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17817                     UNSPEC_SP_TLS_SET))
17818    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17819    (clobber (reg:CC FLAGS_REG))]
17820   ""
17821   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17822   [(set_attr "type" "multi")])
17823
17824 (define_expand "stack_protect_test"
17825   [(match_operand 0 "memory_operand" "")
17826    (match_operand 1 "memory_operand" "")
17827    (match_operand 2 "" "")]
17828   ""
17829 {
17830   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17831
17832   rtx (*insn)(rtx, rtx, rtx);
17833
17834 #ifdef TARGET_THREAD_SSP_OFFSET
17835   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17836   insn = (TARGET_LP64
17837           ? gen_stack_tls_protect_test_di
17838           : gen_stack_tls_protect_test_si);
17839 #else
17840   insn = (TARGET_LP64
17841           ? gen_stack_protect_test_di
17842           : gen_stack_protect_test_si);
17843 #endif
17844
17845   emit_insn (insn (flags, operands[0], operands[1]));
17846
17847   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17848                                   flags, const0_rtx, operands[2]));
17849   DONE;
17850 })
17851
17852 (define_insn "stack_protect_test_<mode>"
17853   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17854         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17855                      (match_operand:PTR 2 "memory_operand" "m")]
17856                     UNSPEC_SP_TEST))
17857    (clobber (match_scratch:PTR 3 "=&r"))]
17858   ""
17859   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17860   [(set_attr "type" "multi")])
17861
17862 (define_insn "stack_tls_protect_test_<mode>"
17863   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17864         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17865                      (match_operand:PTR 2 "const_int_operand" "i")]
17866                     UNSPEC_SP_TLS_TEST))
17867    (clobber (match_scratch:PTR 3 "=r"))]
17868   ""
17869   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17870   [(set_attr "type" "multi")])
17871
17872 (define_insn "sse4_2_crc32<mode>"
17873   [(set (match_operand:SI 0 "register_operand" "=r")
17874         (unspec:SI
17875           [(match_operand:SI 1 "register_operand" "0")
17876            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17877           UNSPEC_CRC32))]
17878   "TARGET_SSE4_2 || TARGET_CRC32"
17879   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17880   [(set_attr "type" "sselog1")
17881    (set_attr "prefix_rep" "1")
17882    (set_attr "prefix_extra" "1")
17883    (set (attr "prefix_data16")
17884      (if_then_else (match_operand:HI 2 "" "")
17885        (const_string "1")
17886        (const_string "*")))
17887    (set (attr "prefix_rex")
17888      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17889        (const_string "1")
17890        (const_string "*")))
17891    (set_attr "mode" "SI")])
17892
17893 (define_insn "sse4_2_crc32di"
17894   [(set (match_operand:DI 0 "register_operand" "=r")
17895         (unspec:DI
17896           [(match_operand:DI 1 "register_operand" "0")
17897            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17898           UNSPEC_CRC32))]
17899   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17900   "crc32{q}\t{%2, %0|%0, %2}"
17901   [(set_attr "type" "sselog1")
17902    (set_attr "prefix_rep" "1")
17903    (set_attr "prefix_extra" "1")
17904    (set_attr "mode" "DI")])
17905
17906 (define_expand "rdpmc"
17907   [(match_operand:DI 0 "register_operand" "")
17908    (match_operand:SI 1 "register_operand" "")]
17909   ""
17910 {
17911   rtx reg = gen_reg_rtx (DImode);
17912   rtx si;
17913
17914   /* Force operand 1 into ECX.  */
17915   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17916   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17917   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17918                                 UNSPECV_RDPMC);
17919
17920   if (TARGET_64BIT)
17921     {
17922       rtvec vec = rtvec_alloc (2);
17923       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17924       rtx upper = gen_reg_rtx (DImode);
17925       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17926                                         gen_rtvec (1, const0_rtx),
17927                                         UNSPECV_RDPMC);
17928       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17929       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17930       emit_insn (load);
17931       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17932                                    NULL, 1, OPTAB_DIRECT);
17933       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17934                                  OPTAB_DIRECT);
17935     }
17936   else
17937     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17938   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17939   DONE;
17940 })
17941
17942 (define_insn "*rdpmc"
17943   [(set (match_operand:DI 0 "register_operand" "=A")
17944         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17945                             UNSPECV_RDPMC))]
17946   "!TARGET_64BIT"
17947   "rdpmc"
17948   [(set_attr "type" "other")
17949    (set_attr "length" "2")])
17950
17951 (define_insn "*rdpmc_rex64"
17952   [(set (match_operand:DI 0 "register_operand" "=a")
17953         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17954                             UNSPECV_RDPMC))
17955   (set (match_operand:DI 1 "register_operand" "=d")
17956        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17957   "TARGET_64BIT"
17958   "rdpmc"
17959   [(set_attr "type" "other")
17960    (set_attr "length" "2")])
17961
17962 (define_expand "rdtsc"
17963   [(set (match_operand:DI 0 "register_operand" "")
17964         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17965   ""
17966 {
17967   if (TARGET_64BIT)
17968     {
17969       rtvec vec = rtvec_alloc (2);
17970       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17971       rtx upper = gen_reg_rtx (DImode);
17972       rtx lower = gen_reg_rtx (DImode);
17973       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17974                                          gen_rtvec (1, const0_rtx),
17975                                          UNSPECV_RDTSC);
17976       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17977       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17978       emit_insn (load);
17979       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17980                                    NULL, 1, OPTAB_DIRECT);
17981       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17982                                    OPTAB_DIRECT);
17983       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17984       DONE;
17985     }
17986 })
17987
17988 (define_insn "*rdtsc"
17989   [(set (match_operand:DI 0 "register_operand" "=A")
17990         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17991   "!TARGET_64BIT"
17992   "rdtsc"
17993   [(set_attr "type" "other")
17994    (set_attr "length" "2")])
17995
17996 (define_insn "*rdtsc_rex64"
17997   [(set (match_operand:DI 0 "register_operand" "=a")
17998         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17999    (set (match_operand:DI 1 "register_operand" "=d")
18000         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18001   "TARGET_64BIT"
18002   "rdtsc"
18003   [(set_attr "type" "other")
18004    (set_attr "length" "2")])
18005
18006 (define_expand "rdtscp"
18007   [(match_operand:DI 0 "register_operand" "")
18008    (match_operand:SI 1 "memory_operand" "")]
18009   ""
18010 {
18011   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18012                                     gen_rtvec (1, const0_rtx),
18013                                     UNSPECV_RDTSCP);
18014   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18015                                     gen_rtvec (1, const0_rtx),
18016                                     UNSPECV_RDTSCP);
18017   rtx reg = gen_reg_rtx (DImode);
18018   rtx tmp = gen_reg_rtx (SImode);
18019
18020   if (TARGET_64BIT)
18021     {
18022       rtvec vec = rtvec_alloc (3);
18023       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18024       rtx upper = gen_reg_rtx (DImode);
18025       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18026       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18027       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18028       emit_insn (load);
18029       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18030                                    NULL, 1, OPTAB_DIRECT);
18031       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18032                                  OPTAB_DIRECT);
18033     }
18034   else
18035     {
18036       rtvec vec = rtvec_alloc (2);
18037       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18038       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18039       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18040       emit_insn (load);
18041     }
18042   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18043   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18044   DONE;
18045 })
18046
18047 (define_insn "*rdtscp"
18048   [(set (match_operand:DI 0 "register_operand" "=A")
18049         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18050    (set (match_operand:SI 1 "register_operand" "=c")
18051         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18052   "!TARGET_64BIT"
18053   "rdtscp"
18054   [(set_attr "type" "other")
18055    (set_attr "length" "3")])
18056
18057 (define_insn "*rdtscp_rex64"
18058   [(set (match_operand:DI 0 "register_operand" "=a")
18059         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18060    (set (match_operand:DI 1 "register_operand" "=d")
18061         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18062    (set (match_operand:SI 2 "register_operand" "=c")
18063         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18064   "TARGET_64BIT"
18065   "rdtscp"
18066   [(set_attr "type" "other")
18067    (set_attr "length" "3")])
18068
18069 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18070 ;;
18071 ;; LWP instructions
18072 ;;
18073 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18074
18075 (define_expand "lwp_llwpcb"
18076   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18077                     UNSPECV_LLWP_INTRINSIC)]
18078   "TARGET_LWP")
18079
18080 (define_insn "*lwp_llwpcb<mode>1"
18081   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18082                     UNSPECV_LLWP_INTRINSIC)]
18083   "TARGET_LWP"
18084   "llwpcb\t%0"
18085   [(set_attr "type" "lwp")
18086    (set_attr "mode" "<MODE>")
18087    (set_attr "length" "5")])
18088
18089 (define_expand "lwp_slwpcb"
18090   [(set (match_operand 0 "register_operand" "=r")
18091         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18092   "TARGET_LWP"
18093 {
18094   rtx (*insn)(rtx);
18095
18096   insn = (TARGET_64BIT
18097           ? gen_lwp_slwpcbdi
18098           : gen_lwp_slwpcbsi);
18099
18100   emit_insn (insn (operands[0]));
18101   DONE;
18102 })
18103
18104 (define_insn "lwp_slwpcb<mode>"
18105   [(set (match_operand:P 0 "register_operand" "=r")
18106         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18107   "TARGET_LWP"
18108   "slwpcb\t%0"
18109   [(set_attr "type" "lwp")
18110    (set_attr "mode" "<MODE>")
18111    (set_attr "length" "5")])
18112
18113 (define_expand "lwp_lwpval<mode>3"
18114   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18115                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18116                      (match_operand:SI 3 "const_int_operand" "i")]
18117                     UNSPECV_LWPVAL_INTRINSIC)]
18118   "TARGET_LWP"
18119   ;; Avoid unused variable warning.
18120   "(void) operands[0];")
18121
18122 (define_insn "*lwp_lwpval<mode>3_1"
18123   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18124                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18125                      (match_operand:SI 2 "const_int_operand" "i")]
18126                     UNSPECV_LWPVAL_INTRINSIC)]
18127   "TARGET_LWP"
18128   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18129   [(set_attr "type" "lwp")
18130    (set_attr "mode" "<MODE>")
18131    (set (attr "length")
18132         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18133
18134 (define_expand "lwp_lwpins<mode>3"
18135   [(set (reg:CCC FLAGS_REG)
18136         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18137                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18138                               (match_operand:SI 3 "const_int_operand" "i")]
18139                              UNSPECV_LWPINS_INTRINSIC))
18140    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18141         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18142   "TARGET_LWP")
18143
18144 (define_insn "*lwp_lwpins<mode>3_1"
18145   [(set (reg:CCC FLAGS_REG)
18146         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18147                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18148                               (match_operand:SI 2 "const_int_operand" "i")]
18149                              UNSPECV_LWPINS_INTRINSIC))]
18150   "TARGET_LWP"
18151   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18152   [(set_attr "type" "lwp")
18153    (set_attr "mode" "<MODE>")
18154    (set (attr "length")
18155         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18156
18157 (define_insn "rdfsbase<mode>"
18158   [(set (match_operand:SWI48 0 "register_operand" "=r")
18159         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18160   "TARGET_64BIT && TARGET_FSGSBASE"
18161   "rdfsbase %0"
18162   [(set_attr "type" "other")
18163    (set_attr "prefix_extra" "2")])
18164
18165 (define_insn "rdgsbase<mode>"
18166   [(set (match_operand:SWI48 0 "register_operand" "=r")
18167         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18168   "TARGET_64BIT && TARGET_FSGSBASE"
18169   "rdgsbase %0"
18170   [(set_attr "type" "other")
18171    (set_attr "prefix_extra" "2")])
18172
18173 (define_insn "wrfsbase<mode>"
18174   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18175                     UNSPECV_WRFSBASE)]
18176   "TARGET_64BIT && TARGET_FSGSBASE"
18177   "wrfsbase %0"
18178   [(set_attr "type" "other")
18179    (set_attr "prefix_extra" "2")])
18180
18181 (define_insn "wrgsbase<mode>"
18182   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18183                     UNSPECV_WRGSBASE)]
18184   "TARGET_64BIT && TARGET_FSGSBASE"
18185   "wrgsbase %0"
18186   [(set_attr "type" "other")
18187    (set_attr "prefix_extra" "2")])
18188
18189 (define_insn "rdrand<mode>_1"
18190   [(set (match_operand:SWI248 0 "register_operand" "=r")
18191         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18192    (set (reg:CCC FLAGS_REG)
18193         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18194   "TARGET_RDRND"
18195   "rdrand\t%0"
18196   [(set_attr "type" "other")
18197    (set_attr "prefix_extra" "1")])
18198
18199 (define_expand "pause"
18200   [(set (match_dup 0)
18201         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18202   ""
18203 {
18204   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18205   MEM_VOLATILE_P (operands[0]) = 1;
18206 })
18207
18208 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18209 ;; They have the same encoding.
18210 (define_insn "*pause"
18211   [(set (match_operand:BLK 0 "" "")
18212         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18213   ""
18214   "rep; nop"
18215   [(set_attr "length" "2")
18216    (set_attr "memory" "unknown")])
18217
18218 (include "mmx.md")
18219 (include "sse.md")
18220 (include "sync.md")