Merge branch 'vendor/GCC47'
[dragonfly.git] / contrib / gcc-4.7 / 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, 2012
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 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;;      delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;;      %b0 would print %al if operands[0] is reg 0.
47 ;; w --  likewise, print the HImode name of the register.
48 ;; k --  likewise, print the SImode name of the register.
49 ;; q --  likewise, print the DImode name of the register.
50 ;; x --  likewise, print the V4SFmode name of the register.
51 ;; t --  likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; Y -- print condition for XOP pcom* instruction.
62 ;; + -- print a branch hint as 'cs' or 'ds' prefix
63 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
64 ;; @ -- print a segment register of thread base pointer load
65
66 (define_c_enum "unspec" [
67   ;; Relocation specifiers
68   UNSPEC_GOT
69   UNSPEC_GOTOFF
70   UNSPEC_GOTPCREL
71   UNSPEC_GOTTPOFF
72   UNSPEC_TPOFF
73   UNSPEC_NTPOFF
74   UNSPEC_DTPOFF
75   UNSPEC_GOTNTPOFF
76   UNSPEC_INDNTPOFF
77   UNSPEC_PLTOFF
78   UNSPEC_MACHOPIC_OFFSET
79   UNSPEC_PCREL
80
81   ;; Prologue support
82   UNSPEC_STACK_ALLOC
83   UNSPEC_SET_GOT
84   UNSPEC_SET_RIP
85   UNSPEC_SET_GOT_OFFSET
86   UNSPEC_MEMORY_BLOCKAGE
87   UNSPEC_STACK_CHECK
88
89   ;; TLS support
90   UNSPEC_TP
91   UNSPEC_TLS_GD
92   UNSPEC_TLS_LD_BASE
93   UNSPEC_TLSDESC
94   UNSPEC_TLS_IE_SUN
95
96   ;; Other random patterns
97   UNSPEC_SCAS
98   UNSPEC_FNSTSW
99   UNSPEC_SAHF
100   UNSPEC_PARITY
101   UNSPEC_FSTCW
102   UNSPEC_ADD_CARRY
103   UNSPEC_FLDCW
104   UNSPEC_REP
105   UNSPEC_LD_MPIC        ; load_macho_picbase
106   UNSPEC_TRUNC_NOOP
107   UNSPEC_DIV_ALREADY_SPLIT
108   UNSPEC_MS_TO_SYSV_CALL
109   UNSPEC_CALL_NEEDS_VZEROUPPER
110   UNSPEC_PAUSE
111   UNSPEC_LEA_ADDR
112   UNSPEC_STOS
113
114   ;; For SSE/MMX support:
115   UNSPEC_FIX_NOTRUNC
116   UNSPEC_MASKMOV
117   UNSPEC_MOVMSK
118   UNSPEC_RCP
119   UNSPEC_RSQRT
120   UNSPEC_PSADBW
121
122   ;; Generic math support
123   UNSPEC_COPYSIGN
124   UNSPEC_IEEE_MIN       ; not commutative
125   UNSPEC_IEEE_MAX       ; not commutative
126
127   ;; x87 Floating point
128   UNSPEC_SIN
129   UNSPEC_COS
130   UNSPEC_FPATAN
131   UNSPEC_FYL2X
132   UNSPEC_FYL2XP1
133   UNSPEC_FRNDINT
134   UNSPEC_FIST
135   UNSPEC_F2XM1
136   UNSPEC_TAN
137   UNSPEC_FXAM
138
139   ;; x87 Rounding
140   UNSPEC_FRNDINT_FLOOR
141   UNSPEC_FRNDINT_CEIL
142   UNSPEC_FRNDINT_TRUNC
143   UNSPEC_FRNDINT_MASK_PM
144   UNSPEC_FIST_FLOOR
145   UNSPEC_FIST_CEIL
146
147   ;; x87 Double output FP
148   UNSPEC_SINCOS_COS
149   UNSPEC_SINCOS_SIN
150   UNSPEC_XTRACT_FRACT
151   UNSPEC_XTRACT_EXP
152   UNSPEC_FSCALE_FRACT
153   UNSPEC_FSCALE_EXP
154   UNSPEC_FPREM_F
155   UNSPEC_FPREM_U
156   UNSPEC_FPREM1_F
157   UNSPEC_FPREM1_U
158
159   UNSPEC_C2_FLAG
160   UNSPEC_FXAM_MEM
161
162   ;; SSP patterns
163   UNSPEC_SP_SET
164   UNSPEC_SP_TEST
165   UNSPEC_SP_TLS_SET
166   UNSPEC_SP_TLS_TEST
167
168   ;; For ROUND support
169   UNSPEC_ROUND
170
171   ;; For CRC32 support
172   UNSPEC_CRC32
173
174   ;; For BMI support
175   UNSPEC_BEXTR
176
177   ;; For BMI2 support
178   UNSPEC_PDEP
179   UNSPEC_PEXT
180 ])
181
182 (define_c_enum "unspecv" [
183   UNSPECV_BLOCKAGE
184   UNSPECV_STACK_PROBE
185   UNSPECV_PROBE_STACK_RANGE
186   UNSPECV_ALIGN
187   UNSPECV_PROLOGUE_USE
188   UNSPECV_SPLIT_STACK_RETURN
189   UNSPECV_CLD
190   UNSPECV_NOPS
191   UNSPECV_RDTSC
192   UNSPECV_RDTSCP
193   UNSPECV_RDPMC
194   UNSPECV_LLWP_INTRINSIC
195   UNSPECV_SLWP_INTRINSIC
196   UNSPECV_LWPVAL_INTRINSIC
197   UNSPECV_LWPINS_INTRINSIC
198   UNSPECV_RDFSBASE
199   UNSPECV_RDGSBASE
200   UNSPECV_WRFSBASE
201   UNSPECV_WRGSBASE
202
203   ;; For RDRAND support
204   UNSPECV_RDRAND
205
206   ;; Non-local goto.
207   UNSPECV_NLGR
208  ])
209
210 ;; Constants to represent rounding modes in the ROUND instruction
211 (define_constants
212   [(ROUND_FLOOR                 0x1)
213    (ROUND_CEIL                  0x2)
214    (ROUND_TRUNC                 0x3)
215    (ROUND_MXCSR                 0x4)
216    (ROUND_NO_EXC                0x8)
217   ])
218
219 ;; Constants to represent pcomtrue/pcomfalse variants
220 (define_constants
221   [(PCOM_FALSE                  0)
222    (PCOM_TRUE                   1)
223    (COM_FALSE_S                 2)
224    (COM_FALSE_P                 3)
225    (COM_TRUE_S                  4)
226    (COM_TRUE_P                  5)
227   ])
228
229 ;; Constants used in the XOP pperm instruction
230 (define_constants
231   [(PPERM_SRC                   0x00)   /* copy source */
232    (PPERM_INVERT                0x20)   /* invert source */
233    (PPERM_REVERSE               0x40)   /* bit reverse source */
234    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
235    (PPERM_ZERO                  0x80)   /* all 0's */
236    (PPERM_ONES                  0xa0)   /* all 1's */
237    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
238    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
239    (PPERM_SRC1                  0x00)   /* use first source byte */
240    (PPERM_SRC2                  0x10)   /* use second source byte */
241    ])
242
243 ;; Registers by name.
244 (define_constants
245   [(AX_REG                       0)
246    (DX_REG                       1)
247    (CX_REG                       2)
248    (BX_REG                       3)
249    (SI_REG                       4)
250    (DI_REG                       5)
251    (BP_REG                       6)
252    (SP_REG                       7)
253    (ST0_REG                      8)
254    (ST1_REG                      9)
255    (ST2_REG                     10)
256    (ST3_REG                     11)
257    (ST4_REG                     12)
258    (ST5_REG                     13)
259    (ST6_REG                     14)
260    (ST7_REG                     15)
261    (FLAGS_REG                   17)
262    (FPSR_REG                    18)
263    (FPCR_REG                    19)
264    (XMM0_REG                    21)
265    (XMM1_REG                    22)
266    (XMM2_REG                    23)
267    (XMM3_REG                    24)
268    (XMM4_REG                    25)
269    (XMM5_REG                    26)
270    (XMM6_REG                    27)
271    (XMM7_REG                    28)
272    (MM0_REG                     29)
273    (MM1_REG                     30)
274    (MM2_REG                     31)
275    (MM3_REG                     32)
276    (MM4_REG                     33)
277    (MM5_REG                     34)
278    (MM6_REG                     35)
279    (MM7_REG                     36)
280    (R8_REG                      37)
281    (R9_REG                      38)
282    (R10_REG                     39)
283    (R11_REG                     40)
284    (R12_REG                     41)
285    (R13_REG                     42)
286    (XMM8_REG                    45)
287    (XMM9_REG                    46)
288    (XMM10_REG                   47)
289    (XMM11_REG                   48)
290    (XMM12_REG                   49)
291    (XMM13_REG                   50)
292    (XMM14_REG                   51)
293    (XMM15_REG                   52)
294   ])
295
296 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
297 ;; from i386.c.
298
299 ;; In C guard expressions, put expressions which may be compile-time
300 ;; constants first.  This allows for better optimization.  For
301 ;; example, write "TARGET_64BIT && reload_completed", not
302 ;; "reload_completed && TARGET_64BIT".
303
304 \f
305 ;; Processor type.
306 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
307                     atom,generic64,amdfam10,bdver1,bdver2,btver1"
308   (const (symbol_ref "ix86_schedule")))
309
310 ;; A basic instruction type.  Refinements due to arguments to be
311 ;; provided in other attributes.
312 (define_attr "type"
313   "other,multi,
314    alu,alu1,negnot,imov,imovx,lea,
315    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
316    icmp,test,ibr,setcc,icmov,
317    push,pop,call,callv,leave,
318    str,bitmanip,
319    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
320    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
321    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
322    ssemuladd,sse4arg,lwp,
323    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
324   (const_string "other"))
325
326 ;; Main data type used by the insn
327 (define_attr "mode"
328   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
329   (const_string "unknown"))
330
331 ;; The CPU unit operations uses.
332 (define_attr "unit" "integer,i387,sse,mmx,unknown"
333   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
334            (const_string "i387")
335          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
336                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
337                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
338            (const_string "sse")
339          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
340            (const_string "mmx")
341          (eq_attr "type" "other")
342            (const_string "unknown")]
343          (const_string "integer")))
344
345 ;; The (bounding maximum) length of an instruction immediate.
346 (define_attr "length_immediate" ""
347   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
348                           bitmanip,imulx")
349            (const_int 0)
350          (eq_attr "unit" "i387,sse,mmx")
351            (const_int 0)
352          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
353                           rotate,rotatex,rotate1,imul,icmp,push,pop")
354            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
355          (eq_attr "type" "imov,test")
356            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
357          (eq_attr "type" "call")
358            (if_then_else (match_operand 0 "constant_call_address_operand" "")
359              (const_int 4)
360              (const_int 0))
361          (eq_attr "type" "callv")
362            (if_then_else (match_operand 1 "constant_call_address_operand" "")
363              (const_int 4)
364              (const_int 0))
365          ;; We don't know the size before shorten_branches.  Expect
366          ;; the instruction to fit for better scheduling.
367          (eq_attr "type" "ibr")
368            (const_int 1)
369          ]
370          (symbol_ref "/* Update immediate_length and other attributes! */
371                       gcc_unreachable (),1")))
372
373 ;; The (bounding maximum) length of an instruction address.
374 (define_attr "length_address" ""
375   (cond [(eq_attr "type" "str,other,multi,fxch")
376            (const_int 0)
377          (and (eq_attr "type" "call")
378               (match_operand 0 "constant_call_address_operand" ""))
379              (const_int 0)
380          (and (eq_attr "type" "callv")
381               (match_operand 1 "constant_call_address_operand" ""))
382              (const_int 0)
383          ]
384          (symbol_ref "ix86_attr_length_address_default (insn)")))
385
386 ;; Set when length prefix is used.
387 (define_attr "prefix_data16" ""
388   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
389            (const_int 0)
390          (eq_attr "mode" "HI")
391            (const_int 1)
392          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
393            (const_int 1)
394         ]
395         (const_int 0)))
396
397 ;; Set when string REP prefix is used.
398 (define_attr "prefix_rep" ""
399   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
400            (const_int 0)
401          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
402            (const_int 1)
403         ]
404         (const_int 0)))
405
406 ;; Set when 0f opcode prefix is used.
407 (define_attr "prefix_0f" ""
408   (if_then_else
409     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
410          (eq_attr "unit" "sse,mmx"))
411     (const_int 1)
412     (const_int 0)))
413
414 ;; Set when REX opcode prefix is used.
415 (define_attr "prefix_rex" ""
416   (cond [(not (match_test "TARGET_64BIT"))
417            (const_int 0)
418          (and (eq_attr "mode" "DI")
419               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
420                    (eq_attr "unit" "!mmx")))
421            (const_int 1)
422          (and (eq_attr "mode" "QI")
423               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
424            (const_int 1)
425          (match_test "x86_extended_reg_mentioned_p (insn)")
426            (const_int 1)
427          (and (eq_attr "type" "imovx")
428               (match_operand:QI 1 "ext_QIreg_operand" ""))
429            (const_int 1)
430         ]
431         (const_int 0)))
432
433 ;; There are also additional prefixes in 3DNOW, SSSE3.
434 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
435 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
436 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
437 (define_attr "prefix_extra" ""
438   (cond [(eq_attr "type" "ssemuladd,sse4arg")
439            (const_int 2)
440          (eq_attr "type" "sseiadd1,ssecvt1")
441            (const_int 1)
442         ]
443         (const_int 0)))
444
445 ;; Prefix used: original, VEX or maybe VEX.
446 (define_attr "prefix" "orig,vex,maybe_vex"
447   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
448     (const_string "vex")
449     (const_string "orig")))
450
451 ;; VEX W bit is used.
452 (define_attr "prefix_vex_w" "" (const_int 0))
453
454 ;; The length of VEX prefix
455 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
456 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
457 ;; still prefix_0f 1, with prefix_extra 1.
458 (define_attr "length_vex" ""
459   (if_then_else (and (eq_attr "prefix_0f" "1")
460                      (eq_attr "prefix_extra" "0"))
461     (if_then_else (eq_attr "prefix_vex_w" "1")
462       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
463       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
464     (if_then_else (eq_attr "prefix_vex_w" "1")
465       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
466       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
467
468 ;; Set when modrm byte is used.
469 (define_attr "modrm" ""
470   (cond [(eq_attr "type" "str,leave")
471            (const_int 0)
472          (eq_attr "unit" "i387")
473            (const_int 0)
474          (and (eq_attr "type" "incdec")
475               (and (not (match_test "TARGET_64BIT"))
476                    (ior (match_operand:SI 1 "register_operand" "")
477                         (match_operand:HI 1 "register_operand" ""))))
478            (const_int 0)
479          (and (eq_attr "type" "push")
480               (not (match_operand 1 "memory_operand" "")))
481            (const_int 0)
482          (and (eq_attr "type" "pop")
483               (not (match_operand 0 "memory_operand" "")))
484            (const_int 0)
485          (and (eq_attr "type" "imov")
486               (and (not (eq_attr "mode" "DI"))
487                    (ior (and (match_operand 0 "register_operand" "")
488                              (match_operand 1 "immediate_operand" ""))
489                         (ior (and (match_operand 0 "ax_reg_operand" "")
490                                   (match_operand 1 "memory_displacement_only_operand" ""))
491                              (and (match_operand 0 "memory_displacement_only_operand" "")
492                                   (match_operand 1 "ax_reg_operand" ""))))))
493            (const_int 0)
494          (and (eq_attr "type" "call")
495               (match_operand 0 "constant_call_address_operand" ""))
496              (const_int 0)
497          (and (eq_attr "type" "callv")
498               (match_operand 1 "constant_call_address_operand" ""))
499              (const_int 0)
500          (and (eq_attr "type" "alu,alu1,icmp,test")
501               (match_operand 0 "ax_reg_operand" ""))
502              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
503          ]
504          (const_int 1)))
505
506 ;; The (bounding maximum) length of an instruction in bytes.
507 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
508 ;; Later we may want to split them and compute proper length as for
509 ;; other insns.
510 (define_attr "length" ""
511   (cond [(eq_attr "type" "other,multi,fistp,frndint")
512            (const_int 16)
513          (eq_attr "type" "fcmp")
514            (const_int 4)
515          (eq_attr "unit" "i387")
516            (plus (const_int 2)
517                  (plus (attr "prefix_data16")
518                        (attr "length_address")))
519          (ior (eq_attr "prefix" "vex")
520               (and (eq_attr "prefix" "maybe_vex")
521                    (match_test "TARGET_AVX")))
522            (plus (attr "length_vex")
523                  (plus (attr "length_immediate")
524                        (plus (attr "modrm")
525                              (attr "length_address"))))]
526          (plus (plus (attr "modrm")
527                      (plus (attr "prefix_0f")
528                            (plus (attr "prefix_rex")
529                                  (plus (attr "prefix_extra")
530                                        (const_int 1)))))
531                (plus (attr "prefix_rep")
532                      (plus (attr "prefix_data16")
533                            (plus (attr "length_immediate")
534                                  (attr "length_address")))))))
535
536 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
537 ;; `store' if there is a simple memory reference therein, or `unknown'
538 ;; if the instruction is complex.
539
540 (define_attr "memory" "none,load,store,both,unknown"
541   (cond [(eq_attr "type" "other,multi,str,lwp")
542            (const_string "unknown")
543          (eq_attr "type" "lea,fcmov,fpspc")
544            (const_string "none")
545          (eq_attr "type" "fistp,leave")
546            (const_string "both")
547          (eq_attr "type" "frndint")
548            (const_string "load")
549          (eq_attr "type" "push")
550            (if_then_else (match_operand 1 "memory_operand" "")
551              (const_string "both")
552              (const_string "store"))
553          (eq_attr "type" "pop")
554            (if_then_else (match_operand 0 "memory_operand" "")
555              (const_string "both")
556              (const_string "load"))
557          (eq_attr "type" "setcc")
558            (if_then_else (match_operand 0 "memory_operand" "")
559              (const_string "store")
560              (const_string "none"))
561          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
562            (if_then_else (ior (match_operand 0 "memory_operand" "")
563                               (match_operand 1 "memory_operand" ""))
564              (const_string "load")
565              (const_string "none"))
566          (eq_attr "type" "ibr")
567            (if_then_else (match_operand 0 "memory_operand" "")
568              (const_string "load")
569              (const_string "none"))
570          (eq_attr "type" "call")
571            (if_then_else (match_operand 0 "constant_call_address_operand" "")
572              (const_string "none")
573              (const_string "load"))
574          (eq_attr "type" "callv")
575            (if_then_else (match_operand 1 "constant_call_address_operand" "")
576              (const_string "none")
577              (const_string "load"))
578          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
579               (match_operand 1 "memory_operand" ""))
580            (const_string "both")
581          (and (match_operand 0 "memory_operand" "")
582               (match_operand 1 "memory_operand" ""))
583            (const_string "both")
584          (match_operand 0 "memory_operand" "")
585            (const_string "store")
586          (match_operand 1 "memory_operand" "")
587            (const_string "load")
588          (and (eq_attr "type"
589                  "!alu1,negnot,ishift1,
590                    imov,imovx,icmp,test,bitmanip,
591                    fmov,fcmp,fsgn,
592                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
593                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
594               (match_operand 2 "memory_operand" ""))
595            (const_string "load")
596          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
597               (match_operand 3 "memory_operand" ""))
598            (const_string "load")
599         ]
600         (const_string "none")))
601
602 ;; Indicates if an instruction has both an immediate and a displacement.
603
604 (define_attr "imm_disp" "false,true,unknown"
605   (cond [(eq_attr "type" "other,multi")
606            (const_string "unknown")
607          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
608               (and (match_operand 0 "memory_displacement_operand" "")
609                    (match_operand 1 "immediate_operand" "")))
610            (const_string "true")
611          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
612               (and (match_operand 0 "memory_displacement_operand" "")
613                    (match_operand 2 "immediate_operand" "")))
614            (const_string "true")
615         ]
616         (const_string "false")))
617
618 ;; Indicates if an FP operation has an integer source.
619
620 (define_attr "fp_int_src" "false,true"
621   (const_string "false"))
622
623 ;; Defines rounding mode of an FP operation.
624
625 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
626   (const_string "any"))
627
628 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
629 (define_attr "use_carry" "0,1" (const_string "0"))
630
631 ;; Define attribute to indicate unaligned ssemov insns
632 (define_attr "movu" "0,1" (const_string "0"))
633
634 ;; Used to control the "enabled" attribute on a per-instruction basis.
635 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
636                     bmi2,fma4,fma"
637   (const_string "base"))
638
639 (define_attr "enabled" ""
640   (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
641          (eq_attr "isa" "sse2_noavx")
642            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
643          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
644          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
645          (eq_attr "isa" "sse4_noavx")
646            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
647          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
648          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
649          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
650          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
651          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
652         ]
653         (const_int 1)))
654
655 ;; Describe a user's asm statement.
656 (define_asm_attributes
657   [(set_attr "length" "128")
658    (set_attr "type" "multi")])
659
660 (define_code_iterator plusminus [plus minus])
661
662 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
663
664 ;; Base name for define_insn
665 (define_code_attr plusminus_insn
666   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
667    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
668
669 ;; Base name for insn mnemonic.
670 (define_code_attr plusminus_mnemonic
671   [(plus "add") (ss_plus "adds") (us_plus "addus")
672    (minus "sub") (ss_minus "subs") (us_minus "subus")])
673 (define_code_attr plusminus_carry_mnemonic
674   [(plus "adc") (minus "sbb")])
675
676 ;; Mark commutative operators as such in constraints.
677 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
678                         (minus "") (ss_minus "") (us_minus "")])
679
680 ;; Mapping of max and min
681 (define_code_iterator maxmin [smax smin umax umin])
682
683 ;; Mapping of signed max and min
684 (define_code_iterator smaxmin [smax smin])
685
686 ;; Mapping of unsigned max and min
687 (define_code_iterator umaxmin [umax umin])
688
689 ;; Base name for integer and FP insn mnemonic
690 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
691                               (umax "maxu") (umin "minu")])
692 (define_code_attr maxmin_float [(smax "max") (smin "min")])
693
694 ;; Mapping of logic operators
695 (define_code_iterator any_logic [and ior xor])
696 (define_code_iterator any_or [ior xor])
697
698 ;; Base name for insn mnemonic.
699 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
700
701 ;; Mapping of logic-shift operators
702 (define_code_iterator any_lshift [ashift lshiftrt])
703
704 ;; Mapping of shift-right operators
705 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
706
707 ;; Base name for define_insn
708 (define_code_attr shift_insn
709   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
710
711 ;; Base name for insn mnemonic.
712 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
713 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
714
715 ;; Mapping of rotate operators
716 (define_code_iterator any_rotate [rotate rotatert])
717
718 ;; Base name for define_insn
719 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
720
721 ;; Base name for insn mnemonic.
722 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
723
724 ;; Mapping of abs neg operators
725 (define_code_iterator absneg [abs neg])
726
727 ;; Base name for x87 insn mnemonic.
728 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
729
730 ;; Used in signed and unsigned widening multiplications.
731 (define_code_iterator any_extend [sign_extend zero_extend])
732
733 ;; Prefix for insn menmonic.
734 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
735
736 ;; Prefix for define_insn
737 (define_code_attr u [(sign_extend "") (zero_extend "u")])
738 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
739
740 ;; All integer modes.
741 (define_mode_iterator SWI1248x [QI HI SI DI])
742
743 ;; All integer modes without QImode.
744 (define_mode_iterator SWI248x [HI SI DI])
745
746 ;; All integer modes without QImode and HImode.
747 (define_mode_iterator SWI48x [SI DI])
748
749 ;; All integer modes without SImode and DImode.
750 (define_mode_iterator SWI12 [QI HI])
751
752 ;; All integer modes without DImode.
753 (define_mode_iterator SWI124 [QI HI SI])
754
755 ;; All integer modes without QImode and DImode.
756 (define_mode_iterator SWI24 [HI SI])
757
758 ;; Single word integer modes.
759 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
760
761 ;; Single word integer modes without QImode.
762 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
763
764 ;; Single word integer modes without QImode and HImode.
765 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
766
767 ;; All math-dependant single and double word integer modes.
768 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
769                              (HI "TARGET_HIMODE_MATH")
770                              SI DI (TI "TARGET_64BIT")])
771
772 ;; Math-dependant single word integer modes.
773 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
774                             (HI "TARGET_HIMODE_MATH")
775                             SI (DI "TARGET_64BIT")])
776
777 ;; Math-dependant integer modes without DImode.
778 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
779                                (HI "TARGET_HIMODE_MATH")
780                                SI])
781
782 ;; Math-dependant single word integer modes without QImode.
783 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
784                                SI (DI "TARGET_64BIT")])
785
786 ;; Double word integer modes.
787 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
788                            (TI "TARGET_64BIT")])
789
790 ;; Double word integer modes as mode attribute.
791 (define_mode_attr DWI [(SI "DI") (DI "TI")])
792 (define_mode_attr dwi [(SI "di") (DI "ti")])
793
794 ;; Half mode for double word integer modes.
795 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
796                             (DI "TARGET_64BIT")])
797
798 ;; Instruction suffix for integer modes.
799 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
800
801 ;; Pointer size prefix for integer modes (Intel asm dialect)
802 (define_mode_attr iptrsize [(QI "BYTE")
803                             (HI "WORD")
804                             (SI "DWORD")
805                             (DI "QWORD")])
806
807 ;; Register class for integer modes.
808 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
809
810 ;; Immediate operand constraint for integer modes.
811 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
812
813 ;; General operand constraint for word modes.
814 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
815
816 ;; Immediate operand constraint for double integer modes.
817 (define_mode_attr di [(SI "nF") (DI "e")])
818
819 ;; Immediate operand constraint for shifts.
820 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
821
822 ;; General operand predicate for integer modes.
823 (define_mode_attr general_operand
824         [(QI "general_operand")
825          (HI "general_operand")
826          (SI "x86_64_general_operand")
827          (DI "x86_64_general_operand")
828          (TI "x86_64_general_operand")])
829
830 ;; General sign/zero extend operand predicate for integer modes.
831 (define_mode_attr general_szext_operand
832         [(QI "general_operand")
833          (HI "general_operand")
834          (SI "x86_64_szext_general_operand")
835          (DI "x86_64_szext_general_operand")])
836
837 ;; Immediate operand predicate for integer modes.
838 (define_mode_attr immediate_operand
839         [(QI "immediate_operand")
840          (HI "immediate_operand")
841          (SI "x86_64_immediate_operand")
842          (DI "x86_64_immediate_operand")])
843
844 ;; Nonmemory operand predicate for integer modes.
845 (define_mode_attr nonmemory_operand
846         [(QI "nonmemory_operand")
847          (HI "nonmemory_operand")
848          (SI "x86_64_nonmemory_operand")
849          (DI "x86_64_nonmemory_operand")])
850
851 ;; Operand predicate for shifts.
852 (define_mode_attr shift_operand
853         [(QI "nonimmediate_operand")
854          (HI "nonimmediate_operand")
855          (SI "nonimmediate_operand")
856          (DI "shiftdi_operand")
857          (TI "register_operand")])
858
859 ;; Operand predicate for shift argument.
860 (define_mode_attr shift_immediate_operand
861         [(QI "const_1_to_31_operand")
862          (HI "const_1_to_31_operand")
863          (SI "const_1_to_31_operand")
864          (DI "const_1_to_63_operand")])
865
866 ;; Input operand predicate for arithmetic left shifts.
867 (define_mode_attr ashl_input_operand
868         [(QI "nonimmediate_operand")
869          (HI "nonimmediate_operand")
870          (SI "nonimmediate_operand")
871          (DI "ashldi_input_operand")
872          (TI "reg_or_pm1_operand")])
873
874 ;; SSE and x87 SFmode and DFmode floating point modes
875 (define_mode_iterator MODEF [SF DF])
876
877 ;; All x87 floating point modes
878 (define_mode_iterator X87MODEF [SF DF XF])
879
880 ;; SSE instruction suffix for various modes
881 (define_mode_attr ssemodesuffix
882   [(SF "ss") (DF "sd")
883    (V8SF "ps") (V4DF "pd")
884    (V4SF "ps") (V2DF "pd")
885    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
886    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
887
888 ;; SSE vector suffix for floating point modes
889 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
890
891 ;; SSE vector mode corresponding to a scalar mode
892 (define_mode_attr ssevecmode
893   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
894
895 ;; Instruction suffix for REX 64bit operators.
896 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
897
898 ;; This mode iterator allows :P to be used for patterns that operate on
899 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
900 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
901
902 ;; This mode iterator allows :PTR to be used for patterns that operate on
903 ;; ptr_mode sized quantities.
904 (define_mode_iterator PTR
905   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
906 \f
907 ;; Scheduling descriptions
908
909 (include "pentium.md")
910 (include "ppro.md")
911 (include "k6.md")
912 (include "athlon.md")
913 (include "bdver1.md")
914 (include "geode.md")
915 (include "atom.md")
916 (include "core2.md")
917
918 \f
919 ;; Operand and operator predicates and constraints
920
921 (include "predicates.md")
922 (include "constraints.md")
923
924 \f
925 ;; Compare and branch/compare and store instructions.
926
927 (define_expand "cbranch<mode>4"
928   [(set (reg:CC FLAGS_REG)
929         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
930                     (match_operand:SDWIM 2 "<general_operand>" "")))
931    (set (pc) (if_then_else
932                (match_operator 0 "ordered_comparison_operator"
933                 [(reg:CC FLAGS_REG) (const_int 0)])
934                (label_ref (match_operand 3 "" ""))
935                (pc)))]
936   ""
937 {
938   if (MEM_P (operands[1]) && MEM_P (operands[2]))
939     operands[1] = force_reg (<MODE>mode, operands[1]);
940   ix86_expand_branch (GET_CODE (operands[0]),
941                       operands[1], operands[2], operands[3]);
942   DONE;
943 })
944
945 (define_expand "cstore<mode>4"
946   [(set (reg:CC FLAGS_REG)
947         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
948                     (match_operand:SWIM 3 "<general_operand>" "")))
949    (set (match_operand:QI 0 "register_operand" "")
950         (match_operator 1 "ordered_comparison_operator"
951           [(reg:CC FLAGS_REG) (const_int 0)]))]
952   ""
953 {
954   if (MEM_P (operands[2]) && MEM_P (operands[3]))
955     operands[2] = force_reg (<MODE>mode, operands[2]);
956   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
957                      operands[2], operands[3]);
958   DONE;
959 })
960
961 (define_expand "cmp<mode>_1"
962   [(set (reg:CC FLAGS_REG)
963         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
964                     (match_operand:SWI48 1 "<general_operand>" "")))])
965
966 (define_insn "*cmp<mode>_ccno_1"
967   [(set (reg FLAGS_REG)
968         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
969                  (match_operand:SWI 1 "const0_operand" "")))]
970   "ix86_match_ccmode (insn, CCNOmode)"
971   "@
972    test{<imodesuffix>}\t%0, %0
973    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
974   [(set_attr "type" "test,icmp")
975    (set_attr "length_immediate" "0,1")
976    (set_attr "mode" "<MODE>")])
977
978 (define_insn "*cmp<mode>_1"
979   [(set (reg FLAGS_REG)
980         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
981                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
982   "ix86_match_ccmode (insn, CCmode)"
983   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
984   [(set_attr "type" "icmp")
985    (set_attr "mode" "<MODE>")])
986
987 (define_insn "*cmp<mode>_minus_1"
988   [(set (reg FLAGS_REG)
989         (compare
990           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
991                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
992           (const_int 0)))]
993   "ix86_match_ccmode (insn, CCGOCmode)"
994   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
995   [(set_attr "type" "icmp")
996    (set_attr "mode" "<MODE>")])
997
998 (define_insn "*cmpqi_ext_1"
999   [(set (reg FLAGS_REG)
1000         (compare
1001           (match_operand:QI 0 "general_operand" "Qm")
1002           (subreg:QI
1003             (zero_extract:SI
1004               (match_operand 1 "ext_register_operand" "Q")
1005               (const_int 8)
1006               (const_int 8)) 0)))]
1007   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1008   "cmp{b}\t{%h1, %0|%0, %h1}"
1009   [(set_attr "type" "icmp")
1010    (set_attr "mode" "QI")])
1011
1012 (define_insn "*cmpqi_ext_1_rex64"
1013   [(set (reg FLAGS_REG)
1014         (compare
1015           (match_operand:QI 0 "register_operand" "Q")
1016           (subreg:QI
1017             (zero_extract:SI
1018               (match_operand 1 "ext_register_operand" "Q")
1019               (const_int 8)
1020               (const_int 8)) 0)))]
1021   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1022   "cmp{b}\t{%h1, %0|%0, %h1}"
1023   [(set_attr "type" "icmp")
1024    (set_attr "mode" "QI")])
1025
1026 (define_insn "*cmpqi_ext_2"
1027   [(set (reg FLAGS_REG)
1028         (compare
1029           (subreg:QI
1030             (zero_extract:SI
1031               (match_operand 0 "ext_register_operand" "Q")
1032               (const_int 8)
1033               (const_int 8)) 0)
1034           (match_operand:QI 1 "const0_operand" "")))]
1035   "ix86_match_ccmode (insn, CCNOmode)"
1036   "test{b}\t%h0, %h0"
1037   [(set_attr "type" "test")
1038    (set_attr "length_immediate" "0")
1039    (set_attr "mode" "QI")])
1040
1041 (define_expand "cmpqi_ext_3"
1042   [(set (reg:CC FLAGS_REG)
1043         (compare:CC
1044           (subreg:QI
1045             (zero_extract:SI
1046               (match_operand 0 "ext_register_operand" "")
1047               (const_int 8)
1048               (const_int 8)) 0)
1049           (match_operand:QI 1 "immediate_operand" "")))])
1050
1051 (define_insn "*cmpqi_ext_3_insn"
1052   [(set (reg FLAGS_REG)
1053         (compare
1054           (subreg:QI
1055             (zero_extract:SI
1056               (match_operand 0 "ext_register_operand" "Q")
1057               (const_int 8)
1058               (const_int 8)) 0)
1059           (match_operand:QI 1 "general_operand" "Qmn")))]
1060   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1061   "cmp{b}\t{%1, %h0|%h0, %1}"
1062   [(set_attr "type" "icmp")
1063    (set_attr "modrm" "1")
1064    (set_attr "mode" "QI")])
1065
1066 (define_insn "*cmpqi_ext_3_insn_rex64"
1067   [(set (reg FLAGS_REG)
1068         (compare
1069           (subreg:QI
1070             (zero_extract:SI
1071               (match_operand 0 "ext_register_operand" "Q")
1072               (const_int 8)
1073               (const_int 8)) 0)
1074           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1075   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076   "cmp{b}\t{%1, %h0|%h0, %1}"
1077   [(set_attr "type" "icmp")
1078    (set_attr "modrm" "1")
1079    (set_attr "mode" "QI")])
1080
1081 (define_insn "*cmpqi_ext_4"
1082   [(set (reg FLAGS_REG)
1083         (compare
1084           (subreg:QI
1085             (zero_extract:SI
1086               (match_operand 0 "ext_register_operand" "Q")
1087               (const_int 8)
1088               (const_int 8)) 0)
1089           (subreg:QI
1090             (zero_extract:SI
1091               (match_operand 1 "ext_register_operand" "Q")
1092               (const_int 8)
1093               (const_int 8)) 0)))]
1094   "ix86_match_ccmode (insn, CCmode)"
1095   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1096   [(set_attr "type" "icmp")
1097    (set_attr "mode" "QI")])
1098
1099 ;; These implement float point compares.
1100 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1101 ;; which would allow mix and match FP modes on the compares.  Which is what
1102 ;; the old patterns did, but with many more of them.
1103
1104 (define_expand "cbranchxf4"
1105   [(set (reg:CC FLAGS_REG)
1106         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1107                     (match_operand:XF 2 "nonmemory_operand" "")))
1108    (set (pc) (if_then_else
1109               (match_operator 0 "ix86_fp_comparison_operator"
1110                [(reg:CC FLAGS_REG)
1111                 (const_int 0)])
1112               (label_ref (match_operand 3 "" ""))
1113               (pc)))]
1114   "TARGET_80387"
1115 {
1116   ix86_expand_branch (GET_CODE (operands[0]),
1117                       operands[1], operands[2], operands[3]);
1118   DONE;
1119 })
1120
1121 (define_expand "cstorexf4"
1122   [(set (reg:CC FLAGS_REG)
1123         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1124                     (match_operand:XF 3 "nonmemory_operand" "")))
1125    (set (match_operand:QI 0 "register_operand" "")
1126               (match_operator 1 "ix86_fp_comparison_operator"
1127                [(reg:CC FLAGS_REG)
1128                 (const_int 0)]))]
1129   "TARGET_80387"
1130 {
1131   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1132                      operands[2], operands[3]);
1133   DONE;
1134 })
1135
1136 (define_expand "cbranch<mode>4"
1137   [(set (reg:CC FLAGS_REG)
1138         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1139                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1140    (set (pc) (if_then_else
1141               (match_operator 0 "ix86_fp_comparison_operator"
1142                [(reg:CC FLAGS_REG)
1143                 (const_int 0)])
1144               (label_ref (match_operand 3 "" ""))
1145               (pc)))]
1146   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1147 {
1148   ix86_expand_branch (GET_CODE (operands[0]),
1149                       operands[1], operands[2], operands[3]);
1150   DONE;
1151 })
1152
1153 (define_expand "cstore<mode>4"
1154   [(set (reg:CC FLAGS_REG)
1155         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1156                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1157    (set (match_operand:QI 0 "register_operand" "")
1158               (match_operator 1 "ix86_fp_comparison_operator"
1159                [(reg:CC FLAGS_REG)
1160                 (const_int 0)]))]
1161   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1162 {
1163   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1164                      operands[2], operands[3]);
1165   DONE;
1166 })
1167
1168 (define_expand "cbranchcc4"
1169   [(set (pc) (if_then_else
1170               (match_operator 0 "comparison_operator"
1171                [(match_operand 1 "flags_reg_operand" "")
1172                 (match_operand 2 "const0_operand" "")])
1173               (label_ref (match_operand 3 "" ""))
1174               (pc)))]
1175   ""
1176 {
1177   ix86_expand_branch (GET_CODE (operands[0]),
1178                       operands[1], operands[2], operands[3]);
1179   DONE;
1180 })
1181
1182 (define_expand "cstorecc4"
1183   [(set (match_operand:QI 0 "register_operand" "")
1184               (match_operator 1 "comparison_operator"
1185                [(match_operand 2 "flags_reg_operand" "")
1186                 (match_operand 3 "const0_operand" "")]))]
1187   ""
1188 {
1189   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1190                      operands[2], operands[3]);
1191   DONE;
1192 })
1193
1194
1195 ;; FP compares, step 1:
1196 ;; Set the FP condition codes.
1197 ;;
1198 ;; CCFPmode     compare with exceptions
1199 ;; CCFPUmode    compare with no exceptions
1200
1201 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1202 ;; used to manage the reg stack popping would not be preserved.
1203
1204 (define_insn "*cmpfp_0"
1205   [(set (match_operand:HI 0 "register_operand" "=a")
1206         (unspec:HI
1207           [(compare:CCFP
1208              (match_operand 1 "register_operand" "f")
1209              (match_operand 2 "const0_operand" ""))]
1210         UNSPEC_FNSTSW))]
1211   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1213   "* return output_fp_compare (insn, operands, false, false);"
1214   [(set_attr "type" "multi")
1215    (set_attr "unit" "i387")
1216    (set (attr "mode")
1217      (cond [(match_operand:SF 1 "" "")
1218               (const_string "SF")
1219             (match_operand:DF 1 "" "")
1220               (const_string "DF")
1221            ]
1222            (const_string "XF")))])
1223
1224 (define_insn_and_split "*cmpfp_0_cc"
1225   [(set (reg:CCFP FLAGS_REG)
1226         (compare:CCFP
1227           (match_operand 1 "register_operand" "f")
1228           (match_operand 2 "const0_operand" "")))
1229    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1230   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1231    && TARGET_SAHF && !TARGET_CMOVE
1232    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1233   "#"
1234   "&& reload_completed"
1235   [(set (match_dup 0)
1236         (unspec:HI
1237           [(compare:CCFP (match_dup 1)(match_dup 2))]
1238         UNSPEC_FNSTSW))
1239    (set (reg:CC FLAGS_REG)
1240         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1241   ""
1242   [(set_attr "type" "multi")
1243    (set_attr "unit" "i387")
1244    (set (attr "mode")
1245      (cond [(match_operand:SF 1 "" "")
1246               (const_string "SF")
1247             (match_operand:DF 1 "" "")
1248               (const_string "DF")
1249            ]
1250            (const_string "XF")))])
1251
1252 (define_insn "*cmpfp_xf"
1253   [(set (match_operand:HI 0 "register_operand" "=a")
1254         (unspec:HI
1255           [(compare:CCFP
1256              (match_operand:XF 1 "register_operand" "f")
1257              (match_operand:XF 2 "register_operand" "f"))]
1258           UNSPEC_FNSTSW))]
1259   "TARGET_80387"
1260   "* return output_fp_compare (insn, operands, false, false);"
1261   [(set_attr "type" "multi")
1262    (set_attr "unit" "i387")
1263    (set_attr "mode" "XF")])
1264
1265 (define_insn_and_split "*cmpfp_xf_cc"
1266   [(set (reg:CCFP FLAGS_REG)
1267         (compare:CCFP
1268           (match_operand:XF 1 "register_operand" "f")
1269           (match_operand:XF 2 "register_operand" "f")))
1270    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1271   "TARGET_80387
1272    && TARGET_SAHF && !TARGET_CMOVE"
1273   "#"
1274   "&& reload_completed"
1275   [(set (match_dup 0)
1276         (unspec:HI
1277           [(compare:CCFP (match_dup 1)(match_dup 2))]
1278         UNSPEC_FNSTSW))
1279    (set (reg:CC FLAGS_REG)
1280         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1281   ""
1282   [(set_attr "type" "multi")
1283    (set_attr "unit" "i387")
1284    (set_attr "mode" "XF")])
1285
1286 (define_insn "*cmpfp_<mode>"
1287   [(set (match_operand:HI 0 "register_operand" "=a")
1288         (unspec:HI
1289           [(compare:CCFP
1290              (match_operand:MODEF 1 "register_operand" "f")
1291              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1292           UNSPEC_FNSTSW))]
1293   "TARGET_80387"
1294   "* return output_fp_compare (insn, operands, false, false);"
1295   [(set_attr "type" "multi")
1296    (set_attr "unit" "i387")
1297    (set_attr "mode" "<MODE>")])
1298
1299 (define_insn_and_split "*cmpfp_<mode>_cc"
1300   [(set (reg:CCFP FLAGS_REG)
1301         (compare:CCFP
1302           (match_operand:MODEF 1 "register_operand" "f")
1303           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1304    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1305   "TARGET_80387
1306    && TARGET_SAHF && !TARGET_CMOVE"
1307   "#"
1308   "&& reload_completed"
1309   [(set (match_dup 0)
1310         (unspec:HI
1311           [(compare:CCFP (match_dup 1)(match_dup 2))]
1312         UNSPEC_FNSTSW))
1313    (set (reg:CC FLAGS_REG)
1314         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1315   ""
1316   [(set_attr "type" "multi")
1317    (set_attr "unit" "i387")
1318    (set_attr "mode" "<MODE>")])
1319
1320 (define_insn "*cmpfp_u"
1321   [(set (match_operand:HI 0 "register_operand" "=a")
1322         (unspec:HI
1323           [(compare:CCFPU
1324              (match_operand 1 "register_operand" "f")
1325              (match_operand 2 "register_operand" "f"))]
1326           UNSPEC_FNSTSW))]
1327   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1328    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1329   "* return output_fp_compare (insn, operands, false, true);"
1330   [(set_attr "type" "multi")
1331    (set_attr "unit" "i387")
1332    (set (attr "mode")
1333      (cond [(match_operand:SF 1 "" "")
1334               (const_string "SF")
1335             (match_operand:DF 1 "" "")
1336               (const_string "DF")
1337            ]
1338            (const_string "XF")))])
1339
1340 (define_insn_and_split "*cmpfp_u_cc"
1341   [(set (reg:CCFPU FLAGS_REG)
1342         (compare:CCFPU
1343           (match_operand 1 "register_operand" "f")
1344           (match_operand 2 "register_operand" "f")))
1345    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1346   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1347    && TARGET_SAHF && !TARGET_CMOVE
1348    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1349   "#"
1350   "&& reload_completed"
1351   [(set (match_dup 0)
1352         (unspec:HI
1353           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1354         UNSPEC_FNSTSW))
1355    (set (reg:CC FLAGS_REG)
1356         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1357   ""
1358   [(set_attr "type" "multi")
1359    (set_attr "unit" "i387")
1360    (set (attr "mode")
1361      (cond [(match_operand:SF 1 "" "")
1362               (const_string "SF")
1363             (match_operand:DF 1 "" "")
1364               (const_string "DF")
1365            ]
1366            (const_string "XF")))])
1367
1368 (define_insn "*cmpfp_<mode>"
1369   [(set (match_operand:HI 0 "register_operand" "=a")
1370         (unspec:HI
1371           [(compare:CCFP
1372              (match_operand 1 "register_operand" "f")
1373              (match_operator 3 "float_operator"
1374                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1375           UNSPEC_FNSTSW))]
1376   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1377    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1378    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1379   "* return output_fp_compare (insn, operands, false, false);"
1380   [(set_attr "type" "multi")
1381    (set_attr "unit" "i387")
1382    (set_attr "fp_int_src" "true")
1383    (set_attr "mode" "<MODE>")])
1384
1385 (define_insn_and_split "*cmpfp_<mode>_cc"
1386   [(set (reg:CCFP FLAGS_REG)
1387         (compare:CCFP
1388           (match_operand 1 "register_operand" "f")
1389           (match_operator 3 "float_operator"
1390             [(match_operand:SWI24 2 "memory_operand" "m")])))
1391    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1392   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1393    && TARGET_SAHF && !TARGET_CMOVE
1394    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1395    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1396   "#"
1397   "&& reload_completed"
1398   [(set (match_dup 0)
1399         (unspec:HI
1400           [(compare:CCFP
1401              (match_dup 1)
1402              (match_op_dup 3 [(match_dup 2)]))]
1403         UNSPEC_FNSTSW))
1404    (set (reg:CC FLAGS_REG)
1405         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1406   ""
1407   [(set_attr "type" "multi")
1408    (set_attr "unit" "i387")
1409    (set_attr "fp_int_src" "true")
1410    (set_attr "mode" "<MODE>")])
1411
1412 ;; FP compares, step 2
1413 ;; Move the fpsw to ax.
1414
1415 (define_insn "x86_fnstsw_1"
1416   [(set (match_operand:HI 0 "register_operand" "=a")
1417         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1418   "TARGET_80387"
1419   "fnstsw\t%0"
1420   [(set (attr "length")
1421         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1422    (set_attr "mode" "SI")
1423    (set_attr "unit" "i387")])
1424
1425 ;; FP compares, step 3
1426 ;; Get ax into flags, general case.
1427
1428 (define_insn "x86_sahf_1"
1429   [(set (reg:CC FLAGS_REG)
1430         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1431                    UNSPEC_SAHF))]
1432   "TARGET_SAHF"
1433 {
1434 #ifndef HAVE_AS_IX86_SAHF
1435   if (TARGET_64BIT)
1436     return ASM_BYTE "0x9e";
1437   else
1438 #endif
1439   return "sahf";
1440 }
1441   [(set_attr "length" "1")
1442    (set_attr "athlon_decode" "vector")
1443    (set_attr "amdfam10_decode" "direct")
1444    (set_attr "bdver1_decode" "direct")
1445    (set_attr "mode" "SI")])
1446
1447 ;; Pentium Pro can do steps 1 through 3 in one go.
1448 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1449 ;; (these i387 instructions set flags directly)
1450 (define_insn "*cmpfp_i_mixed"
1451   [(set (reg:CCFP FLAGS_REG)
1452         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1453                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1454   "TARGET_MIX_SSE_I387
1455    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1456    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1457   "* return output_fp_compare (insn, operands, true, false);"
1458   [(set_attr "type" "fcmp,ssecomi")
1459    (set_attr "prefix" "orig,maybe_vex")
1460    (set (attr "mode")
1461      (if_then_else (match_operand:SF 1 "" "")
1462         (const_string "SF")
1463         (const_string "DF")))
1464    (set (attr "prefix_rep")
1465         (if_then_else (eq_attr "type" "ssecomi")
1466                       (const_string "0")
1467                       (const_string "*")))
1468    (set (attr "prefix_data16")
1469         (cond [(eq_attr "type" "fcmp")
1470                  (const_string "*")
1471                (eq_attr "mode" "DF")
1472                  (const_string "1")
1473               ]
1474               (const_string "0")))
1475    (set_attr "athlon_decode" "vector")
1476    (set_attr "amdfam10_decode" "direct")
1477    (set_attr "bdver1_decode" "double")])
1478
1479 (define_insn "*cmpfp_i_sse"
1480   [(set (reg:CCFP FLAGS_REG)
1481         (compare:CCFP (match_operand 0 "register_operand" "x")
1482                       (match_operand 1 "nonimmediate_operand" "xm")))]
1483   "TARGET_SSE_MATH
1484    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1485    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1486   "* return output_fp_compare (insn, operands, true, false);"
1487   [(set_attr "type" "ssecomi")
1488    (set_attr "prefix" "maybe_vex")
1489    (set (attr "mode")
1490      (if_then_else (match_operand:SF 1 "" "")
1491         (const_string "SF")
1492         (const_string "DF")))
1493    (set_attr "prefix_rep" "0")
1494    (set (attr "prefix_data16")
1495         (if_then_else (eq_attr "mode" "DF")
1496                       (const_string "1")
1497                       (const_string "0")))
1498    (set_attr "athlon_decode" "vector")
1499    (set_attr "amdfam10_decode" "direct")
1500    (set_attr "bdver1_decode" "double")])
1501
1502 (define_insn "*cmpfp_i_i387"
1503   [(set (reg:CCFP FLAGS_REG)
1504         (compare:CCFP (match_operand 0 "register_operand" "f")
1505                       (match_operand 1 "register_operand" "f")))]
1506   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1507    && TARGET_CMOVE
1508    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1509    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1510   "* return output_fp_compare (insn, operands, true, false);"
1511   [(set_attr "type" "fcmp")
1512    (set (attr "mode")
1513      (cond [(match_operand:SF 1 "" "")
1514               (const_string "SF")
1515             (match_operand:DF 1 "" "")
1516               (const_string "DF")
1517            ]
1518            (const_string "XF")))
1519    (set_attr "athlon_decode" "vector")
1520    (set_attr "amdfam10_decode" "direct")
1521    (set_attr "bdver1_decode" "double")])
1522
1523 (define_insn "*cmpfp_iu_mixed"
1524   [(set (reg:CCFPU FLAGS_REG)
1525         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1526                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1527   "TARGET_MIX_SSE_I387
1528    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1529    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1530   "* return output_fp_compare (insn, operands, true, true);"
1531   [(set_attr "type" "fcmp,ssecomi")
1532    (set_attr "prefix" "orig,maybe_vex")
1533    (set (attr "mode")
1534      (if_then_else (match_operand:SF 1 "" "")
1535         (const_string "SF")
1536         (const_string "DF")))
1537    (set (attr "prefix_rep")
1538         (if_then_else (eq_attr "type" "ssecomi")
1539                       (const_string "0")
1540                       (const_string "*")))
1541    (set (attr "prefix_data16")
1542         (cond [(eq_attr "type" "fcmp")
1543                  (const_string "*")
1544                (eq_attr "mode" "DF")
1545                  (const_string "1")
1546               ]
1547               (const_string "0")))
1548    (set_attr "athlon_decode" "vector")
1549    (set_attr "amdfam10_decode" "direct")
1550    (set_attr "bdver1_decode" "double")])
1551
1552 (define_insn "*cmpfp_iu_sse"
1553   [(set (reg:CCFPU FLAGS_REG)
1554         (compare:CCFPU (match_operand 0 "register_operand" "x")
1555                        (match_operand 1 "nonimmediate_operand" "xm")))]
1556   "TARGET_SSE_MATH
1557    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1558    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1559   "* return output_fp_compare (insn, operands, true, true);"
1560   [(set_attr "type" "ssecomi")
1561    (set_attr "prefix" "maybe_vex")
1562    (set (attr "mode")
1563      (if_then_else (match_operand:SF 1 "" "")
1564         (const_string "SF")
1565         (const_string "DF")))
1566    (set_attr "prefix_rep" "0")
1567    (set (attr "prefix_data16")
1568         (if_then_else (eq_attr "mode" "DF")
1569                       (const_string "1")
1570                       (const_string "0")))
1571    (set_attr "athlon_decode" "vector")
1572    (set_attr "amdfam10_decode" "direct")
1573    (set_attr "bdver1_decode" "double")])
1574
1575 (define_insn "*cmpfp_iu_387"
1576   [(set (reg:CCFPU FLAGS_REG)
1577         (compare:CCFPU (match_operand 0 "register_operand" "f")
1578                        (match_operand 1 "register_operand" "f")))]
1579   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1580    && TARGET_CMOVE
1581    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1582    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1583   "* return output_fp_compare (insn, operands, true, true);"
1584   [(set_attr "type" "fcmp")
1585    (set (attr "mode")
1586      (cond [(match_operand:SF 1 "" "")
1587               (const_string "SF")
1588             (match_operand:DF 1 "" "")
1589               (const_string "DF")
1590            ]
1591            (const_string "XF")))
1592    (set_attr "athlon_decode" "vector")
1593    (set_attr "amdfam10_decode" "direct")
1594    (set_attr "bdver1_decode" "direct")])
1595 \f
1596 ;; Push/pop instructions.
1597
1598 (define_insn "*push<mode>2"
1599   [(set (match_operand:DWI 0 "push_operand" "=<")
1600         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1601   ""
1602   "#"
1603   [(set_attr "type" "multi")
1604    (set_attr "mode" "<MODE>")])
1605
1606 (define_split
1607   [(set (match_operand:TI 0 "push_operand" "")
1608         (match_operand:TI 1 "general_operand" ""))]
1609   "TARGET_64BIT && reload_completed
1610    && !SSE_REG_P (operands[1])"
1611   [(const_int 0)]
1612   "ix86_split_long_move (operands); DONE;")
1613
1614 (define_insn "*pushdi2_rex64"
1615   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1616         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1617   "TARGET_64BIT"
1618   "@
1619    push{q}\t%1
1620    #"
1621   [(set_attr "type" "push,multi")
1622    (set_attr "mode" "DI")])
1623
1624 ;; Convert impossible pushes of immediate to existing instructions.
1625 ;; First try to get scratch register and go through it.  In case this
1626 ;; fails, push sign extended lower part first and then overwrite
1627 ;; upper part by 32bit move.
1628 (define_peephole2
1629   [(match_scratch:DI 2 "r")
1630    (set (match_operand:DI 0 "push_operand" "")
1631         (match_operand:DI 1 "immediate_operand" ""))]
1632   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1633    && !x86_64_immediate_operand (operands[1], DImode)"
1634   [(set (match_dup 2) (match_dup 1))
1635    (set (match_dup 0) (match_dup 2))])
1636
1637 ;; We need to define this as both peepholer and splitter for case
1638 ;; peephole2 pass is not run.
1639 ;; "&& 1" is needed to keep it from matching the previous pattern.
1640 (define_peephole2
1641   [(set (match_operand:DI 0 "push_operand" "")
1642         (match_operand:DI 1 "immediate_operand" ""))]
1643   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1644    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1645   [(set (match_dup 0) (match_dup 1))
1646    (set (match_dup 2) (match_dup 3))]
1647 {
1648   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1649
1650   operands[1] = gen_lowpart (DImode, operands[2]);
1651   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1652                                                    GEN_INT (4)));
1653 })
1654
1655 (define_split
1656   [(set (match_operand:DI 0 "push_operand" "")
1657         (match_operand:DI 1 "immediate_operand" ""))]
1658   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1659                     ? epilogue_completed : reload_completed)
1660    && !symbolic_operand (operands[1], DImode)
1661    && !x86_64_immediate_operand (operands[1], DImode)"
1662   [(set (match_dup 0) (match_dup 1))
1663    (set (match_dup 2) (match_dup 3))]
1664 {
1665   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1666
1667   operands[1] = gen_lowpart (DImode, operands[2]);
1668   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1669                                                    GEN_INT (4)));
1670 })
1671
1672 (define_split
1673   [(set (match_operand:DI 0 "push_operand" "")
1674         (match_operand:DI 1 "general_operand" ""))]
1675   "!TARGET_64BIT && reload_completed
1676    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1677   [(const_int 0)]
1678   "ix86_split_long_move (operands); DONE;")
1679
1680 (define_insn "*pushsi2"
1681   [(set (match_operand:SI 0 "push_operand" "=<")
1682         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1683   "!TARGET_64BIT"
1684   "push{l}\t%1"
1685   [(set_attr "type" "push")
1686    (set_attr "mode" "SI")])
1687
1688 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1689 ;; "push a byte/word".  But actually we use pushl, which has the effect
1690 ;; of rounding the amount pushed up to a word.
1691
1692 ;; For TARGET_64BIT we always round up to 8 bytes.
1693 (define_insn "*push<mode>2_rex64"
1694   [(set (match_operand:SWI124 0 "push_operand" "=X")
1695         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1696   "TARGET_64BIT"
1697   "push{q}\t%q1"
1698   [(set_attr "type" "push")
1699    (set_attr "mode" "DI")])
1700
1701 (define_insn "*push<mode>2"
1702   [(set (match_operand:SWI12 0 "push_operand" "=X")
1703         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1704   "!TARGET_64BIT"
1705   "push{l}\t%k1"
1706   [(set_attr "type" "push")
1707    (set_attr "mode" "SI")])
1708
1709 (define_insn "*push<mode>2_prologue"
1710   [(set (match_operand:P 0 "push_operand" "=<")
1711         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1712    (clobber (mem:BLK (scratch)))]
1713   ""
1714   "push{<imodesuffix>}\t%1"
1715   [(set_attr "type" "push")
1716    (set_attr "mode" "<MODE>")])
1717
1718 (define_insn "*pop<mode>1"
1719   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1720         (match_operand:P 1 "pop_operand" ">"))]
1721   ""
1722   "pop{<imodesuffix>}\t%0"
1723   [(set_attr "type" "pop")
1724    (set_attr "mode" "<MODE>")])
1725
1726 (define_insn "*pop<mode>1_epilogue"
1727   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1728         (match_operand:P 1 "pop_operand" ">"))
1729    (clobber (mem:BLK (scratch)))]
1730   ""
1731   "pop{<imodesuffix>}\t%0"
1732   [(set_attr "type" "pop")
1733    (set_attr "mode" "<MODE>")])
1734 \f
1735 ;; Move instructions.
1736
1737 (define_expand "movoi"
1738   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1739         (match_operand:OI 1 "general_operand" ""))]
1740   "TARGET_AVX"
1741   "ix86_expand_move (OImode, operands); DONE;")
1742
1743 (define_expand "movti"
1744   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1745         (match_operand:TI 1 "nonimmediate_operand" ""))]
1746   "TARGET_64BIT || TARGET_SSE"
1747 {
1748   if (TARGET_64BIT)
1749     ix86_expand_move (TImode, operands);
1750   else if (push_operand (operands[0], TImode))
1751     ix86_expand_push (TImode, operands[1]);
1752   else
1753     ix86_expand_vector_move (TImode, operands);
1754   DONE;
1755 })
1756
1757 ;; This expands to what emit_move_complex would generate if we didn't
1758 ;; have a movti pattern.  Having this avoids problems with reload on
1759 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1760 ;; to have around all the time.
1761 (define_expand "movcdi"
1762   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1763         (match_operand:CDI 1 "general_operand" ""))]
1764   ""
1765 {
1766   if (push_operand (operands[0], CDImode))
1767     emit_move_complex_push (CDImode, operands[0], operands[1]);
1768   else
1769     emit_move_complex_parts (operands[0], operands[1]);
1770   DONE;
1771 })
1772
1773 (define_expand "mov<mode>"
1774   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1775         (match_operand:SWI1248x 1 "general_operand" ""))]
1776   ""
1777   "ix86_expand_move (<MODE>mode, operands); DONE;")
1778
1779 (define_insn "*mov<mode>_xor"
1780   [(set (match_operand:SWI48 0 "register_operand" "=r")
1781         (match_operand:SWI48 1 "const0_operand" ""))
1782    (clobber (reg:CC FLAGS_REG))]
1783   "reload_completed"
1784   "xor{l}\t%k0, %k0"
1785   [(set_attr "type" "alu1")
1786    (set_attr "mode" "SI")
1787    (set_attr "length_immediate" "0")])
1788
1789 (define_insn "*mov<mode>_or"
1790   [(set (match_operand:SWI48 0 "register_operand" "=r")
1791         (match_operand:SWI48 1 "const_int_operand" ""))
1792    (clobber (reg:CC FLAGS_REG))]
1793   "reload_completed
1794    && operands[1] == constm1_rtx"
1795   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1796   [(set_attr "type" "alu1")
1797    (set_attr "mode" "<MODE>")
1798    (set_attr "length_immediate" "1")])
1799
1800 (define_insn "*movoi_internal_avx"
1801   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1802         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1803   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1804 {
1805   switch (which_alternative)
1806     {
1807     case 0:
1808       return standard_sse_constant_opcode (insn, operands[1]);
1809     case 1:
1810     case 2:
1811       if (misaligned_operand (operands[0], OImode)
1812           || misaligned_operand (operands[1], OImode))
1813         return "vmovdqu\t{%1, %0|%0, %1}";
1814       else
1815         return "vmovdqa\t{%1, %0|%0, %1}";
1816     default:
1817       gcc_unreachable ();
1818     }
1819 }
1820   [(set_attr "type" "sselog1,ssemov,ssemov")
1821    (set_attr "prefix" "vex")
1822    (set_attr "mode" "OI")])
1823
1824 (define_insn "*movti_internal_rex64"
1825   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,m")
1826         (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1827   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1828 {
1829   switch (which_alternative)
1830     {
1831     case 0:
1832     case 1:
1833       return "#";
1834     case 2:
1835       return standard_sse_constant_opcode (insn, operands[1]);
1836     case 3:
1837     case 4:
1838       /* TDmode values are passed as TImode on the stack.  Moving them
1839          to stack may result in unaligned memory access.  */
1840       if (misaligned_operand (operands[0], TImode)
1841           || misaligned_operand (operands[1], TImode))
1842         {
1843           if (get_attr_mode (insn) == MODE_V4SF)
1844             return "%vmovups\t{%1, %0|%0, %1}";
1845           else
1846             return "%vmovdqu\t{%1, %0|%0, %1}";
1847         }
1848       else
1849         {
1850           if (get_attr_mode (insn) == MODE_V4SF)
1851             return "%vmovaps\t{%1, %0|%0, %1}";
1852           else
1853             return "%vmovdqa\t{%1, %0|%0, %1}";
1854         }
1855     default:
1856       gcc_unreachable ();
1857     }
1858 }
1859   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1860    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1861    (set (attr "mode")
1862         (cond [(eq_attr "alternative" "0,1")
1863                  (const_string "DI")
1864                (ior (not (match_test "TARGET_SSE2"))
1865                     (match_test "optimize_function_for_size_p (cfun)"))
1866                  (const_string "V4SF")
1867                (and (eq_attr "alternative" "4")
1868                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1869                  (const_string "V4SF")
1870                ]
1871                (const_string "TI")))])
1872
1873 (define_split
1874   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1875         (match_operand:TI 1 "general_operand" ""))]
1876   "reload_completed
1877    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1878   [(const_int 0)]
1879   "ix86_split_long_move (operands); DONE;")
1880
1881 (define_insn "*movti_internal_sse"
1882   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1883         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1884   "TARGET_SSE && !TARGET_64BIT
1885    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1886 {
1887   switch (which_alternative)
1888     {
1889     case 0:
1890       return standard_sse_constant_opcode (insn, operands[1]);
1891     case 1:
1892     case 2:
1893       /* TDmode values are passed as TImode on the stack.  Moving them
1894          to stack may result in unaligned memory access.  */
1895       if (misaligned_operand (operands[0], TImode)
1896           || misaligned_operand (operands[1], TImode))
1897         {
1898           if (get_attr_mode (insn) == MODE_V4SF)
1899             return "%vmovups\t{%1, %0|%0, %1}";
1900           else
1901             return "%vmovdqu\t{%1, %0|%0, %1}";
1902         }
1903       else
1904         {
1905           if (get_attr_mode (insn) == MODE_V4SF)
1906             return "%vmovaps\t{%1, %0|%0, %1}";
1907           else
1908             return "%vmovdqa\t{%1, %0|%0, %1}";
1909         }
1910     default:
1911       gcc_unreachable ();
1912     }
1913 }
1914   [(set_attr "type" "sselog1,ssemov,ssemov")
1915    (set_attr "prefix" "maybe_vex")
1916    (set (attr "mode")
1917         (cond [(ior (not (match_test "TARGET_SSE2"))
1918                     (match_test "optimize_function_for_size_p (cfun)"))
1919                  (const_string "V4SF")
1920                (and (eq_attr "alternative" "2")
1921                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1922                  (const_string "V4SF")]
1923               (const_string "TI")))])
1924
1925 (define_insn "*movdi_internal_rex64"
1926   [(set (match_operand:DI 0 "nonimmediate_operand"
1927           "=r,r  ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1928         (match_operand:DI 1 "general_operand"
1929           "Z ,rem,i,re,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1930   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1931 {
1932   switch (get_attr_type (insn))
1933     {
1934     case TYPE_SSECVT:
1935       if (SSE_REG_P (operands[0]))
1936         return "movq2dq\t{%1, %0|%0, %1}";
1937       else
1938         return "movdq2q\t{%1, %0|%0, %1}";
1939
1940     case TYPE_SSEMOV:
1941       if (get_attr_mode (insn) == MODE_TI)
1942         return "%vmovdqa\t{%1, %0|%0, %1}";
1943       /* Handle broken assemblers that require movd instead of movq.  */
1944       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1945         return "%vmovd\t{%1, %0|%0, %1}";
1946       else
1947         return "%vmovq\t{%1, %0|%0, %1}";
1948
1949     case TYPE_MMXMOV:
1950       /* Handle broken assemblers that require movd instead of movq.  */
1951       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1952         return "movd\t{%1, %0|%0, %1}";
1953       else
1954         return "movq\t{%1, %0|%0, %1}";
1955
1956     case TYPE_SSELOG1:
1957       return standard_sse_constant_opcode (insn, operands[1]);
1958
1959     case TYPE_MMX:
1960       return "pxor\t%0, %0";
1961
1962     case TYPE_LEA:
1963       return "lea{q}\t{%E1, %0|%0, %E1}";
1964
1965     default:
1966       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1967       if (get_attr_mode (insn) == MODE_SI)
1968         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1969       else if (which_alternative == 2)
1970         return "movabs{q}\t{%1, %0|%0, %1}";
1971       else if (ix86_use_lea_for_mov (insn, operands))
1972         return "lea{q}\t{%E1, %0|%0, %E1}";
1973       else
1974         return "mov{q}\t{%1, %0|%0, %1}";
1975     }
1976 }
1977   [(set (attr "type")
1978      (cond [(eq_attr "alternative" "4")
1979               (const_string "mmx")
1980             (eq_attr "alternative" "5,6,7,8")
1981               (const_string "mmxmov")
1982             (eq_attr "alternative" "9")
1983               (const_string "sselog1")
1984             (eq_attr "alternative" "10,11,12,13,14")
1985               (const_string "ssemov")
1986             (eq_attr "alternative" "15,16")
1987               (const_string "ssecvt")
1988             (match_operand 1 "pic_32bit_operand" "")
1989               (const_string "lea")
1990            ]
1991            (const_string "imov")))
1992    (set (attr "modrm")
1993      (if_then_else
1994        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1995          (const_string "0")
1996          (const_string "*")))
1997    (set (attr "length_immediate")
1998      (if_then_else
1999        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2000          (const_string "8")
2001          (const_string "*")))
2002    (set (attr "prefix_rex")
2003      (if_then_else (eq_attr "alternative" "7,8")
2004        (const_string "1")
2005        (const_string "*")))
2006    (set (attr "prefix_data16")
2007      (if_then_else (eq_attr "alternative" "10")
2008        (const_string "1")
2009        (const_string "*")))
2010    (set (attr "prefix")
2011      (if_then_else (eq_attr "alternative" "11,12,13,14,15")
2012        (const_string "maybe_vex")
2013        (const_string "orig")))
2014    (set_attr "mode" "SI,DI,DI,DI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2015
2016 ;; Reload patterns to support multi-word load/store
2017 ;; with non-offsetable address.
2018 (define_expand "reload_noff_store"
2019   [(parallel [(match_operand 0 "memory_operand" "=m")
2020               (match_operand 1 "register_operand" "r")
2021               (match_operand:DI 2 "register_operand" "=&r")])]
2022   "TARGET_64BIT"
2023 {
2024   rtx mem = operands[0];
2025   rtx addr = XEXP (mem, 0);
2026
2027   emit_move_insn (operands[2], addr);
2028   mem = replace_equiv_address_nv (mem, operands[2]);
2029
2030   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2031   DONE;
2032 })
2033
2034 (define_expand "reload_noff_load"
2035   [(parallel [(match_operand 0 "register_operand" "=r")
2036               (match_operand 1 "memory_operand" "m")
2037               (match_operand:DI 2 "register_operand" "=r")])]
2038   "TARGET_64BIT"
2039 {
2040   rtx mem = operands[1];
2041   rtx addr = XEXP (mem, 0);
2042
2043   emit_move_insn (operands[2], addr);
2044   mem = replace_equiv_address_nv (mem, operands[2]);
2045
2046   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2047   DONE;
2048 })
2049
2050 (define_insn "*movdi_internal"
2051   [(set (match_operand:DI 0 "nonimmediate_operand"
2052           "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2053         (match_operand:DI 1 "general_operand"
2054           "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2055   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2056 {
2057   switch (get_attr_type (insn))
2058     {
2059     case TYPE_SSECVT:
2060       if (SSE_REG_P (operands[0]))
2061         return "movq2dq\t{%1, %0|%0, %1}";
2062       else
2063         return "movdq2q\t{%1, %0|%0, %1}";
2064
2065     case TYPE_SSEMOV:
2066       switch (get_attr_mode (insn))
2067         {
2068         case MODE_TI:
2069           return "%vmovdqa\t{%1, %0|%0, %1}";
2070         case MODE_DI:
2071            return "%vmovq\t{%1, %0|%0, %1}";
2072         case MODE_V4SF:
2073           return "movaps\t{%1, %0|%0, %1}";
2074         case MODE_V2SF:
2075           return "movlps\t{%1, %0|%0, %1}";
2076         default:
2077           gcc_unreachable ();
2078         }
2079
2080     case TYPE_MMXMOV:
2081       return "movq\t{%1, %0|%0, %1}";
2082
2083     case TYPE_SSELOG1:
2084       return standard_sse_constant_opcode (insn, operands[1]);
2085
2086     case TYPE_MMX:
2087       return "pxor\t%0, %0";
2088
2089     case TYPE_MULTI:
2090       return "#";
2091
2092     default:
2093       gcc_unreachable ();
2094     }
2095 }
2096   [(set (attr "isa")
2097      (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2098               (const_string "sse2")
2099             (eq_attr "alternative" "9,10,11,12")
2100               (const_string "noavx")
2101            ]
2102            (const_string "*")))
2103    (set (attr "type")
2104      (cond [(eq_attr "alternative" "0,1")
2105               (const_string "multi")
2106             (eq_attr "alternative" "2")
2107               (const_string "mmx")
2108             (eq_attr "alternative" "3,4")
2109               (const_string "mmxmov")
2110             (eq_attr "alternative" "5,9")
2111               (const_string "sselog1")
2112             (eq_attr "alternative" "13,14")
2113               (const_string "ssecvt")
2114            ]
2115            (const_string "ssemov")))
2116    (set (attr "prefix")
2117      (if_then_else (eq_attr "alternative" "5,6,7,8")
2118        (const_string "maybe_vex")
2119        (const_string "orig")))
2120    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2121
2122 (define_split
2123   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2124         (match_operand:DI 1 "general_operand" ""))]
2125   "!TARGET_64BIT && reload_completed
2126    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2127    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2128   [(const_int 0)]
2129   "ix86_split_long_move (operands); DONE;")
2130
2131 (define_insn "*movsi_internal"
2132   [(set (match_operand:SI 0 "nonimmediate_operand"
2133                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2134         (match_operand:SI 1 "general_operand"
2135                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2136   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2137 {
2138   switch (get_attr_type (insn))
2139     {
2140     case TYPE_SSELOG1:
2141       return standard_sse_constant_opcode (insn, operands[1]);
2142
2143     case TYPE_SSEMOV:
2144       switch (get_attr_mode (insn))
2145         {
2146         case MODE_TI:
2147           return "%vmovdqa\t{%1, %0|%0, %1}";
2148         case MODE_V4SF:
2149           return "%vmovaps\t{%1, %0|%0, %1}";
2150         case MODE_SI:
2151           return "%vmovd\t{%1, %0|%0, %1}";
2152         case MODE_SF:
2153           return "%vmovss\t{%1, %0|%0, %1}";
2154         default:
2155           gcc_unreachable ();
2156         }
2157
2158     case TYPE_MMX:
2159       return "pxor\t%0, %0";
2160
2161     case TYPE_MMXMOV:
2162       if (get_attr_mode (insn) == MODE_DI)
2163         return "movq\t{%1, %0|%0, %1}";
2164       return "movd\t{%1, %0|%0, %1}";
2165
2166     case TYPE_LEA:
2167       return "lea{l}\t{%E1, %0|%0, %E1}";
2168
2169     default:
2170       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2171       if (ix86_use_lea_for_mov (insn, operands))
2172         return "lea{l}\t{%E1, %0|%0, %E1}";
2173       else
2174         return "mov{l}\t{%1, %0|%0, %1}";
2175     }
2176 }
2177   [(set (attr "type")
2178      (cond [(eq_attr "alternative" "2")
2179               (const_string "mmx")
2180             (eq_attr "alternative" "3,4,5")
2181               (const_string "mmxmov")
2182             (eq_attr "alternative" "6")
2183               (const_string "sselog1")
2184             (eq_attr "alternative" "7,8,9,10,11")
2185               (const_string "ssemov")
2186             (match_operand 1 "pic_32bit_operand" "")
2187               (const_string "lea")
2188            ]
2189            (const_string "imov")))
2190    (set (attr "prefix")
2191      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2192        (const_string "orig")
2193        (const_string "maybe_vex")))
2194    (set (attr "prefix_data16")
2195      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2196        (const_string "1")
2197        (const_string "*")))
2198    (set (attr "mode")
2199      (cond [(eq_attr "alternative" "2,3")
2200               (const_string "DI")
2201             (eq_attr "alternative" "6,7")
2202               (if_then_else
2203                 (not (match_test "TARGET_SSE2"))
2204                 (const_string "V4SF")
2205                 (const_string "TI"))
2206             (and (eq_attr "alternative" "8,9,10,11")
2207                  (not (match_test "TARGET_SSE2")))
2208               (const_string "SF")
2209            ]
2210            (const_string "SI")))])
2211
2212 (define_insn "*movhi_internal"
2213   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2214         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2215   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2216 {
2217   switch (get_attr_type (insn))
2218     {
2219     case TYPE_IMOVX:
2220       /* movzwl is faster than movw on p2 due to partial word stalls,
2221          though not as fast as an aligned movl.  */
2222       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2223     default:
2224       if (get_attr_mode (insn) == MODE_SI)
2225         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2226       else
2227         return "mov{w}\t{%1, %0|%0, %1}";
2228     }
2229 }
2230   [(set (attr "type")
2231      (cond [(match_test "optimize_function_for_size_p (cfun)")
2232               (const_string "imov")
2233             (and (eq_attr "alternative" "0")
2234                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2235                       (not (match_test "TARGET_HIMODE_MATH"))))
2236               (const_string "imov")
2237             (and (eq_attr "alternative" "1,2")
2238                  (match_operand:HI 1 "aligned_operand" ""))
2239               (const_string "imov")
2240             (and (match_test "TARGET_MOVX")
2241                  (eq_attr "alternative" "0,2"))
2242               (const_string "imovx")
2243            ]
2244            (const_string "imov")))
2245     (set (attr "mode")
2246       (cond [(eq_attr "type" "imovx")
2247                (const_string "SI")
2248              (and (eq_attr "alternative" "1,2")
2249                   (match_operand:HI 1 "aligned_operand" ""))
2250                (const_string "SI")
2251              (and (eq_attr "alternative" "0")
2252                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2253                        (not (match_test "TARGET_HIMODE_MATH"))))
2254                (const_string "SI")
2255             ]
2256             (const_string "HI")))])
2257
2258 ;; Situation is quite tricky about when to choose full sized (SImode) move
2259 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2260 ;; partial register dependency machines (such as AMD Athlon), where QImode
2261 ;; moves issue extra dependency and for partial register stalls machines
2262 ;; that don't use QImode patterns (and QImode move cause stall on the next
2263 ;; instruction).
2264 ;;
2265 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2266 ;; register stall machines with, where we use QImode instructions, since
2267 ;; partial register stall can be caused there.  Then we use movzx.
2268 (define_insn "*movqi_internal"
2269   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2270         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2271   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2272 {
2273   switch (get_attr_type (insn))
2274     {
2275     case TYPE_IMOVX:
2276       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2277       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2278     default:
2279       if (get_attr_mode (insn) == MODE_SI)
2280         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2281       else
2282         return "mov{b}\t{%1, %0|%0, %1}";
2283     }
2284 }
2285   [(set (attr "type")
2286      (cond [(and (eq_attr "alternative" "5")
2287                  (not (match_operand:QI 1 "aligned_operand" "")))
2288               (const_string "imovx")
2289             (match_test "optimize_function_for_size_p (cfun)")
2290               (const_string "imov")
2291             (and (eq_attr "alternative" "3")
2292                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2293                       (not (match_test "TARGET_QIMODE_MATH"))))
2294               (const_string "imov")
2295             (eq_attr "alternative" "3,5")
2296               (const_string "imovx")
2297             (and (match_test "TARGET_MOVX")
2298                  (eq_attr "alternative" "2"))
2299               (const_string "imovx")
2300            ]
2301            (const_string "imov")))
2302    (set (attr "mode")
2303       (cond [(eq_attr "alternative" "3,4,5")
2304                (const_string "SI")
2305              (eq_attr "alternative" "6")
2306                (const_string "QI")
2307              (eq_attr "type" "imovx")
2308                (const_string "SI")
2309              (and (eq_attr "type" "imov")
2310                   (and (eq_attr "alternative" "0,1")
2311                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2312                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2313                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2314                (const_string "SI")
2315              ;; Avoid partial register stalls when not using QImode arithmetic
2316              (and (eq_attr "type" "imov")
2317                   (and (eq_attr "alternative" "0,1")
2318                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2319                             (not (match_test "TARGET_QIMODE_MATH")))))
2320                (const_string "SI")
2321            ]
2322            (const_string "QI")))])
2323
2324 ;; Stores and loads of ax to arbitrary constant address.
2325 ;; We fake an second form of instruction to force reload to load address
2326 ;; into register when rax is not available
2327 (define_insn "*movabs<mode>_1"
2328   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2329         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2330   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2331   "@
2332    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2333    mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2334   [(set_attr "type" "imov")
2335    (set_attr "modrm" "0,*")
2336    (set_attr "length_address" "8,0")
2337    (set_attr "length_immediate" "0,*")
2338    (set_attr "memory" "store")
2339    (set_attr "mode" "<MODE>")])
2340
2341 (define_insn "*movabs<mode>_2"
2342   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2343         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2344   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2345   "@
2346    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2347    mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2348   [(set_attr "type" "imov")
2349    (set_attr "modrm" "0,*")
2350    (set_attr "length_address" "8,0")
2351    (set_attr "length_immediate" "0")
2352    (set_attr "memory" "load")
2353    (set_attr "mode" "<MODE>")])
2354
2355 (define_insn "*swap<mode>"
2356   [(set (match_operand:SWI48 0 "register_operand" "+r")
2357         (match_operand:SWI48 1 "register_operand" "+r"))
2358    (set (match_dup 1)
2359         (match_dup 0))]
2360   ""
2361   "xchg{<imodesuffix>}\t%1, %0"
2362   [(set_attr "type" "imov")
2363    (set_attr "mode" "<MODE>")
2364    (set_attr "pent_pair" "np")
2365    (set_attr "athlon_decode" "vector")
2366    (set_attr "amdfam10_decode" "double")
2367    (set_attr "bdver1_decode" "double")])
2368
2369 (define_insn "*swap<mode>_1"
2370   [(set (match_operand:SWI12 0 "register_operand" "+r")
2371         (match_operand:SWI12 1 "register_operand" "+r"))
2372    (set (match_dup 1)
2373         (match_dup 0))]
2374   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2375   "xchg{l}\t%k1, %k0"
2376   [(set_attr "type" "imov")
2377    (set_attr "mode" "SI")
2378    (set_attr "pent_pair" "np")
2379    (set_attr "athlon_decode" "vector")
2380    (set_attr "amdfam10_decode" "double")
2381    (set_attr "bdver1_decode" "double")])
2382
2383 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2384 ;; is disabled for AMDFAM10
2385 (define_insn "*swap<mode>_2"
2386   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2387         (match_operand:SWI12 1 "register_operand" "+<r>"))
2388    (set (match_dup 1)
2389         (match_dup 0))]
2390   "TARGET_PARTIAL_REG_STALL"
2391   "xchg{<imodesuffix>}\t%1, %0"
2392   [(set_attr "type" "imov")
2393    (set_attr "mode" "<MODE>")
2394    (set_attr "pent_pair" "np")
2395    (set_attr "athlon_decode" "vector")])
2396
2397 (define_expand "movstrict<mode>"
2398   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2399         (match_operand:SWI12 1 "general_operand" ""))]
2400   ""
2401 {
2402   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2403     FAIL;
2404   if (GET_CODE (operands[0]) == SUBREG
2405       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2406     FAIL;
2407   /* Don't generate memory->memory moves, go through a register */
2408   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2409     operands[1] = force_reg (<MODE>mode, operands[1]);
2410 })
2411
2412 (define_insn "*movstrict<mode>_1"
2413   [(set (strict_low_part
2414           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2415         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2416   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2417    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2418   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2419   [(set_attr "type" "imov")
2420    (set_attr "mode" "<MODE>")])
2421
2422 (define_insn "*movstrict<mode>_xor"
2423   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2424         (match_operand:SWI12 1 "const0_operand" ""))
2425    (clobber (reg:CC FLAGS_REG))]
2426   "reload_completed"
2427   "xor{<imodesuffix>}\t%0, %0"
2428   [(set_attr "type" "alu1")
2429    (set_attr "mode" "<MODE>")
2430    (set_attr "length_immediate" "0")])
2431
2432 (define_insn "*mov<mode>_extv_1"
2433   [(set (match_operand:SWI24 0 "register_operand" "=R")
2434         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2435                             (const_int 8)
2436                             (const_int 8)))]
2437   ""
2438   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2439   [(set_attr "type" "imovx")
2440    (set_attr "mode" "SI")])
2441
2442 (define_insn "*movqi_extv_1_rex64"
2443   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2444         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2445                          (const_int 8)
2446                          (const_int 8)))]
2447   "TARGET_64BIT"
2448 {
2449   switch (get_attr_type (insn))
2450     {
2451     case TYPE_IMOVX:
2452       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2453     default:
2454       return "mov{b}\t{%h1, %0|%0, %h1}";
2455     }
2456 }
2457   [(set (attr "type")
2458      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2459                         (match_test "TARGET_MOVX"))
2460         (const_string "imovx")
2461         (const_string "imov")))
2462    (set (attr "mode")
2463      (if_then_else (eq_attr "type" "imovx")
2464         (const_string "SI")
2465         (const_string "QI")))])
2466
2467 (define_insn "*movqi_extv_1"
2468   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2469         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2470                          (const_int 8)
2471                          (const_int 8)))]
2472   "!TARGET_64BIT"
2473 {
2474   switch (get_attr_type (insn))
2475     {
2476     case TYPE_IMOVX:
2477       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2478     default:
2479       return "mov{b}\t{%h1, %0|%0, %h1}";
2480     }
2481 }
2482   [(set (attr "type")
2483      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2484                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2485                              (match_test "TARGET_MOVX")))
2486         (const_string "imovx")
2487         (const_string "imov")))
2488    (set (attr "mode")
2489      (if_then_else (eq_attr "type" "imovx")
2490         (const_string "SI")
2491         (const_string "QI")))])
2492
2493 (define_insn "*mov<mode>_extzv_1"
2494   [(set (match_operand:SWI48 0 "register_operand" "=R")
2495         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2496                             (const_int 8)
2497                             (const_int 8)))]
2498   ""
2499   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2500   [(set_attr "type" "imovx")
2501    (set_attr "mode" "SI")])
2502
2503 (define_insn "*movqi_extzv_2_rex64"
2504   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2505         (subreg:QI
2506           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2507                            (const_int 8)
2508                            (const_int 8)) 0))]
2509   "TARGET_64BIT"
2510 {
2511   switch (get_attr_type (insn))
2512     {
2513     case TYPE_IMOVX:
2514       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2515     default:
2516       return "mov{b}\t{%h1, %0|%0, %h1}";
2517     }
2518 }
2519   [(set (attr "type")
2520      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2521                         (match_test "TARGET_MOVX"))
2522         (const_string "imovx")
2523         (const_string "imov")))
2524    (set (attr "mode")
2525      (if_then_else (eq_attr "type" "imovx")
2526         (const_string "SI")
2527         (const_string "QI")))])
2528
2529 (define_insn "*movqi_extzv_2"
2530   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2531         (subreg:QI
2532           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2533                            (const_int 8)
2534                            (const_int 8)) 0))]
2535   "!TARGET_64BIT"
2536 {
2537   switch (get_attr_type (insn))
2538     {
2539     case TYPE_IMOVX:
2540       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2541     default:
2542       return "mov{b}\t{%h1, %0|%0, %h1}";
2543     }
2544 }
2545   [(set (attr "type")
2546      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2547                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2548                              (match_test "TARGET_MOVX")))
2549         (const_string "imovx")
2550         (const_string "imov")))
2551    (set (attr "mode")
2552      (if_then_else (eq_attr "type" "imovx")
2553         (const_string "SI")
2554         (const_string "QI")))])
2555
2556 (define_expand "mov<mode>_insv_1"
2557   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2558                             (const_int 8)
2559                             (const_int 8))
2560         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2561
2562 (define_insn "*mov<mode>_insv_1_rex64"
2563   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2564                              (const_int 8)
2565                              (const_int 8))
2566         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2567   "TARGET_64BIT"
2568 {
2569   if (CONST_INT_P (operands[1]))
2570     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2571   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2572 }
2573   [(set_attr "type" "imov")
2574    (set_attr "mode" "QI")])
2575
2576 (define_insn "*movsi_insv_1"
2577   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2578                          (const_int 8)
2579                          (const_int 8))
2580         (match_operand:SI 1 "general_operand" "Qmn"))]
2581   "!TARGET_64BIT"
2582 {
2583   if (CONST_INT_P (operands[1]))
2584     operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2585   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2586 }
2587   [(set_attr "type" "imov")
2588    (set_attr "mode" "QI")])
2589
2590 (define_insn "*movqi_insv_2"
2591   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2592                          (const_int 8)
2593                          (const_int 8))
2594         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2595                      (const_int 8)))]
2596   ""
2597   "mov{b}\t{%h1, %h0|%h0, %h1}"
2598   [(set_attr "type" "imov")
2599    (set_attr "mode" "QI")])
2600 \f
2601 ;; Floating point push instructions.
2602
2603 (define_insn "*pushtf"
2604   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2605         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2606   "TARGET_SSE2"
2607 {
2608   /* This insn should be already split before reg-stack.  */
2609   gcc_unreachable ();
2610 }
2611   [(set_attr "type" "multi")
2612    (set_attr "unit" "sse,*,*")
2613    (set_attr "mode" "TF,SI,SI")])
2614
2615 ;; %%% Kill this when call knows how to work this out.
2616 (define_split
2617   [(set (match_operand:TF 0 "push_operand" "")
2618         (match_operand:TF 1 "sse_reg_operand" ""))]
2619   "TARGET_SSE2 && reload_completed"
2620   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2621    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2622
2623 (define_insn "*pushxf"
2624   [(set (match_operand:XF 0 "push_operand" "=<,<")
2625         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2626   "optimize_function_for_speed_p (cfun)"
2627 {
2628   /* This insn should be already split before reg-stack.  */
2629   gcc_unreachable ();
2630 }
2631   [(set_attr "type" "multi")
2632    (set_attr "unit" "i387,*")
2633    (set_attr "mode" "XF,SI")])
2634
2635 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2636 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2637 ;; Pushing using integer instructions is longer except for constants
2638 ;; and direct memory references (assuming that any given constant is pushed
2639 ;; only once, but this ought to be handled elsewhere).
2640
2641 (define_insn "*pushxf_nointeger"
2642   [(set (match_operand:XF 0 "push_operand" "=<,<")
2643         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2644   "optimize_function_for_size_p (cfun)"
2645 {
2646   /* This insn should be already split before reg-stack.  */
2647   gcc_unreachable ();
2648 }
2649   [(set_attr "type" "multi")
2650    (set_attr "unit" "i387,*")
2651    (set_attr "mode" "XF,SI")])
2652
2653 ;; %%% Kill this when call knows how to work this out.
2654 (define_split
2655   [(set (match_operand:XF 0 "push_operand" "")
2656         (match_operand:XF 1 "fp_register_operand" ""))]
2657   "reload_completed"
2658   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2659    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2660   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2661
2662 (define_insn "*pushdf_rex64"
2663   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2664         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2665   "TARGET_64BIT"
2666 {
2667   /* This insn should be already split before reg-stack.  */
2668   gcc_unreachable ();
2669 }
2670   [(set_attr "type" "multi")
2671    (set_attr "unit" "i387,*,*")
2672    (set_attr "mode" "DF,DI,DF")])
2673
2674 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2675 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2676 ;; On the average, pushdf using integers can be still shorter.
2677
2678 (define_insn "*pushdf"
2679   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2680         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2681   "!TARGET_64BIT"
2682 {
2683   /* This insn should be already split before reg-stack.  */
2684   gcc_unreachable ();
2685 }
2686   [(set_attr "isa" "*,*,sse2")
2687    (set_attr "type" "multi")
2688    (set_attr "unit" "i387,*,*")
2689    (set_attr "mode" "DF,DI,DF")])
2690
2691 ;; %%% Kill this when call knows how to work this out.
2692 (define_split
2693   [(set (match_operand:DF 0 "push_operand" "")
2694         (match_operand:DF 1 "any_fp_register_operand" ""))]
2695   "reload_completed"
2696   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2697    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2698
2699 (define_insn "*pushsf_rex64"
2700   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2701         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2702   "TARGET_64BIT"
2703 {
2704   /* Anything else should be already split before reg-stack.  */
2705   gcc_assert (which_alternative == 1);
2706   return "push{q}\t%q1";
2707 }
2708   [(set_attr "type" "multi,push,multi")
2709    (set_attr "unit" "i387,*,*")
2710    (set_attr "mode" "SF,DI,SF")])
2711
2712 (define_insn "*pushsf"
2713   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2714         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2715   "!TARGET_64BIT"
2716 {
2717   /* Anything else should be already split before reg-stack.  */
2718   gcc_assert (which_alternative == 1);
2719   return "push{l}\t%1";
2720 }
2721   [(set_attr "type" "multi,push,multi")
2722    (set_attr "unit" "i387,*,*")
2723    (set_attr "mode" "SF,SI,SF")])
2724
2725 ;; %%% Kill this when call knows how to work this out.
2726 (define_split
2727   [(set (match_operand:SF 0 "push_operand" "")
2728         (match_operand:SF 1 "any_fp_register_operand" ""))]
2729   "reload_completed"
2730   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2731    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2732   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2733
2734 (define_split
2735   [(set (match_operand:SF 0 "push_operand" "")
2736         (match_operand:SF 1 "memory_operand" ""))]
2737   "reload_completed
2738    && (operands[2] = find_constant_src (insn))"
2739   [(set (match_dup 0) (match_dup 2))])
2740
2741 (define_split
2742   [(set (match_operand 0 "push_operand" "")
2743         (match_operand 1 "general_operand" ""))]
2744   "reload_completed
2745    && (GET_MODE (operands[0]) == TFmode
2746        || GET_MODE (operands[0]) == XFmode
2747        || GET_MODE (operands[0]) == DFmode)
2748    && !ANY_FP_REG_P (operands[1])"
2749   [(const_int 0)]
2750   "ix86_split_long_move (operands); DONE;")
2751 \f
2752 ;; Floating point move instructions.
2753
2754 (define_expand "movtf"
2755   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2756         (match_operand:TF 1 "nonimmediate_operand" ""))]
2757   "TARGET_64BIT || TARGET_SSE2"
2758 {
2759   ix86_expand_move (TFmode, operands);
2760   DONE;
2761 })
2762
2763 (define_expand "mov<mode>"
2764   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2765         (match_operand:X87MODEF 1 "general_operand" ""))]
2766   ""
2767   "ix86_expand_move (<MODE>mode, operands); DONE;")
2768
2769 (define_insn "*movtf_internal_rex64"
2770   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2771         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,*r"))]
2772   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2773    && (!can_create_pseudo_p ()
2774        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2775        || GET_CODE (operands[1]) != CONST_DOUBLE
2776        || (optimize_function_for_size_p (cfun)
2777            && standard_sse_constant_p (operands[1])
2778            && !memory_operand (operands[0], TFmode))
2779        || (!TARGET_MEMORY_MISMATCH_STALL
2780            && memory_operand (operands[0], TFmode)))"
2781 {
2782   switch (which_alternative)
2783     {
2784     case 0:
2785     case 1:
2786       /* Handle misaligned load/store since we
2787          don't have movmisaligntf pattern. */
2788       if (misaligned_operand (operands[0], TFmode)
2789           || misaligned_operand (operands[1], TFmode))
2790         {
2791           if (get_attr_mode (insn) == MODE_V4SF)
2792             return "%vmovups\t{%1, %0|%0, %1}";
2793           else
2794             return "%vmovdqu\t{%1, %0|%0, %1}";
2795         }
2796       else
2797         {
2798           if (get_attr_mode (insn) == MODE_V4SF)
2799             return "%vmovaps\t{%1, %0|%0, %1}";
2800           else
2801             return "%vmovdqa\t{%1, %0|%0, %1}";
2802         }
2803
2804     case 2:
2805       return standard_sse_constant_opcode (insn, operands[1]);
2806
2807     case 3:
2808     case 4:
2809         return "#";
2810
2811     default:
2812       gcc_unreachable ();
2813     }
2814 }
2815   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2816    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2817    (set (attr "mode")
2818         (cond [(eq_attr "alternative" "0,2")
2819                  (if_then_else
2820                    (match_test "optimize_function_for_size_p (cfun)")
2821                    (const_string "V4SF")
2822                    (const_string "TI"))
2823                (eq_attr "alternative" "1")
2824                  (if_then_else
2825                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2826                         (match_test "optimize_function_for_size_p (cfun)"))
2827                    (const_string "V4SF")
2828                    (const_string "TI"))]
2829                (const_string "DI")))])
2830
2831 (define_insn "*movtf_internal_sse2"
2832   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x")
2833         (match_operand:TF 1 "general_operand"      "xm,x,C"))]
2834   "TARGET_SSE2 && !TARGET_64BIT
2835    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2836    && (!can_create_pseudo_p ()
2837        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2838        || GET_CODE (operands[1]) != CONST_DOUBLE
2839        || (optimize_function_for_size_p (cfun)
2840            && standard_sse_constant_p (operands[1])
2841            && !memory_operand (operands[0], TFmode))
2842        || (!TARGET_MEMORY_MISMATCH_STALL
2843            && memory_operand (operands[0], TFmode)))"
2844 {
2845   switch (which_alternative)
2846     {
2847     case 0:
2848     case 1:
2849       /* Handle misaligned load/store since we
2850          don't have movmisaligntf pattern. */
2851       if (misaligned_operand (operands[0], TFmode)
2852           || misaligned_operand (operands[1], TFmode))
2853         {
2854           if (get_attr_mode (insn) == MODE_V4SF)
2855             return "%vmovups\t{%1, %0|%0, %1}";
2856           else
2857             return "%vmovdqu\t{%1, %0|%0, %1}";
2858         }
2859       else
2860         {
2861           if (get_attr_mode (insn) == MODE_V4SF)
2862             return "%vmovaps\t{%1, %0|%0, %1}";
2863           else
2864             return "%vmovdqa\t{%1, %0|%0, %1}";
2865         }
2866
2867     case 2:
2868       return standard_sse_constant_opcode (insn, operands[1]);
2869
2870     default:
2871       gcc_unreachable ();
2872     }
2873 }
2874   [(set_attr "type" "ssemov,ssemov,sselog1")
2875    (set_attr "prefix" "maybe_vex")
2876    (set (attr "mode")
2877         (cond [(eq_attr "alternative" "0,2")
2878                  (if_then_else
2879                    (match_test "optimize_function_for_size_p (cfun)")
2880                    (const_string "V4SF")
2881                    (const_string "TI"))
2882                (eq_attr "alternative" "1")
2883                  (if_then_else
2884                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2885                         (match_test "optimize_function_for_size_p (cfun)"))
2886                    (const_string "V4SF")
2887                    (const_string "TI"))]
2888                (const_string "DI")))])
2889
2890 (define_insn "*movxf_internal_rex64"
2891   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2892         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,Yx*rC"))]
2893   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2894    && (!can_create_pseudo_p ()
2895        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2896        || GET_CODE (operands[1]) != CONST_DOUBLE
2897        || (optimize_function_for_size_p (cfun)
2898            && standard_80387_constant_p (operands[1]) > 0
2899            && !memory_operand (operands[0], XFmode))
2900        || (!TARGET_MEMORY_MISMATCH_STALL
2901            && memory_operand (operands[0], XFmode)))"
2902 {
2903   switch (which_alternative)
2904     {
2905     case 0:
2906     case 1:
2907       return output_387_reg_move (insn, operands);
2908
2909     case 2:
2910       return standard_80387_constant_opcode (operands[1]);
2911
2912     case 3:
2913     case 4:
2914       return "#";
2915
2916     default:
2917       gcc_unreachable ();
2918     }
2919 }
2920   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2921    (set_attr "mode" "XF,XF,XF,SI,SI")])
2922
2923 ;; Possible store forwarding (partial memory) stall in alternative 4.
2924 (define_insn "*movxf_internal"
2925   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2926         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,Yx*rF"))]
2927   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2928    && (!can_create_pseudo_p ()
2929        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2930        || GET_CODE (operands[1]) != CONST_DOUBLE
2931        || (optimize_function_for_size_p (cfun)
2932            && standard_80387_constant_p (operands[1]) > 0
2933            && !memory_operand (operands[0], XFmode))
2934        || (!TARGET_MEMORY_MISMATCH_STALL
2935            && memory_operand (operands[0], XFmode)))"
2936 {
2937   switch (which_alternative)
2938     {
2939     case 0:
2940     case 1:
2941       return output_387_reg_move (insn, operands);
2942
2943     case 2:
2944       return standard_80387_constant_opcode (operands[1]);
2945
2946     case 3:
2947     case 4:
2948       return "#";
2949
2950     default:
2951       gcc_unreachable ();
2952     }
2953 }
2954   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2955    (set_attr "mode" "XF,XF,XF,SI,SI")])
2956
2957 (define_insn "*movdf_internal_rex64"
2958   [(set (match_operand:DF 0 "nonimmediate_operand"
2959                 "=?Yf*f,?m   ,?Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r ")
2960         (match_operand:DF 1 "general_operand"
2961                 "Yf*fm ,Yf*f ,G    ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
2962   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2963    && (!can_create_pseudo_p ()
2964        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2965        || GET_CODE (operands[1]) != CONST_DOUBLE
2966        || (optimize_function_for_size_p (cfun)
2967            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2968                 && standard_80387_constant_p (operands[1]) > 0)
2969                || (TARGET_SSE2 && TARGET_SSE_MATH
2970                    && standard_sse_constant_p (operands[1]))))
2971        || memory_operand (operands[0], DFmode))"
2972 {
2973   switch (which_alternative)
2974     {
2975     case 0:
2976     case 1:
2977       return output_387_reg_move (insn, operands);
2978
2979     case 2:
2980       return standard_80387_constant_opcode (operands[1]);
2981
2982     case 3:
2983     case 4:
2984       return "mov{q}\t{%1, %0|%0, %1}";
2985
2986     case 5:
2987       return "mov{l}\t{%1, %k0|%k0, %1}";
2988
2989     case 6:
2990       return "movabs{q}\t{%1, %0|%0, %1}";
2991
2992     case 7:
2993       return standard_sse_constant_opcode (insn, operands[1]);
2994
2995     case 8:
2996     case 9:
2997     case 10:
2998       switch (get_attr_mode (insn))
2999         {
3000         case MODE_V2DF:
3001           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3002             return "%vmovapd\t{%1, %0|%0, %1}";
3003         case MODE_V4SF:
3004           return "%vmovaps\t{%1, %0|%0, %1}";
3005
3006         case MODE_DI:
3007           return "%vmovq\t{%1, %0|%0, %1}";
3008         case MODE_DF:
3009           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3010             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3011           return "%vmovsd\t{%1, %0|%0, %1}";
3012         case MODE_V1DF:
3013           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3014         case MODE_V2SF:
3015           return "%vmovlps\t{%1, %d0|%d0, %1}";
3016         default:
3017           gcc_unreachable ();
3018         }
3019
3020     case 11:
3021     case 12:
3022       /* Handle broken assemblers that require movd instead of movq.  */
3023       return "%vmovd\t{%1, %0|%0, %1}";
3024
3025     default:
3026       gcc_unreachable();
3027     }
3028 }
3029   [(set (attr "type")
3030         (cond [(eq_attr "alternative" "0,1,2")
3031                  (const_string "fmov")
3032                (eq_attr "alternative" "3,4,5,6")
3033                  (const_string "imov")
3034                (eq_attr "alternative" "7")
3035                  (const_string "sselog1")
3036               ]
3037               (const_string "ssemov")))
3038    (set (attr "modrm")
3039      (if_then_else
3040        (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3041          (const_string "0")
3042          (const_string "*")))
3043    (set (attr "length_immediate")
3044      (if_then_else
3045        (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3046          (const_string "8")
3047          (const_string "*")))
3048    (set (attr "prefix")
3049      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3050        (const_string "orig")
3051        (const_string "maybe_vex")))
3052    (set (attr "prefix_data16")
3053      (if_then_else (eq_attr "mode" "V1DF")
3054        (const_string "1")
3055        (const_string "*")))
3056    (set (attr "mode")
3057         (cond [(eq_attr "alternative" "0,1,2")
3058                  (const_string "DF")
3059                (eq_attr "alternative" "3,4,6,11,12")
3060                  (const_string "DI")
3061                (eq_attr "alternative" "5")
3062                  (const_string "SI")
3063
3064                /* xorps is one byte shorter.  */
3065                (eq_attr "alternative" "7")
3066                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3067                           (const_string "V4SF")
3068                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3069                           (const_string "TI")
3070                        ]
3071                        (const_string "V2DF"))
3072
3073                /* For architectures resolving dependencies on
3074                   whole SSE registers use APD move to break dependency
3075                   chains, otherwise use short move to avoid extra work.
3076
3077                   movaps encodes one byte shorter.  */
3078                (eq_attr "alternative" "8")
3079                  (cond
3080                    [(match_test "optimize_function_for_size_p (cfun)")
3081                       (const_string "V4SF")
3082                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3083                       (const_string "V2DF")
3084                    ]
3085                    (const_string "DF"))
3086                /* For architectures resolving dependencies on register
3087                   parts we may avoid extra work to zero out upper part
3088                   of register.  */
3089                (eq_attr "alternative" "9")
3090                  (if_then_else
3091                    (match_test "TARGET_SSE_SPLIT_REGS")
3092                    (const_string "V1DF")
3093                    (const_string "DF"))
3094               ]
3095               (const_string "DF")))])
3096
3097 ;; Possible store forwarding (partial memory) stall in alternative 4.
3098 (define_insn "*movdf_internal"
3099   [(set (match_operand:DF 0 "nonimmediate_operand"
3100                 "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3101         (match_operand:DF 1 "general_operand"
3102                 "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
3103   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3104    && (!can_create_pseudo_p ()
3105        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3106        || GET_CODE (operands[1]) != CONST_DOUBLE
3107        || (optimize_function_for_size_p (cfun)
3108            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3109                 && standard_80387_constant_p (operands[1]) > 0)
3110                || (TARGET_SSE2 && TARGET_SSE_MATH
3111                    && standard_sse_constant_p (operands[1])))
3112            && !memory_operand (operands[0], DFmode))
3113        || (!TARGET_MEMORY_MISMATCH_STALL
3114            && memory_operand (operands[0], DFmode)))"
3115 {
3116   switch (which_alternative)
3117     {
3118     case 0:
3119     case 1:
3120       return output_387_reg_move (insn, operands);
3121
3122     case 2:
3123       return standard_80387_constant_opcode (operands[1]);
3124
3125     case 3:
3126     case 4:
3127       return "#";
3128
3129     case 5:
3130     case 9:
3131       return standard_sse_constant_opcode (insn, operands[1]);
3132
3133     case 6:
3134     case 7:
3135     case 8:
3136     case 10:
3137     case 11:
3138     case 12:
3139       switch (get_attr_mode (insn))
3140         {
3141         case MODE_V2DF:
3142           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3143             return "%vmovapd\t{%1, %0|%0, %1}";
3144         case MODE_V4SF:
3145           return "%vmovaps\t{%1, %0|%0, %1}";
3146
3147         case MODE_DI:
3148           return "%vmovq\t{%1, %0|%0, %1}";
3149         case MODE_DF:
3150           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3151             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3152           return "%vmovsd\t{%1, %0|%0, %1}";
3153         case MODE_V1DF:
3154           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3155         case MODE_V2SF:
3156           return "%vmovlps\t{%1, %d0|%d0, %1}";
3157         default:
3158           gcc_unreachable ();
3159         }
3160
3161     default:
3162       gcc_unreachable ();
3163     }
3164 }
3165   [(set (attr "isa")
3166      (if_then_else (eq_attr "alternative" "5,6,7,8")
3167        (const_string "sse2")
3168        (const_string "*")))
3169    (set (attr "type")
3170         (cond [(eq_attr "alternative" "0,1,2")
3171                  (const_string "fmov")
3172                (eq_attr "alternative" "3,4")
3173                  (const_string "multi")
3174                (eq_attr "alternative" "5,9")
3175                  (const_string "sselog1")
3176               ]
3177               (const_string "ssemov")))
3178    (set (attr "prefix")
3179      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3180        (const_string "orig")
3181        (const_string "maybe_vex")))
3182    (set (attr "prefix_data16")
3183      (if_then_else (eq_attr "mode" "V1DF")
3184        (const_string "1")
3185        (const_string "*")))
3186    (set (attr "mode")
3187         (cond [(eq_attr "alternative" "0,1,2")
3188                  (const_string "DF")
3189                (eq_attr "alternative" "3,4")
3190                  (const_string "SI")
3191
3192                /* For SSE1, we have many fewer alternatives.  */
3193                (not (match_test "TARGET_SSE2"))
3194                  (if_then_else
3195                    (eq_attr "alternative" "5,6,9,10")
3196                    (const_string "V4SF")
3197                    (const_string "V2SF"))
3198
3199                /* xorps is one byte shorter.  */
3200                (eq_attr "alternative" "5,9")
3201                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3202                           (const_string "V4SF")
3203                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3204                           (const_string "TI")
3205                        ]
3206                        (const_string "V2DF"))
3207
3208                /* For architectures resolving dependencies on
3209                   whole SSE registers use APD move to break dependency
3210                   chains, otherwise use short move to avoid extra work.
3211
3212                   movaps encodes one byte shorter.  */
3213                (eq_attr "alternative" "6,10")
3214                  (cond
3215                    [(match_test "optimize_function_for_size_p (cfun)")
3216                       (const_string "V4SF")
3217                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3218                       (const_string "V2DF")
3219                    ]
3220                    (const_string "DF"))
3221                /* For architectures resolving dependencies on register
3222                   parts we may avoid extra work to zero out upper part
3223                   of register.  */
3224                (eq_attr "alternative" "7,11")
3225                  (if_then_else
3226                    (match_test "TARGET_SSE_SPLIT_REGS")
3227                    (const_string "V1DF")
3228                    (const_string "DF"))
3229               ]
3230               (const_string "DF")))])
3231
3232 (define_insn "*movsf_internal"
3233   [(set (match_operand:SF 0 "nonimmediate_operand"
3234           "=Yf*f,m   ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3235         (match_operand:SF 1 "general_operand"
3236           "Yf*fm,Yf*f,G   ,rmF,rF,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3237   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3238    && (!can_create_pseudo_p ()
3239        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3240        || GET_CODE (operands[1]) != CONST_DOUBLE
3241        || (optimize_function_for_size_p (cfun)
3242            && ((!TARGET_SSE_MATH
3243                 && standard_80387_constant_p (operands[1]) > 0)
3244                || (TARGET_SSE_MATH
3245                    && standard_sse_constant_p (operands[1]))))
3246        || memory_operand (operands[0], SFmode))"
3247 {
3248   switch (which_alternative)
3249     {
3250     case 0:
3251     case 1:
3252       return output_387_reg_move (insn, operands);
3253
3254     case 2:
3255       return standard_80387_constant_opcode (operands[1]);
3256
3257     case 3:
3258     case 4:
3259       return "mov{l}\t{%1, %0|%0, %1}";
3260
3261     case 5:
3262       return standard_sse_constant_opcode (insn, operands[1]);
3263
3264     case 6:
3265       if (get_attr_mode (insn) == MODE_V4SF)
3266         return "%vmovaps\t{%1, %0|%0, %1}";
3267       if (TARGET_AVX)
3268         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3269
3270     case 7:
3271     case 8:
3272       return "%vmovss\t{%1, %0|%0, %1}";
3273
3274     case 9:
3275     case 10:
3276     case 14:
3277     case 15:
3278       return "movd\t{%1, %0|%0, %1}";
3279
3280     case 11:
3281       return "movq\t{%1, %0|%0, %1}";
3282
3283     case 12:
3284     case 13:
3285       return "%vmovd\t{%1, %0|%0, %1}";
3286
3287     default:
3288       gcc_unreachable ();
3289     }
3290 }
3291   [(set (attr "type")
3292         (cond [(eq_attr "alternative" "0,1,2")
3293                  (const_string "fmov")
3294                (eq_attr "alternative" "3,4")
3295                  (const_string "imov")
3296                (eq_attr "alternative" "5")
3297                  (const_string "sselog1")
3298                (eq_attr "alternative" "9,10,11,14,15")
3299                  (const_string "mmxmov")
3300               ]
3301               (const_string "ssemov")))
3302    (set (attr "prefix")
3303      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3304        (const_string "maybe_vex")
3305        (const_string "orig")))
3306    (set (attr "mode")
3307         (cond [(eq_attr "alternative" "3,4,9,10")
3308                  (const_string "SI")
3309                (eq_attr "alternative" "5")
3310                  (if_then_else
3311                    (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3312                              (match_test "TARGET_SSE2"))
3313                         (not (match_test "optimize_function_for_size_p (cfun)")))
3314                    (const_string "TI")
3315                    (const_string "V4SF"))
3316                /* For architectures resolving dependencies on
3317                   whole SSE registers use APS move to break dependency
3318                   chains, otherwise use short move to avoid extra work.
3319
3320                   Do the same for architectures resolving dependencies on
3321                   the parts.  While in DF mode it is better to always handle
3322                   just register parts, the SF mode is different due to lack
3323                   of instructions to load just part of the register.  It is
3324                   better to maintain the whole registers in single format
3325                   to avoid problems on using packed logical operations.  */
3326                (eq_attr "alternative" "6")
3327                  (if_then_else
3328                    (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3329                         (match_test "TARGET_SSE_SPLIT_REGS"))
3330                    (const_string "V4SF")
3331                    (const_string "SF"))
3332                (eq_attr "alternative" "11")
3333                  (const_string "DI")]
3334                (const_string "SF")))])
3335
3336 (define_split
3337   [(set (match_operand 0 "any_fp_register_operand" "")
3338         (match_operand 1 "memory_operand" ""))]
3339   "reload_completed
3340    && (GET_MODE (operands[0]) == TFmode
3341        || GET_MODE (operands[0]) == XFmode
3342        || GET_MODE (operands[0]) == DFmode
3343        || GET_MODE (operands[0]) == SFmode)
3344    && (operands[2] = find_constant_src (insn))"
3345   [(set (match_dup 0) (match_dup 2))]
3346 {
3347   rtx c = operands[2];
3348   int r = REGNO (operands[0]);
3349
3350   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3351       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3352     FAIL;
3353 })
3354
3355 (define_split
3356   [(set (match_operand 0 "any_fp_register_operand" "")
3357         (float_extend (match_operand 1 "memory_operand" "")))]
3358   "reload_completed
3359    && (GET_MODE (operands[0]) == TFmode
3360        || GET_MODE (operands[0]) == XFmode
3361        || GET_MODE (operands[0]) == DFmode)
3362    && (operands[2] = find_constant_src (insn))"
3363   [(set (match_dup 0) (match_dup 2))]
3364 {
3365   rtx c = operands[2];
3366   int r = REGNO (operands[0]);
3367
3368   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3369       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3370     FAIL;
3371 })
3372
3373 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3374 (define_split
3375   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3376         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3377   "reload_completed
3378    && (standard_80387_constant_p (operands[1]) == 8
3379        || standard_80387_constant_p (operands[1]) == 9)"
3380   [(set (match_dup 0)(match_dup 1))
3381    (set (match_dup 0)
3382         (neg:X87MODEF (match_dup 0)))]
3383 {
3384   REAL_VALUE_TYPE r;
3385
3386   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3387   if (real_isnegzero (&r))
3388     operands[1] = CONST0_RTX (<MODE>mode);
3389   else
3390     operands[1] = CONST1_RTX (<MODE>mode);
3391 })
3392
3393 (define_split
3394   [(set (match_operand 0 "nonimmediate_operand" "")
3395         (match_operand 1 "general_operand" ""))]
3396   "reload_completed
3397    && (GET_MODE (operands[0]) == TFmode
3398        || GET_MODE (operands[0]) == XFmode
3399        || GET_MODE (operands[0]) == DFmode)
3400    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3401   [(const_int 0)]
3402   "ix86_split_long_move (operands); DONE;")
3403
3404 (define_insn "swapxf"
3405   [(set (match_operand:XF 0 "register_operand" "+f")
3406         (match_operand:XF 1 "register_operand" "+f"))
3407    (set (match_dup 1)
3408         (match_dup 0))]
3409   "TARGET_80387"
3410 {
3411   if (STACK_TOP_P (operands[0]))
3412     return "fxch\t%1";
3413   else
3414     return "fxch\t%0";
3415 }
3416   [(set_attr "type" "fxch")
3417    (set_attr "mode" "XF")])
3418
3419 (define_insn "*swap<mode>"
3420   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3421         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3422    (set (match_dup 1)
3423         (match_dup 0))]
3424   "TARGET_80387 || reload_completed"
3425 {
3426   if (STACK_TOP_P (operands[0]))
3427     return "fxch\t%1";
3428   else
3429     return "fxch\t%0";
3430 }
3431   [(set_attr "type" "fxch")
3432    (set_attr "mode" "<MODE>")])
3433 \f
3434 ;; Zero extension instructions
3435
3436 (define_expand "zero_extendsidi2"
3437   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3438         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3439   ""
3440 {
3441   if (!TARGET_64BIT)
3442     {
3443       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3444       DONE;
3445     }
3446 })
3447
3448 (define_insn "*zero_extendsidi2_rex64"
3449   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?!*y,?*Yi,*x")
3450         (zero_extend:DI
3451          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m   ,r   ,m")))]
3452   "TARGET_64BIT"
3453   "@
3454    mov{l}\t{%1, %k0|%k0, %1}
3455    #
3456    movd\t{%1, %0|%0, %1}
3457    movd\t{%1, %0|%0, %1}
3458    %vmovd\t{%1, %0|%0, %1}
3459    %vmovd\t{%1, %0|%0, %1}"
3460   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3461    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3462    (set_attr "prefix_0f" "0,*,*,*,*,*")
3463    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3464
3465 (define_split
3466   [(set (match_operand:DI 0 "memory_operand" "")
3467         (zero_extend:DI (match_dup 0)))]
3468   "TARGET_64BIT"
3469   [(set (match_dup 4) (const_int 0))]
3470   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3471
3472 ;; %%% Kill me once multi-word ops are sane.
3473 (define_insn "zero_extendsidi2_1"
3474   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?!*y,?*Yi,*x")
3475         (zero_extend:DI
3476          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m   ,r   ,m")))
3477    (clobber (reg:CC FLAGS_REG))]
3478   "!TARGET_64BIT"
3479   "@
3480    #
3481    #
3482    #
3483    movd\t{%1, %0|%0, %1}
3484    movd\t{%1, %0|%0, %1}
3485    %vmovd\t{%1, %0|%0, %1}
3486    %vmovd\t{%1, %0|%0, %1}"
3487   [(set_attr "isa" "*,*,*,*,*,*,sse2")
3488    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3489    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3490    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3491
3492 (define_split
3493   [(set (match_operand:DI 0 "register_operand" "")
3494         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3495    (clobber (reg:CC FLAGS_REG))]
3496   "!TARGET_64BIT && reload_completed
3497    && true_regnum (operands[0]) == true_regnum (operands[1])"
3498   [(set (match_dup 4) (const_int 0))]
3499   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3500
3501 (define_split
3502   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3503         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3504    (clobber (reg:CC FLAGS_REG))]
3505   "!TARGET_64BIT && reload_completed
3506    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3507   [(set (match_dup 3) (match_dup 1))
3508    (set (match_dup 4) (const_int 0))]
3509   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3510
3511 (define_insn "zero_extend<mode>di2"
3512   [(set (match_operand:DI 0 "register_operand" "=r")
3513         (zero_extend:DI
3514          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3515   "TARGET_64BIT"
3516   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3517   [(set_attr "type" "imovx")
3518    (set_attr "mode" "SI")])
3519
3520 (define_expand "zero_extendhisi2"
3521   [(set (match_operand:SI 0 "register_operand" "")
3522         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3523   ""
3524 {
3525   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3526     {
3527       operands[1] = force_reg (HImode, operands[1]);
3528       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3529       DONE;
3530     }
3531 })
3532
3533 (define_insn_and_split "zero_extendhisi2_and"
3534   [(set (match_operand:SI 0 "register_operand" "=r")
3535         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3536    (clobber (reg:CC FLAGS_REG))]
3537   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3538   "#"
3539   "&& reload_completed"
3540   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3541               (clobber (reg:CC FLAGS_REG))])]
3542   ""
3543   [(set_attr "type" "alu1")
3544    (set_attr "mode" "SI")])
3545
3546 (define_insn "*zero_extendhisi2_movzwl"
3547   [(set (match_operand:SI 0 "register_operand" "=r")
3548         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3549   "!TARGET_ZERO_EXTEND_WITH_AND
3550    || optimize_function_for_size_p (cfun)"
3551   "movz{wl|x}\t{%1, %0|%0, %1}"
3552   [(set_attr "type" "imovx")
3553    (set_attr "mode" "SI")])
3554
3555 (define_expand "zero_extendqi<mode>2"
3556   [(parallel
3557     [(set (match_operand:SWI24 0 "register_operand" "")
3558           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3559      (clobber (reg:CC FLAGS_REG))])])
3560
3561 (define_insn "*zero_extendqi<mode>2_and"
3562   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3563         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3564    (clobber (reg:CC FLAGS_REG))]
3565   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3566   "#"
3567   [(set_attr "type" "alu1")
3568    (set_attr "mode" "<MODE>")])
3569
3570 ;; When source and destination does not overlap, clear destination
3571 ;; first and then do the movb
3572 (define_split
3573   [(set (match_operand:SWI24 0 "register_operand" "")
3574         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3575    (clobber (reg:CC FLAGS_REG))]
3576   "reload_completed
3577    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3578    && ANY_QI_REG_P (operands[0])
3579    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3580    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3581   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3582 {
3583   operands[2] = gen_lowpart (QImode, operands[0]);
3584   ix86_expand_clear (operands[0]);
3585 })
3586
3587 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3588   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3589         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3590    (clobber (reg:CC FLAGS_REG))]
3591   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3592   "#"
3593   [(set_attr "type" "imovx,alu1")
3594    (set_attr "mode" "<MODE>")])
3595
3596 ;; For the movzbl case strip only the clobber
3597 (define_split
3598   [(set (match_operand:SWI24 0 "register_operand" "")
3599         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3600    (clobber (reg:CC FLAGS_REG))]
3601   "reload_completed
3602    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3603    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3604   [(set (match_dup 0)
3605         (zero_extend:SWI24 (match_dup 1)))])
3606
3607 ; zero extend to SImode to avoid partial register stalls
3608 (define_insn "*zero_extendqi<mode>2_movzbl"
3609   [(set (match_operand:SWI24 0 "register_operand" "=r")
3610         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3611   "reload_completed
3612    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3613   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3614   [(set_attr "type" "imovx")
3615    (set_attr "mode" "SI")])
3616
3617 ;; Rest is handled by single and.
3618 (define_split
3619   [(set (match_operand:SWI24 0 "register_operand" "")
3620         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3621    (clobber (reg:CC FLAGS_REG))]
3622   "reload_completed
3623    && true_regnum (operands[0]) == true_regnum (operands[1])"
3624   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3625               (clobber (reg:CC FLAGS_REG))])])
3626 \f
3627 ;; Sign extension instructions
3628
3629 (define_expand "extendsidi2"
3630   [(set (match_operand:DI 0 "register_operand" "")
3631         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3632   ""
3633 {
3634   if (!TARGET_64BIT)
3635     {
3636       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3637       DONE;
3638     }
3639 })
3640
3641 (define_insn "*extendsidi2_rex64"
3642   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3643         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3644   "TARGET_64BIT"
3645   "@
3646    {cltq|cdqe}
3647    movs{lq|x}\t{%1, %0|%0, %1}"
3648   [(set_attr "type" "imovx")
3649    (set_attr "mode" "DI")
3650    (set_attr "prefix_0f" "0")
3651    (set_attr "modrm" "0,1")])
3652
3653 (define_insn "extendsidi2_1"
3654   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3655         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3656    (clobber (reg:CC FLAGS_REG))
3657    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3658   "!TARGET_64BIT"
3659   "#")
3660
3661 ;; Extend to memory case when source register does die.
3662 (define_split
3663   [(set (match_operand:DI 0 "memory_operand" "")
3664         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3665    (clobber (reg:CC FLAGS_REG))
3666    (clobber (match_operand:SI 2 "register_operand" ""))]
3667   "(reload_completed
3668     && dead_or_set_p (insn, operands[1])
3669     && !reg_mentioned_p (operands[1], operands[0]))"
3670   [(set (match_dup 3) (match_dup 1))
3671    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3672               (clobber (reg:CC FLAGS_REG))])
3673    (set (match_dup 4) (match_dup 1))]
3674   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3675
3676 ;; Extend to memory case when source register does not die.
3677 (define_split
3678   [(set (match_operand:DI 0 "memory_operand" "")
3679         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3680    (clobber (reg:CC FLAGS_REG))
3681    (clobber (match_operand:SI 2 "register_operand" ""))]
3682   "reload_completed"
3683   [(const_int 0)]
3684 {
3685   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3686
3687   emit_move_insn (operands[3], operands[1]);
3688
3689   /* Generate a cltd if possible and doing so it profitable.  */
3690   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3691       && true_regnum (operands[1]) == AX_REG
3692       && true_regnum (operands[2]) == DX_REG)
3693     {
3694       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3695     }
3696   else
3697     {
3698       emit_move_insn (operands[2], operands[1]);
3699       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3700     }
3701   emit_move_insn (operands[4], operands[2]);
3702   DONE;
3703 })
3704
3705 ;; Extend to register case.  Optimize case where source and destination
3706 ;; registers match and cases where we can use cltd.
3707 (define_split
3708   [(set (match_operand:DI 0 "register_operand" "")
3709         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3710    (clobber (reg:CC FLAGS_REG))
3711    (clobber (match_scratch:SI 2 ""))]
3712   "reload_completed"
3713   [(const_int 0)]
3714 {
3715   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3716
3717   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3718     emit_move_insn (operands[3], operands[1]);
3719
3720   /* Generate a cltd if possible and doing so it profitable.  */
3721   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3722       && true_regnum (operands[3]) == AX_REG
3723       && true_regnum (operands[4]) == DX_REG)
3724     {
3725       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3726       DONE;
3727     }
3728
3729   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3730     emit_move_insn (operands[4], operands[1]);
3731
3732   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3733   DONE;
3734 })
3735
3736 (define_insn "extend<mode>di2"
3737   [(set (match_operand:DI 0 "register_operand" "=r")
3738         (sign_extend:DI
3739          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3740   "TARGET_64BIT"
3741   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3742   [(set_attr "type" "imovx")
3743    (set_attr "mode" "DI")])
3744
3745 (define_insn "extendhisi2"
3746   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3747         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3748   ""
3749 {
3750   switch (get_attr_prefix_0f (insn))
3751     {
3752     case 0:
3753       return "{cwtl|cwde}";
3754     default:
3755       return "movs{wl|x}\t{%1, %0|%0, %1}";
3756     }
3757 }
3758   [(set_attr "type" "imovx")
3759    (set_attr "mode" "SI")
3760    (set (attr "prefix_0f")
3761      ;; movsx is short decodable while cwtl is vector decoded.
3762      (if_then_else (and (eq_attr "cpu" "!k6")
3763                         (eq_attr "alternative" "0"))
3764         (const_string "0")
3765         (const_string "1")))
3766    (set (attr "modrm")
3767      (if_then_else (eq_attr "prefix_0f" "0")
3768         (const_string "0")
3769         (const_string "1")))])
3770
3771 (define_insn "*extendhisi2_zext"
3772   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3773         (zero_extend:DI
3774          (sign_extend:SI
3775           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3776   "TARGET_64BIT"
3777 {
3778   switch (get_attr_prefix_0f (insn))
3779     {
3780     case 0:
3781       return "{cwtl|cwde}";
3782     default:
3783       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3784     }
3785 }
3786   [(set_attr "type" "imovx")
3787    (set_attr "mode" "SI")
3788    (set (attr "prefix_0f")
3789      ;; movsx is short decodable while cwtl is vector decoded.
3790      (if_then_else (and (eq_attr "cpu" "!k6")
3791                         (eq_attr "alternative" "0"))
3792         (const_string "0")
3793         (const_string "1")))
3794    (set (attr "modrm")
3795      (if_then_else (eq_attr "prefix_0f" "0")
3796         (const_string "0")
3797         (const_string "1")))])
3798
3799 (define_insn "extendqisi2"
3800   [(set (match_operand:SI 0 "register_operand" "=r")
3801         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3802   ""
3803   "movs{bl|x}\t{%1, %0|%0, %1}"
3804    [(set_attr "type" "imovx")
3805     (set_attr "mode" "SI")])
3806
3807 (define_insn "*extendqisi2_zext"
3808   [(set (match_operand:DI 0 "register_operand" "=r")
3809         (zero_extend:DI
3810           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3811   "TARGET_64BIT"
3812   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3813    [(set_attr "type" "imovx")
3814     (set_attr "mode" "SI")])
3815
3816 (define_insn "extendqihi2"
3817   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3818         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3819   ""
3820 {
3821   switch (get_attr_prefix_0f (insn))
3822     {
3823     case 0:
3824       return "{cbtw|cbw}";
3825     default:
3826       return "movs{bw|x}\t{%1, %0|%0, %1}";
3827     }
3828 }
3829   [(set_attr "type" "imovx")
3830    (set_attr "mode" "HI")
3831    (set (attr "prefix_0f")
3832      ;; movsx is short decodable while cwtl is vector decoded.
3833      (if_then_else (and (eq_attr "cpu" "!k6")
3834                         (eq_attr "alternative" "0"))
3835         (const_string "0")
3836         (const_string "1")))
3837    (set (attr "modrm")
3838      (if_then_else (eq_attr "prefix_0f" "0")
3839         (const_string "0")
3840         (const_string "1")))])
3841 \f
3842 ;; Conversions between float and double.
3843
3844 ;; These are all no-ops in the model used for the 80387.
3845 ;; So just emit moves.
3846
3847 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3848 (define_split
3849   [(set (match_operand:DF 0 "push_operand" "")
3850         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3851   "reload_completed"
3852   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3853    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3854
3855 (define_split
3856   [(set (match_operand:XF 0 "push_operand" "")
3857         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3858   "reload_completed"
3859   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3860    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3861   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3862
3863 (define_expand "extendsfdf2"
3864   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3865         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3866   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3867 {
3868   /* ??? Needed for compress_float_constant since all fp constants
3869      are TARGET_LEGITIMATE_CONSTANT_P.  */
3870   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3871     {
3872       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3873           && standard_80387_constant_p (operands[1]) > 0)
3874         {
3875           operands[1] = simplify_const_unary_operation
3876             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3877           emit_move_insn_1 (operands[0], operands[1]);
3878           DONE;
3879         }
3880       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3881     }
3882 })
3883
3884 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3885    cvtss2sd:
3886       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3887       cvtps2pd xmm2,xmm1
3888    We do the conversion post reload to avoid producing of 128bit spills
3889    that might lead to ICE on 32bit target.  The sequence unlikely combine
3890    anyway.  */
3891 (define_split
3892   [(set (match_operand:DF 0 "register_operand" "")
3893         (float_extend:DF
3894           (match_operand:SF 1 "nonimmediate_operand" "")))]
3895   "TARGET_USE_VECTOR_FP_CONVERTS
3896    && optimize_insn_for_speed_p ()
3897    && reload_completed && SSE_REG_P (operands[0])"
3898    [(set (match_dup 2)
3899          (float_extend:V2DF
3900            (vec_select:V2SF
3901              (match_dup 3)
3902              (parallel [(const_int 0) (const_int 1)]))))]
3903 {
3904   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3905   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3906   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3907      Try to avoid move when unpacking can be done in source.  */
3908   if (REG_P (operands[1]))
3909     {
3910       /* If it is unsafe to overwrite upper half of source, we need
3911          to move to destination and unpack there.  */
3912       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3913            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3914           && true_regnum (operands[0]) != true_regnum (operands[1]))
3915         {
3916           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3917           emit_move_insn (tmp, operands[1]);
3918         }
3919       else
3920         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3921       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3922                                              operands[3]));
3923     }
3924   else
3925     emit_insn (gen_vec_setv4sf_0 (operands[3],
3926                                   CONST0_RTX (V4SFmode), operands[1]));
3927 })
3928
3929 (define_insn "*extendsfdf2_mixed"
3930   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3931         (float_extend:DF
3932           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3933   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3934 {
3935   switch (which_alternative)
3936     {
3937     case 0:
3938     case 1:
3939       return output_387_reg_move (insn, operands);
3940
3941     case 2:
3942       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3943
3944     default:
3945       gcc_unreachable ();
3946     }
3947 }
3948   [(set_attr "type" "fmov,fmov,ssecvt")
3949    (set_attr "prefix" "orig,orig,maybe_vex")
3950    (set_attr "mode" "SF,XF,DF")])
3951
3952 (define_insn "*extendsfdf2_sse"
3953   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3954         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3955   "TARGET_SSE2 && TARGET_SSE_MATH"
3956   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3957   [(set_attr "type" "ssecvt")
3958    (set_attr "prefix" "maybe_vex")
3959    (set_attr "mode" "DF")])
3960
3961 (define_insn "*extendsfdf2_i387"
3962   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3963         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3964   "TARGET_80387"
3965   "* return output_387_reg_move (insn, operands);"
3966   [(set_attr "type" "fmov")
3967    (set_attr "mode" "SF,XF")])
3968
3969 (define_expand "extend<mode>xf2"
3970   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3971         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3972   "TARGET_80387"
3973 {
3974   /* ??? Needed for compress_float_constant since all fp constants
3975      are TARGET_LEGITIMATE_CONSTANT_P.  */
3976   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3977     {
3978       if (standard_80387_constant_p (operands[1]) > 0)
3979         {
3980           operands[1] = simplify_const_unary_operation
3981             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3982           emit_move_insn_1 (operands[0], operands[1]);
3983           DONE;
3984         }
3985       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3986     }
3987 })
3988
3989 (define_insn "*extend<mode>xf2_i387"
3990   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3991         (float_extend:XF
3992           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3993   "TARGET_80387"
3994   "* return output_387_reg_move (insn, operands);"
3995   [(set_attr "type" "fmov")
3996    (set_attr "mode" "<MODE>,XF")])
3997
3998 ;; %%% This seems bad bad news.
3999 ;; This cannot output into an f-reg because there is no way to be sure
4000 ;; of truncating in that case.  Otherwise this is just like a simple move
4001 ;; insn.  So we pretend we can output to a reg in order to get better
4002 ;; register preferencing, but we really use a stack slot.
4003
4004 ;; Conversion from DFmode to SFmode.
4005
4006 (define_expand "truncdfsf2"
4007   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4008         (float_truncate:SF
4009           (match_operand:DF 1 "nonimmediate_operand" "")))]
4010   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4011 {
4012   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4013     ;
4014   else if (flag_unsafe_math_optimizations)
4015     ;
4016   else
4017     {
4018       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4019       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4020       DONE;
4021     }
4022 })
4023
4024 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4025    cvtsd2ss:
4026       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4027       cvtpd2ps xmm2,xmm1
4028    We do the conversion post reload to avoid producing of 128bit spills
4029    that might lead to ICE on 32bit target.  The sequence unlikely combine
4030    anyway.  */
4031 (define_split
4032   [(set (match_operand:SF 0 "register_operand" "")
4033         (float_truncate:SF
4034           (match_operand:DF 1 "nonimmediate_operand" "")))]
4035   "TARGET_USE_VECTOR_FP_CONVERTS
4036    && optimize_insn_for_speed_p ()
4037    && reload_completed && SSE_REG_P (operands[0])"
4038    [(set (match_dup 2)
4039          (vec_concat:V4SF
4040            (float_truncate:V2SF
4041              (match_dup 4))
4042            (match_dup 3)))]
4043 {
4044   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4045   operands[3] = CONST0_RTX (V2SFmode);
4046   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4047   /* Use movsd for loading from memory, unpcklpd for registers.
4048      Try to avoid move when unpacking can be done in source, or SSE3
4049      movddup is available.  */
4050   if (REG_P (operands[1]))
4051     {
4052       if (!TARGET_SSE3
4053           && true_regnum (operands[0]) != true_regnum (operands[1])
4054           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4055               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4056         {
4057           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4058           emit_move_insn (tmp, operands[1]);
4059           operands[1] = tmp;
4060         }
4061       else if (!TARGET_SSE3)
4062         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4063       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4064     }
4065   else
4066     emit_insn (gen_sse2_loadlpd (operands[4],
4067                                  CONST0_RTX (V2DFmode), operands[1]));
4068 })
4069
4070 (define_expand "truncdfsf2_with_temp"
4071   [(parallel [(set (match_operand:SF 0 "" "")
4072                    (float_truncate:SF (match_operand:DF 1 "" "")))
4073               (clobber (match_operand:SF 2 "" ""))])])
4074
4075 (define_insn "*truncdfsf_fast_mixed"
4076   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4077         (float_truncate:SF
4078           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4079   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4080 {
4081   switch (which_alternative)
4082     {
4083     case 0:
4084       return output_387_reg_move (insn, operands);
4085     case 1:
4086       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4087     default:
4088       gcc_unreachable ();
4089     }
4090 }
4091   [(set_attr "type" "fmov,ssecvt")
4092    (set_attr "prefix" "orig,maybe_vex")
4093    (set_attr "mode" "SF")])
4094
4095 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4096 ;; because nothing we do here is unsafe.
4097 (define_insn "*truncdfsf_fast_sse"
4098   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4099         (float_truncate:SF
4100           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4101   "TARGET_SSE2 && TARGET_SSE_MATH"
4102   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4103   [(set_attr "type" "ssecvt")
4104    (set_attr "prefix" "maybe_vex")
4105    (set_attr "mode" "SF")])
4106
4107 (define_insn "*truncdfsf_fast_i387"
4108   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4109         (float_truncate:SF
4110           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4111   "TARGET_80387 && flag_unsafe_math_optimizations"
4112   "* return output_387_reg_move (insn, operands);"
4113   [(set_attr "type" "fmov")
4114    (set_attr "mode" "SF")])
4115
4116 (define_insn "*truncdfsf_mixed"
4117   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4118         (float_truncate:SF
4119           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4120    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4121   "TARGET_MIX_SSE_I387"
4122 {
4123   switch (which_alternative)
4124     {
4125     case 0:
4126       return output_387_reg_move (insn, operands);
4127     case 1:
4128       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4129
4130     default:
4131       return "#";
4132     }
4133 }
4134   [(set_attr "isa" "*,sse2,*,*,*")
4135    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4136    (set_attr "unit" "*,*,i387,i387,i387")
4137    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4138    (set_attr "mode" "SF")])
4139
4140 (define_insn "*truncdfsf_i387"
4141   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4142         (float_truncate:SF
4143           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4144    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4145   "TARGET_80387"
4146 {
4147   switch (which_alternative)
4148     {
4149     case 0:
4150       return output_387_reg_move (insn, operands);
4151
4152     default:
4153       return "#";
4154     }
4155 }
4156   [(set_attr "type" "fmov,multi,multi,multi")
4157    (set_attr "unit" "*,i387,i387,i387")
4158    (set_attr "mode" "SF")])
4159
4160 (define_insn "*truncdfsf2_i387_1"
4161   [(set (match_operand:SF 0 "memory_operand" "=m")
4162         (float_truncate:SF
4163           (match_operand:DF 1 "register_operand" "f")))]
4164   "TARGET_80387
4165    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4166    && !TARGET_MIX_SSE_I387"
4167   "* return output_387_reg_move (insn, operands);"
4168   [(set_attr "type" "fmov")
4169    (set_attr "mode" "SF")])
4170
4171 (define_split
4172   [(set (match_operand:SF 0 "register_operand" "")
4173         (float_truncate:SF
4174          (match_operand:DF 1 "fp_register_operand" "")))
4175    (clobber (match_operand 2 "" ""))]
4176   "reload_completed"
4177   [(set (match_dup 2) (match_dup 1))
4178    (set (match_dup 0) (match_dup 2))]
4179   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4180
4181 ;; Conversion from XFmode to {SF,DF}mode
4182
4183 (define_expand "truncxf<mode>2"
4184   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4185                    (float_truncate:MODEF
4186                      (match_operand:XF 1 "register_operand" "")))
4187               (clobber (match_dup 2))])]
4188   "TARGET_80387"
4189 {
4190   if (flag_unsafe_math_optimizations)
4191     {
4192       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4193       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4194       if (reg != operands[0])
4195         emit_move_insn (operands[0], reg);
4196       DONE;
4197     }
4198   else
4199     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4200 })
4201
4202 (define_insn "*truncxfsf2_mixed"
4203   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4204         (float_truncate:SF
4205           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4206    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4207   "TARGET_80387"
4208 {
4209   gcc_assert (!which_alternative);
4210   return output_387_reg_move (insn, operands);
4211 }
4212   [(set_attr "type" "fmov,multi,multi,multi")
4213    (set_attr "unit" "*,i387,i387,i387")
4214    (set_attr "mode" "SF")])
4215
4216 (define_insn "*truncxfdf2_mixed"
4217   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4218         (float_truncate:DF
4219           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4220    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4221   "TARGET_80387"
4222 {
4223   gcc_assert (!which_alternative);
4224   return output_387_reg_move (insn, operands);
4225 }
4226   [(set_attr "isa" "*,*,sse2,*")
4227    (set_attr "type" "fmov,multi,multi,multi")
4228    (set_attr "unit" "*,i387,i387,i387")
4229    (set_attr "mode" "DF")])
4230
4231 (define_insn "truncxf<mode>2_i387_noop"
4232   [(set (match_operand:MODEF 0 "register_operand" "=f")
4233         (float_truncate:MODEF
4234           (match_operand:XF 1 "register_operand" "f")))]
4235   "TARGET_80387 && flag_unsafe_math_optimizations"
4236   "* return output_387_reg_move (insn, operands);"
4237   [(set_attr "type" "fmov")
4238    (set_attr "mode" "<MODE>")])
4239
4240 (define_insn "*truncxf<mode>2_i387"
4241   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4242         (float_truncate:MODEF
4243           (match_operand:XF 1 "register_operand" "f")))]
4244   "TARGET_80387"
4245   "* return output_387_reg_move (insn, operands);"
4246   [(set_attr "type" "fmov")
4247    (set_attr "mode" "<MODE>")])
4248
4249 (define_split
4250   [(set (match_operand:MODEF 0 "register_operand" "")
4251         (float_truncate:MODEF
4252           (match_operand:XF 1 "register_operand" "")))
4253    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4254   "TARGET_80387 && reload_completed"
4255   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4256    (set (match_dup 0) (match_dup 2))])
4257
4258 (define_split
4259   [(set (match_operand:MODEF 0 "memory_operand" "")
4260         (float_truncate:MODEF
4261           (match_operand:XF 1 "register_operand" "")))
4262    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4263   "TARGET_80387"
4264   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4265 \f
4266 ;; Signed conversion to DImode.
4267
4268 (define_expand "fix_truncxfdi2"
4269   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4270                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4271               (clobber (reg:CC FLAGS_REG))])]
4272   "TARGET_80387"
4273 {
4274   if (TARGET_FISTTP)
4275    {
4276      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4277      DONE;
4278    }
4279 })
4280
4281 (define_expand "fix_trunc<mode>di2"
4282   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4283                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4284               (clobber (reg:CC FLAGS_REG))])]
4285   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4286 {
4287   if (TARGET_FISTTP
4288       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4289    {
4290      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4291      DONE;
4292    }
4293   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4294    {
4295      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4296      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4297      if (out != operands[0])
4298         emit_move_insn (operands[0], out);
4299      DONE;
4300    }
4301 })
4302
4303 ;; Signed conversion to SImode.
4304
4305 (define_expand "fix_truncxfsi2"
4306   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4307                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4308               (clobber (reg:CC FLAGS_REG))])]
4309   "TARGET_80387"
4310 {
4311   if (TARGET_FISTTP)
4312    {
4313      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4314      DONE;
4315    }
4316 })
4317
4318 (define_expand "fix_trunc<mode>si2"
4319   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4320                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4321               (clobber (reg:CC FLAGS_REG))])]
4322   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4323 {
4324   if (TARGET_FISTTP
4325       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4326    {
4327      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4328      DONE;
4329    }
4330   if (SSE_FLOAT_MODE_P (<MODE>mode))
4331    {
4332      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4333      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4334      if (out != operands[0])
4335         emit_move_insn (operands[0], out);
4336      DONE;
4337    }
4338 })
4339
4340 ;; Signed conversion to HImode.
4341
4342 (define_expand "fix_trunc<mode>hi2"
4343   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4344                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4345               (clobber (reg:CC FLAGS_REG))])]
4346   "TARGET_80387
4347    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4348 {
4349   if (TARGET_FISTTP)
4350    {
4351      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4352      DONE;
4353    }
4354 })
4355
4356 ;; Unsigned conversion to SImode.
4357
4358 (define_expand "fixuns_trunc<mode>si2"
4359   [(parallel
4360     [(set (match_operand:SI 0 "register_operand" "")
4361           (unsigned_fix:SI
4362             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4363      (use (match_dup 2))
4364      (clobber (match_scratch:<ssevecmode> 3 ""))
4365      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4366   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4367 {
4368   enum machine_mode mode = <MODE>mode;
4369   enum machine_mode vecmode = <ssevecmode>mode;
4370   REAL_VALUE_TYPE TWO31r;
4371   rtx two31;
4372
4373   if (optimize_insn_for_size_p ())
4374     FAIL;
4375
4376   real_ldexp (&TWO31r, &dconst1, 31);
4377   two31 = const_double_from_real_value (TWO31r, mode);
4378   two31 = ix86_build_const_vector (vecmode, true, two31);
4379   operands[2] = force_reg (vecmode, two31);
4380 })
4381
4382 (define_insn_and_split "*fixuns_trunc<mode>_1"
4383   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4384         (unsigned_fix:SI
4385           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4386    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4387    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4388    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4389   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4390    && optimize_function_for_speed_p (cfun)"
4391   "#"
4392   "&& reload_completed"
4393   [(const_int 0)]
4394 {
4395   ix86_split_convert_uns_si_sse (operands);
4396   DONE;
4397 })
4398
4399 ;; Unsigned conversion to HImode.
4400 ;; Without these patterns, we'll try the unsigned SI conversion which
4401 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4402
4403 (define_expand "fixuns_trunc<mode>hi2"
4404   [(set (match_dup 2)
4405         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4406    (set (match_operand:HI 0 "nonimmediate_operand" "")
4407         (subreg:HI (match_dup 2) 0))]
4408   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4409   "operands[2] = gen_reg_rtx (SImode);")
4410
4411 ;; When SSE is available, it is always faster to use it!
4412 (define_insn "fix_trunc<mode>di_sse"
4413   [(set (match_operand:DI 0 "register_operand" "=r,r")
4414         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4415   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4416    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4417   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4418   [(set_attr "type" "sseicvt")
4419    (set_attr "prefix" "maybe_vex")
4420    (set_attr "prefix_rex" "1")
4421    (set_attr "mode" "<MODE>")
4422    (set_attr "athlon_decode" "double,vector")
4423    (set_attr "amdfam10_decode" "double,double")
4424    (set_attr "bdver1_decode" "double,double")])
4425
4426 (define_insn "fix_trunc<mode>si_sse"
4427   [(set (match_operand:SI 0 "register_operand" "=r,r")
4428         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4429   "SSE_FLOAT_MODE_P (<MODE>mode)
4430    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4431   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4432   [(set_attr "type" "sseicvt")
4433    (set_attr "prefix" "maybe_vex")
4434    (set_attr "mode" "<MODE>")
4435    (set_attr "athlon_decode" "double,vector")
4436    (set_attr "amdfam10_decode" "double,double")
4437    (set_attr "bdver1_decode" "double,double")])
4438
4439 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4440 (define_peephole2
4441   [(set (match_operand:MODEF 0 "register_operand" "")
4442         (match_operand:MODEF 1 "memory_operand" ""))
4443    (set (match_operand:SWI48x 2 "register_operand" "")
4444         (fix:SWI48x (match_dup 0)))]
4445   "TARGET_SHORTEN_X87_SSE
4446    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4447    && peep2_reg_dead_p (2, operands[0])"
4448   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4449
4450 ;; Avoid vector decoded forms of the instruction.
4451 (define_peephole2
4452   [(match_scratch:DF 2 "x")
4453    (set (match_operand:SWI48x 0 "register_operand" "")
4454         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4455   "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4456   [(set (match_dup 2) (match_dup 1))
4457    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4458
4459 (define_peephole2
4460   [(match_scratch:SF 2 "x")
4461    (set (match_operand:SWI48x 0 "register_operand" "")
4462         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4463   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4464   [(set (match_dup 2) (match_dup 1))
4465    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4466
4467 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4468   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4469         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4470   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4471    && TARGET_FISTTP
4472    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4473          && (TARGET_64BIT || <MODE>mode != DImode))
4474         && TARGET_SSE_MATH)
4475    && can_create_pseudo_p ()"
4476   "#"
4477   "&& 1"
4478   [(const_int 0)]
4479 {
4480   if (memory_operand (operands[0], VOIDmode))
4481     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4482   else
4483     {
4484       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4485       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4486                                                             operands[1],
4487                                                             operands[2]));
4488     }
4489   DONE;
4490 }
4491   [(set_attr "type" "fisttp")
4492    (set_attr "mode" "<MODE>")])
4493
4494 (define_insn "fix_trunc<mode>_i387_fisttp"
4495   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4496         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4497    (clobber (match_scratch:XF 2 "=&1f"))]
4498   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4499    && TARGET_FISTTP
4500    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4501          && (TARGET_64BIT || <MODE>mode != DImode))
4502         && TARGET_SSE_MATH)"
4503   "* return output_fix_trunc (insn, operands, true);"
4504   [(set_attr "type" "fisttp")
4505    (set_attr "mode" "<MODE>")])
4506
4507 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4508   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4509         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4510    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4511    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4512   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4513    && TARGET_FISTTP
4514    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4515         && (TARGET_64BIT || <MODE>mode != DImode))
4516         && TARGET_SSE_MATH)"
4517   "#"
4518   [(set_attr "type" "fisttp")
4519    (set_attr "mode" "<MODE>")])
4520
4521 (define_split
4522   [(set (match_operand:SWI248x 0 "register_operand" "")
4523         (fix:SWI248x (match_operand 1 "register_operand" "")))
4524    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4525    (clobber (match_scratch 3 ""))]
4526   "reload_completed"
4527   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4528               (clobber (match_dup 3))])
4529    (set (match_dup 0) (match_dup 2))])
4530
4531 (define_split
4532   [(set (match_operand:SWI248x 0 "memory_operand" "")
4533         (fix:SWI248x (match_operand 1 "register_operand" "")))
4534    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4535    (clobber (match_scratch 3 ""))]
4536   "reload_completed"
4537   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4538               (clobber (match_dup 3))])])
4539
4540 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4541 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4542 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4543 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4544 ;; function in i386.c.
4545 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4546   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4547         (fix:SWI248x (match_operand 1 "register_operand" "")))
4548    (clobber (reg:CC FLAGS_REG))]
4549   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4550    && !TARGET_FISTTP
4551    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4552          && (TARGET_64BIT || <MODE>mode != DImode))
4553    && can_create_pseudo_p ()"
4554   "#"
4555   "&& 1"
4556   [(const_int 0)]
4557 {
4558   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4559
4560   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4561   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4562   if (memory_operand (operands[0], VOIDmode))
4563     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4564                                          operands[2], operands[3]));
4565   else
4566     {
4567       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4568       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4569                                                      operands[2], operands[3],
4570                                                      operands[4]));
4571     }
4572   DONE;
4573 }
4574   [(set_attr "type" "fistp")
4575    (set_attr "i387_cw" "trunc")
4576    (set_attr "mode" "<MODE>")])
4577
4578 (define_insn "fix_truncdi_i387"
4579   [(set (match_operand:DI 0 "memory_operand" "=m")
4580         (fix:DI (match_operand 1 "register_operand" "f")))
4581    (use (match_operand:HI 2 "memory_operand" "m"))
4582    (use (match_operand:HI 3 "memory_operand" "m"))
4583    (clobber (match_scratch:XF 4 "=&1f"))]
4584   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4585    && !TARGET_FISTTP
4586    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4587   "* return output_fix_trunc (insn, operands, false);"
4588   [(set_attr "type" "fistp")
4589    (set_attr "i387_cw" "trunc")
4590    (set_attr "mode" "DI")])
4591
4592 (define_insn "fix_truncdi_i387_with_temp"
4593   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4594         (fix:DI (match_operand 1 "register_operand" "f,f")))
4595    (use (match_operand:HI 2 "memory_operand" "m,m"))
4596    (use (match_operand:HI 3 "memory_operand" "m,m"))
4597    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4598    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4599   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4600    && !TARGET_FISTTP
4601    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4602   "#"
4603   [(set_attr "type" "fistp")
4604    (set_attr "i387_cw" "trunc")
4605    (set_attr "mode" "DI")])
4606
4607 (define_split
4608   [(set (match_operand:DI 0 "register_operand" "")
4609         (fix:DI (match_operand 1 "register_operand" "")))
4610    (use (match_operand:HI 2 "memory_operand" ""))
4611    (use (match_operand:HI 3 "memory_operand" ""))
4612    (clobber (match_operand:DI 4 "memory_operand" ""))
4613    (clobber (match_scratch 5 ""))]
4614   "reload_completed"
4615   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4616               (use (match_dup 2))
4617               (use (match_dup 3))
4618               (clobber (match_dup 5))])
4619    (set (match_dup 0) (match_dup 4))])
4620
4621 (define_split
4622   [(set (match_operand:DI 0 "memory_operand" "")
4623         (fix:DI (match_operand 1 "register_operand" "")))
4624    (use (match_operand:HI 2 "memory_operand" ""))
4625    (use (match_operand:HI 3 "memory_operand" ""))
4626    (clobber (match_operand:DI 4 "memory_operand" ""))
4627    (clobber (match_scratch 5 ""))]
4628   "reload_completed"
4629   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4630               (use (match_dup 2))
4631               (use (match_dup 3))
4632               (clobber (match_dup 5))])])
4633
4634 (define_insn "fix_trunc<mode>_i387"
4635   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4636         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4637    (use (match_operand:HI 2 "memory_operand" "m"))
4638    (use (match_operand:HI 3 "memory_operand" "m"))]
4639   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4640    && !TARGET_FISTTP
4641    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4642   "* return output_fix_trunc (insn, operands, false);"
4643   [(set_attr "type" "fistp")
4644    (set_attr "i387_cw" "trunc")
4645    (set_attr "mode" "<MODE>")])
4646
4647 (define_insn "fix_trunc<mode>_i387_with_temp"
4648   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4649         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4650    (use (match_operand:HI 2 "memory_operand" "m,m"))
4651    (use (match_operand:HI 3 "memory_operand" "m,m"))
4652    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4653   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4654    && !TARGET_FISTTP
4655    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4656   "#"
4657   [(set_attr "type" "fistp")
4658    (set_attr "i387_cw" "trunc")
4659    (set_attr "mode" "<MODE>")])
4660
4661 (define_split
4662   [(set (match_operand:SWI24 0 "register_operand" "")
4663         (fix:SWI24 (match_operand 1 "register_operand" "")))
4664    (use (match_operand:HI 2 "memory_operand" ""))
4665    (use (match_operand:HI 3 "memory_operand" ""))
4666    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4667   "reload_completed"
4668   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4669               (use (match_dup 2))
4670               (use (match_dup 3))])
4671    (set (match_dup 0) (match_dup 4))])
4672
4673 (define_split
4674   [(set (match_operand:SWI24 0 "memory_operand" "")
4675         (fix:SWI24 (match_operand 1 "register_operand" "")))
4676    (use (match_operand:HI 2 "memory_operand" ""))
4677    (use (match_operand:HI 3 "memory_operand" ""))
4678    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4679   "reload_completed"
4680   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4681               (use (match_dup 2))
4682               (use (match_dup 3))])])
4683
4684 (define_insn "x86_fnstcw_1"
4685   [(set (match_operand:HI 0 "memory_operand" "=m")
4686         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4687   "TARGET_80387"
4688   "fnstcw\t%0"
4689   [(set (attr "length")
4690         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4691    (set_attr "mode" "HI")
4692    (set_attr "unit" "i387")
4693    (set_attr "bdver1_decode" "vector")])
4694
4695 (define_insn "x86_fldcw_1"
4696   [(set (reg:HI FPCR_REG)
4697         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4698   "TARGET_80387"
4699   "fldcw\t%0"
4700   [(set (attr "length")
4701         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4702    (set_attr "mode" "HI")
4703    (set_attr "unit" "i387")
4704    (set_attr "athlon_decode" "vector")
4705    (set_attr "amdfam10_decode" "vector")
4706    (set_attr "bdver1_decode" "vector")])
4707 \f
4708 ;; Conversion between fixed point and floating point.
4709
4710 ;; Even though we only accept memory inputs, the backend _really_
4711 ;; wants to be able to do this between registers.
4712
4713 (define_expand "floathi<mode>2"
4714   [(set (match_operand:X87MODEF 0 "register_operand" "")
4715         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4716   "TARGET_80387
4717    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4718        || TARGET_MIX_SSE_I387)")
4719
4720 ;; Pre-reload splitter to add memory clobber to the pattern.
4721 (define_insn_and_split "*floathi<mode>2_1"
4722   [(set (match_operand:X87MODEF 0 "register_operand" "")
4723         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4724   "TARGET_80387
4725    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4726        || TARGET_MIX_SSE_I387)
4727    && can_create_pseudo_p ()"
4728   "#"
4729   "&& 1"
4730   [(parallel [(set (match_dup 0)
4731               (float:X87MODEF (match_dup 1)))
4732    (clobber (match_dup 2))])]
4733   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4734
4735 (define_insn "*floathi<mode>2_i387_with_temp"
4736   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4737         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4738   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4739   "TARGET_80387
4740    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4741        || TARGET_MIX_SSE_I387)"
4742   "#"
4743   [(set_attr "type" "fmov,multi")
4744    (set_attr "mode" "<MODE>")
4745    (set_attr "unit" "*,i387")
4746    (set_attr "fp_int_src" "true")])
4747
4748 (define_insn "*floathi<mode>2_i387"
4749   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4750         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4751   "TARGET_80387
4752    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4753        || TARGET_MIX_SSE_I387)"
4754   "fild%Z1\t%1"
4755   [(set_attr "type" "fmov")
4756    (set_attr "mode" "<MODE>")
4757    (set_attr "fp_int_src" "true")])
4758
4759 (define_split
4760   [(set (match_operand:X87MODEF 0 "register_operand" "")
4761         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4762    (clobber (match_operand:HI 2 "memory_operand" ""))]
4763   "TARGET_80387
4764    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4765        || TARGET_MIX_SSE_I387)
4766    && reload_completed"
4767   [(set (match_dup 2) (match_dup 1))
4768    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4769
4770 (define_split
4771   [(set (match_operand:X87MODEF 0 "register_operand" "")
4772         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4773    (clobber (match_operand:HI 2 "memory_operand" ""))]
4774    "TARGET_80387
4775     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4776         || TARGET_MIX_SSE_I387)
4777     && reload_completed"
4778   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4779
4780 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4781   [(set (match_operand:X87MODEF 0 "register_operand" "")
4782         (float:X87MODEF
4783           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4784   "TARGET_80387
4785    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4786        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4787 {
4788   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4789         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4790       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4791     {
4792       rtx reg = gen_reg_rtx (XFmode);
4793       rtx (*insn)(rtx, rtx);
4794
4795       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4796
4797       if (<X87MODEF:MODE>mode == SFmode)
4798         insn = gen_truncxfsf2;
4799       else if (<X87MODEF:MODE>mode == DFmode)
4800         insn = gen_truncxfdf2;
4801       else
4802         gcc_unreachable ();
4803
4804       emit_insn (insn (operands[0], reg));
4805       DONE;
4806     }
4807 })
4808
4809 ;; Pre-reload splitter to add memory clobber to the pattern.
4810 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4811   [(set (match_operand:X87MODEF 0 "register_operand" "")
4812         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4813   "((TARGET_80387
4814      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4815      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4816            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4817          || TARGET_MIX_SSE_I387))
4818     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4819         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4820         && ((<SWI48x:MODE>mode == SImode
4821              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4822              && optimize_function_for_speed_p (cfun)
4823              && flag_trapping_math)
4824             || !(TARGET_INTER_UNIT_CONVERSIONS
4825                  || optimize_function_for_size_p (cfun)))))
4826    && can_create_pseudo_p ()"
4827   "#"
4828   "&& 1"
4829   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4830               (clobber (match_dup 2))])]
4831 {
4832   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4833
4834   /* Avoid store forwarding (partial memory) stall penalty
4835      by passing DImode value through XMM registers.  */
4836   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4837       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4838       && optimize_function_for_speed_p (cfun))
4839     {
4840       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4841                                                             operands[1],
4842                                                             operands[2]));
4843       DONE;
4844     }
4845 })
4846
4847 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4848   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4849         (float:MODEF
4850           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4851    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4852   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4853    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4854   "#"
4855   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4856    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4857    (set_attr "unit" "*,i387,*,*,*")
4858    (set_attr "athlon_decode" "*,*,double,direct,double")
4859    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4860    (set_attr "bdver1_decode" "*,*,double,direct,double")
4861    (set_attr "fp_int_src" "true")])
4862
4863 (define_insn "*floatsi<mode>2_vector_mixed"
4864   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4865         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4866   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4867    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4868   "@
4869    fild%Z1\t%1
4870    #"
4871   [(set_attr "type" "fmov,sseicvt")
4872    (set_attr "mode" "<MODE>,<ssevecmode>")
4873    (set_attr "unit" "i387,*")
4874    (set_attr "athlon_decode" "*,direct")
4875    (set_attr "amdfam10_decode" "*,double")
4876    (set_attr "bdver1_decode" "*,direct")
4877    (set_attr "fp_int_src" "true")])
4878
4879 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4880   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4881         (float:MODEF
4882           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4883    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4884   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4885    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4886   "#"
4887   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4888    (set_attr "mode" "<MODEF:MODE>")
4889    (set_attr "unit" "*,i387,*,*")
4890    (set_attr "athlon_decode" "*,*,double,direct")
4891    (set_attr "amdfam10_decode" "*,*,vector,double")
4892    (set_attr "bdver1_decode" "*,*,double,direct")
4893    (set_attr "fp_int_src" "true")])
4894
4895 (define_split
4896   [(set (match_operand:MODEF 0 "register_operand" "")
4897         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4898    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4899   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4900    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4901    && TARGET_INTER_UNIT_CONVERSIONS
4902    && reload_completed
4903    && (SSE_REG_P (operands[0])
4904        || (GET_CODE (operands[0]) == SUBREG
4905            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4906   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4907
4908 (define_split
4909   [(set (match_operand:MODEF 0 "register_operand" "")
4910         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4911    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4912   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4913    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4914    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4915    && reload_completed
4916    && (SSE_REG_P (operands[0])
4917        || (GET_CODE (operands[0]) == SUBREG
4918            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4919   [(set (match_dup 2) (match_dup 1))
4920    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4921
4922 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4923   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4924         (float:MODEF
4925           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4926   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4927    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4928    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4929   "@
4930    fild%Z1\t%1
4931    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4932    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4933   [(set_attr "type" "fmov,sseicvt,sseicvt")
4934    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4935    (set_attr "mode" "<MODEF:MODE>")
4936    (set (attr "prefix_rex")
4937      (if_then_else
4938        (and (eq_attr "prefix" "maybe_vex")
4939             (match_test "<SWI48x:MODE>mode == DImode"))
4940        (const_string "1")
4941        (const_string "*")))
4942    (set_attr "unit" "i387,*,*")
4943    (set_attr "athlon_decode" "*,double,direct")
4944    (set_attr "amdfam10_decode" "*,vector,double")
4945    (set_attr "bdver1_decode" "*,double,direct")
4946    (set_attr "fp_int_src" "true")])
4947
4948 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4949   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4950         (float:MODEF
4951           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4952   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4953    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4954    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4955   "@
4956    fild%Z1\t%1
4957    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4958   [(set_attr "type" "fmov,sseicvt")
4959    (set_attr "prefix" "orig,maybe_vex")
4960    (set_attr "mode" "<MODEF:MODE>")
4961    (set (attr "prefix_rex")
4962      (if_then_else
4963        (and (eq_attr "prefix" "maybe_vex")
4964             (match_test "<SWI48x:MODE>mode == DImode"))
4965        (const_string "1")
4966        (const_string "*")))
4967    (set_attr "athlon_decode" "*,direct")
4968    (set_attr "amdfam10_decode" "*,double")
4969    (set_attr "bdver1_decode" "*,direct")
4970    (set_attr "fp_int_src" "true")])
4971
4972 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4973   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4974         (float:MODEF
4975           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4976    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4977   "TARGET_SSE2 && TARGET_SSE_MATH
4978    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4979   "#"
4980   [(set_attr "type" "sseicvt")
4981    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4982    (set_attr "athlon_decode" "double,direct,double")
4983    (set_attr "amdfam10_decode" "vector,double,double")
4984    (set_attr "bdver1_decode" "double,direct,double")
4985    (set_attr "fp_int_src" "true")])
4986
4987 (define_insn "*floatsi<mode>2_vector_sse"
4988   [(set (match_operand:MODEF 0 "register_operand" "=x")
4989         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4990   "TARGET_SSE2 && TARGET_SSE_MATH
4991    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4992   "#"
4993   [(set_attr "type" "sseicvt")
4994    (set_attr "mode" "<MODE>")
4995    (set_attr "athlon_decode" "direct")
4996    (set_attr "amdfam10_decode" "double")
4997    (set_attr "bdver1_decode" "direct")
4998    (set_attr "fp_int_src" "true")])
4999
5000 (define_split
5001   [(set (match_operand:MODEF 0 "register_operand" "")
5002         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5003    (clobber (match_operand:SI 2 "memory_operand" ""))]
5004   "TARGET_SSE2 && TARGET_SSE_MATH
5005    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5006    && reload_completed
5007    && (SSE_REG_P (operands[0])
5008        || (GET_CODE (operands[0]) == SUBREG
5009            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5010   [(const_int 0)]
5011 {
5012   rtx op1 = operands[1];
5013
5014   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5015                                      <MODE>mode, 0);
5016   if (GET_CODE (op1) == SUBREG)
5017     op1 = SUBREG_REG (op1);
5018
5019   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5020     {
5021       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5022       emit_insn (gen_sse2_loadld (operands[4],
5023                                   CONST0_RTX (V4SImode), operands[1]));
5024     }
5025   /* We can ignore possible trapping value in the
5026      high part of SSE register for non-trapping math. */
5027   else if (SSE_REG_P (op1) && !flag_trapping_math)
5028     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5029   else
5030     {
5031       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5032       emit_move_insn (operands[2], operands[1]);
5033       emit_insn (gen_sse2_loadld (operands[4],
5034                                   CONST0_RTX (V4SImode), operands[2]));
5035     }
5036   if (<ssevecmode>mode == V4SFmode)
5037     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5038   else
5039     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5040   DONE;
5041 })
5042
5043 (define_split
5044   [(set (match_operand:MODEF 0 "register_operand" "")
5045         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5046    (clobber (match_operand:SI 2 "memory_operand" ""))]
5047   "TARGET_SSE2 && TARGET_SSE_MATH
5048    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5049    && reload_completed
5050    && (SSE_REG_P (operands[0])
5051        || (GET_CODE (operands[0]) == SUBREG
5052            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5053   [(const_int 0)]
5054 {
5055   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5056                                      <MODE>mode, 0);
5057   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5058
5059   emit_insn (gen_sse2_loadld (operands[4],
5060                               CONST0_RTX (V4SImode), operands[1]));
5061   if (<ssevecmode>mode == V4SFmode)
5062     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5063   else
5064     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5065   DONE;
5066 })
5067
5068 (define_split
5069   [(set (match_operand:MODEF 0 "register_operand" "")
5070         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5071   "TARGET_SSE2 && TARGET_SSE_MATH
5072    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5073    && reload_completed
5074    && (SSE_REG_P (operands[0])
5075        || (GET_CODE (operands[0]) == SUBREG
5076            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5077   [(const_int 0)]
5078 {
5079   rtx op1 = operands[1];
5080
5081   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5082                                      <MODE>mode, 0);
5083   if (GET_CODE (op1) == SUBREG)
5084     op1 = SUBREG_REG (op1);
5085
5086   if (GENERAL_REG_P (op1))
5087     {
5088       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5089       if (TARGET_INTER_UNIT_MOVES)
5090         emit_insn (gen_sse2_loadld (operands[4],
5091                                     CONST0_RTX (V4SImode), operands[1]));
5092       else
5093         {
5094           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5095                                               operands[1]);
5096           emit_insn (gen_sse2_loadld (operands[4],
5097                                       CONST0_RTX (V4SImode), operands[5]));
5098           ix86_free_from_memory (GET_MODE (operands[1]));
5099         }
5100     }
5101   /* We can ignore possible trapping value in the
5102      high part of SSE register for non-trapping math. */
5103   else if (SSE_REG_P (op1) && !flag_trapping_math)
5104     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5105   else
5106     gcc_unreachable ();
5107   if (<ssevecmode>mode == V4SFmode)
5108     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5109   else
5110     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5111   DONE;
5112 })
5113
5114 (define_split
5115   [(set (match_operand:MODEF 0 "register_operand" "")
5116         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5117   "TARGET_SSE2 && TARGET_SSE_MATH
5118    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5119    && reload_completed
5120    && (SSE_REG_P (operands[0])
5121        || (GET_CODE (operands[0]) == SUBREG
5122            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5123   [(const_int 0)]
5124 {
5125   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5126                                      <MODE>mode, 0);
5127   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5128
5129   emit_insn (gen_sse2_loadld (operands[4],
5130                               CONST0_RTX (V4SImode), operands[1]));
5131   if (<ssevecmode>mode == V4SFmode)
5132     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5133   else
5134     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5135   DONE;
5136 })
5137
5138 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5139   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5140         (float:MODEF
5141           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5142   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5143   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5144    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5145   "#"
5146   [(set_attr "type" "sseicvt")
5147    (set_attr "mode" "<MODEF:MODE>")
5148    (set_attr "athlon_decode" "double,direct")
5149    (set_attr "amdfam10_decode" "vector,double")
5150    (set_attr "bdver1_decode" "double,direct")
5151    (set_attr "fp_int_src" "true")])
5152
5153 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5154   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5155         (float:MODEF
5156           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5157   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5158    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5159    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5160   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5161   [(set_attr "type" "sseicvt")
5162    (set_attr "prefix" "maybe_vex")
5163    (set_attr "mode" "<MODEF:MODE>")
5164    (set (attr "prefix_rex")
5165      (if_then_else
5166        (and (eq_attr "prefix" "maybe_vex")
5167             (match_test "<SWI48x:MODE>mode == DImode"))
5168        (const_string "1")
5169        (const_string "*")))
5170    (set_attr "athlon_decode" "double,direct")
5171    (set_attr "amdfam10_decode" "vector,double")
5172    (set_attr "bdver1_decode" "double,direct")
5173    (set_attr "fp_int_src" "true")])
5174
5175 (define_split
5176   [(set (match_operand:MODEF 0 "register_operand" "")
5177         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5178    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5179   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5180    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5181    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5182    && reload_completed
5183    && (SSE_REG_P (operands[0])
5184        || (GET_CODE (operands[0]) == SUBREG
5185            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5186   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5187
5188 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5189   [(set (match_operand:MODEF 0 "register_operand" "=x")
5190         (float:MODEF
5191           (match_operand:SWI48x 1 "memory_operand" "m")))]
5192   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5193    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5194    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5195   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5196   [(set_attr "type" "sseicvt")
5197    (set_attr "prefix" "maybe_vex")
5198    (set_attr "mode" "<MODEF:MODE>")
5199    (set (attr "prefix_rex")
5200      (if_then_else
5201        (and (eq_attr "prefix" "maybe_vex")
5202             (match_test "<SWI48x:MODE>mode == DImode"))
5203        (const_string "1")
5204        (const_string "*")))
5205    (set_attr "athlon_decode" "direct")
5206    (set_attr "amdfam10_decode" "double")
5207    (set_attr "bdver1_decode" "direct")
5208    (set_attr "fp_int_src" "true")])
5209
5210 (define_split
5211   [(set (match_operand:MODEF 0 "register_operand" "")
5212         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5213    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5214   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5215    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5216    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5217    && reload_completed
5218    && (SSE_REG_P (operands[0])
5219        || (GET_CODE (operands[0]) == SUBREG
5220            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5221   [(set (match_dup 2) (match_dup 1))
5222    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5223
5224 (define_split
5225   [(set (match_operand:MODEF 0 "register_operand" "")
5226         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5227    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5228   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5229    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5230    && reload_completed
5231    && (SSE_REG_P (operands[0])
5232        || (GET_CODE (operands[0]) == SUBREG
5233            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5234   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5235
5236 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5237   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5238         (float:X87MODEF
5239           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5240   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5241   "TARGET_80387
5242    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5243   "@
5244    fild%Z1\t%1
5245    #"
5246   [(set_attr "type" "fmov,multi")
5247    (set_attr "mode" "<X87MODEF:MODE>")
5248    (set_attr "unit" "*,i387")
5249    (set_attr "fp_int_src" "true")])
5250
5251 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5252   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5253         (float:X87MODEF
5254           (match_operand:SWI48x 1 "memory_operand" "m")))]
5255   "TARGET_80387
5256    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5257   "fild%Z1\t%1"
5258   [(set_attr "type" "fmov")
5259    (set_attr "mode" "<X87MODEF:MODE>")
5260    (set_attr "fp_int_src" "true")])
5261
5262 (define_split
5263   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5264         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5265    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5266   "TARGET_80387
5267    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5268    && reload_completed"
5269   [(set (match_dup 2) (match_dup 1))
5270    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5271
5272 (define_split
5273   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5274         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5275    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5276   "TARGET_80387
5277    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5278    && reload_completed"
5279   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5280
5281 ;; Avoid store forwarding (partial memory) stall penalty
5282 ;; by passing DImode value through XMM registers.  */
5283
5284 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5285   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5286         (float:X87MODEF
5287           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5288    (clobber (match_scratch:V4SI 3 "=X,x"))
5289    (clobber (match_scratch:V4SI 4 "=X,x"))
5290    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5291   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5292    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5293    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5294   "#"
5295   [(set_attr "type" "multi")
5296    (set_attr "mode" "<X87MODEF:MODE>")
5297    (set_attr "unit" "i387")
5298    (set_attr "fp_int_src" "true")])
5299
5300 (define_split
5301   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5302         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5303    (clobber (match_scratch:V4SI 3 ""))
5304    (clobber (match_scratch:V4SI 4 ""))
5305    (clobber (match_operand:DI 2 "memory_operand" ""))]
5306   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5307    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5308    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5309    && reload_completed"
5310   [(set (match_dup 2) (match_dup 3))
5311    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5312 {
5313   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5314      Assemble the 64-bit DImode value in an xmm register.  */
5315   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5316                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5317   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5318                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5319   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5320                                          operands[4]));
5321
5322   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5323 })
5324
5325 (define_split
5326   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5327         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5328    (clobber (match_scratch:V4SI 3 ""))
5329    (clobber (match_scratch:V4SI 4 ""))
5330    (clobber (match_operand:DI 2 "memory_operand" ""))]
5331   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5332    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5333    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5334    && reload_completed"
5335   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5336
5337 ;; Avoid store forwarding (partial memory) stall penalty by extending
5338 ;; SImode value to DImode through XMM register instead of pushing two
5339 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5340 ;; targets benefit from this optimization. Also note that fild
5341 ;; loads from memory only.
5342
5343 (define_insn "*floatunssi<mode>2_1"
5344   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5345         (unsigned_float:X87MODEF
5346           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5347    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5348    (clobber (match_scratch:SI 3 "=X,x"))]
5349   "!TARGET_64BIT
5350    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5351    && TARGET_SSE"
5352   "#"
5353   [(set_attr "type" "multi")
5354    (set_attr "mode" "<MODE>")])
5355
5356 (define_split
5357   [(set (match_operand:X87MODEF 0 "register_operand" "")
5358         (unsigned_float:X87MODEF
5359           (match_operand:SI 1 "register_operand" "")))
5360    (clobber (match_operand:DI 2 "memory_operand" ""))
5361    (clobber (match_scratch:SI 3 ""))]
5362   "!TARGET_64BIT
5363    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5364    && TARGET_SSE
5365    && reload_completed"
5366   [(set (match_dup 2) (match_dup 1))
5367    (set (match_dup 0)
5368         (float:X87MODEF (match_dup 2)))]
5369   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5370
5371 (define_split
5372   [(set (match_operand:X87MODEF 0 "register_operand" "")
5373         (unsigned_float:X87MODEF
5374           (match_operand:SI 1 "memory_operand" "")))
5375    (clobber (match_operand:DI 2 "memory_operand" ""))
5376    (clobber (match_scratch:SI 3 ""))]
5377   "!TARGET_64BIT
5378    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5379    && TARGET_SSE
5380    && reload_completed"
5381   [(set (match_dup 2) (match_dup 3))
5382    (set (match_dup 0)
5383         (float:X87MODEF (match_dup 2)))]
5384 {
5385   emit_move_insn (operands[3], operands[1]);
5386   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5387 })
5388
5389 (define_expand "floatunssi<mode>2"
5390   [(parallel
5391      [(set (match_operand:X87MODEF 0 "register_operand" "")
5392            (unsigned_float:X87MODEF
5393              (match_operand:SI 1 "nonimmediate_operand" "")))
5394       (clobber (match_dup 2))
5395       (clobber (match_scratch:SI 3 ""))])]
5396   "!TARGET_64BIT
5397    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5398         && TARGET_SSE)
5399        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5400 {
5401   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5402     {
5403       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5404       DONE;
5405     }
5406   else
5407     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5408 })
5409
5410 (define_expand "floatunsdisf2"
5411   [(use (match_operand:SF 0 "register_operand" ""))
5412    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5413   "TARGET_64BIT && TARGET_SSE_MATH"
5414   "x86_emit_floatuns (operands); DONE;")
5415
5416 (define_expand "floatunsdidf2"
5417   [(use (match_operand:DF 0 "register_operand" ""))
5418    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5419   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5420    && TARGET_SSE2 && TARGET_SSE_MATH"
5421 {
5422   if (TARGET_64BIT)
5423     x86_emit_floatuns (operands);
5424   else
5425     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5426   DONE;
5427 })
5428 \f
5429 ;; Load effective address instructions
5430
5431 (define_insn_and_split "*lea<mode>"
5432   [(set (match_operand:SWI48 0 "register_operand" "=r")
5433         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5434   ""
5435 {
5436   rtx addr = operands[1];
5437
5438   if (SImode_address_operand (addr, VOIDmode))
5439     {
5440       gcc_assert (TARGET_64BIT);
5441       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5442     }
5443   else 
5444     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5445 }
5446   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5447   [(const_int 0)]
5448 {
5449   ix86_split_lea_for_addr (operands, <MODE>mode);
5450   DONE;
5451 }
5452   [(set_attr "type" "lea")
5453    (set (attr "mode")
5454      (if_then_else
5455        (match_operand 1 "SImode_address_operand")
5456        (const_string "SI")
5457        (const_string "<MODE>")))])
5458 \f
5459 ;; Add instructions
5460
5461 (define_expand "add<mode>3"
5462   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5463         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5464                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5465   ""
5466   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5467
5468 (define_insn_and_split "*add<dwi>3_doubleword"
5469   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5470         (plus:<DWI>
5471           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5472           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5473    (clobber (reg:CC FLAGS_REG))]
5474   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5475   "#"
5476   "reload_completed"
5477   [(parallel [(set (reg:CC FLAGS_REG)
5478                    (unspec:CC [(match_dup 1) (match_dup 2)]
5479                               UNSPEC_ADD_CARRY))
5480               (set (match_dup 0)
5481                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5482    (parallel [(set (match_dup 3)
5483                    (plus:DWIH
5484                      (match_dup 4)
5485                      (plus:DWIH
5486                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5487                        (match_dup 5))))
5488               (clobber (reg:CC FLAGS_REG))])]
5489   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5490
5491 (define_insn "*add<mode>3_cc"
5492   [(set (reg:CC FLAGS_REG)
5493         (unspec:CC
5494           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5495            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5496           UNSPEC_ADD_CARRY))
5497    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5498         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5499   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5500   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5501   [(set_attr "type" "alu")
5502    (set_attr "mode" "<MODE>")])
5503
5504 (define_insn "addqi3_cc"
5505   [(set (reg:CC FLAGS_REG)
5506         (unspec:CC
5507           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5508            (match_operand:QI 2 "general_operand" "qn,qm")]
5509           UNSPEC_ADD_CARRY))
5510    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5511         (plus:QI (match_dup 1) (match_dup 2)))]
5512   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5513   "add{b}\t{%2, %0|%0, %2}"
5514   [(set_attr "type" "alu")
5515    (set_attr "mode" "QI")])
5516
5517 (define_insn "*add<mode>_1"
5518   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5519         (plus:SWI48
5520           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5521           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5522    (clobber (reg:CC FLAGS_REG))]
5523   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5524 {
5525   switch (get_attr_type (insn))
5526     {
5527     case TYPE_LEA:
5528       return "#";
5529
5530     case TYPE_INCDEC:
5531       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5532       if (operands[2] == const1_rtx)
5533         return "inc{<imodesuffix>}\t%0";
5534       else
5535         {
5536           gcc_assert (operands[2] == constm1_rtx);
5537           return "dec{<imodesuffix>}\t%0";
5538         }
5539
5540     default:
5541       /* For most processors, ADD is faster than LEA.  This alternative
5542          was added to use ADD as much as possible.  */
5543       if (which_alternative == 2)
5544         {
5545           rtx tmp;
5546           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5547         }
5548         
5549       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5550       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5551         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5552
5553       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5554     }
5555 }
5556   [(set (attr "type")
5557      (cond [(eq_attr "alternative" "3")
5558               (const_string "lea")
5559             (match_operand:SWI48 2 "incdec_operand" "")
5560               (const_string "incdec")
5561            ]
5562            (const_string "alu")))
5563    (set (attr "length_immediate")
5564       (if_then_else
5565         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5566         (const_string "1")
5567         (const_string "*")))
5568    (set_attr "mode" "<MODE>")])
5569
5570 ;; It may seem that nonimmediate operand is proper one for operand 1.
5571 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5572 ;; we take care in ix86_binary_operator_ok to not allow two memory
5573 ;; operands so proper swapping will be done in reload.  This allow
5574 ;; patterns constructed from addsi_1 to match.
5575
5576 (define_insn "addsi_1_zext"
5577   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5578         (zero_extend:DI
5579           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5580                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5581    (clobber (reg:CC FLAGS_REG))]
5582   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5583 {
5584   switch (get_attr_type (insn))
5585     {
5586     case TYPE_LEA:
5587       return "#";
5588
5589     case TYPE_INCDEC:
5590       if (operands[2] == const1_rtx)
5591         return "inc{l}\t%k0";
5592       else
5593         {
5594           gcc_assert (operands[2] == constm1_rtx);
5595           return "dec{l}\t%k0";
5596         }
5597
5598     default:
5599       /* For most processors, ADD is faster than LEA.  This alternative
5600          was added to use ADD as much as possible.  */
5601       if (which_alternative == 1)
5602         {
5603           rtx tmp;
5604           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5605         }
5606
5607       if (x86_maybe_negate_const_int (&operands[2], SImode))
5608         return "sub{l}\t{%2, %k0|%k0, %2}";
5609
5610       return "add{l}\t{%2, %k0|%k0, %2}";
5611     }
5612 }
5613   [(set (attr "type")
5614      (cond [(eq_attr "alternative" "2")
5615               (const_string "lea")
5616             (match_operand:SI 2 "incdec_operand" "")
5617               (const_string "incdec")
5618            ]
5619            (const_string "alu")))
5620    (set (attr "length_immediate")
5621       (if_then_else
5622         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5623         (const_string "1")
5624         (const_string "*")))
5625    (set_attr "mode" "SI")])
5626
5627 (define_insn "*addhi_1"
5628   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5629         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5630                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5631    (clobber (reg:CC FLAGS_REG))]
5632   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5633 {
5634   switch (get_attr_type (insn))
5635     {
5636     case TYPE_LEA:
5637       return "#";
5638
5639     case TYPE_INCDEC:
5640       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641       if (operands[2] == const1_rtx)
5642         return "inc{w}\t%0";
5643       else
5644         {
5645           gcc_assert (operands[2] == constm1_rtx);
5646           return "dec{w}\t%0";
5647         }
5648
5649     default:
5650       /* For most processors, ADD is faster than LEA.  This alternative
5651          was added to use ADD as much as possible.  */
5652       if (which_alternative == 2)
5653         {
5654           rtx tmp;
5655           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5656         }
5657
5658       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5659       if (x86_maybe_negate_const_int (&operands[2], HImode))
5660         return "sub{w}\t{%2, %0|%0, %2}";
5661
5662       return "add{w}\t{%2, %0|%0, %2}";
5663     }
5664 }
5665   [(set (attr "type")
5666      (cond [(eq_attr "alternative" "3")
5667               (const_string "lea")
5668             (match_operand:HI 2 "incdec_operand" "")
5669               (const_string "incdec")
5670            ]
5671            (const_string "alu")))
5672    (set (attr "length_immediate")
5673       (if_then_else
5674         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5675         (const_string "1")
5676         (const_string "*")))
5677    (set_attr "mode" "HI,HI,HI,SI")])
5678
5679 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5680 (define_insn "*addqi_1"
5681   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5682         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5683                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5684    (clobber (reg:CC FLAGS_REG))]
5685   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5686 {
5687   bool widen = (which_alternative == 3 || which_alternative == 4);
5688
5689   switch (get_attr_type (insn))
5690     {
5691     case TYPE_LEA:
5692       return "#";
5693
5694     case TYPE_INCDEC:
5695       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5696       if (operands[2] == const1_rtx)
5697         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5698       else
5699         {
5700           gcc_assert (operands[2] == constm1_rtx);
5701           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5702         }
5703
5704     default:
5705       /* For most processors, ADD is faster than LEA.  These alternatives
5706          were added to use ADD as much as possible.  */
5707       if (which_alternative == 2 || which_alternative == 4)
5708         {
5709           rtx tmp;
5710           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5711         }
5712
5713       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5714       if (x86_maybe_negate_const_int (&operands[2], QImode))
5715         {
5716           if (widen)
5717             return "sub{l}\t{%2, %k0|%k0, %2}";
5718           else
5719             return "sub{b}\t{%2, %0|%0, %2}";
5720         }
5721       if (widen)
5722         return "add{l}\t{%k2, %k0|%k0, %k2}";
5723       else
5724         return "add{b}\t{%2, %0|%0, %2}";
5725     }
5726 }
5727   [(set (attr "type")
5728      (cond [(eq_attr "alternative" "5")
5729               (const_string "lea")
5730             (match_operand:QI 2 "incdec_operand" "")
5731               (const_string "incdec")
5732            ]
5733            (const_string "alu")))
5734    (set (attr "length_immediate")
5735       (if_then_else
5736         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5737         (const_string "1")
5738         (const_string "*")))
5739    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5740
5741 (define_insn "*addqi_1_slp"
5742   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5743         (plus:QI (match_dup 0)
5744                  (match_operand:QI 1 "general_operand" "qn,qm")))
5745    (clobber (reg:CC FLAGS_REG))]
5746   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5747    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5748 {
5749   switch (get_attr_type (insn))
5750     {
5751     case TYPE_INCDEC:
5752       if (operands[1] == const1_rtx)
5753         return "inc{b}\t%0";
5754       else
5755         {
5756           gcc_assert (operands[1] == constm1_rtx);
5757           return "dec{b}\t%0";
5758         }
5759
5760     default:
5761       if (x86_maybe_negate_const_int (&operands[1], QImode))
5762         return "sub{b}\t{%1, %0|%0, %1}";
5763
5764       return "add{b}\t{%1, %0|%0, %1}";
5765     }
5766 }
5767   [(set (attr "type")
5768      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5769         (const_string "incdec")
5770         (const_string "alu1")))
5771    (set (attr "memory")
5772      (if_then_else (match_operand 1 "memory_operand" "")
5773         (const_string "load")
5774         (const_string "none")))
5775    (set_attr "mode" "QI")])
5776
5777 ;; Split non destructive adds if we cannot use lea.
5778 (define_split
5779   [(set (match_operand:SWI48 0 "register_operand" "")
5780         (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5781               (match_operand:SWI48 2 "nonmemory_operand" "")))
5782    (clobber (reg:CC FLAGS_REG))]
5783   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5784   [(set (match_dup 0) (match_dup 1))
5785    (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5786               (clobber (reg:CC FLAGS_REG))])])
5787
5788 ;; Convert add to the lea pattern to avoid flags dependency.
5789 (define_split
5790   [(set (match_operand:SWI 0 "register_operand" "")
5791         (plus:SWI (match_operand:SWI 1 "register_operand" "")
5792                   (match_operand:SWI 2 "<nonmemory_operand>" "")))
5793    (clobber (reg:CC FLAGS_REG))]
5794   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5795   [(const_int 0)]
5796 {
5797   enum machine_mode mode = <MODE>mode;
5798   rtx pat;
5799
5800   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5801     { 
5802       mode = SImode; 
5803       operands[0] = gen_lowpart (mode, operands[0]);
5804       operands[1] = gen_lowpart (mode, operands[1]);
5805       operands[2] = gen_lowpart (mode, operands[2]);
5806     }
5807
5808   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5809
5810   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5811   DONE;
5812 })
5813
5814 ;; Convert add to the lea pattern to avoid flags dependency.
5815 (define_split
5816   [(set (match_operand:DI 0 "register_operand" "")
5817         (zero_extend:DI
5818           (plus:SI (match_operand:SI 1 "register_operand" "")
5819                    (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5820    (clobber (reg:CC FLAGS_REG))]
5821   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5822   [(set (match_dup 0)
5823         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5824
5825 (define_insn "*add<mode>_2"
5826   [(set (reg FLAGS_REG)
5827         (compare
5828           (plus:SWI
5829             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5830             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5831           (const_int 0)))
5832    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5833         (plus:SWI (match_dup 1) (match_dup 2)))]
5834   "ix86_match_ccmode (insn, CCGOCmode)
5835    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5836 {
5837   switch (get_attr_type (insn))
5838     {
5839     case TYPE_INCDEC:
5840       if (operands[2] == const1_rtx)
5841         return "inc{<imodesuffix>}\t%0";
5842       else
5843         {
5844           gcc_assert (operands[2] == constm1_rtx);
5845           return "dec{<imodesuffix>}\t%0";
5846         }
5847
5848     default:
5849       if (which_alternative == 2)
5850         {
5851           rtx tmp;
5852           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5853         }
5854         
5855       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5856       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5857         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5858
5859       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5860     }
5861 }
5862   [(set (attr "type")
5863      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5864         (const_string "incdec")
5865         (const_string "alu")))
5866    (set (attr "length_immediate")
5867       (if_then_else
5868         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5869         (const_string "1")
5870         (const_string "*")))
5871    (set_attr "mode" "<MODE>")])
5872
5873 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5874 (define_insn "*addsi_2_zext"
5875   [(set (reg FLAGS_REG)
5876         (compare
5877           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5878                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5879           (const_int 0)))
5880    (set (match_operand:DI 0 "register_operand" "=r,r")
5881         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5882   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5883    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5884 {
5885   switch (get_attr_type (insn))
5886     {
5887     case TYPE_INCDEC:
5888       if (operands[2] == const1_rtx)
5889         return "inc{l}\t%k0";
5890       else
5891         {
5892           gcc_assert (operands[2] == constm1_rtx);
5893           return "dec{l}\t%k0";
5894         }
5895
5896     default:
5897       if (which_alternative == 1)
5898         {
5899           rtx tmp;
5900           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5901         }
5902
5903       if (x86_maybe_negate_const_int (&operands[2], SImode))
5904         return "sub{l}\t{%2, %k0|%k0, %2}";
5905
5906       return "add{l}\t{%2, %k0|%k0, %2}";
5907     }
5908 }
5909   [(set (attr "type")
5910      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5911         (const_string "incdec")
5912         (const_string "alu")))
5913    (set (attr "length_immediate")
5914       (if_then_else
5915         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5916         (const_string "1")
5917         (const_string "*")))
5918    (set_attr "mode" "SI")])
5919
5920 (define_insn "*add<mode>_3"
5921   [(set (reg FLAGS_REG)
5922         (compare
5923           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5924           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5925    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5926   "ix86_match_ccmode (insn, CCZmode)
5927    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5928 {
5929   switch (get_attr_type (insn))
5930     {
5931     case TYPE_INCDEC:
5932       if (operands[2] == const1_rtx)
5933         return "inc{<imodesuffix>}\t%0";
5934       else
5935         {
5936           gcc_assert (operands[2] == constm1_rtx);
5937           return "dec{<imodesuffix>}\t%0";
5938         }
5939
5940     default:
5941       if (which_alternative == 1)
5942         {
5943           rtx tmp;
5944           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5945         }
5946
5947       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5948       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5949         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5950
5951       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5952     }
5953 }
5954   [(set (attr "type")
5955      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5956         (const_string "incdec")
5957         (const_string "alu")))
5958    (set (attr "length_immediate")
5959       (if_then_else
5960         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5961         (const_string "1")
5962         (const_string "*")))
5963    (set_attr "mode" "<MODE>")])
5964
5965 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5966 (define_insn "*addsi_3_zext"
5967   [(set (reg FLAGS_REG)
5968         (compare
5969           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5970           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5971    (set (match_operand:DI 0 "register_operand" "=r,r")
5972         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5973   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5974    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5975 {
5976   switch (get_attr_type (insn))
5977     {
5978     case TYPE_INCDEC:
5979       if (operands[2] == const1_rtx)
5980         return "inc{l}\t%k0";
5981       else
5982         {
5983           gcc_assert (operands[2] == constm1_rtx);
5984           return "dec{l}\t%k0";
5985         }
5986
5987     default:
5988       if (which_alternative == 1)
5989         {
5990           rtx tmp;
5991           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5992         }
5993
5994       if (x86_maybe_negate_const_int (&operands[2], SImode))
5995         return "sub{l}\t{%2, %k0|%k0, %2}";
5996
5997       return "add{l}\t{%2, %k0|%k0, %2}";
5998     }
5999 }
6000   [(set (attr "type")
6001      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6002         (const_string "incdec")
6003         (const_string "alu")))
6004    (set (attr "length_immediate")
6005       (if_then_else
6006         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6007         (const_string "1")
6008         (const_string "*")))
6009    (set_attr "mode" "SI")])
6010
6011 ; For comparisons against 1, -1 and 128, we may generate better code
6012 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6013 ; is matched then.  We can't accept general immediate, because for
6014 ; case of overflows,  the result is messed up.
6015 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6016 ; only for comparisons not depending on it.
6017
6018 (define_insn "*adddi_4"
6019   [(set (reg FLAGS_REG)
6020         (compare
6021           (match_operand:DI 1 "nonimmediate_operand" "0")
6022           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6023    (clobber (match_scratch:DI 0 "=rm"))]
6024   "TARGET_64BIT
6025    && ix86_match_ccmode (insn, CCGCmode)"
6026 {
6027   switch (get_attr_type (insn))
6028     {
6029     case TYPE_INCDEC:
6030       if (operands[2] == constm1_rtx)
6031         return "inc{q}\t%0";
6032       else
6033         {
6034           gcc_assert (operands[2] == const1_rtx);
6035           return "dec{q}\t%0";
6036         }
6037
6038     default:
6039       if (x86_maybe_negate_const_int (&operands[2], DImode))
6040         return "add{q}\t{%2, %0|%0, %2}";
6041
6042       return "sub{q}\t{%2, %0|%0, %2}";
6043     }
6044 }
6045   [(set (attr "type")
6046      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6047         (const_string "incdec")
6048         (const_string "alu")))
6049    (set (attr "length_immediate")
6050       (if_then_else
6051         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6052         (const_string "1")
6053         (const_string "*")))
6054    (set_attr "mode" "DI")])
6055
6056 ; For comparisons against 1, -1 and 128, we may generate better code
6057 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6058 ; is matched then.  We can't accept general immediate, because for
6059 ; case of overflows,  the result is messed up.
6060 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6061 ; only for comparisons not depending on it.
6062
6063 (define_insn "*add<mode>_4"
6064   [(set (reg FLAGS_REG)
6065         (compare
6066           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6067           (match_operand:SWI124 2 "const_int_operand" "n")))
6068    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6069   "ix86_match_ccmode (insn, CCGCmode)"
6070 {
6071   switch (get_attr_type (insn))
6072     {
6073     case TYPE_INCDEC:
6074       if (operands[2] == constm1_rtx)
6075         return "inc{<imodesuffix>}\t%0";
6076       else
6077         {
6078           gcc_assert (operands[2] == const1_rtx);
6079           return "dec{<imodesuffix>}\t%0";
6080         }
6081
6082     default:
6083       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6084         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6085
6086       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6087     }
6088 }
6089   [(set (attr "type")
6090      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6091         (const_string "incdec")
6092         (const_string "alu")))
6093    (set (attr "length_immediate")
6094       (if_then_else
6095         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6096         (const_string "1")
6097         (const_string "*")))
6098    (set_attr "mode" "<MODE>")])
6099
6100 (define_insn "*add<mode>_5"
6101   [(set (reg FLAGS_REG)
6102         (compare
6103           (plus:SWI
6104             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6105             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6106           (const_int 0)))
6107    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6108   "ix86_match_ccmode (insn, CCGOCmode)
6109    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6110 {
6111   switch (get_attr_type (insn))
6112     {
6113     case TYPE_INCDEC:
6114       if (operands[2] == const1_rtx)
6115         return "inc{<imodesuffix>}\t%0";
6116       else
6117         {
6118           gcc_assert (operands[2] == constm1_rtx);
6119           return "dec{<imodesuffix>}\t%0";
6120         }
6121
6122     default:
6123       if (which_alternative == 1)
6124         {
6125           rtx tmp;
6126           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6127         }
6128
6129       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6130       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6131         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6132
6133       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6134     }
6135 }
6136   [(set (attr "type")
6137      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6138         (const_string "incdec")
6139         (const_string "alu")))
6140    (set (attr "length_immediate")
6141       (if_then_else
6142         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6143         (const_string "1")
6144         (const_string "*")))
6145    (set_attr "mode" "<MODE>")])
6146
6147 (define_insn "*addqi_ext_1_rex64"
6148   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6149                          (const_int 8)
6150                          (const_int 8))
6151         (plus:SI
6152           (zero_extract:SI
6153             (match_operand 1 "ext_register_operand" "0")
6154             (const_int 8)
6155             (const_int 8))
6156           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6157    (clobber (reg:CC FLAGS_REG))]
6158   "TARGET_64BIT"
6159 {
6160   switch (get_attr_type (insn))
6161     {
6162     case TYPE_INCDEC:
6163       if (operands[2] == const1_rtx)
6164         return "inc{b}\t%h0";
6165       else
6166         {
6167           gcc_assert (operands[2] == constm1_rtx);
6168           return "dec{b}\t%h0";
6169         }
6170
6171     default:
6172       return "add{b}\t{%2, %h0|%h0, %2}";
6173     }
6174 }
6175   [(set (attr "type")
6176      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6177         (const_string "incdec")
6178         (const_string "alu")))
6179    (set_attr "modrm" "1")
6180    (set_attr "mode" "QI")])
6181
6182 (define_insn "addqi_ext_1"
6183   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6184                          (const_int 8)
6185                          (const_int 8))
6186         (plus:SI
6187           (zero_extract:SI
6188             (match_operand 1 "ext_register_operand" "0")
6189             (const_int 8)
6190             (const_int 8))
6191           (match_operand:QI 2 "general_operand" "Qmn")))
6192    (clobber (reg:CC FLAGS_REG))]
6193   "!TARGET_64BIT"
6194 {
6195   switch (get_attr_type (insn))
6196     {
6197     case TYPE_INCDEC:
6198       if (operands[2] == const1_rtx)
6199         return "inc{b}\t%h0";
6200       else
6201         {
6202           gcc_assert (operands[2] == constm1_rtx);
6203           return "dec{b}\t%h0";
6204         }
6205
6206     default:
6207       return "add{b}\t{%2, %h0|%h0, %2}";
6208     }
6209 }
6210   [(set (attr "type")
6211      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6212         (const_string "incdec")
6213         (const_string "alu")))
6214    (set_attr "modrm" "1")
6215    (set_attr "mode" "QI")])
6216
6217 (define_insn "*addqi_ext_2"
6218   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6219                          (const_int 8)
6220                          (const_int 8))
6221         (plus:SI
6222           (zero_extract:SI
6223             (match_operand 1 "ext_register_operand" "%0")
6224             (const_int 8)
6225             (const_int 8))
6226           (zero_extract:SI
6227             (match_operand 2 "ext_register_operand" "Q")
6228             (const_int 8)
6229             (const_int 8))))
6230    (clobber (reg:CC FLAGS_REG))]
6231   ""
6232   "add{b}\t{%h2, %h0|%h0, %h2}"
6233   [(set_attr "type" "alu")
6234    (set_attr "mode" "QI")])
6235
6236 ;; The lea patterns for modes less than 32 bits need to be matched by
6237 ;; several insns converted to real lea by splitters.
6238
6239 (define_insn_and_split "*lea_general_1"
6240   [(set (match_operand 0 "register_operand" "=r")
6241         (plus (plus (match_operand 1 "index_register_operand" "l")
6242                     (match_operand 2 "register_operand" "r"))
6243               (match_operand 3 "immediate_operand" "i")))]
6244   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6245    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6246    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6247    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6248    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6249        || GET_MODE (operands[3]) == VOIDmode)"
6250   "#"
6251   "&& reload_completed"
6252   [(const_int 0)]
6253 {
6254   enum machine_mode mode = SImode;
6255   rtx pat;
6256
6257   operands[0] = gen_lowpart (mode, operands[0]);
6258   operands[1] = gen_lowpart (mode, operands[1]);
6259   operands[2] = gen_lowpart (mode, operands[2]);
6260   operands[3] = gen_lowpart (mode, operands[3]);
6261
6262   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6263                       operands[3]);
6264
6265   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6266   DONE;
6267 }
6268   [(set_attr "type" "lea")
6269    (set_attr "mode" "SI")])
6270
6271 (define_insn_and_split "*lea_general_2"
6272   [(set (match_operand 0 "register_operand" "=r")
6273         (plus (mult (match_operand 1 "index_register_operand" "l")
6274                     (match_operand 2 "const248_operand" "n"))
6275               (match_operand 3 "nonmemory_operand" "ri")))]
6276   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6277    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6278    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6279    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6280        || GET_MODE (operands[3]) == VOIDmode)"
6281   "#"
6282   "&& reload_completed"
6283   [(const_int 0)]
6284 {
6285   enum machine_mode mode = SImode;
6286   rtx pat;
6287
6288   operands[0] = gen_lowpart (mode, operands[0]);
6289   operands[1] = gen_lowpart (mode, operands[1]);
6290   operands[3] = gen_lowpart (mode, operands[3]);
6291
6292   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6293                       operands[3]);
6294
6295   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6296   DONE;
6297 }
6298   [(set_attr "type" "lea")
6299    (set_attr "mode" "SI")])
6300
6301 (define_insn_and_split "*lea_general_3"
6302   [(set (match_operand 0 "register_operand" "=r")
6303         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6304                           (match_operand 2 "const248_operand" "n"))
6305                     (match_operand 3 "register_operand" "r"))
6306               (match_operand 4 "immediate_operand" "i")))]
6307   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6308    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6309    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6310    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6311   "#"
6312   "&& reload_completed"
6313   [(const_int 0)]
6314 {
6315   enum machine_mode mode = SImode;
6316   rtx pat;
6317
6318   operands[0] = gen_lowpart (mode, operands[0]);
6319   operands[1] = gen_lowpart (mode, operands[1]);
6320   operands[3] = gen_lowpart (mode, operands[3]);
6321   operands[4] = gen_lowpart (mode, operands[4]);
6322
6323   pat = gen_rtx_PLUS (mode,
6324                       gen_rtx_PLUS (mode,
6325                                     gen_rtx_MULT (mode, operands[1],
6326                                                         operands[2]),
6327                                     operands[3]),
6328                       operands[4]);
6329
6330   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6331   DONE;
6332 }
6333   [(set_attr "type" "lea")
6334    (set_attr "mode" "SI")])
6335
6336 (define_insn_and_split "*lea_general_4"
6337   [(set (match_operand 0 "register_operand" "=r")
6338         (any_or (ashift
6339                   (match_operand 1 "index_register_operand" "l")
6340                   (match_operand 2 "const_int_operand" "n"))
6341                 (match_operand 3 "const_int_operand" "n")))]
6342   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6343       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6344     || GET_MODE (operands[0]) == SImode
6345     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6346    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6347    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6348    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6349        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6350   "#"
6351   "&& reload_completed"
6352   [(const_int 0)]
6353 {
6354   enum machine_mode mode = GET_MODE (operands[0]);
6355   rtx pat;
6356
6357   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6358     { 
6359       mode = SImode; 
6360       operands[0] = gen_lowpart (mode, operands[0]);
6361       operands[1] = gen_lowpart (mode, operands[1]);
6362     }
6363
6364   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6365
6366   pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6367                        INTVAL (operands[3]));
6368
6369   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6370   DONE;
6371 }
6372   [(set_attr "type" "lea")
6373    (set (attr "mode")
6374       (if_then_else (match_operand:DI 0 "" "")
6375         (const_string "DI")
6376         (const_string "SI")))])
6377 \f
6378 ;; Subtract instructions
6379
6380 (define_expand "sub<mode>3"
6381   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6382         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6383                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6384   ""
6385   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6386
6387 (define_insn_and_split "*sub<dwi>3_doubleword"
6388   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6389         (minus:<DWI>
6390           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6391           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6392    (clobber (reg:CC FLAGS_REG))]
6393   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6394   "#"
6395   "reload_completed"
6396   [(parallel [(set (reg:CC FLAGS_REG)
6397                    (compare:CC (match_dup 1) (match_dup 2)))
6398               (set (match_dup 0)
6399                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6400    (parallel [(set (match_dup 3)
6401                    (minus:DWIH
6402                      (match_dup 4)
6403                      (plus:DWIH
6404                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6405                        (match_dup 5))))
6406               (clobber (reg:CC FLAGS_REG))])]
6407   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6408
6409 (define_insn "*sub<mode>_1"
6410   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6411         (minus:SWI
6412           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6413           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6414    (clobber (reg:CC FLAGS_REG))]
6415   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6416   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6417   [(set_attr "type" "alu")
6418    (set_attr "mode" "<MODE>")])
6419
6420 (define_insn "*subsi_1_zext"
6421   [(set (match_operand:DI 0 "register_operand" "=r")
6422         (zero_extend:DI
6423           (minus:SI (match_operand:SI 1 "register_operand" "0")
6424                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6425    (clobber (reg:CC FLAGS_REG))]
6426   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6427   "sub{l}\t{%2, %k0|%k0, %2}"
6428   [(set_attr "type" "alu")
6429    (set_attr "mode" "SI")])
6430
6431 (define_insn "*subqi_1_slp"
6432   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6433         (minus:QI (match_dup 0)
6434                   (match_operand:QI 1 "general_operand" "qn,qm")))
6435    (clobber (reg:CC FLAGS_REG))]
6436   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6437    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6438   "sub{b}\t{%1, %0|%0, %1}"
6439   [(set_attr "type" "alu1")
6440    (set_attr "mode" "QI")])
6441
6442 (define_insn "*sub<mode>_2"
6443   [(set (reg FLAGS_REG)
6444         (compare
6445           (minus:SWI
6446             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6447             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6448           (const_int 0)))
6449    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6450         (minus:SWI (match_dup 1) (match_dup 2)))]
6451   "ix86_match_ccmode (insn, CCGOCmode)
6452    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6453   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6454   [(set_attr "type" "alu")
6455    (set_attr "mode" "<MODE>")])
6456
6457 (define_insn "*subsi_2_zext"
6458   [(set (reg FLAGS_REG)
6459         (compare
6460           (minus:SI (match_operand:SI 1 "register_operand" "0")
6461                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6462           (const_int 0)))
6463    (set (match_operand:DI 0 "register_operand" "=r")
6464         (zero_extend:DI
6465           (minus:SI (match_dup 1)
6466                     (match_dup 2))))]
6467   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6468    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6469   "sub{l}\t{%2, %k0|%k0, %2}"
6470   [(set_attr "type" "alu")
6471    (set_attr "mode" "SI")])
6472
6473 (define_insn "*sub<mode>_3"
6474   [(set (reg FLAGS_REG)
6475         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6476                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6477    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6478         (minus:SWI (match_dup 1) (match_dup 2)))]
6479   "ix86_match_ccmode (insn, CCmode)
6480    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6481   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6482   [(set_attr "type" "alu")
6483    (set_attr "mode" "<MODE>")])
6484
6485 (define_insn "*subsi_3_zext"
6486   [(set (reg FLAGS_REG)
6487         (compare (match_operand:SI 1 "register_operand" "0")
6488                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6489    (set (match_operand:DI 0 "register_operand" "=r")
6490         (zero_extend:DI
6491           (minus:SI (match_dup 1)
6492                     (match_dup 2))))]
6493   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6494    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6495   "sub{l}\t{%2, %1|%1, %2}"
6496   [(set_attr "type" "alu")
6497    (set_attr "mode" "SI")])
6498 \f
6499 ;; Add with carry and subtract with borrow
6500
6501 (define_expand "<plusminus_insn><mode>3_carry"
6502   [(parallel
6503     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6504           (plusminus:SWI
6505             (match_operand:SWI 1 "nonimmediate_operand" "")
6506             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6507                        [(match_operand 3 "flags_reg_operand" "")
6508                         (const_int 0)])
6509                       (match_operand:SWI 2 "<general_operand>" ""))))
6510      (clobber (reg:CC FLAGS_REG))])]
6511   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6512
6513 (define_insn "*<plusminus_insn><mode>3_carry"
6514   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6515         (plusminus:SWI
6516           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6517           (plus:SWI
6518             (match_operator 3 "ix86_carry_flag_operator"
6519              [(reg FLAGS_REG) (const_int 0)])
6520             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6521    (clobber (reg:CC FLAGS_REG))]
6522   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6523   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6524   [(set_attr "type" "alu")
6525    (set_attr "use_carry" "1")
6526    (set_attr "pent_pair" "pu")
6527    (set_attr "mode" "<MODE>")])
6528
6529 (define_insn "*addsi3_carry_zext"
6530   [(set (match_operand:DI 0 "register_operand" "=r")
6531         (zero_extend:DI
6532           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6533                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6534                              [(reg FLAGS_REG) (const_int 0)])
6535                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6536    (clobber (reg:CC FLAGS_REG))]
6537   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6538   "adc{l}\t{%2, %k0|%k0, %2}"
6539   [(set_attr "type" "alu")
6540    (set_attr "use_carry" "1")
6541    (set_attr "pent_pair" "pu")
6542    (set_attr "mode" "SI")])
6543
6544 (define_insn "*subsi3_carry_zext"
6545   [(set (match_operand:DI 0 "register_operand" "=r")
6546         (zero_extend:DI
6547           (minus:SI (match_operand:SI 1 "register_operand" "0")
6548                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6549                               [(reg FLAGS_REG) (const_int 0)])
6550                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6551    (clobber (reg:CC FLAGS_REG))]
6552   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6553   "sbb{l}\t{%2, %k0|%k0, %2}"
6554   [(set_attr "type" "alu")
6555    (set_attr "pent_pair" "pu")
6556    (set_attr "mode" "SI")])
6557 \f
6558 ;; Overflow setting add instructions
6559
6560 (define_insn "*add<mode>3_cconly_overflow"
6561   [(set (reg:CCC FLAGS_REG)
6562         (compare:CCC
6563           (plus:SWI
6564             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6565             (match_operand:SWI 2 "<general_operand>" "<g>"))
6566           (match_dup 1)))
6567    (clobber (match_scratch:SWI 0 "=<r>"))]
6568   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6569   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6570   [(set_attr "type" "alu")
6571    (set_attr "mode" "<MODE>")])
6572
6573 (define_insn "*add<mode>3_cc_overflow"
6574   [(set (reg:CCC FLAGS_REG)
6575         (compare:CCC
6576             (plus:SWI
6577                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6578                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6579             (match_dup 1)))
6580    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6581         (plus:SWI (match_dup 1) (match_dup 2)))]
6582   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6583   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6584   [(set_attr "type" "alu")
6585    (set_attr "mode" "<MODE>")])
6586
6587 (define_insn "*addsi3_zext_cc_overflow"
6588   [(set (reg:CCC FLAGS_REG)
6589         (compare:CCC
6590           (plus:SI
6591             (match_operand:SI 1 "nonimmediate_operand" "%0")
6592             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6593           (match_dup 1)))
6594    (set (match_operand:DI 0 "register_operand" "=r")
6595         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6596   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6597   "add{l}\t{%2, %k0|%k0, %2}"
6598   [(set_attr "type" "alu")
6599    (set_attr "mode" "SI")])
6600
6601 ;; The patterns that match these are at the end of this file.
6602
6603 (define_expand "<plusminus_insn>xf3"
6604   [(set (match_operand:XF 0 "register_operand" "")
6605         (plusminus:XF
6606           (match_operand:XF 1 "register_operand" "")
6607           (match_operand:XF 2 "register_operand" "")))]
6608   "TARGET_80387")
6609
6610 (define_expand "<plusminus_insn><mode>3"
6611   [(set (match_operand:MODEF 0 "register_operand" "")
6612         (plusminus:MODEF
6613           (match_operand:MODEF 1 "register_operand" "")
6614           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6615   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6616     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6617 \f
6618 ;; Multiply instructions
6619
6620 (define_expand "mul<mode>3"
6621   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6622                    (mult:SWIM248
6623                      (match_operand:SWIM248 1 "register_operand" "")
6624                      (match_operand:SWIM248 2 "<general_operand>" "")))
6625               (clobber (reg:CC FLAGS_REG))])])
6626
6627 (define_expand "mulqi3"
6628   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6629                    (mult:QI
6630                      (match_operand:QI 1 "register_operand" "")
6631                      (match_operand:QI 2 "nonimmediate_operand" "")))
6632               (clobber (reg:CC FLAGS_REG))])]
6633   "TARGET_QIMODE_MATH")
6634
6635 ;; On AMDFAM10
6636 ;; IMUL reg32/64, reg32/64, imm8        Direct
6637 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6638 ;; IMUL reg32/64, reg32/64, imm32       Direct
6639 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6640 ;; IMUL reg32/64, reg32/64              Direct
6641 ;; IMUL reg32/64, mem32/64              Direct
6642 ;;
6643 ;; On BDVER1, all above IMULs use DirectPath
6644
6645 (define_insn "*mul<mode>3_1"
6646   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6647         (mult:SWI48
6648           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6649           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6650    (clobber (reg:CC FLAGS_REG))]
6651   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6652   "@
6653    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6654    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6655    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6656   [(set_attr "type" "imul")
6657    (set_attr "prefix_0f" "0,0,1")
6658    (set (attr "athlon_decode")
6659         (cond [(eq_attr "cpu" "athlon")
6660                   (const_string "vector")
6661                (eq_attr "alternative" "1")
6662                   (const_string "vector")
6663                (and (eq_attr "alternative" "2")
6664                     (match_operand 1 "memory_operand" ""))
6665                   (const_string "vector")]
6666               (const_string "direct")))
6667    (set (attr "amdfam10_decode")
6668         (cond [(and (eq_attr "alternative" "0,1")
6669                     (match_operand 1 "memory_operand" ""))
6670                   (const_string "vector")]
6671               (const_string "direct")))
6672    (set_attr "bdver1_decode" "direct")
6673    (set_attr "mode" "<MODE>")])
6674
6675 (define_insn "*mulsi3_1_zext"
6676   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6677         (zero_extend:DI
6678           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6679                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6680    (clobber (reg:CC FLAGS_REG))]
6681   "TARGET_64BIT
6682    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6683   "@
6684    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6685    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6686    imul{l}\t{%2, %k0|%k0, %2}"
6687   [(set_attr "type" "imul")
6688    (set_attr "prefix_0f" "0,0,1")
6689    (set (attr "athlon_decode")
6690         (cond [(eq_attr "cpu" "athlon")
6691                   (const_string "vector")
6692                (eq_attr "alternative" "1")
6693                   (const_string "vector")
6694                (and (eq_attr "alternative" "2")
6695                     (match_operand 1 "memory_operand" ""))
6696                   (const_string "vector")]
6697               (const_string "direct")))
6698    (set (attr "amdfam10_decode")
6699         (cond [(and (eq_attr "alternative" "0,1")
6700                     (match_operand 1 "memory_operand" ""))
6701                   (const_string "vector")]
6702               (const_string "direct")))
6703    (set_attr "bdver1_decode" "direct")
6704    (set_attr "mode" "SI")])
6705
6706 ;; On AMDFAM10
6707 ;; IMUL reg16, reg16, imm8      VectorPath
6708 ;; IMUL reg16, mem16, imm8      VectorPath
6709 ;; IMUL reg16, reg16, imm16     VectorPath
6710 ;; IMUL reg16, mem16, imm16     VectorPath
6711 ;; IMUL reg16, reg16            Direct
6712 ;; IMUL reg16, mem16            Direct
6713 ;;
6714 ;; On BDVER1, all HI MULs use DoublePath
6715
6716 (define_insn "*mulhi3_1"
6717   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6718         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6719                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6720    (clobber (reg:CC FLAGS_REG))]
6721   "TARGET_HIMODE_MATH
6722    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6723   "@
6724    imul{w}\t{%2, %1, %0|%0, %1, %2}
6725    imul{w}\t{%2, %1, %0|%0, %1, %2}
6726    imul{w}\t{%2, %0|%0, %2}"
6727   [(set_attr "type" "imul")
6728    (set_attr "prefix_0f" "0,0,1")
6729    (set (attr "athlon_decode")
6730         (cond [(eq_attr "cpu" "athlon")
6731                   (const_string "vector")
6732                (eq_attr "alternative" "1,2")
6733                   (const_string "vector")]
6734               (const_string "direct")))
6735    (set (attr "amdfam10_decode")
6736         (cond [(eq_attr "alternative" "0,1")
6737                   (const_string "vector")]
6738               (const_string "direct")))
6739    (set_attr "bdver1_decode" "double")
6740    (set_attr "mode" "HI")])
6741
6742 ;;On AMDFAM10 and BDVER1
6743 ;; MUL reg8     Direct
6744 ;; MUL mem8     Direct
6745
6746 (define_insn "*mulqi3_1"
6747   [(set (match_operand:QI 0 "register_operand" "=a")
6748         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6749                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6750    (clobber (reg:CC FLAGS_REG))]
6751   "TARGET_QIMODE_MATH
6752    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6753   "mul{b}\t%2"
6754   [(set_attr "type" "imul")
6755    (set_attr "length_immediate" "0")
6756    (set (attr "athlon_decode")
6757      (if_then_else (eq_attr "cpu" "athlon")
6758         (const_string "vector")
6759         (const_string "direct")))
6760    (set_attr "amdfam10_decode" "direct")
6761    (set_attr "bdver1_decode" "direct")
6762    (set_attr "mode" "QI")])
6763
6764 (define_expand "<u>mul<mode><dwi>3"
6765   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6766                    (mult:<DWI>
6767                      (any_extend:<DWI>
6768                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6769                      (any_extend:<DWI>
6770                        (match_operand:DWIH 2 "register_operand" ""))))
6771               (clobber (reg:CC FLAGS_REG))])])
6772
6773 (define_expand "<u>mulqihi3"
6774   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6775                    (mult:HI
6776                      (any_extend:HI
6777                        (match_operand:QI 1 "nonimmediate_operand" ""))
6778                      (any_extend:HI
6779                        (match_operand:QI 2 "register_operand" ""))))
6780               (clobber (reg:CC FLAGS_REG))])]
6781   "TARGET_QIMODE_MATH")
6782
6783 (define_insn "*bmi2_umulditi3_1"
6784   [(set (match_operand:DI 0 "register_operand" "=r")
6785         (mult:DI
6786           (match_operand:DI 2 "nonimmediate_operand" "%d")
6787           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6788    (set (match_operand:DI 1 "register_operand" "=r")
6789         (truncate:DI
6790           (lshiftrt:TI
6791             (mult:TI (zero_extend:TI (match_dup 2))
6792                      (zero_extend:TI (match_dup 3)))
6793             (const_int 64))))]
6794   "TARGET_64BIT && TARGET_BMI2
6795    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796   "mulx\t{%3, %0, %1|%1, %0, %3}"
6797   [(set_attr "type" "imulx")
6798    (set_attr "prefix" "vex")
6799    (set_attr "mode" "DI")])
6800
6801 (define_insn "*bmi2_umulsidi3_1"
6802   [(set (match_operand:SI 0 "register_operand" "=r")
6803         (mult:SI
6804           (match_operand:SI 2 "nonimmediate_operand" "%d")
6805           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6806    (set (match_operand:SI 1 "register_operand" "=r")
6807         (truncate:SI
6808           (lshiftrt:DI
6809             (mult:DI (zero_extend:DI (match_dup 2))
6810                      (zero_extend:DI (match_dup 3)))
6811             (const_int 32))))]
6812   "!TARGET_64BIT && TARGET_BMI2
6813    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6814   "mulx\t{%3, %0, %1|%1, %0, %3}"
6815   [(set_attr "type" "imulx")
6816    (set_attr "prefix" "vex")
6817    (set_attr "mode" "SI")])
6818
6819 (define_insn "*umul<mode><dwi>3_1"
6820   [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6821         (mult:<DWI>
6822           (zero_extend:<DWI>
6823             (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6824           (zero_extend:<DWI>
6825             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6826    (clobber (reg:CC FLAGS_REG))]
6827   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6828   "@
6829    mul{<imodesuffix>}\t%2
6830    #"
6831   [(set_attr "isa" "*,bmi2")
6832    (set_attr "type" "imul,imulx")
6833    (set_attr "length_immediate" "0,*")
6834    (set (attr "athlon_decode")
6835         (cond [(eq_attr "alternative" "0")
6836                  (if_then_else (eq_attr "cpu" "athlon")
6837                    (const_string "vector")
6838                    (const_string "double"))]
6839               (const_string "*")))
6840    (set_attr "amdfam10_decode" "double,*")
6841    (set_attr "bdver1_decode" "direct,*")
6842    (set_attr "prefix" "orig,vex")
6843    (set_attr "mode" "<MODE>")])
6844
6845 ;; Convert mul to the mulx pattern to avoid flags dependency.
6846 (define_split
6847  [(set (match_operand:<DWI> 0 "register_operand" "")
6848        (mult:<DWI>
6849          (zero_extend:<DWI>
6850            (match_operand:DWIH 1 "register_operand" ""))
6851          (zero_extend:<DWI>
6852            (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6853   (clobber (reg:CC FLAGS_REG))]
6854  "TARGET_BMI2 && reload_completed
6855   && true_regnum (operands[1]) == DX_REG"
6856   [(parallel [(set (match_dup 3)
6857                    (mult:DWIH (match_dup 1) (match_dup 2)))
6858               (set (match_dup 4)
6859                    (truncate:DWIH
6860                      (lshiftrt:<DWI>
6861                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6862                                    (zero_extend:<DWI> (match_dup 2)))
6863                        (match_dup 5))))])]
6864 {
6865   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6866
6867   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6868 })
6869
6870 (define_insn "*mul<mode><dwi>3_1"
6871   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6872         (mult:<DWI>
6873           (sign_extend:<DWI>
6874             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6875           (sign_extend:<DWI>
6876             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6877    (clobber (reg:CC FLAGS_REG))]
6878   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6879   "imul{<imodesuffix>}\t%2"
6880   [(set_attr "type" "imul")
6881    (set_attr "length_immediate" "0")
6882    (set (attr "athlon_decode")
6883      (if_then_else (eq_attr "cpu" "athlon")
6884         (const_string "vector")
6885         (const_string "double")))
6886    (set_attr "amdfam10_decode" "double")
6887    (set_attr "bdver1_decode" "direct")
6888    (set_attr "mode" "<MODE>")])
6889
6890 (define_insn "*<u>mulqihi3_1"
6891   [(set (match_operand:HI 0 "register_operand" "=a")
6892         (mult:HI
6893           (any_extend:HI
6894             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6895           (any_extend:HI
6896             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6897    (clobber (reg:CC FLAGS_REG))]
6898   "TARGET_QIMODE_MATH
6899    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6900   "<sgnprefix>mul{b}\t%2"
6901   [(set_attr "type" "imul")
6902    (set_attr "length_immediate" "0")
6903    (set (attr "athlon_decode")
6904      (if_then_else (eq_attr "cpu" "athlon")
6905         (const_string "vector")
6906         (const_string "direct")))
6907    (set_attr "amdfam10_decode" "direct")
6908    (set_attr "bdver1_decode" "direct")
6909    (set_attr "mode" "QI")])
6910
6911 (define_expand "<s>mul<mode>3_highpart"
6912   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6913                    (truncate:SWI48
6914                      (lshiftrt:<DWI>
6915                        (mult:<DWI>
6916                          (any_extend:<DWI>
6917                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6918                          (any_extend:<DWI>
6919                            (match_operand:SWI48 2 "register_operand" "")))
6920                        (match_dup 4))))
6921               (clobber (match_scratch:SWI48 3 ""))
6922               (clobber (reg:CC FLAGS_REG))])]
6923   ""
6924   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6925
6926 (define_insn "*<s>muldi3_highpart_1"
6927   [(set (match_operand:DI 0 "register_operand" "=d")
6928         (truncate:DI
6929           (lshiftrt:TI
6930             (mult:TI
6931               (any_extend:TI
6932                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6933               (any_extend:TI
6934                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6935             (const_int 64))))
6936    (clobber (match_scratch:DI 3 "=1"))
6937    (clobber (reg:CC FLAGS_REG))]
6938   "TARGET_64BIT
6939    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6940   "<sgnprefix>mul{q}\t%2"
6941   [(set_attr "type" "imul")
6942    (set_attr "length_immediate" "0")
6943    (set (attr "athlon_decode")
6944      (if_then_else (eq_attr "cpu" "athlon")
6945         (const_string "vector")
6946         (const_string "double")))
6947    (set_attr "amdfam10_decode" "double")
6948    (set_attr "bdver1_decode" "direct")
6949    (set_attr "mode" "DI")])
6950
6951 (define_insn "*<s>mulsi3_highpart_1"
6952   [(set (match_operand:SI 0 "register_operand" "=d")
6953         (truncate:SI
6954           (lshiftrt:DI
6955             (mult:DI
6956               (any_extend:DI
6957                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6958               (any_extend:DI
6959                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6960             (const_int 32))))
6961    (clobber (match_scratch:SI 3 "=1"))
6962    (clobber (reg:CC FLAGS_REG))]
6963   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6964   "<sgnprefix>mul{l}\t%2"
6965   [(set_attr "type" "imul")
6966    (set_attr "length_immediate" "0")
6967    (set (attr "athlon_decode")
6968      (if_then_else (eq_attr "cpu" "athlon")
6969         (const_string "vector")
6970         (const_string "double")))
6971    (set_attr "amdfam10_decode" "double")
6972    (set_attr "bdver1_decode" "direct")
6973    (set_attr "mode" "SI")])
6974
6975 (define_insn "*<s>mulsi3_highpart_zext"
6976   [(set (match_operand:DI 0 "register_operand" "=d")
6977         (zero_extend:DI (truncate:SI
6978           (lshiftrt:DI
6979             (mult:DI (any_extend:DI
6980                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6981                      (any_extend:DI
6982                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6983             (const_int 32)))))
6984    (clobber (match_scratch:SI 3 "=1"))
6985    (clobber (reg:CC FLAGS_REG))]
6986   "TARGET_64BIT
6987    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6988   "<sgnprefix>mul{l}\t%2"
6989   [(set_attr "type" "imul")
6990    (set_attr "length_immediate" "0")
6991    (set (attr "athlon_decode")
6992      (if_then_else (eq_attr "cpu" "athlon")
6993         (const_string "vector")
6994         (const_string "double")))
6995    (set_attr "amdfam10_decode" "double")
6996    (set_attr "bdver1_decode" "direct")
6997    (set_attr "mode" "SI")])
6998
6999 ;; The patterns that match these are at the end of this file.
7000
7001 (define_expand "mulxf3"
7002   [(set (match_operand:XF 0 "register_operand" "")
7003         (mult:XF (match_operand:XF 1 "register_operand" "")
7004                  (match_operand:XF 2 "register_operand" "")))]
7005   "TARGET_80387")
7006
7007 (define_expand "mul<mode>3"
7008   [(set (match_operand:MODEF 0 "register_operand" "")
7009         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7010                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7011   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7012     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7013 \f
7014 ;; Divide instructions
7015
7016 ;; The patterns that match these are at the end of this file.
7017
7018 (define_expand "divxf3"
7019   [(set (match_operand:XF 0 "register_operand" "")
7020         (div:XF (match_operand:XF 1 "register_operand" "")
7021                 (match_operand:XF 2 "register_operand" "")))]
7022   "TARGET_80387")
7023
7024 (define_expand "divdf3"
7025   [(set (match_operand:DF 0 "register_operand" "")
7026         (div:DF (match_operand:DF 1 "register_operand" "")
7027                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7028    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7029     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7030
7031 (define_expand "divsf3"
7032   [(set (match_operand:SF 0 "register_operand" "")
7033         (div:SF (match_operand:SF 1 "register_operand" "")
7034                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7035   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7036     || TARGET_SSE_MATH"
7037 {
7038   if (TARGET_SSE_MATH
7039       && TARGET_RECIP_DIV
7040       && optimize_insn_for_speed_p ()
7041       && flag_finite_math_only && !flag_trapping_math
7042       && flag_unsafe_math_optimizations)
7043     {
7044       ix86_emit_swdivsf (operands[0], operands[1],
7045                          operands[2], SFmode);
7046       DONE;
7047     }
7048 })
7049 \f
7050 ;; Divmod instructions.
7051
7052 (define_expand "divmod<mode>4"
7053   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7054                    (div:SWIM248
7055                      (match_operand:SWIM248 1 "register_operand" "")
7056                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7057               (set (match_operand:SWIM248 3 "register_operand" "")
7058                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7059               (clobber (reg:CC FLAGS_REG))])])
7060
7061 ;; Split with 8bit unsigned divide:
7062 ;;      if (dividend an divisor are in [0-255])
7063 ;;         use 8bit unsigned integer divide
7064 ;;       else
7065 ;;         use original integer divide
7066 (define_split
7067   [(set (match_operand:SWI48 0 "register_operand" "")
7068         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7069                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7070    (set (match_operand:SWI48 1 "register_operand" "")
7071         (mod:SWI48 (match_dup 2) (match_dup 3)))
7072    (clobber (reg:CC FLAGS_REG))]
7073   "TARGET_USE_8BIT_IDIV
7074    && TARGET_QIMODE_MATH
7075    && can_create_pseudo_p ()
7076    && !optimize_insn_for_size_p ()"
7077   [(const_int 0)]
7078   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7079
7080 (define_insn_and_split "divmod<mode>4_1"
7081   [(set (match_operand:SWI48 0 "register_operand" "=a")
7082         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7083                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7084    (set (match_operand:SWI48 1 "register_operand" "=&d")
7085         (mod:SWI48 (match_dup 2) (match_dup 3)))
7086    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7087    (clobber (reg:CC FLAGS_REG))]
7088   ""
7089   "#"
7090   "reload_completed"
7091   [(parallel [(set (match_dup 1)
7092                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7093               (clobber (reg:CC FLAGS_REG))])
7094    (parallel [(set (match_dup 0)
7095                    (div:SWI48 (match_dup 2) (match_dup 3)))
7096               (set (match_dup 1)
7097                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7098               (use (match_dup 1))
7099               (clobber (reg:CC FLAGS_REG))])]
7100 {
7101   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7102
7103   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7104     operands[4] = operands[2];
7105   else
7106     {
7107       /* Avoid use of cltd in favor of a mov+shift.  */
7108       emit_move_insn (operands[1], operands[2]);
7109       operands[4] = operands[1];
7110     }
7111 }
7112   [(set_attr "type" "multi")
7113    (set_attr "mode" "<MODE>")])
7114
7115 (define_insn_and_split "*divmod<mode>4"
7116   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7117         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7118                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7119    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7120         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7121    (clobber (reg:CC FLAGS_REG))]
7122   ""
7123   "#"
7124   "reload_completed"
7125   [(parallel [(set (match_dup 1)
7126                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7127               (clobber (reg:CC FLAGS_REG))])
7128    (parallel [(set (match_dup 0)
7129                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7130               (set (match_dup 1)
7131                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7132               (use (match_dup 1))
7133               (clobber (reg:CC FLAGS_REG))])]
7134 {
7135   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7136
7137   if (<MODE>mode != HImode
7138       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7139     operands[4] = operands[2];
7140   else
7141     {
7142       /* Avoid use of cltd in favor of a mov+shift.  */
7143       emit_move_insn (operands[1], operands[2]);
7144       operands[4] = operands[1];
7145     }
7146 }
7147   [(set_attr "type" "multi")
7148    (set_attr "mode" "<MODE>")])
7149
7150 (define_insn "*divmod<mode>4_noext"
7151   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7152         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7153                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7154    (set (match_operand:SWIM248 1 "register_operand" "=d")
7155         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7156    (use (match_operand:SWIM248 4 "register_operand" "1"))
7157    (clobber (reg:CC FLAGS_REG))]
7158   ""
7159   "idiv{<imodesuffix>}\t%3"
7160   [(set_attr "type" "idiv")
7161    (set_attr "mode" "<MODE>")])
7162
7163 (define_expand "divmodqi4"
7164   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7165                    (div:QI
7166                      (match_operand:QI 1 "register_operand" "")
7167                      (match_operand:QI 2 "nonimmediate_operand" "")))
7168               (set (match_operand:QI 3 "register_operand" "")
7169                    (mod:QI (match_dup 1) (match_dup 2)))
7170               (clobber (reg:CC FLAGS_REG))])]
7171   "TARGET_QIMODE_MATH"
7172 {
7173   rtx div, mod, insn;
7174   rtx tmp0, tmp1;
7175   
7176   tmp0 = gen_reg_rtx (HImode);
7177   tmp1 = gen_reg_rtx (HImode);
7178
7179   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7180      in AX.  */
7181   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7182   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7183
7184   /* Extract remainder from AH.  */
7185   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7186   insn = emit_move_insn (operands[3], tmp1);
7187
7188   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7189   set_unique_reg_note (insn, REG_EQUAL, mod);
7190
7191   /* Extract quotient from AL.  */
7192   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7193
7194   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7195   set_unique_reg_note (insn, REG_EQUAL, div);
7196
7197   DONE;
7198 })
7199
7200 ;; Divide AX by r/m8, with result stored in
7201 ;; AL <- Quotient
7202 ;; AH <- Remainder
7203 ;; Change div/mod to HImode and extend the second argument to HImode
7204 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7205 ;; combine may fail.
7206 (define_insn "divmodhiqi3"
7207   [(set (match_operand:HI 0 "register_operand" "=a")
7208         (ior:HI
7209           (ashift:HI
7210             (zero_extend:HI
7211               (truncate:QI
7212                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7213                         (sign_extend:HI
7214                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7215             (const_int 8))
7216           (zero_extend:HI
7217             (truncate:QI
7218               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7219    (clobber (reg:CC FLAGS_REG))]
7220   "TARGET_QIMODE_MATH"
7221   "idiv{b}\t%2"
7222   [(set_attr "type" "idiv")
7223    (set_attr "mode" "QI")])
7224
7225 (define_expand "udivmod<mode>4"
7226   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7227                    (udiv:SWIM248
7228                      (match_operand:SWIM248 1 "register_operand" "")
7229                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7230               (set (match_operand:SWIM248 3 "register_operand" "")
7231                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7232               (clobber (reg:CC FLAGS_REG))])])
7233
7234 ;; Split with 8bit unsigned divide:
7235 ;;      if (dividend an divisor are in [0-255])
7236 ;;         use 8bit unsigned integer divide
7237 ;;       else
7238 ;;         use original integer divide
7239 (define_split
7240   [(set (match_operand:SWI48 0 "register_operand" "")
7241         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7242                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7243    (set (match_operand:SWI48 1 "register_operand" "")
7244         (umod:SWI48 (match_dup 2) (match_dup 3)))
7245    (clobber (reg:CC FLAGS_REG))]
7246   "TARGET_USE_8BIT_IDIV
7247    && TARGET_QIMODE_MATH
7248    && can_create_pseudo_p ()
7249    && !optimize_insn_for_size_p ()"
7250   [(const_int 0)]
7251   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7252
7253 (define_insn_and_split "udivmod<mode>4_1"
7254   [(set (match_operand:SWI48 0 "register_operand" "=a")
7255         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7256                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7257    (set (match_operand:SWI48 1 "register_operand" "=&d")
7258         (umod:SWI48 (match_dup 2) (match_dup 3)))
7259    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7260    (clobber (reg:CC FLAGS_REG))]
7261   ""
7262   "#"
7263   "reload_completed"
7264   [(set (match_dup 1) (const_int 0))
7265    (parallel [(set (match_dup 0)
7266                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7267               (set (match_dup 1)
7268                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7269               (use (match_dup 1))
7270               (clobber (reg:CC FLAGS_REG))])]
7271   ""
7272   [(set_attr "type" "multi")
7273    (set_attr "mode" "<MODE>")])
7274
7275 (define_insn_and_split "*udivmod<mode>4"
7276   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7277         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7278                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7279    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7280         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7281    (clobber (reg:CC FLAGS_REG))]
7282   ""
7283   "#"
7284   "reload_completed"
7285   [(set (match_dup 1) (const_int 0))
7286    (parallel [(set (match_dup 0)
7287                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7288               (set (match_dup 1)
7289                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7290               (use (match_dup 1))
7291               (clobber (reg:CC FLAGS_REG))])]
7292   ""
7293   [(set_attr "type" "multi")
7294    (set_attr "mode" "<MODE>")])
7295
7296 (define_insn "*udivmod<mode>4_noext"
7297   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7298         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7299                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7300    (set (match_operand:SWIM248 1 "register_operand" "=d")
7301         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7302    (use (match_operand:SWIM248 4 "register_operand" "1"))
7303    (clobber (reg:CC FLAGS_REG))]
7304   ""
7305   "div{<imodesuffix>}\t%3"
7306   [(set_attr "type" "idiv")
7307    (set_attr "mode" "<MODE>")])
7308
7309 (define_expand "udivmodqi4"
7310   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7311                    (udiv:QI
7312                      (match_operand:QI 1 "register_operand" "")
7313                      (match_operand:QI 2 "nonimmediate_operand" "")))
7314               (set (match_operand:QI 3 "register_operand" "")
7315                    (umod:QI (match_dup 1) (match_dup 2)))
7316               (clobber (reg:CC FLAGS_REG))])]
7317   "TARGET_QIMODE_MATH"
7318 {
7319   rtx div, mod, insn;
7320   rtx tmp0, tmp1;
7321   
7322   tmp0 = gen_reg_rtx (HImode);
7323   tmp1 = gen_reg_rtx (HImode);
7324
7325   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7326      in AX.  */
7327   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7328   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7329
7330   /* Extract remainder from AH.  */
7331   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7332   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7333   insn = emit_move_insn (operands[3], tmp1);
7334
7335   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7336   set_unique_reg_note (insn, REG_EQUAL, mod);
7337
7338   /* Extract quotient from AL.  */
7339   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7340
7341   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7342   set_unique_reg_note (insn, REG_EQUAL, div);
7343
7344   DONE;
7345 })
7346
7347 (define_insn "udivmodhiqi3"
7348   [(set (match_operand:HI 0 "register_operand" "=a")
7349         (ior:HI
7350           (ashift:HI
7351             (zero_extend:HI
7352               (truncate:QI
7353                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7354                         (zero_extend:HI
7355                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7356             (const_int 8))
7357           (zero_extend:HI
7358             (truncate:QI
7359               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7360    (clobber (reg:CC FLAGS_REG))]
7361   "TARGET_QIMODE_MATH"
7362   "div{b}\t%2"
7363   [(set_attr "type" "idiv")
7364    (set_attr "mode" "QI")])
7365
7366 ;; We cannot use div/idiv for double division, because it causes
7367 ;; "division by zero" on the overflow and that's not what we expect
7368 ;; from truncate.  Because true (non truncating) double division is
7369 ;; never generated, we can't create this insn anyway.
7370 ;
7371 ;(define_insn ""
7372 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7373 ;       (truncate:SI
7374 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7375 ;                  (zero_extend:DI
7376 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7377 ;   (set (match_operand:SI 3 "register_operand" "=d")
7378 ;       (truncate:SI
7379 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7380 ;   (clobber (reg:CC FLAGS_REG))]
7381 ;  ""
7382 ;  "div{l}\t{%2, %0|%0, %2}"
7383 ;  [(set_attr "type" "idiv")])
7384 \f
7385 ;;- Logical AND instructions
7386
7387 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7388 ;; Note that this excludes ah.
7389
7390 (define_expand "testsi_ccno_1"
7391   [(set (reg:CCNO FLAGS_REG)
7392         (compare:CCNO
7393           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7394                   (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7395           (const_int 0)))])
7396
7397 (define_expand "testqi_ccz_1"
7398   [(set (reg:CCZ FLAGS_REG)
7399         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7400                              (match_operand:QI 1 "nonmemory_operand" ""))
7401                  (const_int 0)))])
7402
7403 (define_expand "testdi_ccno_1"
7404   [(set (reg:CCNO FLAGS_REG)
7405         (compare:CCNO
7406           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7407                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7408           (const_int 0)))]
7409   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7410
7411 (define_insn "*testdi_1"
7412   [(set (reg FLAGS_REG)
7413         (compare
7414          (and:DI
7415           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7416           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7417          (const_int 0)))]
7418   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7419    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7420   "@
7421    test{l}\t{%k1, %k0|%k0, %k1}
7422    test{l}\t{%k1, %k0|%k0, %k1}
7423    test{q}\t{%1, %0|%0, %1}
7424    test{q}\t{%1, %0|%0, %1}
7425    test{q}\t{%1, %0|%0, %1}"
7426   [(set_attr "type" "test")
7427    (set_attr "modrm" "0,1,0,1,1")
7428    (set_attr "mode" "SI,SI,DI,DI,DI")])
7429
7430 (define_insn "*testqi_1_maybe_si"
7431   [(set (reg FLAGS_REG)
7432         (compare
7433           (and:QI
7434             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7435             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7436           (const_int 0)))]
7437    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7438     && ix86_match_ccmode (insn,
7439                          CONST_INT_P (operands[1])
7440                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7441 {
7442   if (which_alternative == 3)
7443     {
7444       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7445         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7446       return "test{l}\t{%1, %k0|%k0, %1}";
7447     }
7448   return "test{b}\t{%1, %0|%0, %1}";
7449 }
7450   [(set_attr "type" "test")
7451    (set_attr "modrm" "0,1,1,1")
7452    (set_attr "mode" "QI,QI,QI,SI")
7453    (set_attr "pent_pair" "uv,np,uv,np")])
7454
7455 (define_insn "*test<mode>_1"
7456   [(set (reg FLAGS_REG)
7457         (compare
7458          (and:SWI124
7459           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7460           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7461          (const_int 0)))]
7462   "ix86_match_ccmode (insn, CCNOmode)
7463    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7464   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7465   [(set_attr "type" "test")
7466    (set_attr "modrm" "0,1,1")
7467    (set_attr "mode" "<MODE>")
7468    (set_attr "pent_pair" "uv,np,uv")])
7469
7470 (define_expand "testqi_ext_ccno_0"
7471   [(set (reg:CCNO FLAGS_REG)
7472         (compare:CCNO
7473           (and:SI
7474             (zero_extract:SI
7475               (match_operand 0 "ext_register_operand" "")
7476               (const_int 8)
7477               (const_int 8))
7478             (match_operand 1 "const_int_operand" ""))
7479           (const_int 0)))])
7480
7481 (define_insn "*testqi_ext_0"
7482   [(set (reg FLAGS_REG)
7483         (compare
7484           (and:SI
7485             (zero_extract:SI
7486               (match_operand 0 "ext_register_operand" "Q")
7487               (const_int 8)
7488               (const_int 8))
7489             (match_operand 1 "const_int_operand" "n"))
7490           (const_int 0)))]
7491   "ix86_match_ccmode (insn, CCNOmode)"
7492   "test{b}\t{%1, %h0|%h0, %1}"
7493   [(set_attr "type" "test")
7494    (set_attr "mode" "QI")
7495    (set_attr "length_immediate" "1")
7496    (set_attr "modrm" "1")
7497    (set_attr "pent_pair" "np")])
7498
7499 (define_insn "*testqi_ext_1_rex64"
7500   [(set (reg FLAGS_REG)
7501         (compare
7502           (and:SI
7503             (zero_extract:SI
7504               (match_operand 0 "ext_register_operand" "Q")
7505               (const_int 8)
7506               (const_int 8))
7507             (zero_extend:SI
7508               (match_operand:QI 1 "register_operand" "Q")))
7509           (const_int 0)))]
7510   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7511   "test{b}\t{%1, %h0|%h0, %1}"
7512   [(set_attr "type" "test")
7513    (set_attr "mode" "QI")])
7514
7515 (define_insn "*testqi_ext_1"
7516   [(set (reg FLAGS_REG)
7517         (compare
7518           (and:SI
7519             (zero_extract:SI
7520               (match_operand 0 "ext_register_operand" "Q")
7521               (const_int 8)
7522               (const_int 8))
7523             (zero_extend:SI
7524               (match_operand:QI 1 "general_operand" "Qm")))
7525           (const_int 0)))]
7526   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7527   "test{b}\t{%1, %h0|%h0, %1}"
7528   [(set_attr "type" "test")
7529    (set_attr "mode" "QI")])
7530
7531 (define_insn "*testqi_ext_2"
7532   [(set (reg FLAGS_REG)
7533         (compare
7534           (and:SI
7535             (zero_extract:SI
7536               (match_operand 0 "ext_register_operand" "Q")
7537               (const_int 8)
7538               (const_int 8))
7539             (zero_extract:SI
7540               (match_operand 1 "ext_register_operand" "Q")
7541               (const_int 8)
7542               (const_int 8)))
7543           (const_int 0)))]
7544   "ix86_match_ccmode (insn, CCNOmode)"
7545   "test{b}\t{%h1, %h0|%h0, %h1}"
7546   [(set_attr "type" "test")
7547    (set_attr "mode" "QI")])
7548
7549 (define_insn "*testqi_ext_3_rex64"
7550   [(set (reg FLAGS_REG)
7551         (compare (zero_extract:DI
7552                    (match_operand 0 "nonimmediate_operand" "rm")
7553                    (match_operand:DI 1 "const_int_operand" "")
7554                    (match_operand:DI 2 "const_int_operand" ""))
7555                  (const_int 0)))]
7556   "TARGET_64BIT
7557    && ix86_match_ccmode (insn, CCNOmode)
7558    && INTVAL (operands[1]) > 0
7559    && INTVAL (operands[2]) >= 0
7560    /* Ensure that resulting mask is zero or sign extended operand.  */
7561    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7562        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7563            && INTVAL (operands[1]) > 32))
7564    && (GET_MODE (operands[0]) == SImode
7565        || GET_MODE (operands[0]) == DImode
7566        || GET_MODE (operands[0]) == HImode
7567        || GET_MODE (operands[0]) == QImode)"
7568   "#")
7569
7570 ;; Combine likes to form bit extractions for some tests.  Humor it.
7571 (define_insn "*testqi_ext_3"
7572   [(set (reg FLAGS_REG)
7573         (compare (zero_extract:SI
7574                    (match_operand 0 "nonimmediate_operand" "rm")
7575                    (match_operand:SI 1 "const_int_operand" "")
7576                    (match_operand:SI 2 "const_int_operand" ""))
7577                  (const_int 0)))]
7578   "ix86_match_ccmode (insn, CCNOmode)
7579    && INTVAL (operands[1]) > 0
7580    && INTVAL (operands[2]) >= 0
7581    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7582    && (GET_MODE (operands[0]) == SImode
7583        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7584        || GET_MODE (operands[0]) == HImode
7585        || GET_MODE (operands[0]) == QImode)"
7586   "#")
7587
7588 (define_split
7589   [(set (match_operand 0 "flags_reg_operand" "")
7590         (match_operator 1 "compare_operator"
7591           [(zero_extract
7592              (match_operand 2 "nonimmediate_operand" "")
7593              (match_operand 3 "const_int_operand" "")
7594              (match_operand 4 "const_int_operand" ""))
7595            (const_int 0)]))]
7596   "ix86_match_ccmode (insn, CCNOmode)"
7597   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7598 {
7599   rtx val = operands[2];
7600   HOST_WIDE_INT len = INTVAL (operands[3]);
7601   HOST_WIDE_INT pos = INTVAL (operands[4]);
7602   HOST_WIDE_INT mask;
7603   enum machine_mode mode, submode;
7604
7605   mode = GET_MODE (val);
7606   if (MEM_P (val))
7607     {
7608       /* ??? Combine likes to put non-volatile mem extractions in QImode
7609          no matter the size of the test.  So find a mode that works.  */
7610       if (! MEM_VOLATILE_P (val))
7611         {
7612           mode = smallest_mode_for_size (pos + len, MODE_INT);
7613           val = adjust_address (val, mode, 0);
7614         }
7615     }
7616   else if (GET_CODE (val) == SUBREG
7617            && (submode = GET_MODE (SUBREG_REG (val)),
7618                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7619            && pos + len <= GET_MODE_BITSIZE (submode)
7620            && GET_MODE_CLASS (submode) == MODE_INT)
7621     {
7622       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7623       mode = submode;
7624       val = SUBREG_REG (val);
7625     }
7626   else if (mode == HImode && pos + len <= 8)
7627     {
7628       /* Small HImode tests can be converted to QImode.  */
7629       mode = QImode;
7630       val = gen_lowpart (QImode, val);
7631     }
7632
7633   if (len == HOST_BITS_PER_WIDE_INT)
7634     mask = -1;
7635   else
7636     mask = ((HOST_WIDE_INT)1 << len) - 1;
7637   mask <<= pos;
7638
7639   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7640 })
7641
7642 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7643 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7644 ;; this is relatively important trick.
7645 ;; Do the conversion only post-reload to avoid limiting of the register class
7646 ;; to QI regs.
7647 (define_split
7648   [(set (match_operand 0 "flags_reg_operand" "")
7649         (match_operator 1 "compare_operator"
7650           [(and (match_operand 2 "register_operand" "")
7651                 (match_operand 3 "const_int_operand" ""))
7652            (const_int 0)]))]
7653    "reload_completed
7654     && QI_REG_P (operands[2])
7655     && GET_MODE (operands[2]) != QImode
7656     && ((ix86_match_ccmode (insn, CCZmode)
7657          && !(INTVAL (operands[3]) & ~(255 << 8)))
7658         || (ix86_match_ccmode (insn, CCNOmode)
7659             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7660   [(set (match_dup 0)
7661         (match_op_dup 1
7662           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7663                    (match_dup 3))
7664            (const_int 0)]))]
7665 {
7666   operands[2] = gen_lowpart (SImode, operands[2]);
7667   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7668 })
7669
7670 (define_split
7671   [(set (match_operand 0 "flags_reg_operand" "")
7672         (match_operator 1 "compare_operator"
7673           [(and (match_operand 2 "nonimmediate_operand" "")
7674                 (match_operand 3 "const_int_operand" ""))
7675            (const_int 0)]))]
7676    "reload_completed
7677     && GET_MODE (operands[2]) != QImode
7678     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7679     && ((ix86_match_ccmode (insn, CCZmode)
7680          && !(INTVAL (operands[3]) & ~255))
7681         || (ix86_match_ccmode (insn, CCNOmode)
7682             && !(INTVAL (operands[3]) & ~127)))"
7683   [(set (match_dup 0)
7684         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7685                          (const_int 0)]))]
7686 {
7687   operands[2] = gen_lowpart (QImode, operands[2]);
7688   operands[3] = gen_lowpart (QImode, operands[3]);
7689 })
7690
7691 ;; %%% This used to optimize known byte-wide and operations to memory,
7692 ;; and sometimes to QImode registers.  If this is considered useful,
7693 ;; it should be done with splitters.
7694
7695 (define_expand "and<mode>3"
7696   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7697         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7698                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7699   ""
7700 {
7701   if (<MODE>mode == DImode
7702       && GET_CODE (operands[2]) == CONST_INT
7703       && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7704       && REG_P (operands[1]))
7705     emit_insn (gen_zero_extendsidi2 (operands[0],
7706                                      gen_lowpart (SImode, operands[1])));
7707   else
7708     ix86_expand_binary_operator (AND, <MODE>mode, operands);
7709   DONE;
7710 })
7711
7712 (define_insn "*anddi_1"
7713   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7714         (and:DI
7715          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7716          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7717    (clobber (reg:CC FLAGS_REG))]
7718   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7719 {
7720   switch (get_attr_type (insn))
7721     {
7722     case TYPE_IMOVX:
7723       {
7724         enum machine_mode mode;
7725
7726         gcc_assert (CONST_INT_P (operands[2]));
7727         if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7728           mode = SImode;
7729         else if (INTVAL (operands[2]) == 0xffff)
7730           mode = HImode;
7731         else
7732           {
7733             gcc_assert (INTVAL (operands[2]) == 0xff);
7734             mode = QImode;
7735           }
7736
7737         operands[1] = gen_lowpart (mode, operands[1]);
7738         if (mode == SImode)
7739           return "mov{l}\t{%1, %k0|%k0, %1}";
7740         else if (mode == HImode)
7741           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7742         else
7743           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7744       }
7745
7746     default:
7747       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7748       if (get_attr_mode (insn) == MODE_SI)
7749         return "and{l}\t{%k2, %k0|%k0, %k2}";
7750       else
7751         return "and{q}\t{%2, %0|%0, %2}";
7752     }
7753 }
7754   [(set_attr "type" "alu,alu,alu,imovx")
7755    (set_attr "length_immediate" "*,*,*,0")
7756    (set (attr "prefix_rex")
7757      (if_then_else
7758        (and (eq_attr "type" "imovx")
7759             (and (match_test "INTVAL (operands[2]) == 0xff")
7760                  (match_operand 1 "ext_QIreg_operand" "")))
7761        (const_string "1")
7762        (const_string "*")))
7763    (set_attr "mode" "SI,DI,DI,SI")])
7764
7765 (define_insn "*andsi_1"
7766   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7767         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7768                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7769    (clobber (reg:CC FLAGS_REG))]
7770   "ix86_binary_operator_ok (AND, SImode, operands)"
7771 {
7772   switch (get_attr_type (insn))
7773     {
7774     case TYPE_IMOVX:
7775       {
7776         enum machine_mode mode;
7777
7778         gcc_assert (CONST_INT_P (operands[2]));
7779         if (INTVAL (operands[2]) == 0xffff)
7780           mode = HImode;
7781         else
7782           {
7783             gcc_assert (INTVAL (operands[2]) == 0xff);
7784             mode = QImode;
7785           }
7786
7787         operands[1] = gen_lowpart (mode, operands[1]);
7788         if (mode == HImode)
7789           return "movz{wl|x}\t{%1, %0|%0, %1}";
7790         else
7791           return "movz{bl|x}\t{%1, %0|%0, %1}";
7792       }
7793
7794     default:
7795       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7796       return "and{l}\t{%2, %0|%0, %2}";
7797     }
7798 }
7799   [(set_attr "type" "alu,alu,imovx")
7800    (set (attr "prefix_rex")
7801      (if_then_else
7802        (and (eq_attr "type" "imovx")
7803             (and (match_test "INTVAL (operands[2]) == 0xff")
7804                  (match_operand 1 "ext_QIreg_operand" "")))
7805        (const_string "1")
7806        (const_string "*")))
7807    (set_attr "length_immediate" "*,*,0")
7808    (set_attr "mode" "SI")])
7809
7810 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7811 (define_insn "*andsi_1_zext"
7812   [(set (match_operand:DI 0 "register_operand" "=r")
7813         (zero_extend:DI
7814           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7815                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7816    (clobber (reg:CC FLAGS_REG))]
7817   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7818   "and{l}\t{%2, %k0|%k0, %2}"
7819   [(set_attr "type" "alu")
7820    (set_attr "mode" "SI")])
7821
7822 (define_insn "*andhi_1"
7823   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7824         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7825                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7826    (clobber (reg:CC FLAGS_REG))]
7827   "ix86_binary_operator_ok (AND, HImode, operands)"
7828 {
7829   switch (get_attr_type (insn))
7830     {
7831     case TYPE_IMOVX:
7832       gcc_assert (CONST_INT_P (operands[2]));
7833       gcc_assert (INTVAL (operands[2]) == 0xff);
7834       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7835
7836     default:
7837       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7838
7839       return "and{w}\t{%2, %0|%0, %2}";
7840     }
7841 }
7842   [(set_attr "type" "alu,alu,imovx")
7843    (set_attr "length_immediate" "*,*,0")
7844    (set (attr "prefix_rex")
7845      (if_then_else
7846        (and (eq_attr "type" "imovx")
7847             (match_operand 1 "ext_QIreg_operand" ""))
7848        (const_string "1")
7849        (const_string "*")))
7850    (set_attr "mode" "HI,HI,SI")])
7851
7852 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7853 (define_insn "*andqi_1"
7854   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7855         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7856                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7857    (clobber (reg:CC FLAGS_REG))]
7858   "ix86_binary_operator_ok (AND, QImode, operands)"
7859   "@
7860    and{b}\t{%2, %0|%0, %2}
7861    and{b}\t{%2, %0|%0, %2}
7862    and{l}\t{%k2, %k0|%k0, %k2}"
7863   [(set_attr "type" "alu")
7864    (set_attr "mode" "QI,QI,SI")])
7865
7866 (define_insn "*andqi_1_slp"
7867   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7868         (and:QI (match_dup 0)
7869                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7870    (clobber (reg:CC FLAGS_REG))]
7871   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7872    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7873   "and{b}\t{%1, %0|%0, %1}"
7874   [(set_attr "type" "alu1")
7875    (set_attr "mode" "QI")])
7876
7877 (define_split
7878   [(set (match_operand 0 "register_operand" "")
7879         (and (match_dup 0)
7880              (const_int -65536)))
7881    (clobber (reg:CC FLAGS_REG))]
7882   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7883     || optimize_function_for_size_p (cfun)"
7884   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7885   "operands[1] = gen_lowpart (HImode, operands[0]);")
7886
7887 (define_split
7888   [(set (match_operand 0 "ext_register_operand" "")
7889         (and (match_dup 0)
7890              (const_int -256)))
7891    (clobber (reg:CC FLAGS_REG))]
7892   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7893    && reload_completed"
7894   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7895   "operands[1] = gen_lowpart (QImode, operands[0]);")
7896
7897 (define_split
7898   [(set (match_operand 0 "ext_register_operand" "")
7899         (and (match_dup 0)
7900              (const_int -65281)))
7901    (clobber (reg:CC FLAGS_REG))]
7902   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7903    && reload_completed"
7904   [(parallel [(set (zero_extract:SI (match_dup 0)
7905                                     (const_int 8)
7906                                     (const_int 8))
7907                    (xor:SI
7908                      (zero_extract:SI (match_dup 0)
7909                                       (const_int 8)
7910                                       (const_int 8))
7911                      (zero_extract:SI (match_dup 0)
7912                                       (const_int 8)
7913                                       (const_int 8))))
7914               (clobber (reg:CC FLAGS_REG))])]
7915   "operands[0] = gen_lowpart (SImode, operands[0]);")
7916
7917 (define_insn "*anddi_2"
7918   [(set (reg FLAGS_REG)
7919         (compare
7920          (and:DI
7921           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7922           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7923          (const_int 0)))
7924    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7925         (and:DI (match_dup 1) (match_dup 2)))]
7926   "TARGET_64BIT
7927    && ix86_match_ccmode
7928         (insn,
7929          /* If we are going to emit andl instead of andq, and the operands[2]
7930             constant might have the SImode sign bit set, make sure the sign
7931             flag isn't tested, because the instruction will set the sign flag
7932             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
7933             conservatively assume it might have bit 31 set.  */
7934          (satisfies_constraint_Z (operands[2])
7935           && (!CONST_INT_P (operands[2])
7936               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7937          ? CCZmode : CCNOmode)
7938    && ix86_binary_operator_ok (AND, DImode, operands)"
7939   "@
7940    and{l}\t{%k2, %k0|%k0, %k2}
7941    and{q}\t{%2, %0|%0, %2}
7942    and{q}\t{%2, %0|%0, %2}"
7943   [(set_attr "type" "alu")
7944    (set_attr "mode" "SI,DI,DI")])
7945
7946 (define_insn "*andqi_2_maybe_si"
7947   [(set (reg FLAGS_REG)
7948         (compare (and:QI
7949                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7950                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7951                  (const_int 0)))
7952    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7953         (and:QI (match_dup 1) (match_dup 2)))]
7954   "ix86_binary_operator_ok (AND, QImode, operands)
7955    && ix86_match_ccmode (insn,
7956                          CONST_INT_P (operands[2])
7957                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7958 {
7959   if (which_alternative == 2)
7960     {
7961       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7962         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7963       return "and{l}\t{%2, %k0|%k0, %2}";
7964     }
7965   return "and{b}\t{%2, %0|%0, %2}";
7966 }
7967   [(set_attr "type" "alu")
7968    (set_attr "mode" "QI,QI,SI")])
7969
7970 (define_insn "*and<mode>_2"
7971   [(set (reg FLAGS_REG)
7972         (compare (and:SWI124
7973                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7974                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7975                  (const_int 0)))
7976    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7977         (and:SWI124 (match_dup 1) (match_dup 2)))]
7978   "ix86_match_ccmode (insn, CCNOmode)
7979    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7980   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7981   [(set_attr "type" "alu")
7982    (set_attr "mode" "<MODE>")])
7983
7984 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7985 (define_insn "*andsi_2_zext"
7986   [(set (reg FLAGS_REG)
7987         (compare (and:SI
7988                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7989                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7990                  (const_int 0)))
7991    (set (match_operand:DI 0 "register_operand" "=r")
7992         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7993   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7994    && ix86_binary_operator_ok (AND, SImode, operands)"
7995   "and{l}\t{%2, %k0|%k0, %2}"
7996   [(set_attr "type" "alu")
7997    (set_attr "mode" "SI")])
7998
7999 (define_insn "*andqi_2_slp"
8000   [(set (reg FLAGS_REG)
8001         (compare (and:QI
8002                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8003                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8004                  (const_int 0)))
8005    (set (strict_low_part (match_dup 0))
8006         (and:QI (match_dup 0) (match_dup 1)))]
8007   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8008    && ix86_match_ccmode (insn, CCNOmode)
8009    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8010   "and{b}\t{%1, %0|%0, %1}"
8011   [(set_attr "type" "alu1")
8012    (set_attr "mode" "QI")])
8013
8014 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8015 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8016 ;; for a QImode operand, which of course failed.
8017 (define_insn "andqi_ext_0"
8018   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8019                          (const_int 8)
8020                          (const_int 8))
8021         (and:SI
8022           (zero_extract:SI
8023             (match_operand 1 "ext_register_operand" "0")
8024             (const_int 8)
8025             (const_int 8))
8026           (match_operand 2 "const_int_operand" "n")))
8027    (clobber (reg:CC FLAGS_REG))]
8028   ""
8029   "and{b}\t{%2, %h0|%h0, %2}"
8030   [(set_attr "type" "alu")
8031    (set_attr "length_immediate" "1")
8032    (set_attr "modrm" "1")
8033    (set_attr "mode" "QI")])
8034
8035 ;; Generated by peephole translating test to and.  This shows up
8036 ;; often in fp comparisons.
8037 (define_insn "*andqi_ext_0_cc"
8038   [(set (reg FLAGS_REG)
8039         (compare
8040           (and:SI
8041             (zero_extract:SI
8042               (match_operand 1 "ext_register_operand" "0")
8043               (const_int 8)
8044               (const_int 8))
8045             (match_operand 2 "const_int_operand" "n"))
8046           (const_int 0)))
8047    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8048                          (const_int 8)
8049                          (const_int 8))
8050         (and:SI
8051           (zero_extract:SI
8052             (match_dup 1)
8053             (const_int 8)
8054             (const_int 8))
8055           (match_dup 2)))]
8056   "ix86_match_ccmode (insn, CCNOmode)"
8057   "and{b}\t{%2, %h0|%h0, %2}"
8058   [(set_attr "type" "alu")
8059    (set_attr "length_immediate" "1")
8060    (set_attr "modrm" "1")
8061    (set_attr "mode" "QI")])
8062
8063 (define_insn "*andqi_ext_1_rex64"
8064   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8065                          (const_int 8)
8066                          (const_int 8))
8067         (and:SI
8068           (zero_extract:SI
8069             (match_operand 1 "ext_register_operand" "0")
8070             (const_int 8)
8071             (const_int 8))
8072           (zero_extend:SI
8073             (match_operand 2 "ext_register_operand" "Q"))))
8074    (clobber (reg:CC FLAGS_REG))]
8075   "TARGET_64BIT"
8076   "and{b}\t{%2, %h0|%h0, %2}"
8077   [(set_attr "type" "alu")
8078    (set_attr "length_immediate" "0")
8079    (set_attr "mode" "QI")])
8080
8081 (define_insn "*andqi_ext_1"
8082   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8083                          (const_int 8)
8084                          (const_int 8))
8085         (and:SI
8086           (zero_extract:SI
8087             (match_operand 1 "ext_register_operand" "0")
8088             (const_int 8)
8089             (const_int 8))
8090           (zero_extend:SI
8091             (match_operand:QI 2 "general_operand" "Qm"))))
8092    (clobber (reg:CC FLAGS_REG))]
8093   "!TARGET_64BIT"
8094   "and{b}\t{%2, %h0|%h0, %2}"
8095   [(set_attr "type" "alu")
8096    (set_attr "length_immediate" "0")
8097    (set_attr "mode" "QI")])
8098
8099 (define_insn "*andqi_ext_2"
8100   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8101                          (const_int 8)
8102                          (const_int 8))
8103         (and:SI
8104           (zero_extract:SI
8105             (match_operand 1 "ext_register_operand" "%0")
8106             (const_int 8)
8107             (const_int 8))
8108           (zero_extract:SI
8109             (match_operand 2 "ext_register_operand" "Q")
8110             (const_int 8)
8111             (const_int 8))))
8112    (clobber (reg:CC FLAGS_REG))]
8113   ""
8114   "and{b}\t{%h2, %h0|%h0, %h2}"
8115   [(set_attr "type" "alu")
8116    (set_attr "length_immediate" "0")
8117    (set_attr "mode" "QI")])
8118
8119 ;; Convert wide AND instructions with immediate operand to shorter QImode
8120 ;; equivalents when possible.
8121 ;; Don't do the splitting with memory operands, since it introduces risk
8122 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8123 ;; for size, but that can (should?) be handled by generic code instead.
8124 (define_split
8125   [(set (match_operand 0 "register_operand" "")
8126         (and (match_operand 1 "register_operand" "")
8127              (match_operand 2 "const_int_operand" "")))
8128    (clobber (reg:CC FLAGS_REG))]
8129    "reload_completed
8130     && QI_REG_P (operands[0])
8131     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8132     && !(~INTVAL (operands[2]) & ~(255 << 8))
8133     && GET_MODE (operands[0]) != QImode"
8134   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8135                    (and:SI (zero_extract:SI (match_dup 1)
8136                                             (const_int 8) (const_int 8))
8137                            (match_dup 2)))
8138               (clobber (reg:CC FLAGS_REG))])]
8139 {
8140   operands[0] = gen_lowpart (SImode, operands[0]);
8141   operands[1] = gen_lowpart (SImode, operands[1]);
8142   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8143 })
8144
8145 ;; Since AND can be encoded with sign extended immediate, this is only
8146 ;; profitable when 7th bit is not set.
8147 (define_split
8148   [(set (match_operand 0 "register_operand" "")
8149         (and (match_operand 1 "general_operand" "")
8150              (match_operand 2 "const_int_operand" "")))
8151    (clobber (reg:CC FLAGS_REG))]
8152    "reload_completed
8153     && ANY_QI_REG_P (operands[0])
8154     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8155     && !(~INTVAL (operands[2]) & ~255)
8156     && !(INTVAL (operands[2]) & 128)
8157     && GET_MODE (operands[0]) != QImode"
8158   [(parallel [(set (strict_low_part (match_dup 0))
8159                    (and:QI (match_dup 1)
8160                            (match_dup 2)))
8161               (clobber (reg:CC FLAGS_REG))])]
8162 {
8163   operands[0] = gen_lowpart (QImode, operands[0]);
8164   operands[1] = gen_lowpart (QImode, operands[1]);
8165   operands[2] = gen_lowpart (QImode, operands[2]);
8166 })
8167 \f
8168 ;; Logical inclusive and exclusive OR instructions
8169
8170 ;; %%% This used to optimize known byte-wide and operations to memory.
8171 ;; If this is considered useful, it should be done with splitters.
8172
8173 (define_expand "<code><mode>3"
8174   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8175         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8176                      (match_operand:SWIM 2 "<general_operand>" "")))]
8177   ""
8178   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8179
8180 (define_insn "*<code><mode>_1"
8181   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8182         (any_or:SWI248
8183          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8184          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8185    (clobber (reg:CC FLAGS_REG))]
8186   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8187   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8188   [(set_attr "type" "alu")
8189    (set_attr "mode" "<MODE>")])
8190
8191 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8192 (define_insn "*<code>qi_1"
8193   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8194         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8195                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8196    (clobber (reg:CC FLAGS_REG))]
8197   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8198   "@
8199    <logic>{b}\t{%2, %0|%0, %2}
8200    <logic>{b}\t{%2, %0|%0, %2}
8201    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8202   [(set_attr "type" "alu")
8203    (set_attr "mode" "QI,QI,SI")])
8204
8205 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8206 (define_insn "*<code>si_1_zext"
8207   [(set (match_operand:DI 0 "register_operand" "=r")
8208         (zero_extend:DI
8209          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8210                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8211    (clobber (reg:CC FLAGS_REG))]
8212   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8213   "<logic>{l}\t{%2, %k0|%k0, %2}"
8214   [(set_attr "type" "alu")
8215    (set_attr "mode" "SI")])
8216
8217 (define_insn "*<code>si_1_zext_imm"
8218   [(set (match_operand:DI 0 "register_operand" "=r")
8219         (any_or:DI
8220          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8221          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8222    (clobber (reg:CC FLAGS_REG))]
8223   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8224   "<logic>{l}\t{%2, %k0|%k0, %2}"
8225   [(set_attr "type" "alu")
8226    (set_attr "mode" "SI")])
8227
8228 (define_insn "*<code>qi_1_slp"
8229   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8230         (any_or:QI (match_dup 0)
8231                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8232    (clobber (reg:CC FLAGS_REG))]
8233   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8234    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8235   "<logic>{b}\t{%1, %0|%0, %1}"
8236   [(set_attr "type" "alu1")
8237    (set_attr "mode" "QI")])
8238
8239 (define_insn "*<code><mode>_2"
8240   [(set (reg FLAGS_REG)
8241         (compare (any_or:SWI
8242                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8243                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8244                  (const_int 0)))
8245    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8246         (any_or:SWI (match_dup 1) (match_dup 2)))]
8247   "ix86_match_ccmode (insn, CCNOmode)
8248    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8249   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8250   [(set_attr "type" "alu")
8251    (set_attr "mode" "<MODE>")])
8252
8253 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8254 ;; ??? Special case for immediate operand is missing - it is tricky.
8255 (define_insn "*<code>si_2_zext"
8256   [(set (reg FLAGS_REG)
8257         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8258                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8259                  (const_int 0)))
8260    (set (match_operand:DI 0 "register_operand" "=r")
8261         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8262   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8263    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8264   "<logic>{l}\t{%2, %k0|%k0, %2}"
8265   [(set_attr "type" "alu")
8266    (set_attr "mode" "SI")])
8267
8268 (define_insn "*<code>si_2_zext_imm"
8269   [(set (reg FLAGS_REG)
8270         (compare (any_or:SI
8271                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8272                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8273                  (const_int 0)))
8274    (set (match_operand:DI 0 "register_operand" "=r")
8275         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8276   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8277    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8278   "<logic>{l}\t{%2, %k0|%k0, %2}"
8279   [(set_attr "type" "alu")
8280    (set_attr "mode" "SI")])
8281
8282 (define_insn "*<code>qi_2_slp"
8283   [(set (reg FLAGS_REG)
8284         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8285                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8286                  (const_int 0)))
8287    (set (strict_low_part (match_dup 0))
8288         (any_or:QI (match_dup 0) (match_dup 1)))]
8289   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8290    && ix86_match_ccmode (insn, CCNOmode)
8291    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8292   "<logic>{b}\t{%1, %0|%0, %1}"
8293   [(set_attr "type" "alu1")
8294    (set_attr "mode" "QI")])
8295
8296 (define_insn "*<code><mode>_3"
8297   [(set (reg FLAGS_REG)
8298         (compare (any_or:SWI
8299                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8300                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8301                  (const_int 0)))
8302    (clobber (match_scratch:SWI 0 "=<r>"))]
8303   "ix86_match_ccmode (insn, CCNOmode)
8304    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8305   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8306   [(set_attr "type" "alu")
8307    (set_attr "mode" "<MODE>")])
8308
8309 (define_insn "*<code>qi_ext_0"
8310   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8311                          (const_int 8)
8312                          (const_int 8))
8313         (any_or:SI
8314           (zero_extract:SI
8315             (match_operand 1 "ext_register_operand" "0")
8316             (const_int 8)
8317             (const_int 8))
8318           (match_operand 2 "const_int_operand" "n")))
8319    (clobber (reg:CC FLAGS_REG))]
8320   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8321   "<logic>{b}\t{%2, %h0|%h0, %2}"
8322   [(set_attr "type" "alu")
8323    (set_attr "length_immediate" "1")
8324    (set_attr "modrm" "1")
8325    (set_attr "mode" "QI")])
8326
8327 (define_insn "*<code>qi_ext_1_rex64"
8328   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8329                          (const_int 8)
8330                          (const_int 8))
8331         (any_or:SI
8332           (zero_extract:SI
8333             (match_operand 1 "ext_register_operand" "0")
8334             (const_int 8)
8335             (const_int 8))
8336           (zero_extend:SI
8337             (match_operand 2 "ext_register_operand" "Q"))))
8338    (clobber (reg:CC FLAGS_REG))]
8339   "TARGET_64BIT
8340    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8341   "<logic>{b}\t{%2, %h0|%h0, %2}"
8342   [(set_attr "type" "alu")
8343    (set_attr "length_immediate" "0")
8344    (set_attr "mode" "QI")])
8345
8346 (define_insn "*<code>qi_ext_1"
8347   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8348                          (const_int 8)
8349                          (const_int 8))
8350         (any_or:SI
8351           (zero_extract:SI
8352             (match_operand 1 "ext_register_operand" "0")
8353             (const_int 8)
8354             (const_int 8))
8355           (zero_extend:SI
8356             (match_operand:QI 2 "general_operand" "Qm"))))
8357    (clobber (reg:CC FLAGS_REG))]
8358   "!TARGET_64BIT
8359    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8360   "<logic>{b}\t{%2, %h0|%h0, %2}"
8361   [(set_attr "type" "alu")
8362    (set_attr "length_immediate" "0")
8363    (set_attr "mode" "QI")])
8364
8365 (define_insn "*<code>qi_ext_2"
8366   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8367                          (const_int 8)
8368                          (const_int 8))
8369         (any_or:SI
8370           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8371                            (const_int 8)
8372                            (const_int 8))
8373           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8374                            (const_int 8)
8375                            (const_int 8))))
8376    (clobber (reg:CC FLAGS_REG))]
8377   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8378   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8379   [(set_attr "type" "alu")
8380    (set_attr "length_immediate" "0")
8381    (set_attr "mode" "QI")])
8382
8383 (define_split
8384   [(set (match_operand 0 "register_operand" "")
8385         (any_or (match_operand 1 "register_operand" "")
8386                 (match_operand 2 "const_int_operand" "")))
8387    (clobber (reg:CC FLAGS_REG))]
8388    "reload_completed
8389     && QI_REG_P (operands[0])
8390     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8391     && !(INTVAL (operands[2]) & ~(255 << 8))
8392     && GET_MODE (operands[0]) != QImode"
8393   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8394                    (any_or:SI (zero_extract:SI (match_dup 1)
8395                                                (const_int 8) (const_int 8))
8396                               (match_dup 2)))
8397               (clobber (reg:CC FLAGS_REG))])]
8398 {
8399   operands[0] = gen_lowpart (SImode, operands[0]);
8400   operands[1] = gen_lowpart (SImode, operands[1]);
8401   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8402 })
8403
8404 ;; Since OR can be encoded with sign extended immediate, this is only
8405 ;; profitable when 7th bit is set.
8406 (define_split
8407   [(set (match_operand 0 "register_operand" "")
8408         (any_or (match_operand 1 "general_operand" "")
8409                 (match_operand 2 "const_int_operand" "")))
8410    (clobber (reg:CC FLAGS_REG))]
8411    "reload_completed
8412     && ANY_QI_REG_P (operands[0])
8413     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8414     && !(INTVAL (operands[2]) & ~255)
8415     && (INTVAL (operands[2]) & 128)
8416     && GET_MODE (operands[0]) != QImode"
8417   [(parallel [(set (strict_low_part (match_dup 0))
8418                    (any_or:QI (match_dup 1)
8419                               (match_dup 2)))
8420               (clobber (reg:CC FLAGS_REG))])]
8421 {
8422   operands[0] = gen_lowpart (QImode, operands[0]);
8423   operands[1] = gen_lowpart (QImode, operands[1]);
8424   operands[2] = gen_lowpart (QImode, operands[2]);
8425 })
8426
8427 (define_expand "xorqi_cc_ext_1"
8428   [(parallel [
8429      (set (reg:CCNO FLAGS_REG)
8430           (compare:CCNO
8431             (xor:SI
8432               (zero_extract:SI
8433                 (match_operand 1 "ext_register_operand" "")
8434                 (const_int 8)
8435                 (const_int 8))
8436               (match_operand:QI 2 "general_operand" ""))
8437             (const_int 0)))
8438      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8439                            (const_int 8)
8440                            (const_int 8))
8441           (xor:SI
8442             (zero_extract:SI
8443              (match_dup 1)
8444              (const_int 8)
8445              (const_int 8))
8446             (match_dup 2)))])])
8447
8448 (define_insn "*xorqi_cc_ext_1_rex64"
8449   [(set (reg FLAGS_REG)
8450         (compare
8451           (xor:SI
8452             (zero_extract:SI
8453               (match_operand 1 "ext_register_operand" "0")
8454               (const_int 8)
8455               (const_int 8))
8456             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8457           (const_int 0)))
8458    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459                          (const_int 8)
8460                          (const_int 8))
8461         (xor:SI
8462           (zero_extract:SI
8463            (match_dup 1)
8464            (const_int 8)
8465            (const_int 8))
8466           (match_dup 2)))]
8467   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8468   "xor{b}\t{%2, %h0|%h0, %2}"
8469   [(set_attr "type" "alu")
8470    (set_attr "modrm" "1")
8471    (set_attr "mode" "QI")])
8472
8473 (define_insn "*xorqi_cc_ext_1"
8474   [(set (reg FLAGS_REG)
8475         (compare
8476           (xor:SI
8477             (zero_extract:SI
8478               (match_operand 1 "ext_register_operand" "0")
8479               (const_int 8)
8480               (const_int 8))
8481             (match_operand:QI 2 "general_operand" "qmn"))
8482           (const_int 0)))
8483    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8484                          (const_int 8)
8485                          (const_int 8))
8486         (xor:SI
8487           (zero_extract:SI
8488            (match_dup 1)
8489            (const_int 8)
8490            (const_int 8))
8491           (match_dup 2)))]
8492   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8493   "xor{b}\t{%2, %h0|%h0, %2}"
8494   [(set_attr "type" "alu")
8495    (set_attr "modrm" "1")
8496    (set_attr "mode" "QI")])
8497 \f
8498 ;; Negation instructions
8499
8500 (define_expand "neg<mode>2"
8501   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8502         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8503   ""
8504   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8505
8506 (define_insn_and_split "*neg<dwi>2_doubleword"
8507   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8508         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8509    (clobber (reg:CC FLAGS_REG))]
8510   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8511   "#"
8512   "reload_completed"
8513   [(parallel
8514     [(set (reg:CCZ FLAGS_REG)
8515           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8516      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8517    (parallel
8518     [(set (match_dup 2)
8519           (plus:DWIH (match_dup 3)
8520                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8521                                 (const_int 0))))
8522      (clobber (reg:CC FLAGS_REG))])
8523    (parallel
8524     [(set (match_dup 2)
8525           (neg:DWIH (match_dup 2)))
8526      (clobber (reg:CC FLAGS_REG))])]
8527   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8528
8529 (define_insn "*neg<mode>2_1"
8530   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8531         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8532    (clobber (reg:CC FLAGS_REG))]
8533   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8534   "neg{<imodesuffix>}\t%0"
8535   [(set_attr "type" "negnot")
8536    (set_attr "mode" "<MODE>")])
8537
8538 ;; Combine is quite creative about this pattern.
8539 (define_insn "*negsi2_1_zext"
8540   [(set (match_operand:DI 0 "register_operand" "=r")
8541         (lshiftrt:DI
8542           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8543                              (const_int 32)))
8544         (const_int 32)))
8545    (clobber (reg:CC FLAGS_REG))]
8546   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8547   "neg{l}\t%k0"
8548   [(set_attr "type" "negnot")
8549    (set_attr "mode" "SI")])
8550
8551 ;; The problem with neg is that it does not perform (compare x 0),
8552 ;; it really performs (compare 0 x), which leaves us with the zero
8553 ;; flag being the only useful item.
8554
8555 (define_insn "*neg<mode>2_cmpz"
8556   [(set (reg:CCZ FLAGS_REG)
8557         (compare:CCZ
8558           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8559                    (const_int 0)))
8560    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8561         (neg:SWI (match_dup 1)))]
8562   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8563   "neg{<imodesuffix>}\t%0"
8564   [(set_attr "type" "negnot")
8565    (set_attr "mode" "<MODE>")])
8566
8567 (define_insn "*negsi2_cmpz_zext"
8568   [(set (reg:CCZ FLAGS_REG)
8569         (compare:CCZ
8570           (lshiftrt:DI
8571             (neg:DI (ashift:DI
8572                       (match_operand:DI 1 "register_operand" "0")
8573                       (const_int 32)))
8574             (const_int 32))
8575           (const_int 0)))
8576    (set (match_operand:DI 0 "register_operand" "=r")
8577         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8578                                         (const_int 32)))
8579                      (const_int 32)))]
8580   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8581   "neg{l}\t%k0"
8582   [(set_attr "type" "negnot")
8583    (set_attr "mode" "SI")])
8584
8585 ;; Changing of sign for FP values is doable using integer unit too.
8586
8587 (define_expand "<code><mode>2"
8588   [(set (match_operand:X87MODEF 0 "register_operand" "")
8589         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8590   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8591   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8592
8593 (define_insn "*absneg<mode>2_mixed"
8594   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8595         (match_operator:MODEF 3 "absneg_operator"
8596           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8597    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8598    (clobber (reg:CC FLAGS_REG))]
8599   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8600   "#")
8601
8602 (define_insn "*absneg<mode>2_sse"
8603   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8604         (match_operator:MODEF 3 "absneg_operator"
8605           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8606    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8607    (clobber (reg:CC FLAGS_REG))]
8608   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8609   "#")
8610
8611 (define_insn "*absneg<mode>2_i387"
8612   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8613         (match_operator:X87MODEF 3 "absneg_operator"
8614           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8615    (use (match_operand 2 "" ""))
8616    (clobber (reg:CC FLAGS_REG))]
8617   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8618   "#")
8619
8620 (define_expand "<code>tf2"
8621   [(set (match_operand:TF 0 "register_operand" "")
8622         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8623   "TARGET_SSE2"
8624   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8625
8626 (define_insn "*absnegtf2_sse"
8627   [(set (match_operand:TF 0 "register_operand" "=x,x")
8628         (match_operator:TF 3 "absneg_operator"
8629           [(match_operand:TF 1 "register_operand" "0,x")]))
8630    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8631    (clobber (reg:CC FLAGS_REG))]
8632   "TARGET_SSE2"
8633   "#")
8634
8635 ;; Splitters for fp abs and neg.
8636
8637 (define_split
8638   [(set (match_operand 0 "fp_register_operand" "")
8639         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8640    (use (match_operand 2 "" ""))
8641    (clobber (reg:CC FLAGS_REG))]
8642   "reload_completed"
8643   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8644
8645 (define_split
8646   [(set (match_operand 0 "register_operand" "")
8647         (match_operator 3 "absneg_operator"
8648           [(match_operand 1 "register_operand" "")]))
8649    (use (match_operand 2 "nonimmediate_operand" ""))
8650    (clobber (reg:CC FLAGS_REG))]
8651   "reload_completed && SSE_REG_P (operands[0])"
8652   [(set (match_dup 0) (match_dup 3))]
8653 {
8654   enum machine_mode mode = GET_MODE (operands[0]);
8655   enum machine_mode vmode = GET_MODE (operands[2]);
8656   rtx tmp;
8657
8658   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8659   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8660   if (operands_match_p (operands[0], operands[2]))
8661     {
8662       tmp = operands[1];
8663       operands[1] = operands[2];
8664       operands[2] = tmp;
8665     }
8666   if (GET_CODE (operands[3]) == ABS)
8667     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8668   else
8669     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8670   operands[3] = tmp;
8671 })
8672
8673 (define_split
8674   [(set (match_operand:SF 0 "register_operand" "")
8675         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8676    (use (match_operand:V4SF 2 "" ""))
8677    (clobber (reg:CC FLAGS_REG))]
8678   "reload_completed"
8679   [(parallel [(set (match_dup 0) (match_dup 1))
8680               (clobber (reg:CC FLAGS_REG))])]
8681 {
8682   rtx tmp;
8683   operands[0] = gen_lowpart (SImode, operands[0]);
8684   if (GET_CODE (operands[1]) == ABS)
8685     {
8686       tmp = gen_int_mode (0x7fffffff, SImode);
8687       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8688     }
8689   else
8690     {
8691       tmp = gen_int_mode (0x80000000, SImode);
8692       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8693     }
8694   operands[1] = tmp;
8695 })
8696
8697 (define_split
8698   [(set (match_operand:DF 0 "register_operand" "")
8699         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8700    (use (match_operand 2 "" ""))
8701    (clobber (reg:CC FLAGS_REG))]
8702   "reload_completed"
8703   [(parallel [(set (match_dup 0) (match_dup 1))
8704               (clobber (reg:CC FLAGS_REG))])]
8705 {
8706   rtx tmp;
8707   if (TARGET_64BIT)
8708     {
8709       tmp = gen_lowpart (DImode, operands[0]);
8710       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8711       operands[0] = tmp;
8712
8713       if (GET_CODE (operands[1]) == ABS)
8714         tmp = const0_rtx;
8715       else
8716         tmp = gen_rtx_NOT (DImode, tmp);
8717     }
8718   else
8719     {
8720       operands[0] = gen_highpart (SImode, operands[0]);
8721       if (GET_CODE (operands[1]) == ABS)
8722         {
8723           tmp = gen_int_mode (0x7fffffff, SImode);
8724           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8725         }
8726       else
8727         {
8728           tmp = gen_int_mode (0x80000000, SImode);
8729           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8730         }
8731     }
8732   operands[1] = tmp;
8733 })
8734
8735 (define_split
8736   [(set (match_operand:XF 0 "register_operand" "")
8737         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8738    (use (match_operand 2 "" ""))
8739    (clobber (reg:CC FLAGS_REG))]
8740   "reload_completed"
8741   [(parallel [(set (match_dup 0) (match_dup 1))
8742               (clobber (reg:CC FLAGS_REG))])]
8743 {
8744   rtx tmp;
8745   operands[0] = gen_rtx_REG (SImode,
8746                              true_regnum (operands[0])
8747                              + (TARGET_64BIT ? 1 : 2));
8748   if (GET_CODE (operands[1]) == ABS)
8749     {
8750       tmp = GEN_INT (0x7fff);
8751       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8752     }
8753   else
8754     {
8755       tmp = GEN_INT (0x8000);
8756       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8757     }
8758   operands[1] = tmp;
8759 })
8760
8761 ;; Conditionalize these after reload. If they match before reload, we
8762 ;; lose the clobber and ability to use integer instructions.
8763
8764 (define_insn "*<code><mode>2_1"
8765   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8766         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8767   "TARGET_80387
8768    && (reload_completed
8769        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8770   "f<absneg_mnemonic>"
8771   [(set_attr "type" "fsgn")
8772    (set_attr "mode" "<MODE>")])
8773
8774 (define_insn "*<code>extendsfdf2"
8775   [(set (match_operand:DF 0 "register_operand" "=f")
8776         (absneg:DF (float_extend:DF
8777                      (match_operand:SF 1 "register_operand" "0"))))]
8778   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8779   "f<absneg_mnemonic>"
8780   [(set_attr "type" "fsgn")
8781    (set_attr "mode" "DF")])
8782
8783 (define_insn "*<code>extendsfxf2"
8784   [(set (match_operand:XF 0 "register_operand" "=f")
8785         (absneg:XF (float_extend:XF
8786                      (match_operand:SF 1 "register_operand" "0"))))]
8787   "TARGET_80387"
8788   "f<absneg_mnemonic>"
8789   [(set_attr "type" "fsgn")
8790    (set_attr "mode" "XF")])
8791
8792 (define_insn "*<code>extenddfxf2"
8793   [(set (match_operand:XF 0 "register_operand" "=f")
8794         (absneg:XF (float_extend:XF
8795                      (match_operand:DF 1 "register_operand" "0"))))]
8796   "TARGET_80387"
8797   "f<absneg_mnemonic>"
8798   [(set_attr "type" "fsgn")
8799    (set_attr "mode" "XF")])
8800
8801 ;; Copysign instructions
8802
8803 (define_mode_iterator CSGNMODE [SF DF TF])
8804 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8805
8806 (define_expand "copysign<mode>3"
8807   [(match_operand:CSGNMODE 0 "register_operand" "")
8808    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8809    (match_operand:CSGNMODE 2 "register_operand" "")]
8810   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8811    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8812   "ix86_expand_copysign (operands); DONE;")
8813
8814 (define_insn_and_split "copysign<mode>3_const"
8815   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8816         (unspec:CSGNMODE
8817           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8818            (match_operand:CSGNMODE 2 "register_operand" "0")
8819            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8820           UNSPEC_COPYSIGN))]
8821   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8822    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8823   "#"
8824   "&& reload_completed"
8825   [(const_int 0)]
8826   "ix86_split_copysign_const (operands); DONE;")
8827
8828 (define_insn "copysign<mode>3_var"
8829   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8830         (unspec:CSGNMODE
8831           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8832            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8833            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8834            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8835           UNSPEC_COPYSIGN))
8836    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8837   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8838    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8839   "#")
8840
8841 (define_split
8842   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8843         (unspec:CSGNMODE
8844           [(match_operand:CSGNMODE 2 "register_operand" "")
8845            (match_operand:CSGNMODE 3 "register_operand" "")
8846            (match_operand:<CSGNVMODE> 4 "" "")
8847            (match_operand:<CSGNVMODE> 5 "" "")]
8848           UNSPEC_COPYSIGN))
8849    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8850   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8851     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8852    && reload_completed"
8853   [(const_int 0)]
8854   "ix86_split_copysign_var (operands); DONE;")
8855 \f
8856 ;; One complement instructions
8857
8858 (define_expand "one_cmpl<mode>2"
8859   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8860         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8861   ""
8862   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8863
8864 (define_insn "*one_cmpl<mode>2_1"
8865   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8866         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8867   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8868   "not{<imodesuffix>}\t%0"
8869   [(set_attr "type" "negnot")
8870    (set_attr "mode" "<MODE>")])
8871
8872 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8873 (define_insn "*one_cmplqi2_1"
8874   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8875         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8876   "ix86_unary_operator_ok (NOT, QImode, operands)"
8877   "@
8878    not{b}\t%0
8879    not{l}\t%k0"
8880   [(set_attr "type" "negnot")
8881    (set_attr "mode" "QI,SI")])
8882
8883 ;; ??? Currently never generated - xor is used instead.
8884 (define_insn "*one_cmplsi2_1_zext"
8885   [(set (match_operand:DI 0 "register_operand" "=r")
8886         (zero_extend:DI
8887           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8888   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8889   "not{l}\t%k0"
8890   [(set_attr "type" "negnot")
8891    (set_attr "mode" "SI")])
8892
8893 (define_insn "*one_cmpl<mode>2_2"
8894   [(set (reg FLAGS_REG)
8895         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8896                  (const_int 0)))
8897    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8898         (not:SWI (match_dup 1)))]
8899   "ix86_match_ccmode (insn, CCNOmode)
8900    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8901   "#"
8902   [(set_attr "type" "alu1")
8903    (set_attr "mode" "<MODE>")])
8904
8905 (define_split
8906   [(set (match_operand 0 "flags_reg_operand" "")
8907         (match_operator 2 "compare_operator"
8908           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8909            (const_int 0)]))
8910    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8911         (not:SWI (match_dup 3)))]
8912   "ix86_match_ccmode (insn, CCNOmode)"
8913   [(parallel [(set (match_dup 0)
8914                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8915                                     (const_int 0)]))
8916               (set (match_dup 1)
8917                    (xor:SWI (match_dup 3) (const_int -1)))])])
8918
8919 ;; ??? Currently never generated - xor is used instead.
8920 (define_insn "*one_cmplsi2_2_zext"
8921   [(set (reg FLAGS_REG)
8922         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8923                  (const_int 0)))
8924    (set (match_operand:DI 0 "register_operand" "=r")
8925         (zero_extend:DI (not:SI (match_dup 1))))]
8926   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8927    && ix86_unary_operator_ok (NOT, SImode, operands)"
8928   "#"
8929   [(set_attr "type" "alu1")
8930    (set_attr "mode" "SI")])
8931
8932 (define_split
8933   [(set (match_operand 0 "flags_reg_operand" "")
8934         (match_operator 2 "compare_operator"
8935           [(not:SI (match_operand:SI 3 "register_operand" ""))
8936            (const_int 0)]))
8937    (set (match_operand:DI 1 "register_operand" "")
8938         (zero_extend:DI (not:SI (match_dup 3))))]
8939   "ix86_match_ccmode (insn, CCNOmode)"
8940   [(parallel [(set (match_dup 0)
8941                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8942                                     (const_int 0)]))
8943               (set (match_dup 1)
8944                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8945 \f
8946 ;; Shift instructions
8947
8948 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8949 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8950 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8951 ;; from the assembler input.
8952 ;;
8953 ;; This instruction shifts the target reg/mem as usual, but instead of
8954 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8955 ;; is a left shift double, bits are taken from the high order bits of
8956 ;; reg, else if the insn is a shift right double, bits are taken from the
8957 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8958 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8959 ;;
8960 ;; Since sh[lr]d does not change the `reg' operand, that is done
8961 ;; separately, making all shifts emit pairs of shift double and normal
8962 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8963 ;; support a 63 bit shift, each shift where the count is in a reg expands
8964 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8965 ;;
8966 ;; If the shift count is a constant, we need never emit more than one
8967 ;; shift pair, instead using moves and sign extension for counts greater
8968 ;; than 31.
8969
8970 (define_expand "ashl<mode>3"
8971   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8972         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8973                       (match_operand:QI 2 "nonmemory_operand" "")))]
8974   ""
8975   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8976
8977 (define_insn "*ashl<mode>3_doubleword"
8978   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8979         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8980                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8981    (clobber (reg:CC FLAGS_REG))]
8982   ""
8983   "#"
8984   [(set_attr "type" "multi")])
8985
8986 (define_split
8987   [(set (match_operand:DWI 0 "register_operand" "")
8988         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8989                     (match_operand:QI 2 "nonmemory_operand" "")))
8990    (clobber (reg:CC FLAGS_REG))]
8991   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8992   [(const_int 0)]
8993   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8994
8995 ;; By default we don't ask for a scratch register, because when DWImode
8996 ;; values are manipulated, registers are already at a premium.  But if
8997 ;; we have one handy, we won't turn it away.
8998
8999 (define_peephole2
9000   [(match_scratch:DWIH 3 "r")
9001    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9002                    (ashift:<DWI>
9003                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9004                      (match_operand:QI 2 "nonmemory_operand" "")))
9005               (clobber (reg:CC FLAGS_REG))])
9006    (match_dup 3)]
9007   "TARGET_CMOVE"
9008   [(const_int 0)]
9009   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9010
9011 (define_insn "x86_64_shld"
9012   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9013         (ior:DI (ashift:DI (match_dup 0)
9014                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9015                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9016                   (minus:QI (const_int 64) (match_dup 2)))))
9017    (clobber (reg:CC FLAGS_REG))]
9018   "TARGET_64BIT"
9019   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9020   [(set_attr "type" "ishift")
9021    (set_attr "prefix_0f" "1")
9022    (set_attr "mode" "DI")
9023    (set_attr "athlon_decode" "vector")
9024    (set_attr "amdfam10_decode" "vector")
9025    (set_attr "bdver1_decode" "vector")])
9026
9027 (define_insn "x86_shld"
9028   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9029         (ior:SI (ashift:SI (match_dup 0)
9030                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9031                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9032                   (minus:QI (const_int 32) (match_dup 2)))))
9033    (clobber (reg:CC FLAGS_REG))]
9034   ""
9035   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9036   [(set_attr "type" "ishift")
9037    (set_attr "prefix_0f" "1")
9038    (set_attr "mode" "SI")
9039    (set_attr "pent_pair" "np")
9040    (set_attr "athlon_decode" "vector")
9041    (set_attr "amdfam10_decode" "vector")
9042    (set_attr "bdver1_decode" "vector")])
9043
9044 (define_expand "x86_shift<mode>_adj_1"
9045   [(set (reg:CCZ FLAGS_REG)
9046         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9047                              (match_dup 4))
9048                      (const_int 0)))
9049    (set (match_operand:SWI48 0 "register_operand" "")
9050         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9051                             (match_operand:SWI48 1 "register_operand" "")
9052                             (match_dup 0)))
9053    (set (match_dup 1)
9054         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9055                             (match_operand:SWI48 3 "register_operand" "")
9056                             (match_dup 1)))]
9057   "TARGET_CMOVE"
9058   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9059
9060 (define_expand "x86_shift<mode>_adj_2"
9061   [(use (match_operand:SWI48 0 "register_operand" ""))
9062    (use (match_operand:SWI48 1 "register_operand" ""))
9063    (use (match_operand:QI 2 "register_operand" ""))]
9064   ""
9065 {
9066   rtx label = gen_label_rtx ();
9067   rtx tmp;
9068
9069   emit_insn (gen_testqi_ccz_1 (operands[2],
9070                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9071
9072   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9073   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9074   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9075                               gen_rtx_LABEL_REF (VOIDmode, label),
9076                               pc_rtx);
9077   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9078   JUMP_LABEL (tmp) = label;
9079
9080   emit_move_insn (operands[0], operands[1]);
9081   ix86_expand_clear (operands[1]);
9082
9083   emit_label (label);
9084   LABEL_NUSES (label) = 1;
9085
9086   DONE;
9087 })
9088
9089 ;; Avoid useless masking of count operand.
9090 (define_insn "*ashl<mode>3_mask"
9091   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9092         (ashift:SWI48
9093           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9094           (subreg:QI
9095             (and:SI
9096               (match_operand:SI 2 "register_operand" "c")
9097               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9098    (clobber (reg:CC FLAGS_REG))]
9099   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9100    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9101       == GET_MODE_BITSIZE (<MODE>mode)-1"
9102 {
9103   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9104 }
9105   [(set_attr "type" "ishift")
9106    (set_attr "mode" "<MODE>")])
9107
9108 (define_insn "*bmi2_ashl<mode>3_1"
9109   [(set (match_operand:SWI48 0 "register_operand" "=r")
9110         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9111                       (match_operand:SWI48 2 "register_operand" "r")))]
9112   "TARGET_BMI2"
9113   "shlx\t{%2, %1, %0|%0, %1, %2}"
9114   [(set_attr "type" "ishiftx")
9115    (set_attr "mode" "<MODE>")])
9116
9117 (define_insn "*ashl<mode>3_1"
9118   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9119         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9120                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9121    (clobber (reg:CC FLAGS_REG))]
9122   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9123 {
9124   switch (get_attr_type (insn))
9125     {
9126     case TYPE_LEA:
9127     case TYPE_ISHIFTX:
9128       return "#";
9129
9130     case TYPE_ALU:
9131       gcc_assert (operands[2] == const1_rtx);
9132       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9133       return "add{<imodesuffix>}\t%0, %0";
9134
9135     default:
9136       if (operands[2] == const1_rtx
9137           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9138         return "sal{<imodesuffix>}\t%0";
9139       else
9140         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9141     }
9142 }
9143   [(set_attr "isa" "*,*,bmi2")
9144    (set (attr "type")
9145      (cond [(eq_attr "alternative" "1")
9146               (const_string "lea")
9147             (eq_attr "alternative" "2")
9148               (const_string "ishiftx")
9149             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9150                       (match_operand 0 "register_operand" ""))
9151                  (match_operand 2 "const1_operand" ""))
9152               (const_string "alu")
9153            ]
9154            (const_string "ishift")))
9155    (set (attr "length_immediate")
9156      (if_then_else
9157        (ior (eq_attr "type" "alu")
9158             (and (eq_attr "type" "ishift")
9159                  (and (match_operand 2 "const1_operand" "")
9160                       (ior (match_test "TARGET_SHIFT1")
9161                            (match_test "optimize_function_for_size_p (cfun)")))))
9162        (const_string "0")
9163        (const_string "*")))
9164    (set_attr "mode" "<MODE>")])
9165
9166 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9167 (define_split
9168   [(set (match_operand:SWI48 0 "register_operand" "")
9169         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9170                       (match_operand:QI 2 "register_operand" "")))
9171    (clobber (reg:CC FLAGS_REG))]
9172   "TARGET_BMI2 && reload_completed"
9173   [(set (match_dup 0)
9174         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9175   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9176
9177 (define_insn "*bmi2_ashlsi3_1_zext"
9178   [(set (match_operand:DI 0 "register_operand" "=r")
9179         (zero_extend:DI
9180           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9181                      (match_operand:SI 2 "register_operand" "r"))))]
9182   "TARGET_64BIT && TARGET_BMI2"
9183   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9184   [(set_attr "type" "ishiftx")
9185    (set_attr "mode" "SI")])
9186
9187 (define_insn "*ashlsi3_1_zext"
9188   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9189         (zero_extend:DI
9190           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9191                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9192    (clobber (reg:CC FLAGS_REG))]
9193   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9194 {
9195   switch (get_attr_type (insn))
9196     {
9197     case TYPE_LEA:
9198     case TYPE_ISHIFTX:
9199       return "#";
9200
9201     case TYPE_ALU:
9202       gcc_assert (operands[2] == const1_rtx);
9203       return "add{l}\t%k0, %k0";
9204
9205     default:
9206       if (operands[2] == const1_rtx
9207           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9208         return "sal{l}\t%k0";
9209       else
9210         return "sal{l}\t{%2, %k0|%k0, %2}";
9211     }
9212 }
9213   [(set_attr "isa" "*,*,bmi2")
9214    (set (attr "type")
9215      (cond [(eq_attr "alternative" "1")
9216               (const_string "lea")
9217             (eq_attr "alternative" "2")
9218               (const_string "ishiftx")
9219             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9220                  (match_operand 2 "const1_operand" ""))
9221               (const_string "alu")
9222            ]
9223            (const_string "ishift")))
9224    (set (attr "length_immediate")
9225      (if_then_else
9226        (ior (eq_attr "type" "alu")
9227             (and (eq_attr "type" "ishift")
9228                  (and (match_operand 2 "const1_operand" "")
9229                       (ior (match_test "TARGET_SHIFT1")
9230                            (match_test "optimize_function_for_size_p (cfun)")))))
9231        (const_string "0")
9232        (const_string "*")))
9233    (set_attr "mode" "SI")])
9234
9235 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9236 (define_split
9237   [(set (match_operand:DI 0 "register_operand" "")
9238         (zero_extend:DI
9239           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9240                      (match_operand:QI 2 "register_operand" ""))))
9241    (clobber (reg:CC FLAGS_REG))]
9242   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9243   [(set (match_dup 0)
9244         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9245   "operands[2] = gen_lowpart (SImode, operands[2]);")
9246
9247 (define_insn "*ashlhi3_1"
9248   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9249         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9250                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9251    (clobber (reg:CC FLAGS_REG))]
9252   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9253 {
9254   switch (get_attr_type (insn))
9255     {
9256     case TYPE_LEA:
9257       return "#";
9258
9259     case TYPE_ALU:
9260       gcc_assert (operands[2] == const1_rtx);
9261       return "add{w}\t%0, %0";
9262
9263     default:
9264       if (operands[2] == const1_rtx
9265           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9266         return "sal{w}\t%0";
9267       else
9268         return "sal{w}\t{%2, %0|%0, %2}";
9269     }
9270 }
9271   [(set (attr "type")
9272      (cond [(eq_attr "alternative" "1")
9273               (const_string "lea")
9274             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9275                       (match_operand 0 "register_operand" ""))
9276                  (match_operand 2 "const1_operand" ""))
9277               (const_string "alu")
9278            ]
9279            (const_string "ishift")))
9280    (set (attr "length_immediate")
9281      (if_then_else
9282        (ior (eq_attr "type" "alu")
9283             (and (eq_attr "type" "ishift")
9284                  (and (match_operand 2 "const1_operand" "")
9285                       (ior (match_test "TARGET_SHIFT1")
9286                            (match_test "optimize_function_for_size_p (cfun)")))))
9287        (const_string "0")
9288        (const_string "*")))
9289    (set_attr "mode" "HI,SI")])
9290
9291 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9292 (define_insn "*ashlqi3_1"
9293   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9294         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9295                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9296    (clobber (reg:CC FLAGS_REG))]
9297   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9298 {
9299   switch (get_attr_type (insn))
9300     {
9301     case TYPE_LEA:
9302       return "#";
9303
9304     case TYPE_ALU:
9305       gcc_assert (operands[2] == const1_rtx);
9306       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9307         return "add{l}\t%k0, %k0";
9308       else
9309         return "add{b}\t%0, %0";
9310
9311     default:
9312       if (operands[2] == const1_rtx
9313           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9314         {
9315           if (get_attr_mode (insn) == MODE_SI)
9316             return "sal{l}\t%k0";
9317           else
9318             return "sal{b}\t%0";
9319         }
9320       else
9321         {
9322           if (get_attr_mode (insn) == MODE_SI)
9323             return "sal{l}\t{%2, %k0|%k0, %2}";
9324           else
9325             return "sal{b}\t{%2, %0|%0, %2}";
9326         }
9327     }
9328 }
9329   [(set (attr "type")
9330      (cond [(eq_attr "alternative" "2")
9331               (const_string "lea")
9332             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9333                       (match_operand 0 "register_operand" ""))
9334                  (match_operand 2 "const1_operand" ""))
9335               (const_string "alu")
9336            ]
9337            (const_string "ishift")))
9338    (set (attr "length_immediate")
9339      (if_then_else
9340        (ior (eq_attr "type" "alu")
9341             (and (eq_attr "type" "ishift")
9342                  (and (match_operand 2 "const1_operand" "")
9343                       (ior (match_test "TARGET_SHIFT1")
9344                            (match_test "optimize_function_for_size_p (cfun)")))))
9345        (const_string "0")
9346        (const_string "*")))
9347    (set_attr "mode" "QI,SI,SI")])
9348
9349 (define_insn "*ashlqi3_1_slp"
9350   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9351         (ashift:QI (match_dup 0)
9352                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9353    (clobber (reg:CC FLAGS_REG))]
9354   "(optimize_function_for_size_p (cfun)
9355     || !TARGET_PARTIAL_FLAG_REG_STALL
9356     || (operands[1] == const1_rtx
9357         && (TARGET_SHIFT1
9358             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9359 {
9360   switch (get_attr_type (insn))
9361     {
9362     case TYPE_ALU:
9363       gcc_assert (operands[1] == const1_rtx);
9364       return "add{b}\t%0, %0";
9365
9366     default:
9367       if (operands[1] == const1_rtx
9368           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9369         return "sal{b}\t%0";
9370       else
9371         return "sal{b}\t{%1, %0|%0, %1}";
9372     }
9373 }
9374   [(set (attr "type")
9375      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9376                       (match_operand 0 "register_operand" ""))
9377                  (match_operand 1 "const1_operand" ""))
9378               (const_string "alu")
9379            ]
9380            (const_string "ishift1")))
9381    (set (attr "length_immediate")
9382      (if_then_else
9383        (ior (eq_attr "type" "alu")
9384             (and (eq_attr "type" "ishift1")
9385                  (and (match_operand 1 "const1_operand" "")
9386                       (ior (match_test "TARGET_SHIFT1")
9387                            (match_test "optimize_function_for_size_p (cfun)")))))
9388        (const_string "0")
9389        (const_string "*")))
9390    (set_attr "mode" "QI")])
9391
9392 ;; Convert ashift to the lea pattern to avoid flags dependency.
9393 (define_split
9394   [(set (match_operand 0 "register_operand" "")
9395         (ashift (match_operand 1 "index_register_operand" "")
9396                 (match_operand:QI 2 "const_int_operand" "")))
9397    (clobber (reg:CC FLAGS_REG))]
9398   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9399    && reload_completed
9400    && true_regnum (operands[0]) != true_regnum (operands[1])"
9401   [(const_int 0)]
9402 {
9403   enum machine_mode mode = GET_MODE (operands[0]);
9404   rtx pat;
9405
9406   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9407     { 
9408       mode = SImode; 
9409       operands[0] = gen_lowpart (mode, operands[0]);
9410       operands[1] = gen_lowpart (mode, operands[1]);
9411     }
9412
9413   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9414
9415   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9416
9417   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9418   DONE;
9419 })
9420
9421 ;; Convert ashift to the lea pattern to avoid flags dependency.
9422 (define_split
9423   [(set (match_operand:DI 0 "register_operand" "")
9424         (zero_extend:DI
9425           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9426                      (match_operand:QI 2 "const_int_operand" ""))))
9427    (clobber (reg:CC FLAGS_REG))]
9428   "TARGET_64BIT && reload_completed
9429    && true_regnum (operands[0]) != true_regnum (operands[1])"
9430   [(set (match_dup 0)
9431         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9432 {
9433   operands[1] = gen_lowpart (DImode, operands[1]);
9434   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9435 })
9436
9437 ;; This pattern can't accept a variable shift count, since shifts by
9438 ;; zero don't affect the flags.  We assume that shifts by constant
9439 ;; zero are optimized away.
9440 (define_insn "*ashl<mode>3_cmp"
9441   [(set (reg FLAGS_REG)
9442         (compare
9443           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9444                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9445           (const_int 0)))
9446    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9447         (ashift:SWI (match_dup 1) (match_dup 2)))]
9448   "(optimize_function_for_size_p (cfun)
9449     || !TARGET_PARTIAL_FLAG_REG_STALL
9450     || (operands[2] == const1_rtx
9451         && (TARGET_SHIFT1
9452             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9453    && ix86_match_ccmode (insn, CCGOCmode)
9454    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9455 {
9456   switch (get_attr_type (insn))
9457     {
9458     case TYPE_ALU:
9459       gcc_assert (operands[2] == const1_rtx);
9460       return "add{<imodesuffix>}\t%0, %0";
9461
9462     default:
9463       if (operands[2] == const1_rtx
9464           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9465         return "sal{<imodesuffix>}\t%0";
9466       else
9467         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9468     }
9469 }
9470   [(set (attr "type")
9471      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9472                       (match_operand 0 "register_operand" ""))
9473                  (match_operand 2 "const1_operand" ""))
9474               (const_string "alu")
9475            ]
9476            (const_string "ishift")))
9477    (set (attr "length_immediate")
9478      (if_then_else
9479        (ior (eq_attr "type" "alu")
9480             (and (eq_attr "type" "ishift")
9481                  (and (match_operand 2 "const1_operand" "")
9482                       (ior (match_test "TARGET_SHIFT1")
9483                            (match_test "optimize_function_for_size_p (cfun)")))))
9484        (const_string "0")
9485        (const_string "*")))
9486    (set_attr "mode" "<MODE>")])
9487
9488 (define_insn "*ashlsi3_cmp_zext"
9489   [(set (reg FLAGS_REG)
9490         (compare
9491           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9492                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9493           (const_int 0)))
9494    (set (match_operand:DI 0 "register_operand" "=r")
9495         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9496   "TARGET_64BIT
9497    && (optimize_function_for_size_p (cfun)
9498        || !TARGET_PARTIAL_FLAG_REG_STALL
9499        || (operands[2] == const1_rtx
9500            && (TARGET_SHIFT1
9501                || TARGET_DOUBLE_WITH_ADD)))
9502    && ix86_match_ccmode (insn, CCGOCmode)
9503    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9504 {
9505   switch (get_attr_type (insn))
9506     {
9507     case TYPE_ALU:
9508       gcc_assert (operands[2] == const1_rtx);
9509       return "add{l}\t%k0, %k0";
9510
9511     default:
9512       if (operands[2] == const1_rtx
9513           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9514         return "sal{l}\t%k0";
9515       else
9516         return "sal{l}\t{%2, %k0|%k0, %2}";
9517     }
9518 }
9519   [(set (attr "type")
9520      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9521                  (match_operand 2 "const1_operand" ""))
9522               (const_string "alu")
9523            ]
9524            (const_string "ishift")))
9525    (set (attr "length_immediate")
9526      (if_then_else
9527        (ior (eq_attr "type" "alu")
9528             (and (eq_attr "type" "ishift")
9529                  (and (match_operand 2 "const1_operand" "")
9530                       (ior (match_test "TARGET_SHIFT1")
9531                            (match_test "optimize_function_for_size_p (cfun)")))))
9532        (const_string "0")
9533        (const_string "*")))
9534    (set_attr "mode" "SI")])
9535
9536 (define_insn "*ashl<mode>3_cconly"
9537   [(set (reg FLAGS_REG)
9538         (compare
9539           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9540                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9541           (const_int 0)))
9542    (clobber (match_scratch:SWI 0 "=<r>"))]
9543   "(optimize_function_for_size_p (cfun)
9544     || !TARGET_PARTIAL_FLAG_REG_STALL
9545     || (operands[2] == const1_rtx
9546         && (TARGET_SHIFT1
9547             || TARGET_DOUBLE_WITH_ADD)))
9548    && ix86_match_ccmode (insn, CCGOCmode)"
9549 {
9550   switch (get_attr_type (insn))
9551     {
9552     case TYPE_ALU:
9553       gcc_assert (operands[2] == const1_rtx);
9554       return "add{<imodesuffix>}\t%0, %0";
9555
9556     default:
9557       if (operands[2] == const1_rtx
9558           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9559         return "sal{<imodesuffix>}\t%0";
9560       else
9561         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9562     }
9563 }
9564   [(set (attr "type")
9565      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9566                       (match_operand 0 "register_operand" ""))
9567                  (match_operand 2 "const1_operand" ""))
9568               (const_string "alu")
9569            ]
9570            (const_string "ishift")))
9571    (set (attr "length_immediate")
9572      (if_then_else
9573        (ior (eq_attr "type" "alu")
9574             (and (eq_attr "type" "ishift")
9575                  (and (match_operand 2 "const1_operand" "")
9576                       (ior (match_test "TARGET_SHIFT1")
9577                            (match_test "optimize_function_for_size_p (cfun)")))))
9578        (const_string "0")
9579        (const_string "*")))
9580    (set_attr "mode" "<MODE>")])
9581
9582 ;; See comment above `ashl<mode>3' about how this works.
9583
9584 (define_expand "<shift_insn><mode>3"
9585   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9586         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9587                            (match_operand:QI 2 "nonmemory_operand" "")))]
9588   ""
9589   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9590
9591 ;; Avoid useless masking of count operand.
9592 (define_insn "*<shift_insn><mode>3_mask"
9593   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9594         (any_shiftrt:SWI48
9595           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9596           (subreg:QI
9597             (and:SI
9598               (match_operand:SI 2 "register_operand" "c")
9599               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9600    (clobber (reg:CC FLAGS_REG))]
9601   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9602    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9603       == GET_MODE_BITSIZE (<MODE>mode)-1"
9604 {
9605   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9606 }
9607   [(set_attr "type" "ishift")
9608    (set_attr "mode" "<MODE>")])
9609
9610 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9611   [(set (match_operand:DWI 0 "register_operand" "=r")
9612         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9613                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9614    (clobber (reg:CC FLAGS_REG))]
9615   ""
9616   "#"
9617   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9618   [(const_int 0)]
9619   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9620   [(set_attr "type" "multi")])
9621
9622 ;; By default we don't ask for a scratch register, because when DWImode
9623 ;; values are manipulated, registers are already at a premium.  But if
9624 ;; we have one handy, we won't turn it away.
9625
9626 (define_peephole2
9627   [(match_scratch:DWIH 3 "r")
9628    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9629                    (any_shiftrt:<DWI>
9630                      (match_operand:<DWI> 1 "register_operand" "")
9631                      (match_operand:QI 2 "nonmemory_operand" "")))
9632               (clobber (reg:CC FLAGS_REG))])
9633    (match_dup 3)]
9634   "TARGET_CMOVE"
9635   [(const_int 0)]
9636   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9637
9638 (define_insn "x86_64_shrd"
9639   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9640         (ior:DI (ashiftrt:DI (match_dup 0)
9641                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9642                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9643                   (minus:QI (const_int 64) (match_dup 2)))))
9644    (clobber (reg:CC FLAGS_REG))]
9645   "TARGET_64BIT"
9646   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9647   [(set_attr "type" "ishift")
9648    (set_attr "prefix_0f" "1")
9649    (set_attr "mode" "DI")
9650    (set_attr "athlon_decode" "vector")
9651    (set_attr "amdfam10_decode" "vector")
9652    (set_attr "bdver1_decode" "vector")])
9653
9654 (define_insn "x86_shrd"
9655   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9656         (ior:SI (ashiftrt:SI (match_dup 0)
9657                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9658                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9659                   (minus:QI (const_int 32) (match_dup 2)))))
9660    (clobber (reg:CC FLAGS_REG))]
9661   ""
9662   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9663   [(set_attr "type" "ishift")
9664    (set_attr "prefix_0f" "1")
9665    (set_attr "mode" "SI")
9666    (set_attr "pent_pair" "np")
9667    (set_attr "athlon_decode" "vector")
9668    (set_attr "amdfam10_decode" "vector")
9669    (set_attr "bdver1_decode" "vector")])
9670
9671 (define_insn "ashrdi3_cvt"
9672   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9673         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9674                      (match_operand:QI 2 "const_int_operand" "")))
9675    (clobber (reg:CC FLAGS_REG))]
9676   "TARGET_64BIT && INTVAL (operands[2]) == 63
9677    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9678    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9679   "@
9680    {cqto|cqo}
9681    sar{q}\t{%2, %0|%0, %2}"
9682   [(set_attr "type" "imovx,ishift")
9683    (set_attr "prefix_0f" "0,*")
9684    (set_attr "length_immediate" "0,*")
9685    (set_attr "modrm" "0,1")
9686    (set_attr "mode" "DI")])
9687
9688 (define_insn "ashrsi3_cvt"
9689   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9690         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9691                      (match_operand:QI 2 "const_int_operand" "")))
9692    (clobber (reg:CC FLAGS_REG))]
9693   "INTVAL (operands[2]) == 31
9694    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9695    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9696   "@
9697    {cltd|cdq}
9698    sar{l}\t{%2, %0|%0, %2}"
9699   [(set_attr "type" "imovx,ishift")
9700    (set_attr "prefix_0f" "0,*")
9701    (set_attr "length_immediate" "0,*")
9702    (set_attr "modrm" "0,1")
9703    (set_attr "mode" "SI")])
9704
9705 (define_insn "*ashrsi3_cvt_zext"
9706   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9707         (zero_extend:DI
9708           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9709                        (match_operand:QI 2 "const_int_operand" ""))))
9710    (clobber (reg:CC FLAGS_REG))]
9711   "TARGET_64BIT && INTVAL (operands[2]) == 31
9712    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9713    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9714   "@
9715    {cltd|cdq}
9716    sar{l}\t{%2, %k0|%k0, %2}"
9717   [(set_attr "type" "imovx,ishift")
9718    (set_attr "prefix_0f" "0,*")
9719    (set_attr "length_immediate" "0,*")
9720    (set_attr "modrm" "0,1")
9721    (set_attr "mode" "SI")])
9722
9723 (define_expand "x86_shift<mode>_adj_3"
9724   [(use (match_operand:SWI48 0 "register_operand" ""))
9725    (use (match_operand:SWI48 1 "register_operand" ""))
9726    (use (match_operand:QI 2 "register_operand" ""))]
9727   ""
9728 {
9729   rtx label = gen_label_rtx ();
9730   rtx tmp;
9731
9732   emit_insn (gen_testqi_ccz_1 (operands[2],
9733                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9734
9735   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9736   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9737   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9738                               gen_rtx_LABEL_REF (VOIDmode, label),
9739                               pc_rtx);
9740   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9741   JUMP_LABEL (tmp) = label;
9742
9743   emit_move_insn (operands[0], operands[1]);
9744   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9745                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9746   emit_label (label);
9747   LABEL_NUSES (label) = 1;
9748
9749   DONE;
9750 })
9751
9752 (define_insn "*bmi2_<shift_insn><mode>3_1"
9753   [(set (match_operand:SWI48 0 "register_operand" "=r")
9754         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9755                            (match_operand:SWI48 2 "register_operand" "r")))]
9756   "TARGET_BMI2"
9757   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9758   [(set_attr "type" "ishiftx")
9759    (set_attr "mode" "<MODE>")])
9760
9761 (define_insn "*<shift_insn><mode>3_1"
9762   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9763         (any_shiftrt:SWI48
9764           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9765           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9766    (clobber (reg:CC FLAGS_REG))]
9767   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9768 {
9769   switch (get_attr_type (insn))
9770     {
9771     case TYPE_ISHIFTX:
9772       return "#";
9773
9774     default:
9775       if (operands[2] == const1_rtx
9776           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9777         return "<shift>{<imodesuffix>}\t%0";
9778       else
9779         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9780     }
9781 }
9782   [(set_attr "isa" "*,bmi2")
9783    (set_attr "type" "ishift,ishiftx")
9784    (set (attr "length_immediate")
9785      (if_then_else
9786        (and (match_operand 2 "const1_operand" "")
9787             (ior (match_test "TARGET_SHIFT1")
9788                  (match_test "optimize_function_for_size_p (cfun)")))
9789        (const_string "0")
9790        (const_string "*")))
9791    (set_attr "mode" "<MODE>")])
9792
9793 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9794 (define_split
9795   [(set (match_operand:SWI48 0 "register_operand" "")
9796         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9797                            (match_operand:QI 2 "register_operand" "")))
9798    (clobber (reg:CC FLAGS_REG))]
9799   "TARGET_BMI2 && reload_completed"
9800   [(set (match_dup 0)
9801         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9802   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9803
9804 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9805   [(set (match_operand:DI 0 "register_operand" "=r")
9806         (zero_extend:DI
9807           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9808                           (match_operand:SI 2 "register_operand" "r"))))]
9809   "TARGET_64BIT && TARGET_BMI2"
9810   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9811   [(set_attr "type" "ishiftx")
9812    (set_attr "mode" "SI")])
9813
9814 (define_insn "*<shift_insn>si3_1_zext"
9815   [(set (match_operand:DI 0 "register_operand" "=r,r")
9816         (zero_extend:DI
9817           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9818                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9819    (clobber (reg:CC FLAGS_REG))]
9820   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9821 {
9822   switch (get_attr_type (insn))
9823     {
9824     case TYPE_ISHIFTX:
9825       return "#";
9826
9827     default:
9828       if (operands[2] == const1_rtx
9829           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9830         return "<shift>{l}\t%k0";
9831       else
9832         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9833     }
9834 }
9835   [(set_attr "isa" "*,bmi2")
9836    (set_attr "type" "ishift,ishiftx")
9837    (set (attr "length_immediate")
9838      (if_then_else
9839        (and (match_operand 2 "const1_operand" "")
9840             (ior (match_test "TARGET_SHIFT1")
9841                  (match_test "optimize_function_for_size_p (cfun)")))
9842        (const_string "0")
9843        (const_string "*")))
9844    (set_attr "mode" "SI")])
9845
9846 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9847 (define_split
9848   [(set (match_operand:DI 0 "register_operand" "")
9849         (zero_extend:DI
9850           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9851                           (match_operand:QI 2 "register_operand" ""))))
9852    (clobber (reg:CC FLAGS_REG))]
9853   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9854   [(set (match_dup 0)
9855         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9856   "operands[2] = gen_lowpart (SImode, operands[2]);")
9857
9858 (define_insn "*<shift_insn><mode>3_1"
9859   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9860         (any_shiftrt:SWI12
9861           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9862           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9863    (clobber (reg:CC FLAGS_REG))]
9864   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9865 {
9866   if (operands[2] == const1_rtx
9867       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9868     return "<shift>{<imodesuffix>}\t%0";
9869   else
9870     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9871 }
9872   [(set_attr "type" "ishift")
9873    (set (attr "length_immediate")
9874      (if_then_else
9875        (and (match_operand 2 "const1_operand" "")
9876             (ior (match_test "TARGET_SHIFT1")
9877                  (match_test "optimize_function_for_size_p (cfun)")))
9878        (const_string "0")
9879        (const_string "*")))
9880    (set_attr "mode" "<MODE>")])
9881
9882 (define_insn "*<shift_insn>qi3_1_slp"
9883   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9884         (any_shiftrt:QI (match_dup 0)
9885                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9886    (clobber (reg:CC FLAGS_REG))]
9887   "(optimize_function_for_size_p (cfun)
9888     || !TARGET_PARTIAL_REG_STALL
9889     || (operands[1] == const1_rtx
9890         && TARGET_SHIFT1))"
9891 {
9892   if (operands[1] == const1_rtx
9893       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9894     return "<shift>{b}\t%0";
9895   else
9896     return "<shift>{b}\t{%1, %0|%0, %1}";
9897 }
9898   [(set_attr "type" "ishift1")
9899    (set (attr "length_immediate")
9900      (if_then_else
9901        (and (match_operand 1 "const1_operand" "")
9902             (ior (match_test "TARGET_SHIFT1")
9903                  (match_test "optimize_function_for_size_p (cfun)")))
9904        (const_string "0")
9905        (const_string "*")))
9906    (set_attr "mode" "QI")])
9907
9908 ;; This pattern can't accept a variable shift count, since shifts by
9909 ;; zero don't affect the flags.  We assume that shifts by constant
9910 ;; zero are optimized away.
9911 (define_insn "*<shift_insn><mode>3_cmp"
9912   [(set (reg FLAGS_REG)
9913         (compare
9914           (any_shiftrt:SWI
9915             (match_operand:SWI 1 "nonimmediate_operand" "0")
9916             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9917           (const_int 0)))
9918    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9919         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9920   "(optimize_function_for_size_p (cfun)
9921     || !TARGET_PARTIAL_FLAG_REG_STALL
9922     || (operands[2] == const1_rtx
9923         && TARGET_SHIFT1))
9924    && ix86_match_ccmode (insn, CCGOCmode)
9925    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9926 {
9927   if (operands[2] == const1_rtx
9928       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9929     return "<shift>{<imodesuffix>}\t%0";
9930   else
9931     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9932 }
9933   [(set_attr "type" "ishift")
9934    (set (attr "length_immediate")
9935      (if_then_else
9936        (and (match_operand 2 "const1_operand" "")
9937             (ior (match_test "TARGET_SHIFT1")
9938                  (match_test "optimize_function_for_size_p (cfun)")))
9939        (const_string "0")
9940        (const_string "*")))
9941    (set_attr "mode" "<MODE>")])
9942
9943 (define_insn "*<shift_insn>si3_cmp_zext"
9944   [(set (reg FLAGS_REG)
9945         (compare
9946           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9947                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9948           (const_int 0)))
9949    (set (match_operand:DI 0 "register_operand" "=r")
9950         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9951   "TARGET_64BIT
9952    && (optimize_function_for_size_p (cfun)
9953        || !TARGET_PARTIAL_FLAG_REG_STALL
9954        || (operands[2] == const1_rtx
9955            && TARGET_SHIFT1))
9956    && ix86_match_ccmode (insn, CCGOCmode)
9957    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9958 {
9959   if (operands[2] == const1_rtx
9960       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9961     return "<shift>{l}\t%k0";
9962   else
9963     return "<shift>{l}\t{%2, %k0|%k0, %2}";
9964 }
9965   [(set_attr "type" "ishift")
9966    (set (attr "length_immediate")
9967      (if_then_else
9968        (and (match_operand 2 "const1_operand" "")
9969             (ior (match_test "TARGET_SHIFT1")
9970                  (match_test "optimize_function_for_size_p (cfun)")))
9971        (const_string "0")
9972        (const_string "*")))
9973    (set_attr "mode" "SI")])
9974
9975 (define_insn "*<shift_insn><mode>3_cconly"
9976   [(set (reg FLAGS_REG)
9977         (compare
9978           (any_shiftrt:SWI
9979             (match_operand:SWI 1 "register_operand" "0")
9980             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9981           (const_int 0)))
9982    (clobber (match_scratch:SWI 0 "=<r>"))]
9983   "(optimize_function_for_size_p (cfun)
9984     || !TARGET_PARTIAL_FLAG_REG_STALL
9985     || (operands[2] == const1_rtx
9986         && TARGET_SHIFT1))
9987    && ix86_match_ccmode (insn, CCGOCmode)"
9988 {
9989   if (operands[2] == const1_rtx
9990       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9991     return "<shift>{<imodesuffix>}\t%0";
9992   else
9993     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9994 }
9995   [(set_attr "type" "ishift")
9996    (set (attr "length_immediate")
9997      (if_then_else
9998        (and (match_operand 2 "const1_operand" "")
9999             (ior (match_test "TARGET_SHIFT1")
10000                  (match_test "optimize_function_for_size_p (cfun)")))
10001        (const_string "0")
10002        (const_string "*")))
10003    (set_attr "mode" "<MODE>")])
10004 \f
10005 ;; Rotate instructions
10006
10007 (define_expand "<rotate_insn>ti3"
10008   [(set (match_operand:TI 0 "register_operand" "")
10009         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10010                        (match_operand:QI 2 "nonmemory_operand" "")))]
10011   "TARGET_64BIT"
10012 {
10013   if (const_1_to_63_operand (operands[2], VOIDmode))
10014     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10015                 (operands[0], operands[1], operands[2]));
10016   else
10017     FAIL;
10018
10019   DONE;
10020 })
10021
10022 (define_expand "<rotate_insn>di3"
10023   [(set (match_operand:DI 0 "shiftdi_operand" "")
10024         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10025                        (match_operand:QI 2 "nonmemory_operand" "")))]
10026  ""
10027 {
10028   if (TARGET_64BIT)
10029     ix86_expand_binary_operator (<CODE>, DImode, operands);
10030   else if (const_1_to_31_operand (operands[2], VOIDmode))
10031     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10032                 (operands[0], operands[1], operands[2]));
10033   else
10034     FAIL;
10035
10036   DONE;
10037 })
10038
10039 (define_expand "<rotate_insn><mode>3"
10040   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10041         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10042                             (match_operand:QI 2 "nonmemory_operand" "")))]
10043   ""
10044   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10045
10046 ;; Avoid useless masking of count operand.
10047 (define_insn "*<rotate_insn><mode>3_mask"
10048   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10049         (any_rotate:SWI48
10050           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10051           (subreg:QI
10052             (and:SI
10053               (match_operand:SI 2 "register_operand" "c")
10054               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10055    (clobber (reg:CC FLAGS_REG))]
10056   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10057    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10058       == GET_MODE_BITSIZE (<MODE>mode)-1"
10059 {
10060   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10061 }
10062   [(set_attr "type" "rotate")
10063    (set_attr "mode" "<MODE>")])
10064
10065 ;; Implement rotation using two double-precision
10066 ;; shift instructions and a scratch register.
10067
10068 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10069  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10070        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10071                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10072   (clobber (reg:CC FLAGS_REG))
10073   (clobber (match_scratch:DWIH 3 "=&r"))]
10074  ""
10075  "#"
10076  "reload_completed"
10077  [(set (match_dup 3) (match_dup 4))
10078   (parallel
10079    [(set (match_dup 4)
10080          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10081                    (lshiftrt:DWIH (match_dup 5)
10082                                   (minus:QI (match_dup 6) (match_dup 2)))))
10083     (clobber (reg:CC FLAGS_REG))])
10084   (parallel
10085    [(set (match_dup 5)
10086          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10087                    (lshiftrt:DWIH (match_dup 3)
10088                                   (minus:QI (match_dup 6) (match_dup 2)))))
10089     (clobber (reg:CC FLAGS_REG))])]
10090 {
10091   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10092
10093   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10094 })
10095
10096 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10097  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10098        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10099                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10100   (clobber (reg:CC FLAGS_REG))
10101   (clobber (match_scratch:DWIH 3 "=&r"))]
10102  ""
10103  "#"
10104  "reload_completed"
10105  [(set (match_dup 3) (match_dup 4))
10106   (parallel
10107    [(set (match_dup 4)
10108          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10109                    (ashift:DWIH (match_dup 5)
10110                                 (minus:QI (match_dup 6) (match_dup 2)))))
10111     (clobber (reg:CC FLAGS_REG))])
10112   (parallel
10113    [(set (match_dup 5)
10114          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10115                    (ashift:DWIH (match_dup 3)
10116                                 (minus:QI (match_dup 6) (match_dup 2)))))
10117     (clobber (reg:CC FLAGS_REG))])]
10118 {
10119   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10120
10121   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10122 })
10123
10124 (define_insn "*bmi2_rorx<mode>3_1"
10125   [(set (match_operand:SWI48 0 "register_operand" "=r")
10126         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10127                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10128   "TARGET_BMI2"
10129   "rorx\t{%2, %1, %0|%0, %1, %2}"
10130   [(set_attr "type" "rotatex")
10131    (set_attr "mode" "<MODE>")])
10132
10133 (define_insn "*<rotate_insn><mode>3_1"
10134   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10135         (any_rotate:SWI48
10136           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10137           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10138    (clobber (reg:CC FLAGS_REG))]
10139   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10140 {
10141   switch (get_attr_type (insn))
10142     {
10143     case TYPE_ROTATEX:
10144       return "#";
10145
10146     default:
10147       if (operands[2] == const1_rtx
10148           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10149         return "<rotate>{<imodesuffix>}\t%0";
10150       else
10151         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10152     }
10153 }
10154   [(set_attr "isa" "*,bmi2")
10155    (set_attr "type" "rotate,rotatex")
10156    (set (attr "length_immediate")
10157      (if_then_else
10158        (and (eq_attr "type" "rotate")
10159             (and (match_operand 2 "const1_operand" "")
10160                  (ior (match_test "TARGET_SHIFT1")
10161                       (match_test "optimize_function_for_size_p (cfun)"))))
10162        (const_string "0")
10163        (const_string "*")))
10164    (set_attr "mode" "<MODE>")])
10165
10166 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10167 (define_split
10168   [(set (match_operand:SWI48 0 "register_operand" "")
10169         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10170                       (match_operand:QI 2 "immediate_operand" "")))
10171    (clobber (reg:CC FLAGS_REG))]
10172   "TARGET_BMI2 && reload_completed"
10173   [(set (match_dup 0)
10174         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10175 {
10176   operands[2]
10177     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10178 })
10179
10180 (define_split
10181   [(set (match_operand:SWI48 0 "register_operand" "")
10182         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10183                         (match_operand:QI 2 "immediate_operand" "")))
10184    (clobber (reg:CC FLAGS_REG))]
10185   "TARGET_BMI2 && reload_completed"
10186   [(set (match_dup 0)
10187         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10188
10189 (define_insn "*bmi2_rorxsi3_1_zext"
10190   [(set (match_operand:DI 0 "register_operand" "=r")
10191         (zero_extend:DI
10192           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10193                        (match_operand:QI 2 "immediate_operand" "I"))))]
10194   "TARGET_64BIT && TARGET_BMI2"
10195   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10196   [(set_attr "type" "rotatex")
10197    (set_attr "mode" "SI")])
10198
10199 (define_insn "*<rotate_insn>si3_1_zext"
10200   [(set (match_operand:DI 0 "register_operand" "=r,r")
10201         (zero_extend:DI
10202           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10203                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10204    (clobber (reg:CC FLAGS_REG))]
10205   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10206 {
10207   switch (get_attr_type (insn))
10208     {
10209     case TYPE_ROTATEX:
10210       return "#";
10211
10212     default:
10213       if (operands[2] == const1_rtx
10214           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10215         return "<rotate>{l}\t%k0";
10216       else
10217         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10218     }
10219 }
10220   [(set_attr "isa" "*,bmi2")
10221    (set_attr "type" "rotate,rotatex")
10222    (set (attr "length_immediate")
10223      (if_then_else
10224        (and (eq_attr "type" "rotate")
10225             (and (match_operand 2 "const1_operand" "")
10226                  (ior (match_test "TARGET_SHIFT1")
10227                       (match_test "optimize_function_for_size_p (cfun)"))))
10228        (const_string "0")
10229        (const_string "*")))
10230    (set_attr "mode" "SI")])
10231
10232 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10233 (define_split
10234   [(set (match_operand:DI 0 "register_operand" "")
10235         (zero_extend:DI
10236           (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10237                      (match_operand:QI 2 "immediate_operand" ""))))
10238    (clobber (reg:CC FLAGS_REG))]
10239   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10240   [(set (match_dup 0)
10241         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10242 {
10243   operands[2]
10244     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10245 })
10246
10247 (define_split
10248   [(set (match_operand:DI 0 "register_operand" "")
10249         (zero_extend:DI
10250           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10251                        (match_operand:QI 2 "immediate_operand" ""))))
10252    (clobber (reg:CC FLAGS_REG))]
10253   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10254   [(set (match_dup 0)
10255         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10256
10257 (define_insn "*<rotate_insn><mode>3_1"
10258   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10259         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10260                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10261    (clobber (reg:CC FLAGS_REG))]
10262   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10263 {
10264   if (operands[2] == const1_rtx
10265       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10266     return "<rotate>{<imodesuffix>}\t%0";
10267   else
10268     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10269 }
10270   [(set_attr "type" "rotate")
10271    (set (attr "length_immediate")
10272      (if_then_else
10273        (and (match_operand 2 "const1_operand" "")
10274             (ior (match_test "TARGET_SHIFT1")
10275                  (match_test "optimize_function_for_size_p (cfun)")))
10276        (const_string "0")
10277        (const_string "*")))
10278    (set_attr "mode" "<MODE>")])
10279
10280 (define_insn "*<rotate_insn>qi3_1_slp"
10281   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10282         (any_rotate:QI (match_dup 0)
10283                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10284    (clobber (reg:CC FLAGS_REG))]
10285   "(optimize_function_for_size_p (cfun)
10286     || !TARGET_PARTIAL_REG_STALL
10287     || (operands[1] == const1_rtx
10288         && TARGET_SHIFT1))"
10289 {
10290   if (operands[1] == const1_rtx
10291       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10292     return "<rotate>{b}\t%0";
10293   else
10294     return "<rotate>{b}\t{%1, %0|%0, %1}";
10295 }
10296   [(set_attr "type" "rotate1")
10297    (set (attr "length_immediate")
10298      (if_then_else
10299        (and (match_operand 1 "const1_operand" "")
10300             (ior (match_test "TARGET_SHIFT1")
10301                  (match_test "optimize_function_for_size_p (cfun)")))
10302        (const_string "0")
10303        (const_string "*")))
10304    (set_attr "mode" "QI")])
10305
10306 (define_split
10307  [(set (match_operand:HI 0 "register_operand" "")
10308        (any_rotate:HI (match_dup 0) (const_int 8)))
10309   (clobber (reg:CC FLAGS_REG))]
10310  "reload_completed
10311   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10312  [(parallel [(set (strict_low_part (match_dup 0))
10313                   (bswap:HI (match_dup 0)))
10314              (clobber (reg:CC FLAGS_REG))])])
10315 \f
10316 ;; Bit set / bit test instructions
10317
10318 (define_expand "extv"
10319   [(set (match_operand:SI 0 "register_operand" "")
10320         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10321                          (match_operand:SI 2 "const8_operand" "")
10322                          (match_operand:SI 3 "const8_operand" "")))]
10323   ""
10324 {
10325   /* Handle extractions from %ah et al.  */
10326   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10327     FAIL;
10328
10329   /* From mips.md: extract_bit_field doesn't verify that our source
10330      matches the predicate, so check it again here.  */
10331   if (! ext_register_operand (operands[1], VOIDmode))
10332     FAIL;
10333 })
10334
10335 (define_expand "extzv"
10336   [(set (match_operand:SI 0 "register_operand" "")
10337         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10338                          (match_operand:SI 2 "const8_operand" "")
10339                          (match_operand:SI 3 "const8_operand" "")))]
10340   ""
10341 {
10342   /* Handle extractions from %ah et al.  */
10343   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10344     FAIL;
10345
10346   /* From mips.md: extract_bit_field doesn't verify that our source
10347      matches the predicate, so check it again here.  */
10348   if (! ext_register_operand (operands[1], VOIDmode))
10349     FAIL;
10350 })
10351
10352 (define_expand "insv"
10353   [(set (zero_extract (match_operand 0 "register_operand" "")
10354                       (match_operand 1 "const_int_operand" "")
10355                       (match_operand 2 "const_int_operand" ""))
10356         (match_operand 3 "register_operand" ""))]
10357   ""
10358 {
10359   rtx (*gen_mov_insv_1) (rtx, rtx);
10360
10361   if (ix86_expand_pinsr (operands))
10362     DONE;
10363
10364   /* Handle insertions to %ah et al.  */
10365   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10366     FAIL;
10367
10368   /* From mips.md: insert_bit_field doesn't verify that our source
10369      matches the predicate, so check it again here.  */
10370   if (! ext_register_operand (operands[0], VOIDmode))
10371     FAIL;
10372
10373   gen_mov_insv_1 = (TARGET_64BIT
10374                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10375
10376   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10377   DONE;
10378 })
10379
10380 ;; %%% bts, btr, btc, bt.
10381 ;; In general these instructions are *slow* when applied to memory,
10382 ;; since they enforce atomic operation.  When applied to registers,
10383 ;; it depends on the cpu implementation.  They're never faster than
10384 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10385 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10386 ;; within the instruction itself, so operating on bits in the high
10387 ;; 32-bits of a register becomes easier.
10388 ;;
10389 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10390 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10391 ;; negdf respectively, so they can never be disabled entirely.
10392
10393 (define_insn "*btsq"
10394   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10395                          (const_int 1)
10396                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10397         (const_int 1))
10398    (clobber (reg:CC FLAGS_REG))]
10399   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10400   "bts{q}\t{%1, %0|%0, %1}"
10401   [(set_attr "type" "alu1")
10402    (set_attr "prefix_0f" "1")
10403    (set_attr "mode" "DI")])
10404
10405 (define_insn "*btrq"
10406   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10407                          (const_int 1)
10408                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10409         (const_int 0))
10410    (clobber (reg:CC FLAGS_REG))]
10411   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10412   "btr{q}\t{%1, %0|%0, %1}"
10413   [(set_attr "type" "alu1")
10414    (set_attr "prefix_0f" "1")
10415    (set_attr "mode" "DI")])
10416
10417 (define_insn "*btcq"
10418   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10419                          (const_int 1)
10420                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10421         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10422    (clobber (reg:CC FLAGS_REG))]
10423   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10424   "btc{q}\t{%1, %0|%0, %1}"
10425   [(set_attr "type" "alu1")
10426    (set_attr "prefix_0f" "1")
10427    (set_attr "mode" "DI")])
10428
10429 ;; Allow Nocona to avoid these instructions if a register is available.
10430
10431 (define_peephole2
10432   [(match_scratch:DI 2 "r")
10433    (parallel [(set (zero_extract:DI
10434                      (match_operand:DI 0 "register_operand" "")
10435                      (const_int 1)
10436                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10437                    (const_int 1))
10438               (clobber (reg:CC FLAGS_REG))])]
10439   "TARGET_64BIT && !TARGET_USE_BT"
10440   [(const_int 0)]
10441 {
10442   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10443   rtx op1;
10444
10445   if (HOST_BITS_PER_WIDE_INT >= 64)
10446     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10447   else if (i < HOST_BITS_PER_WIDE_INT)
10448     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10449   else
10450     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10451
10452   op1 = immed_double_const (lo, hi, DImode);
10453   if (i >= 31)
10454     {
10455       emit_move_insn (operands[2], op1);
10456       op1 = operands[2];
10457     }
10458
10459   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10460   DONE;
10461 })
10462
10463 (define_peephole2
10464   [(match_scratch:DI 2 "r")
10465    (parallel [(set (zero_extract:DI
10466                      (match_operand:DI 0 "register_operand" "")
10467                      (const_int 1)
10468                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10469                    (const_int 0))
10470               (clobber (reg:CC FLAGS_REG))])]
10471   "TARGET_64BIT && !TARGET_USE_BT"
10472   [(const_int 0)]
10473 {
10474   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10475   rtx op1;
10476
10477   if (HOST_BITS_PER_WIDE_INT >= 64)
10478     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10479   else if (i < HOST_BITS_PER_WIDE_INT)
10480     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10481   else
10482     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10483
10484   op1 = immed_double_const (~lo, ~hi, DImode);
10485   if (i >= 32)
10486     {
10487       emit_move_insn (operands[2], op1);
10488       op1 = operands[2];
10489     }
10490
10491   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10492   DONE;
10493 })
10494
10495 (define_peephole2
10496   [(match_scratch:DI 2 "r")
10497    (parallel [(set (zero_extract:DI
10498                      (match_operand:DI 0 "register_operand" "")
10499                      (const_int 1)
10500                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10501               (not:DI (zero_extract:DI
10502                         (match_dup 0) (const_int 1) (match_dup 1))))
10503               (clobber (reg:CC FLAGS_REG))])]
10504   "TARGET_64BIT && !TARGET_USE_BT"
10505   [(const_int 0)]
10506 {
10507   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10508   rtx op1;
10509
10510   if (HOST_BITS_PER_WIDE_INT >= 64)
10511     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10512   else if (i < HOST_BITS_PER_WIDE_INT)
10513     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10514   else
10515     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10516
10517   op1 = immed_double_const (lo, hi, DImode);
10518   if (i >= 31)
10519     {
10520       emit_move_insn (operands[2], op1);
10521       op1 = operands[2];
10522     }
10523
10524   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10525   DONE;
10526 })
10527
10528 (define_insn "*bt<mode>"
10529   [(set (reg:CCC FLAGS_REG)
10530         (compare:CCC
10531           (zero_extract:SWI48
10532             (match_operand:SWI48 0 "register_operand" "r")
10533             (const_int 1)
10534             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10535           (const_int 0)))]
10536   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10537   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10538   [(set_attr "type" "alu1")
10539    (set_attr "prefix_0f" "1")
10540    (set_attr "mode" "<MODE>")])
10541 \f
10542 ;; Store-flag instructions.
10543
10544 ;; For all sCOND expanders, also expand the compare or test insn that
10545 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10546
10547 (define_insn_and_split "*setcc_di_1"
10548   [(set (match_operand:DI 0 "register_operand" "=q")
10549         (match_operator:DI 1 "ix86_comparison_operator"
10550           [(reg FLAGS_REG) (const_int 0)]))]
10551   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10552   "#"
10553   "&& reload_completed"
10554   [(set (match_dup 2) (match_dup 1))
10555    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10556 {
10557   PUT_MODE (operands[1], QImode);
10558   operands[2] = gen_lowpart (QImode, operands[0]);
10559 })
10560
10561 (define_insn_and_split "*setcc_si_1_and"
10562   [(set (match_operand:SI 0 "register_operand" "=q")
10563         (match_operator:SI 1 "ix86_comparison_operator"
10564           [(reg FLAGS_REG) (const_int 0)]))
10565    (clobber (reg:CC FLAGS_REG))]
10566   "!TARGET_PARTIAL_REG_STALL
10567    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10568   "#"
10569   "&& reload_completed"
10570   [(set (match_dup 2) (match_dup 1))
10571    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10572               (clobber (reg:CC FLAGS_REG))])]
10573 {
10574   PUT_MODE (operands[1], QImode);
10575   operands[2] = gen_lowpart (QImode, operands[0]);
10576 })
10577
10578 (define_insn_and_split "*setcc_si_1_movzbl"
10579   [(set (match_operand:SI 0 "register_operand" "=q")
10580         (match_operator:SI 1 "ix86_comparison_operator"
10581           [(reg FLAGS_REG) (const_int 0)]))]
10582   "!TARGET_PARTIAL_REG_STALL
10583    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10584   "#"
10585   "&& reload_completed"
10586   [(set (match_dup 2) (match_dup 1))
10587    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10588 {
10589   PUT_MODE (operands[1], QImode);
10590   operands[2] = gen_lowpart (QImode, operands[0]);
10591 })
10592
10593 (define_insn "*setcc_qi"
10594   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10595         (match_operator:QI 1 "ix86_comparison_operator"
10596           [(reg FLAGS_REG) (const_int 0)]))]
10597   ""
10598   "set%C1\t%0"
10599   [(set_attr "type" "setcc")
10600    (set_attr "mode" "QI")])
10601
10602 (define_insn "*setcc_qi_slp"
10603   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10604         (match_operator:QI 1 "ix86_comparison_operator"
10605           [(reg FLAGS_REG) (const_int 0)]))]
10606   ""
10607   "set%C1\t%0"
10608   [(set_attr "type" "setcc")
10609    (set_attr "mode" "QI")])
10610
10611 ;; In general it is not safe to assume too much about CCmode registers,
10612 ;; so simplify-rtx stops when it sees a second one.  Under certain
10613 ;; conditions this is safe on x86, so help combine not create
10614 ;;
10615 ;;      seta    %al
10616 ;;      testb   %al, %al
10617 ;;      sete    %al
10618
10619 (define_split
10620   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10621         (ne:QI (match_operator 1 "ix86_comparison_operator"
10622                  [(reg FLAGS_REG) (const_int 0)])
10623             (const_int 0)))]
10624   ""
10625   [(set (match_dup 0) (match_dup 1))]
10626   "PUT_MODE (operands[1], QImode);")
10627
10628 (define_split
10629   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10630         (ne:QI (match_operator 1 "ix86_comparison_operator"
10631                  [(reg FLAGS_REG) (const_int 0)])
10632             (const_int 0)))]
10633   ""
10634   [(set (match_dup 0) (match_dup 1))]
10635   "PUT_MODE (operands[1], QImode);")
10636
10637 (define_split
10638   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10639         (eq:QI (match_operator 1 "ix86_comparison_operator"
10640                  [(reg FLAGS_REG) (const_int 0)])
10641             (const_int 0)))]
10642   ""
10643   [(set (match_dup 0) (match_dup 1))]
10644 {
10645   rtx new_op1 = copy_rtx (operands[1]);
10646   operands[1] = new_op1;
10647   PUT_MODE (new_op1, QImode);
10648   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10649                                              GET_MODE (XEXP (new_op1, 0))));
10650
10651   /* Make sure that (a) the CCmode we have for the flags is strong
10652      enough for the reversed compare or (b) we have a valid FP compare.  */
10653   if (! ix86_comparison_operator (new_op1, VOIDmode))
10654     FAIL;
10655 })
10656
10657 (define_split
10658   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10659         (eq:QI (match_operator 1 "ix86_comparison_operator"
10660                  [(reg FLAGS_REG) (const_int 0)])
10661             (const_int 0)))]
10662   ""
10663   [(set (match_dup 0) (match_dup 1))]
10664 {
10665   rtx new_op1 = copy_rtx (operands[1]);
10666   operands[1] = new_op1;
10667   PUT_MODE (new_op1, QImode);
10668   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10669                                              GET_MODE (XEXP (new_op1, 0))));
10670
10671   /* Make sure that (a) the CCmode we have for the flags is strong
10672      enough for the reversed compare or (b) we have a valid FP compare.  */
10673   if (! ix86_comparison_operator (new_op1, VOIDmode))
10674     FAIL;
10675 })
10676
10677 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10678 ;; subsequent logical operations are used to imitate conditional moves.
10679 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10680 ;; it directly.
10681
10682 (define_insn "setcc_<mode>_sse"
10683   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10684         (match_operator:MODEF 3 "sse_comparison_operator"
10685           [(match_operand:MODEF 1 "register_operand" "0,x")
10686            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10687   "SSE_FLOAT_MODE_P (<MODE>mode)"
10688   "@
10689    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10690    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10691   [(set_attr "isa" "noavx,avx")
10692    (set_attr "type" "ssecmp")
10693    (set_attr "length_immediate" "1")
10694    (set_attr "prefix" "orig,vex")
10695    (set_attr "mode" "<MODE>")])
10696 \f
10697 ;; Basic conditional jump instructions.
10698 ;; We ignore the overflow flag for signed branch instructions.
10699
10700 (define_insn "*jcc_1"
10701   [(set (pc)
10702         (if_then_else (match_operator 1 "ix86_comparison_operator"
10703                                       [(reg FLAGS_REG) (const_int 0)])
10704                       (label_ref (match_operand 0 "" ""))
10705                       (pc)))]
10706   ""
10707   "%+j%C1\t%l0"
10708   [(set_attr "type" "ibr")
10709    (set_attr "modrm" "0")
10710    (set (attr "length")
10711            (if_then_else (and (ge (minus (match_dup 0) (pc))
10712                                   (const_int -126))
10713                               (lt (minus (match_dup 0) (pc))
10714                                   (const_int 128)))
10715              (const_int 2)
10716              (const_int 6)))])
10717
10718 (define_insn "*jcc_2"
10719   [(set (pc)
10720         (if_then_else (match_operator 1 "ix86_comparison_operator"
10721                                       [(reg FLAGS_REG) (const_int 0)])
10722                       (pc)
10723                       (label_ref (match_operand 0 "" ""))))]
10724   ""
10725   "%+j%c1\t%l0"
10726   [(set_attr "type" "ibr")
10727    (set_attr "modrm" "0")
10728    (set (attr "length")
10729            (if_then_else (and (ge (minus (match_dup 0) (pc))
10730                                   (const_int -126))
10731                               (lt (minus (match_dup 0) (pc))
10732                                   (const_int 128)))
10733              (const_int 2)
10734              (const_int 6)))])
10735
10736 ;; In general it is not safe to assume too much about CCmode registers,
10737 ;; so simplify-rtx stops when it sees a second one.  Under certain
10738 ;; conditions this is safe on x86, so help combine not create
10739 ;;
10740 ;;      seta    %al
10741 ;;      testb   %al, %al
10742 ;;      je      Lfoo
10743
10744 (define_split
10745   [(set (pc)
10746         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10747                                       [(reg FLAGS_REG) (const_int 0)])
10748                           (const_int 0))
10749                       (label_ref (match_operand 1 "" ""))
10750                       (pc)))]
10751   ""
10752   [(set (pc)
10753         (if_then_else (match_dup 0)
10754                       (label_ref (match_dup 1))
10755                       (pc)))]
10756   "PUT_MODE (operands[0], VOIDmode);")
10757
10758 (define_split
10759   [(set (pc)
10760         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10761                                       [(reg FLAGS_REG) (const_int 0)])
10762                           (const_int 0))
10763                       (label_ref (match_operand 1 "" ""))
10764                       (pc)))]
10765   ""
10766   [(set (pc)
10767         (if_then_else (match_dup 0)
10768                       (label_ref (match_dup 1))
10769                       (pc)))]
10770 {
10771   rtx new_op0 = copy_rtx (operands[0]);
10772   operands[0] = new_op0;
10773   PUT_MODE (new_op0, VOIDmode);
10774   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10775                                              GET_MODE (XEXP (new_op0, 0))));
10776
10777   /* Make sure that (a) the CCmode we have for the flags is strong
10778      enough for the reversed compare or (b) we have a valid FP compare.  */
10779   if (! ix86_comparison_operator (new_op0, VOIDmode))
10780     FAIL;
10781 })
10782
10783 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10784 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10785 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10786 ;; appropriate modulo of the bit offset value.
10787
10788 (define_insn_and_split "*jcc_bt<mode>"
10789   [(set (pc)
10790         (if_then_else (match_operator 0 "bt_comparison_operator"
10791                         [(zero_extract:SWI48
10792                            (match_operand:SWI48 1 "register_operand" "r")
10793                            (const_int 1)
10794                            (zero_extend:SI
10795                              (match_operand:QI 2 "register_operand" "r")))
10796                          (const_int 0)])
10797                       (label_ref (match_operand 3 "" ""))
10798                       (pc)))
10799    (clobber (reg:CC FLAGS_REG))]
10800   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10801   "#"
10802   "&& 1"
10803   [(set (reg:CCC FLAGS_REG)
10804         (compare:CCC
10805           (zero_extract:SWI48
10806             (match_dup 1)
10807             (const_int 1)
10808             (match_dup 2))
10809           (const_int 0)))
10810    (set (pc)
10811         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10812                       (label_ref (match_dup 3))
10813                       (pc)))]
10814 {
10815   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10816
10817   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10818 })
10819
10820 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10821 ;; also for DImode, this is what combine produces.
10822 (define_insn_and_split "*jcc_bt<mode>_mask"
10823   [(set (pc)
10824         (if_then_else (match_operator 0 "bt_comparison_operator"
10825                         [(zero_extract:SWI48
10826                            (match_operand:SWI48 1 "register_operand" "r")
10827                            (const_int 1)
10828                            (and:SI
10829                              (match_operand:SI 2 "register_operand" "r")
10830                              (match_operand:SI 3 "const_int_operand" "n")))])
10831                       (label_ref (match_operand 4 "" ""))
10832                       (pc)))
10833    (clobber (reg:CC FLAGS_REG))]
10834   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10835    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10836       == GET_MODE_BITSIZE (<MODE>mode)-1"
10837   "#"
10838   "&& 1"
10839   [(set (reg:CCC FLAGS_REG)
10840         (compare:CCC
10841           (zero_extract:SWI48
10842             (match_dup 1)
10843             (const_int 1)
10844             (match_dup 2))
10845           (const_int 0)))
10846    (set (pc)
10847         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10848                       (label_ref (match_dup 4))
10849                       (pc)))]
10850 {
10851   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10852
10853   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10854 })
10855
10856 (define_insn_and_split "*jcc_btsi_1"
10857   [(set (pc)
10858         (if_then_else (match_operator 0 "bt_comparison_operator"
10859                         [(and:SI
10860                            (lshiftrt:SI
10861                              (match_operand:SI 1 "register_operand" "r")
10862                              (match_operand:QI 2 "register_operand" "r"))
10863                            (const_int 1))
10864                          (const_int 0)])
10865                       (label_ref (match_operand 3 "" ""))
10866                       (pc)))
10867    (clobber (reg:CC FLAGS_REG))]
10868   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10869   "#"
10870   "&& 1"
10871   [(set (reg:CCC FLAGS_REG)
10872         (compare:CCC
10873           (zero_extract:SI
10874             (match_dup 1)
10875             (const_int 1)
10876             (match_dup 2))
10877           (const_int 0)))
10878    (set (pc)
10879         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10880                       (label_ref (match_dup 3))
10881                       (pc)))]
10882 {
10883   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10884
10885   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10886 })
10887
10888 ;; avoid useless masking of bit offset operand
10889 (define_insn_and_split "*jcc_btsi_mask_1"
10890   [(set (pc)
10891         (if_then_else
10892           (match_operator 0 "bt_comparison_operator"
10893             [(and:SI
10894                (lshiftrt:SI
10895                  (match_operand:SI 1 "register_operand" "r")
10896                  (subreg:QI
10897                    (and:SI
10898                      (match_operand:SI 2 "register_operand" "r")
10899                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10900                (const_int 1))
10901              (const_int 0)])
10902           (label_ref (match_operand 4 "" ""))
10903           (pc)))
10904    (clobber (reg:CC FLAGS_REG))]
10905   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10906    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10907   "#"
10908   "&& 1"
10909   [(set (reg:CCC FLAGS_REG)
10910         (compare:CCC
10911           (zero_extract:SI
10912             (match_dup 1)
10913             (const_int 1)
10914             (match_dup 2))
10915           (const_int 0)))
10916    (set (pc)
10917         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10918                       (label_ref (match_dup 4))
10919                       (pc)))]
10920   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10921
10922 ;; Define combination compare-and-branch fp compare instructions to help
10923 ;; combine.
10924
10925 (define_insn "*fp_jcc_1_387"
10926   [(set (pc)
10927         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10928                         [(match_operand 1 "register_operand" "f")
10929                          (match_operand 2 "nonimmediate_operand" "fm")])
10930           (label_ref (match_operand 3 "" ""))
10931           (pc)))
10932    (clobber (reg:CCFP FPSR_REG))
10933    (clobber (reg:CCFP FLAGS_REG))
10934    (clobber (match_scratch:HI 4 "=a"))]
10935   "TARGET_80387
10936    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10937    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10938    && SELECT_CC_MODE (GET_CODE (operands[0]),
10939                       operands[1], operands[2]) == CCFPmode
10940    && !TARGET_CMOVE"
10941   "#")
10942
10943 (define_insn "*fp_jcc_1r_387"
10944   [(set (pc)
10945         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10946                         [(match_operand 1 "register_operand" "f")
10947                          (match_operand 2 "nonimmediate_operand" "fm")])
10948           (pc)
10949           (label_ref (match_operand 3 "" ""))))
10950    (clobber (reg:CCFP FPSR_REG))
10951    (clobber (reg:CCFP FLAGS_REG))
10952    (clobber (match_scratch:HI 4 "=a"))]
10953   "TARGET_80387
10954    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10955    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10956    && SELECT_CC_MODE (GET_CODE (operands[0]),
10957                       operands[1], operands[2]) == CCFPmode
10958    && !TARGET_CMOVE"
10959   "#")
10960
10961 (define_insn "*fp_jcc_2_387"
10962   [(set (pc)
10963         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10964                         [(match_operand 1 "register_operand" "f")
10965                          (match_operand 2 "register_operand" "f")])
10966           (label_ref (match_operand 3 "" ""))
10967           (pc)))
10968    (clobber (reg:CCFP FPSR_REG))
10969    (clobber (reg:CCFP FLAGS_REG))
10970    (clobber (match_scratch:HI 4 "=a"))]
10971   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10972    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10973    && !TARGET_CMOVE"
10974   "#")
10975
10976 (define_insn "*fp_jcc_2r_387"
10977   [(set (pc)
10978         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10979                         [(match_operand 1 "register_operand" "f")
10980                          (match_operand 2 "register_operand" "f")])
10981           (pc)
10982           (label_ref (match_operand 3 "" ""))))
10983    (clobber (reg:CCFP FPSR_REG))
10984    (clobber (reg:CCFP FLAGS_REG))
10985    (clobber (match_scratch:HI 4 "=a"))]
10986   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10987    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10988    && !TARGET_CMOVE"
10989   "#")
10990
10991 (define_insn "*fp_jcc_3_387"
10992   [(set (pc)
10993         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10994                         [(match_operand 1 "register_operand" "f")
10995                          (match_operand 2 "const0_operand" "")])
10996           (label_ref (match_operand 3 "" ""))
10997           (pc)))
10998    (clobber (reg:CCFP FPSR_REG))
10999    (clobber (reg:CCFP FLAGS_REG))
11000    (clobber (match_scratch:HI 4 "=a"))]
11001   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11002    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11003    && SELECT_CC_MODE (GET_CODE (operands[0]),
11004                       operands[1], operands[2]) == CCFPmode
11005    && !TARGET_CMOVE"
11006   "#")
11007
11008 (define_split
11009   [(set (pc)
11010         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11011                         [(match_operand 1 "register_operand" "")
11012                          (match_operand 2 "nonimmediate_operand" "")])
11013           (match_operand 3 "" "")
11014           (match_operand 4 "" "")))
11015    (clobber (reg:CCFP FPSR_REG))
11016    (clobber (reg:CCFP FLAGS_REG))]
11017   "reload_completed"
11018   [(const_int 0)]
11019 {
11020   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11021                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11022   DONE;
11023 })
11024
11025 (define_split
11026   [(set (pc)
11027         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11028                         [(match_operand 1 "register_operand" "")
11029                          (match_operand 2 "general_operand" "")])
11030           (match_operand 3 "" "")
11031           (match_operand 4 "" "")))
11032    (clobber (reg:CCFP FPSR_REG))
11033    (clobber (reg:CCFP FLAGS_REG))
11034    (clobber (match_scratch:HI 5 "=a"))]
11035   "reload_completed"
11036   [(const_int 0)]
11037 {
11038   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11039                         operands[3], operands[4], operands[5], NULL_RTX);
11040   DONE;
11041 })
11042
11043 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11044 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11045 ;; with a precedence over other operators and is always put in the first
11046 ;; place. Swap condition and operands to match ficom instruction.
11047
11048 (define_insn "*fp_jcc_4_<mode>_387"
11049   [(set (pc)
11050         (if_then_else
11051           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11052             [(match_operator 1 "float_operator"
11053               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11054              (match_operand 3 "register_operand" "f,f")])
11055           (label_ref (match_operand 4 "" ""))
11056           (pc)))
11057    (clobber (reg:CCFP FPSR_REG))
11058    (clobber (reg:CCFP FLAGS_REG))
11059    (clobber (match_scratch:HI 5 "=a,a"))]
11060   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11061    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11062    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11063    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11064    && !TARGET_CMOVE"
11065   "#")
11066
11067 (define_split
11068   [(set (pc)
11069         (if_then_else
11070           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11071             [(match_operator 1 "float_operator"
11072               [(match_operand:SWI24 2 "memory_operand" "")])
11073              (match_operand 3 "register_operand" "")])
11074           (match_operand 4 "" "")
11075           (match_operand 5 "" "")))
11076    (clobber (reg:CCFP FPSR_REG))
11077    (clobber (reg:CCFP FLAGS_REG))
11078    (clobber (match_scratch:HI 6 "=a"))]
11079   "reload_completed"
11080   [(const_int 0)]
11081 {
11082   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11083
11084   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11085                         operands[3], operands[7],
11086                         operands[4], operands[5], operands[6], NULL_RTX);
11087   DONE;
11088 })
11089
11090 ;; %%% Kill this when reload knows how to do it.
11091 (define_split
11092   [(set (pc)
11093         (if_then_else
11094           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11095             [(match_operator 1 "float_operator"
11096               [(match_operand:SWI24 2 "register_operand" "")])
11097              (match_operand 3 "register_operand" "")])
11098           (match_operand 4 "" "")
11099           (match_operand 5 "" "")))
11100    (clobber (reg:CCFP FPSR_REG))
11101    (clobber (reg:CCFP FLAGS_REG))
11102    (clobber (match_scratch:HI 6 "=a"))]
11103   "reload_completed"
11104   [(const_int 0)]
11105 {
11106   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11107   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11108
11109   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11110                         operands[3], operands[7],
11111                         operands[4], operands[5], operands[6], operands[2]);
11112   DONE;
11113 })
11114 \f
11115 ;; Unconditional and other jump instructions
11116
11117 (define_insn "jump"
11118   [(set (pc)
11119         (label_ref (match_operand 0 "" "")))]
11120   ""
11121   "jmp\t%l0"
11122   [(set_attr "type" "ibr")
11123    (set (attr "length")
11124            (if_then_else (and (ge (minus (match_dup 0) (pc))
11125                                   (const_int -126))
11126                               (lt (minus (match_dup 0) (pc))
11127                                   (const_int 128)))
11128              (const_int 2)
11129              (const_int 5)))
11130    (set_attr "modrm" "0")])
11131
11132 (define_expand "indirect_jump"
11133   [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11134
11135 (define_insn "*indirect_jump"
11136   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11137   ""
11138   "jmp\t%A0"
11139   [(set_attr "type" "ibr")
11140    (set_attr "length_immediate" "0")])
11141
11142 (define_expand "tablejump"
11143   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11144               (use (label_ref (match_operand 1 "" "")))])]
11145   ""
11146 {
11147   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11148      relative.  Convert the relative address to an absolute address.  */
11149   if (flag_pic)
11150     {
11151       rtx op0, op1;
11152       enum rtx_code code;
11153
11154       /* We can't use @GOTOFF for text labels on VxWorks;
11155          see gotoff_operand.  */
11156       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11157         {
11158           code = PLUS;
11159           op0 = operands[0];
11160           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11161         }
11162       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11163         {
11164           code = PLUS;
11165           op0 = operands[0];
11166           op1 = pic_offset_table_rtx;
11167         }
11168       else
11169         {
11170           code = MINUS;
11171           op0 = pic_offset_table_rtx;
11172           op1 = operands[0];
11173         }
11174
11175       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11176                                          OPTAB_DIRECT);
11177     }
11178   else if (TARGET_X32)
11179     operands[0] = convert_memory_address (Pmode, operands[0]);
11180 })
11181
11182 (define_insn "*tablejump_1"
11183   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11184    (use (label_ref (match_operand 1 "" "")))]
11185   ""
11186   "jmp\t%A0"
11187   [(set_attr "type" "ibr")
11188    (set_attr "length_immediate" "0")])
11189 \f
11190 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11191
11192 (define_peephole2
11193   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11194    (set (match_operand:QI 1 "register_operand" "")
11195         (match_operator:QI 2 "ix86_comparison_operator"
11196           [(reg FLAGS_REG) (const_int 0)]))
11197    (set (match_operand 3 "q_regs_operand" "")
11198         (zero_extend (match_dup 1)))]
11199   "(peep2_reg_dead_p (3, operands[1])
11200     || operands_match_p (operands[1], operands[3]))
11201    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11202   [(set (match_dup 4) (match_dup 0))
11203    (set (strict_low_part (match_dup 5))
11204         (match_dup 2))]
11205 {
11206   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11207   operands[5] = gen_lowpart (QImode, operands[3]);
11208   ix86_expand_clear (operands[3]);
11209 })
11210
11211 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11212
11213 (define_peephole2
11214   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11215    (set (match_operand:QI 1 "register_operand" "")
11216         (match_operator:QI 2 "ix86_comparison_operator"
11217           [(reg FLAGS_REG) (const_int 0)]))
11218    (parallel [(set (match_operand 3 "q_regs_operand" "")
11219                    (zero_extend (match_dup 1)))
11220               (clobber (reg:CC FLAGS_REG))])]
11221   "(peep2_reg_dead_p (3, operands[1])
11222     || operands_match_p (operands[1], operands[3]))
11223    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11224   [(set (match_dup 4) (match_dup 0))
11225    (set (strict_low_part (match_dup 5))
11226         (match_dup 2))]
11227 {
11228   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11229   operands[5] = gen_lowpart (QImode, operands[3]);
11230   ix86_expand_clear (operands[3]);
11231 })
11232 \f
11233 ;; Call instructions.
11234
11235 ;; The predicates normally associated with named expanders are not properly
11236 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11237 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11238
11239 ;; P6 processors will jump to the address after the decrement when %esp
11240 ;; is used as a call operand, so they will execute return address as a code.
11241 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11242
11243 ;; Register constraint for call instruction.
11244 (define_mode_attr c [(SI "l") (DI "r")])
11245
11246 ;; Call subroutine returning no value.
11247
11248 (define_expand "call"
11249   [(call (match_operand:QI 0 "" "")
11250          (match_operand 1 "" ""))
11251    (use (match_operand 2 "" ""))]
11252   ""
11253 {
11254   ix86_expand_call (NULL, operands[0], operands[1],
11255                     operands[2], NULL, false);
11256   DONE;
11257 })
11258
11259 (define_expand "sibcall"
11260   [(call (match_operand:QI 0 "" "")
11261          (match_operand 1 "" ""))
11262    (use (match_operand 2 "" ""))]
11263   ""
11264 {
11265   ix86_expand_call (NULL, operands[0], operands[1],
11266                     operands[2], NULL, true);
11267   DONE;
11268 })
11269
11270 (define_insn_and_split "*call_vzeroupper"
11271   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11272          (match_operand 1 "" ""))
11273    (unspec [(match_operand 2 "const_int_operand" "")]
11274            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11275   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11276   "#"
11277   "&& reload_completed"
11278   [(const_int 0)]
11279   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11280   [(set_attr "type" "call")])
11281
11282 (define_insn "*call"
11283   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11284          (match_operand 1 "" ""))]
11285   "!SIBLING_CALL_P (insn)"
11286   "* return ix86_output_call_insn (insn, operands[0]);"
11287   [(set_attr "type" "call")])
11288
11289 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11290   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11291          (match_operand 1 "" ""))
11292    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11293    (clobber (reg:TI XMM6_REG))
11294    (clobber (reg:TI XMM7_REG))
11295    (clobber (reg:TI XMM8_REG))
11296    (clobber (reg:TI XMM9_REG))
11297    (clobber (reg:TI XMM10_REG))
11298    (clobber (reg:TI XMM11_REG))
11299    (clobber (reg:TI XMM12_REG))
11300    (clobber (reg:TI XMM13_REG))
11301    (clobber (reg:TI XMM14_REG))
11302    (clobber (reg:TI XMM15_REG))
11303    (clobber (reg:DI SI_REG))
11304    (clobber (reg:DI DI_REG))
11305    (unspec [(match_operand 2 "const_int_operand" "")]
11306            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11307   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11308   "#"
11309   "&& reload_completed"
11310   [(const_int 0)]
11311   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11312   [(set_attr "type" "call")])
11313
11314 (define_insn "*call_rex64_ms_sysv"
11315   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11316          (match_operand 1 "" ""))
11317    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11318    (clobber (reg:TI XMM6_REG))
11319    (clobber (reg:TI XMM7_REG))
11320    (clobber (reg:TI XMM8_REG))
11321    (clobber (reg:TI XMM9_REG))
11322    (clobber (reg:TI XMM10_REG))
11323    (clobber (reg:TI XMM11_REG))
11324    (clobber (reg:TI XMM12_REG))
11325    (clobber (reg:TI XMM13_REG))
11326    (clobber (reg:TI XMM14_REG))
11327    (clobber (reg:TI XMM15_REG))
11328    (clobber (reg:DI SI_REG))
11329    (clobber (reg:DI DI_REG))]
11330   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11331   "* return ix86_output_call_insn (insn, operands[0]);"
11332   [(set_attr "type" "call")])
11333
11334 (define_insn_and_split "*sibcall_vzeroupper"
11335   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11336          (match_operand 1 "" ""))
11337    (unspec [(match_operand 2 "const_int_operand" "")]
11338            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11339   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11340   "#"
11341   "&& reload_completed"
11342   [(const_int 0)]
11343   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11344   [(set_attr "type" "call")])
11345
11346 (define_insn "*sibcall"
11347   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11348          (match_operand 1 "" ""))]
11349   "SIBLING_CALL_P (insn)"
11350   "* return ix86_output_call_insn (insn, operands[0]);"
11351   [(set_attr "type" "call")])
11352
11353 (define_expand "call_pop"
11354   [(parallel [(call (match_operand:QI 0 "" "")
11355                     (match_operand:SI 1 "" ""))
11356               (set (reg:SI SP_REG)
11357                    (plus:SI (reg:SI SP_REG)
11358                             (match_operand:SI 3 "" "")))])]
11359   "!TARGET_64BIT"
11360 {
11361   ix86_expand_call (NULL, operands[0], operands[1],
11362                     operands[2], operands[3], false);
11363   DONE;
11364 })
11365
11366 (define_insn_and_split "*call_pop_vzeroupper"
11367   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11368          (match_operand:SI 1 "" ""))
11369    (set (reg:SI SP_REG)
11370         (plus:SI (reg:SI SP_REG)
11371                  (match_operand:SI 2 "immediate_operand" "i")))
11372    (unspec [(match_operand 3 "const_int_operand" "")]
11373            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11374   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11375   "#"
11376   "&& reload_completed"
11377   [(const_int 0)]
11378   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11379   [(set_attr "type" "call")])
11380
11381 (define_insn "*call_pop"
11382   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11383          (match_operand 1 "" ""))
11384    (set (reg:SI SP_REG)
11385         (plus:SI (reg:SI SP_REG)
11386                  (match_operand:SI 2 "immediate_operand" "i")))]
11387   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11388   "* return ix86_output_call_insn (insn, operands[0]);"
11389   [(set_attr "type" "call")])
11390
11391 (define_insn_and_split "*sibcall_pop_vzeroupper"
11392   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11393          (match_operand 1 "" ""))
11394    (set (reg:SI SP_REG)
11395         (plus:SI (reg:SI SP_REG)
11396                  (match_operand:SI 2 "immediate_operand" "i")))
11397    (unspec [(match_operand 3 "const_int_operand" "")]
11398            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11399   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11400   "#"
11401   "&& reload_completed"
11402   [(const_int 0)]
11403   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11404   [(set_attr "type" "call")])
11405
11406 (define_insn "*sibcall_pop"
11407   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11408          (match_operand 1 "" ""))
11409    (set (reg:SI SP_REG)
11410         (plus:SI (reg:SI SP_REG)
11411                  (match_operand:SI 2 "immediate_operand" "i")))]
11412   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11413   "* return ix86_output_call_insn (insn, operands[0]);"
11414   [(set_attr "type" "call")])
11415
11416 ;; Call subroutine, returning value in operand 0
11417
11418 (define_expand "call_value"
11419   [(set (match_operand 0 "" "")
11420         (call (match_operand:QI 1 "" "")
11421               (match_operand 2 "" "")))
11422    (use (match_operand 3 "" ""))]
11423   ""
11424 {
11425   ix86_expand_call (operands[0], operands[1], operands[2],
11426                     operands[3], NULL, false);
11427   DONE;
11428 })
11429
11430 (define_expand "sibcall_value"
11431   [(set (match_operand 0 "" "")
11432         (call (match_operand:QI 1 "" "")
11433               (match_operand 2 "" "")))
11434    (use (match_operand 3 "" ""))]
11435   ""
11436 {
11437   ix86_expand_call (operands[0], operands[1], operands[2],
11438                     operands[3], NULL, true);
11439   DONE;
11440 })
11441
11442 (define_insn_and_split "*call_value_vzeroupper"
11443   [(set (match_operand 0 "" "")
11444         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11445               (match_operand 2 "" "")))
11446    (unspec [(match_operand 3 "const_int_operand" "")]
11447            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11448   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11449   "#"
11450   "&& reload_completed"
11451   [(const_int 0)]
11452   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11453   [(set_attr "type" "callv")])
11454
11455 (define_insn "*call_value"
11456   [(set (match_operand 0 "" "")
11457         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11458               (match_operand 2 "" "")))]
11459   "!SIBLING_CALL_P (insn)"
11460   "* return ix86_output_call_insn (insn, operands[1]);"
11461   [(set_attr "type" "callv")])
11462
11463 (define_insn_and_split "*sibcall_value_vzeroupper"
11464   [(set (match_operand 0 "" "")
11465         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11466               (match_operand 2 "" "")))
11467    (unspec [(match_operand 3 "const_int_operand" "")]
11468            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11469   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11470   "#"
11471   "&& reload_completed"
11472   [(const_int 0)]
11473   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11474   [(set_attr "type" "callv")])
11475
11476 (define_insn "*sibcall_value"
11477   [(set (match_operand 0 "" "")
11478         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11479               (match_operand 2 "" "")))]
11480   "SIBLING_CALL_P (insn)"
11481   "* return ix86_output_call_insn (insn, operands[1]);"
11482   [(set_attr "type" "callv")])
11483
11484 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11485   [(set (match_operand 0 "" "")
11486         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11487               (match_operand 2 "" "")))
11488    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11489    (clobber (reg:TI XMM6_REG))
11490    (clobber (reg:TI XMM7_REG))
11491    (clobber (reg:TI XMM8_REG))
11492    (clobber (reg:TI XMM9_REG))
11493    (clobber (reg:TI XMM10_REG))
11494    (clobber (reg:TI XMM11_REG))
11495    (clobber (reg:TI XMM12_REG))
11496    (clobber (reg:TI XMM13_REG))
11497    (clobber (reg:TI XMM14_REG))
11498    (clobber (reg:TI XMM15_REG))
11499    (clobber (reg:DI SI_REG))
11500    (clobber (reg:DI DI_REG))
11501    (unspec [(match_operand 3 "const_int_operand" "")]
11502            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11503   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11504   "#"
11505   "&& reload_completed"
11506   [(const_int 0)]
11507   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11508   [(set_attr "type" "callv")])
11509
11510 (define_insn "*call_value_rex64_ms_sysv"
11511   [(set (match_operand 0 "" "")
11512         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11513               (match_operand 2 "" "")))
11514    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11515    (clobber (reg:TI XMM6_REG))
11516    (clobber (reg:TI XMM7_REG))
11517    (clobber (reg:TI XMM8_REG))
11518    (clobber (reg:TI XMM9_REG))
11519    (clobber (reg:TI XMM10_REG))
11520    (clobber (reg:TI XMM11_REG))
11521    (clobber (reg:TI XMM12_REG))
11522    (clobber (reg:TI XMM13_REG))
11523    (clobber (reg:TI XMM14_REG))
11524    (clobber (reg:TI XMM15_REG))
11525    (clobber (reg:DI SI_REG))
11526    (clobber (reg:DI DI_REG))]
11527   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11528   "* return ix86_output_call_insn (insn, operands[1]);"
11529   [(set_attr "type" "callv")])
11530
11531 (define_expand "call_value_pop"
11532   [(parallel [(set (match_operand 0 "" "")
11533                    (call (match_operand:QI 1 "" "")
11534                          (match_operand:SI 2 "" "")))
11535               (set (reg:SI SP_REG)
11536                    (plus:SI (reg:SI SP_REG)
11537                             (match_operand:SI 4 "" "")))])]
11538   "!TARGET_64BIT"
11539 {
11540   ix86_expand_call (operands[0], operands[1], operands[2],
11541                     operands[3], operands[4], false);
11542   DONE;
11543 })
11544
11545 (define_insn_and_split "*call_value_pop_vzeroupper"
11546   [(set (match_operand 0 "" "")
11547         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11548               (match_operand 2 "" "")))
11549    (set (reg:SI SP_REG)
11550         (plus:SI (reg:SI SP_REG)
11551                  (match_operand:SI 3 "immediate_operand" "i")))
11552    (unspec [(match_operand 4 "const_int_operand" "")]
11553            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11554   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11555   "#"
11556   "&& reload_completed"
11557   [(const_int 0)]
11558   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11559   [(set_attr "type" "callv")])
11560
11561 (define_insn "*call_value_pop"
11562   [(set (match_operand 0 "" "")
11563         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11564               (match_operand 2 "" "")))
11565    (set (reg:SI SP_REG)
11566         (plus:SI (reg:SI SP_REG)
11567                  (match_operand:SI 3 "immediate_operand" "i")))]
11568   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11569   "* return ix86_output_call_insn (insn, operands[1]);"
11570   [(set_attr "type" "callv")])
11571
11572 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11573   [(set (match_operand 0 "" "")
11574         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11575               (match_operand 2 "" "")))
11576    (set (reg:SI SP_REG)
11577         (plus:SI (reg:SI SP_REG)
11578                  (match_operand:SI 3 "immediate_operand" "i")))
11579    (unspec [(match_operand 4 "const_int_operand" "")]
11580            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11581   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11582   "#"
11583   "&& reload_completed"
11584   [(const_int 0)]
11585   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11586   [(set_attr "type" "callv")])
11587
11588 (define_insn "*sibcall_value_pop"
11589   [(set (match_operand 0 "" "")
11590         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11591               (match_operand 2 "" "")))
11592    (set (reg:SI SP_REG)
11593         (plus:SI (reg:SI SP_REG)
11594                  (match_operand:SI 3 "immediate_operand" "i")))]
11595   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11596   "* return ix86_output_call_insn (insn, operands[1]);"
11597   [(set_attr "type" "callv")])
11598
11599 ;; Call subroutine returning any type.
11600
11601 (define_expand "untyped_call"
11602   [(parallel [(call (match_operand 0 "" "")
11603                     (const_int 0))
11604               (match_operand 1 "" "")
11605               (match_operand 2 "" "")])]
11606   ""
11607 {
11608   int i;
11609
11610   /* In order to give reg-stack an easier job in validating two
11611      coprocessor registers as containing a possible return value,
11612      simply pretend the untyped call returns a complex long double
11613      value. 
11614
11615      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11616      and should have the default ABI.  */
11617
11618   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11619                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11620                     operands[0], const0_rtx,
11621                     GEN_INT ((TARGET_64BIT
11622                               ? (ix86_abi == SYSV_ABI
11623                                  ? X86_64_SSE_REGPARM_MAX
11624                                  : X86_64_MS_SSE_REGPARM_MAX)
11625                               : X86_32_SSE_REGPARM_MAX)
11626                              - 1),
11627                     NULL, false);
11628
11629   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11630     {
11631       rtx set = XVECEXP (operands[2], 0, i);
11632       emit_move_insn (SET_DEST (set), SET_SRC (set));
11633     }
11634
11635   /* The optimizer does not know that the call sets the function value
11636      registers we stored in the result block.  We avoid problems by
11637      claiming that all hard registers are used and clobbered at this
11638      point.  */
11639   emit_insn (gen_blockage ());
11640
11641   DONE;
11642 })
11643 \f
11644 ;; Prologue and epilogue instructions
11645
11646 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11647 ;; all of memory.  This blocks insns from being moved across this point.
11648
11649 (define_insn "blockage"
11650   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11651   ""
11652   ""
11653   [(set_attr "length" "0")])
11654
11655 ;; Do not schedule instructions accessing memory across this point.
11656
11657 (define_expand "memory_blockage"
11658   [(set (match_dup 0)
11659         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11660   ""
11661 {
11662   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11663   MEM_VOLATILE_P (operands[0]) = 1;
11664 })
11665
11666 (define_insn "*memory_blockage"
11667   [(set (match_operand:BLK 0 "" "")
11668         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11669   ""
11670   ""
11671   [(set_attr "length" "0")])
11672
11673 ;; As USE insns aren't meaningful after reload, this is used instead
11674 ;; to prevent deleting instructions setting registers for PIC code
11675 (define_insn "prologue_use"
11676   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11677   ""
11678   ""
11679   [(set_attr "length" "0")])
11680
11681 ;; Insn emitted into the body of a function to return from a function.
11682 ;; This is only done if the function's epilogue is known to be simple.
11683 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11684
11685 (define_expand "return"
11686   [(simple_return)]
11687   "ix86_can_use_return_insn_p ()"
11688 {
11689   ix86_maybe_emit_epilogue_vzeroupper ();
11690   if (crtl->args.pops_args)
11691     {
11692       rtx popc = GEN_INT (crtl->args.pops_args);
11693       emit_jump_insn (gen_simple_return_pop_internal (popc));
11694       DONE;
11695     }
11696 })
11697
11698 ;; We need to disable this for TARGET_SEH, as otherwise
11699 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11700 ;; the maximum size of prologue in unwind information.
11701
11702 (define_expand "simple_return"
11703   [(simple_return)]
11704   "!TARGET_SEH"
11705 {
11706   ix86_maybe_emit_epilogue_vzeroupper ();
11707   if (crtl->args.pops_args)
11708     {
11709       rtx popc = GEN_INT (crtl->args.pops_args);
11710       emit_jump_insn (gen_simple_return_pop_internal (popc));
11711       DONE;
11712     }
11713 })
11714
11715 (define_insn "simple_return_internal"
11716   [(simple_return)]
11717   "reload_completed"
11718   "ret"
11719   [(set_attr "length" "1")
11720    (set_attr "atom_unit" "jeu")
11721    (set_attr "length_immediate" "0")
11722    (set_attr "modrm" "0")])
11723
11724 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11725 ;; instruction Athlon and K8 have.
11726
11727 (define_insn "simple_return_internal_long"
11728   [(simple_return)
11729    (unspec [(const_int 0)] UNSPEC_REP)]
11730   "reload_completed"
11731   "rep\;ret"
11732   [(set_attr "length" "2")
11733    (set_attr "atom_unit" "jeu")
11734    (set_attr "length_immediate" "0")
11735    (set_attr "prefix_rep" "1")
11736    (set_attr "modrm" "0")])
11737
11738 (define_insn "simple_return_pop_internal"
11739   [(simple_return)
11740    (use (match_operand:SI 0 "const_int_operand" ""))]
11741   "reload_completed"
11742   "ret\t%0"
11743   [(set_attr "length" "3")
11744    (set_attr "atom_unit" "jeu")
11745    (set_attr "length_immediate" "2")
11746    (set_attr "modrm" "0")])
11747
11748 (define_insn "simple_return_indirect_internal"
11749   [(simple_return)
11750    (use (match_operand:SI 0 "register_operand" "r"))]
11751   "reload_completed"
11752   "jmp\t%A0"
11753   [(set_attr "type" "ibr")
11754    (set_attr "length_immediate" "0")])
11755
11756 (define_insn "nop"
11757   [(const_int 0)]
11758   ""
11759   "nop"
11760   [(set_attr "length" "1")
11761    (set_attr "length_immediate" "0")
11762    (set_attr "modrm" "0")])
11763
11764 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11765 (define_insn "nops"
11766   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11767                     UNSPECV_NOPS)]
11768   "reload_completed"
11769 {
11770   int num = INTVAL (operands[0]);
11771
11772   gcc_assert (num >= 1 && num <= 8);
11773
11774   while (num--)
11775     fputs ("\tnop\n", asm_out_file);
11776
11777   return "";
11778 }
11779   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11780    (set_attr "length_immediate" "0")
11781    (set_attr "modrm" "0")])
11782
11783 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11784 ;; branch prediction penalty for the third jump in a 16-byte
11785 ;; block on K8.
11786
11787 (define_insn "pad"
11788   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11789   ""
11790 {
11791 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11792   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11793 #else
11794   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11795      The align insn is used to avoid 3 jump instructions in the row to improve
11796      branch prediction and the benefits hardly outweigh the cost of extra 8
11797      nops on the average inserted by full alignment pseudo operation.  */
11798 #endif
11799   return "";
11800 }
11801   [(set_attr "length" "16")])
11802
11803 (define_expand "prologue"
11804   [(const_int 0)]
11805   ""
11806   "ix86_expand_prologue (); DONE;")
11807
11808 (define_insn "set_got"
11809   [(set (match_operand:SI 0 "register_operand" "=r")
11810         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11811    (clobber (reg:CC FLAGS_REG))]
11812   "!TARGET_64BIT"
11813   "* return output_set_got (operands[0], NULL_RTX);"
11814   [(set_attr "type" "multi")
11815    (set_attr "length" "12")])
11816
11817 (define_insn "set_got_labelled"
11818   [(set (match_operand:SI 0 "register_operand" "=r")
11819         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11820          UNSPEC_SET_GOT))
11821    (clobber (reg:CC FLAGS_REG))]
11822   "!TARGET_64BIT"
11823   "* return output_set_got (operands[0], operands[1]);"
11824   [(set_attr "type" "multi")
11825    (set_attr "length" "12")])
11826
11827 (define_insn "set_got_rex64"
11828   [(set (match_operand:DI 0 "register_operand" "=r")
11829         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11830   "TARGET_64BIT"
11831   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11832   [(set_attr "type" "lea")
11833    (set_attr "length_address" "4")
11834    (set_attr "mode" "DI")])
11835
11836 (define_insn "set_rip_rex64"
11837   [(set (match_operand:DI 0 "register_operand" "=r")
11838         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11839   "TARGET_64BIT"
11840   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11841   [(set_attr "type" "lea")
11842    (set_attr "length_address" "4")
11843    (set_attr "mode" "DI")])
11844
11845 (define_insn "set_got_offset_rex64"
11846   [(set (match_operand:DI 0 "register_operand" "=r")
11847         (unspec:DI
11848           [(label_ref (match_operand 1 "" ""))]
11849           UNSPEC_SET_GOT_OFFSET))]
11850   "TARGET_LP64"
11851   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11852   [(set_attr "type" "imov")
11853    (set_attr "length_immediate" "0")
11854    (set_attr "length_address" "8")
11855    (set_attr "mode" "DI")])
11856
11857 (define_expand "epilogue"
11858   [(const_int 0)]
11859   ""
11860   "ix86_expand_epilogue (1); DONE;")
11861
11862 (define_expand "sibcall_epilogue"
11863   [(const_int 0)]
11864   ""
11865   "ix86_expand_epilogue (0); DONE;")
11866
11867 (define_expand "eh_return"
11868   [(use (match_operand 0 "register_operand" ""))]
11869   ""
11870 {
11871   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11872
11873   /* Tricky bit: we write the address of the handler to which we will
11874      be returning into someone else's stack frame, one word below the
11875      stack address we wish to restore.  */
11876   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11877   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11878   tmp = gen_rtx_MEM (Pmode, tmp);
11879   emit_move_insn (tmp, ra);
11880
11881   emit_jump_insn (gen_eh_return_internal ());
11882   emit_barrier ();
11883   DONE;
11884 })
11885
11886 (define_insn_and_split "eh_return_internal"
11887   [(eh_return)]
11888   ""
11889   "#"
11890   "epilogue_completed"
11891   [(const_int 0)]
11892   "ix86_expand_epilogue (2); DONE;")
11893
11894 (define_insn "leave"
11895   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11896    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11897    (clobber (mem:BLK (scratch)))]
11898   "!TARGET_64BIT"
11899   "leave"
11900   [(set_attr "type" "leave")])
11901
11902 (define_insn "leave_rex64"
11903   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11904    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11905    (clobber (mem:BLK (scratch)))]
11906   "TARGET_64BIT"
11907   "leave"
11908   [(set_attr "type" "leave")])
11909 \f
11910 ;; Handle -fsplit-stack.
11911
11912 (define_expand "split_stack_prologue"
11913   [(const_int 0)]
11914   ""
11915 {
11916   ix86_expand_split_stack_prologue ();
11917   DONE;
11918 })
11919
11920 ;; In order to support the call/return predictor, we use a return
11921 ;; instruction which the middle-end doesn't see.
11922 (define_insn "split_stack_return"
11923   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11924                      UNSPECV_SPLIT_STACK_RETURN)]
11925   ""
11926 {
11927   if (operands[0] == const0_rtx)
11928     return "ret";
11929   else
11930     return "ret\t%0";
11931 }
11932   [(set_attr "atom_unit" "jeu")
11933    (set_attr "modrm" "0")
11934    (set (attr "length")
11935         (if_then_else (match_operand:SI 0 "const0_operand" "")
11936                       (const_int 1)
11937                       (const_int 3)))
11938    (set (attr "length_immediate")
11939         (if_then_else (match_operand:SI 0 "const0_operand" "")
11940                       (const_int 0)
11941                       (const_int 2)))])
11942
11943 ;; If there are operand 0 bytes available on the stack, jump to
11944 ;; operand 1.
11945
11946 (define_expand "split_stack_space_check"
11947   [(set (pc) (if_then_else
11948               (ltu (minus (reg SP_REG)
11949                           (match_operand 0 "register_operand" ""))
11950                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11951               (label_ref (match_operand 1 "" ""))
11952               (pc)))]
11953   ""
11954 {
11955   rtx reg, size, limit;
11956
11957   reg = gen_reg_rtx (Pmode);
11958   size = force_reg (Pmode, operands[0]);
11959   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11960   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11961                           UNSPEC_STACK_CHECK);
11962   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11963   ix86_expand_branch (GEU, reg, limit, operands[1]);
11964
11965   DONE;
11966 })
11967 \f
11968 ;; Bit manipulation instructions.
11969
11970 (define_expand "ffs<mode>2"
11971   [(set (match_dup 2) (const_int -1))
11972    (parallel [(set (reg:CCZ FLAGS_REG)
11973                    (compare:CCZ
11974                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11975                      (const_int 0)))
11976               (set (match_operand:SWI48 0 "register_operand" "")
11977                    (ctz:SWI48 (match_dup 1)))])
11978    (set (match_dup 0) (if_then_else:SWI48
11979                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11980                         (match_dup 2)
11981                         (match_dup 0)))
11982    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11983               (clobber (reg:CC FLAGS_REG))])]
11984   ""
11985 {
11986   if (<MODE>mode == SImode && !TARGET_CMOVE)
11987     {
11988       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11989       DONE;
11990     }
11991   operands[2] = gen_reg_rtx (<MODE>mode);
11992 })
11993
11994 (define_insn_and_split "ffssi2_no_cmove"
11995   [(set (match_operand:SI 0 "register_operand" "=r")
11996         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11997    (clobber (match_scratch:SI 2 "=&q"))
11998    (clobber (reg:CC FLAGS_REG))]
11999   "!TARGET_CMOVE"
12000   "#"
12001   "&& reload_completed"
12002   [(parallel [(set (reg:CCZ FLAGS_REG)
12003                    (compare:CCZ (match_dup 1) (const_int 0)))
12004               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12005    (set (strict_low_part (match_dup 3))
12006         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12007    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12008               (clobber (reg:CC FLAGS_REG))])
12009    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12010               (clobber (reg:CC FLAGS_REG))])
12011    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12012               (clobber (reg:CC FLAGS_REG))])]
12013 {
12014   operands[3] = gen_lowpart (QImode, operands[2]);
12015   ix86_expand_clear (operands[2]);
12016 })
12017
12018 (define_insn "*ffs<mode>_1"
12019   [(set (reg:CCZ FLAGS_REG)
12020         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12021                      (const_int 0)))
12022    (set (match_operand:SWI48 0 "register_operand" "=r")
12023         (ctz:SWI48 (match_dup 1)))]
12024   ""
12025   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12026   [(set_attr "type" "alu1")
12027    (set_attr "prefix_0f" "1")
12028    (set_attr "mode" "<MODE>")])
12029
12030 (define_insn "ctz<mode>2"
12031   [(set (match_operand:SWI248 0 "register_operand" "=r")
12032         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12033    (clobber (reg:CC FLAGS_REG))]
12034   ""
12035 {
12036   if (TARGET_BMI)
12037     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12038   else
12039     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12040 }
12041   [(set_attr "type" "alu1")
12042    (set_attr "prefix_0f" "1")
12043    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12044    (set_attr "mode" "<MODE>")])
12045
12046 (define_expand "clz<mode>2"
12047   [(parallel
12048      [(set (match_operand:SWI248 0 "register_operand" "")
12049            (minus:SWI248
12050              (match_dup 2)
12051              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12052       (clobber (reg:CC FLAGS_REG))])
12053    (parallel
12054      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12055       (clobber (reg:CC FLAGS_REG))])]
12056   ""
12057 {
12058   if (TARGET_LZCNT)
12059     {
12060       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12061       DONE;
12062     }
12063   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12064 })
12065
12066 (define_insn "clz<mode>2_lzcnt"
12067   [(set (match_operand:SWI248 0 "register_operand" "=r")
12068         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12069    (clobber (reg:CC FLAGS_REG))]
12070   "TARGET_LZCNT"
12071   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12072   [(set_attr "prefix_rep" "1")
12073    (set_attr "type" "bitmanip")
12074    (set_attr "mode" "<MODE>")])
12075
12076 ;; BMI instructions.
12077 (define_insn "*bmi_andn_<mode>"
12078   [(set (match_operand:SWI48 0 "register_operand" "=r")
12079         (and:SWI48
12080           (not:SWI48
12081             (match_operand:SWI48 1 "register_operand" "r"))
12082             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12083    (clobber (reg:CC FLAGS_REG))]
12084   "TARGET_BMI"
12085   "andn\t{%2, %1, %0|%0, %1, %2}"
12086   [(set_attr "type" "bitmanip")
12087    (set_attr "mode" "<MODE>")])
12088
12089 (define_insn "bmi_bextr_<mode>"
12090   [(set (match_operand:SWI48 0 "register_operand" "=r")
12091         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12092                        (match_operand:SWI48 2 "register_operand" "r")]
12093                        UNSPEC_BEXTR))
12094    (clobber (reg:CC FLAGS_REG))]
12095   "TARGET_BMI"
12096   "bextr\t{%2, %1, %0|%0, %1, %2}"
12097   [(set_attr "type" "bitmanip")
12098    (set_attr "mode" "<MODE>")])
12099
12100 (define_insn "*bmi_blsi_<mode>"
12101   [(set (match_operand:SWI48 0 "register_operand" "=r")
12102         (and:SWI48
12103           (neg:SWI48
12104             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12105           (match_dup 1)))
12106    (clobber (reg:CC FLAGS_REG))]
12107   "TARGET_BMI"
12108   "blsi\t{%1, %0|%0, %1}"
12109   [(set_attr "type" "bitmanip")
12110    (set_attr "mode" "<MODE>")])
12111
12112 (define_insn "*bmi_blsmsk_<mode>"
12113   [(set (match_operand:SWI48 0 "register_operand" "=r")
12114         (xor:SWI48
12115           (plus:SWI48
12116             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12117             (const_int -1))
12118           (match_dup 1)))
12119    (clobber (reg:CC FLAGS_REG))]
12120   "TARGET_BMI"
12121   "blsmsk\t{%1, %0|%0, %1}"
12122   [(set_attr "type" "bitmanip")
12123    (set_attr "mode" "<MODE>")])
12124
12125 (define_insn "*bmi_blsr_<mode>"
12126   [(set (match_operand:SWI48 0 "register_operand" "=r")
12127         (and:SWI48
12128           (plus:SWI48
12129             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12130             (const_int -1))
12131           (match_dup 1)))
12132    (clobber (reg:CC FLAGS_REG))]
12133    "TARGET_BMI"
12134    "blsr\t{%1, %0|%0, %1}"
12135   [(set_attr "type" "bitmanip")
12136    (set_attr "mode" "<MODE>")])
12137
12138 ;; BMI2 instructions.
12139 (define_insn "bmi2_bzhi_<mode>3"
12140   [(set (match_operand:SWI48 0 "register_operand" "=r")
12141         (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12142                                    (match_operand:SWI48 2 "register_operand" "r"))
12143                    (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12144    (clobber (reg:CC FLAGS_REG))]
12145   "TARGET_BMI2"
12146   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12147   [(set_attr "type" "bitmanip")
12148    (set_attr "prefix" "vex")
12149    (set_attr "mode" "<MODE>")])
12150
12151 (define_insn "bmi2_pdep_<mode>3"
12152   [(set (match_operand:SWI48 0 "register_operand" "=r")
12153         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12154                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12155                        UNSPEC_PDEP))]
12156   "TARGET_BMI2"
12157   "pdep\t{%2, %1, %0|%0, %1, %2}"
12158   [(set_attr "type" "bitmanip")
12159    (set_attr "prefix" "vex")
12160    (set_attr "mode" "<MODE>")])
12161
12162 (define_insn "bmi2_pext_<mode>3"
12163   [(set (match_operand:SWI48 0 "register_operand" "=r")
12164         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12165                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12166                        UNSPEC_PEXT))]
12167   "TARGET_BMI2"
12168   "pext\t{%2, %1, %0|%0, %1, %2}"
12169   [(set_attr "type" "bitmanip")
12170    (set_attr "prefix" "vex")
12171    (set_attr "mode" "<MODE>")])
12172
12173 ;; TBM instructions.
12174 (define_insn "tbm_bextri_<mode>"
12175   [(set (match_operand:SWI48 0 "register_operand" "=r")
12176         (zero_extract:SWI48
12177           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12178           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12179           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12180    (clobber (reg:CC FLAGS_REG))]
12181    "TARGET_TBM"
12182 {
12183   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12184   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12185 }
12186   [(set_attr "type" "bitmanip")
12187    (set_attr "mode" "<MODE>")])
12188
12189 (define_insn "*tbm_blcfill_<mode>"
12190   [(set (match_operand:SWI48 0 "register_operand" "=r")
12191         (and:SWI48
12192           (plus:SWI48
12193             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12194             (const_int 1))
12195           (match_dup 1)))
12196    (clobber (reg:CC FLAGS_REG))]
12197    "TARGET_TBM"
12198    "blcfill\t{%1, %0|%0, %1}"
12199   [(set_attr "type" "bitmanip")
12200    (set_attr "mode" "<MODE>")])
12201
12202 (define_insn "*tbm_blci_<mode>"
12203   [(set (match_operand:SWI48 0 "register_operand" "=r")
12204         (ior:SWI48
12205           (not:SWI48
12206             (plus:SWI48
12207               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12208               (const_int 1)))
12209           (match_dup 1)))
12210    (clobber (reg:CC FLAGS_REG))]
12211    "TARGET_TBM"
12212    "blci\t{%1, %0|%0, %1}"
12213   [(set_attr "type" "bitmanip")
12214    (set_attr "mode" "<MODE>")])
12215
12216 (define_insn "*tbm_blcic_<mode>"
12217   [(set (match_operand:SWI48 0 "register_operand" "=r")
12218         (and:SWI48
12219           (plus:SWI48
12220             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12221             (const_int 1))
12222           (not:SWI48
12223             (match_dup 1))))
12224    (clobber (reg:CC FLAGS_REG))]
12225    "TARGET_TBM"
12226    "blcic\t{%1, %0|%0, %1}"
12227   [(set_attr "type" "bitmanip")
12228    (set_attr "mode" "<MODE>")])
12229
12230 (define_insn "*tbm_blcmsk_<mode>"
12231   [(set (match_operand:SWI48 0 "register_operand" "=r")
12232         (xor:SWI48
12233           (plus:SWI48
12234             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12235             (const_int 1))
12236           (match_dup 1)))
12237    (clobber (reg:CC FLAGS_REG))]
12238    "TARGET_TBM"
12239    "blcmsk\t{%1, %0|%0, %1}"
12240   [(set_attr "type" "bitmanip")
12241    (set_attr "mode" "<MODE>")])
12242
12243 (define_insn "*tbm_blcs_<mode>"
12244   [(set (match_operand:SWI48 0 "register_operand" "=r")
12245         (ior:SWI48
12246           (plus:SWI48
12247             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12248             (const_int 1))
12249           (match_dup 1)))
12250    (clobber (reg:CC FLAGS_REG))]
12251    "TARGET_TBM"
12252    "blcs\t{%1, %0|%0, %1}"
12253   [(set_attr "type" "bitmanip")
12254    (set_attr "mode" "<MODE>")])
12255
12256 (define_insn "*tbm_blsfill_<mode>"
12257   [(set (match_operand:SWI48 0 "register_operand" "=r")
12258         (ior:SWI48
12259           (plus:SWI48
12260             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12261             (const_int -1))
12262           (match_dup 1)))
12263    (clobber (reg:CC FLAGS_REG))]
12264    "TARGET_TBM"
12265    "blsfill\t{%1, %0|%0, %1}"
12266   [(set_attr "type" "bitmanip")
12267    (set_attr "mode" "<MODE>")])
12268
12269 (define_insn "*tbm_blsic_<mode>"
12270   [(set (match_operand:SWI48 0 "register_operand" "=r")
12271         (ior:SWI48
12272           (plus:SWI48
12273             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12274             (const_int -1))
12275           (not:SWI48
12276             (match_dup 1))))
12277    (clobber (reg:CC FLAGS_REG))]
12278    "TARGET_TBM"
12279    "blsic\t{%1, %0|%0, %1}"
12280   [(set_attr "type" "bitmanip")
12281    (set_attr "mode" "<MODE>")])
12282
12283 (define_insn "*tbm_t1mskc_<mode>"
12284   [(set (match_operand:SWI48 0 "register_operand" "=r")
12285         (ior:SWI48
12286           (plus:SWI48
12287             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12288             (const_int 1))
12289           (not:SWI48
12290             (match_dup 1))))
12291    (clobber (reg:CC FLAGS_REG))]
12292    "TARGET_TBM"
12293    "t1mskc\t{%1, %0|%0, %1}"
12294   [(set_attr "type" "bitmanip")
12295    (set_attr "mode" "<MODE>")])
12296
12297 (define_insn "*tbm_tzmsk_<mode>"
12298   [(set (match_operand:SWI48 0 "register_operand" "=r")
12299         (and:SWI48
12300           (plus:SWI48
12301             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12302             (const_int -1))
12303           (not:SWI48
12304             (match_dup 1))))
12305    (clobber (reg:CC FLAGS_REG))]
12306    "TARGET_TBM"
12307    "tzmsk\t{%1, %0|%0, %1}"
12308   [(set_attr "type" "bitmanip")
12309    (set_attr "mode" "<MODE>")])
12310
12311 (define_insn "bsr_rex64"
12312   [(set (match_operand:DI 0 "register_operand" "=r")
12313         (minus:DI (const_int 63)
12314                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12315    (clobber (reg:CC FLAGS_REG))]
12316   "TARGET_64BIT"
12317   "bsr{q}\t{%1, %0|%0, %1}"
12318   [(set_attr "type" "alu1")
12319    (set_attr "prefix_0f" "1")
12320    (set_attr "mode" "DI")])
12321
12322 (define_insn "bsr"
12323   [(set (match_operand:SI 0 "register_operand" "=r")
12324         (minus:SI (const_int 31)
12325                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12326    (clobber (reg:CC FLAGS_REG))]
12327   ""
12328   "bsr{l}\t{%1, %0|%0, %1}"
12329   [(set_attr "type" "alu1")
12330    (set_attr "prefix_0f" "1")
12331    (set_attr "mode" "SI")])
12332
12333 (define_insn "*bsrhi"
12334   [(set (match_operand:HI 0 "register_operand" "=r")
12335         (minus:HI (const_int 15)
12336                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12337    (clobber (reg:CC FLAGS_REG))]
12338   ""
12339   "bsr{w}\t{%1, %0|%0, %1}"
12340   [(set_attr "type" "alu1")
12341    (set_attr "prefix_0f" "1")
12342    (set_attr "mode" "HI")])
12343
12344 (define_insn "popcount<mode>2"
12345   [(set (match_operand:SWI248 0 "register_operand" "=r")
12346         (popcount:SWI248
12347           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "TARGET_POPCNT"
12350 {
12351 #if TARGET_MACHO
12352   return "popcnt\t{%1, %0|%0, %1}";
12353 #else
12354   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12355 #endif
12356 }
12357   [(set_attr "prefix_rep" "1")
12358    (set_attr "type" "bitmanip")
12359    (set_attr "mode" "<MODE>")])
12360
12361 (define_insn "*popcount<mode>2_cmp"
12362   [(set (reg FLAGS_REG)
12363         (compare
12364           (popcount:SWI248
12365             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12366           (const_int 0)))
12367    (set (match_operand:SWI248 0 "register_operand" "=r")
12368         (popcount:SWI248 (match_dup 1)))]
12369   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12370 {
12371 #if TARGET_MACHO
12372   return "popcnt\t{%1, %0|%0, %1}";
12373 #else
12374   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12375 #endif
12376 }
12377   [(set_attr "prefix_rep" "1")
12378    (set_attr "type" "bitmanip")
12379    (set_attr "mode" "<MODE>")])
12380
12381 (define_insn "*popcountsi2_cmp_zext"
12382   [(set (reg FLAGS_REG)
12383         (compare
12384           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12385           (const_int 0)))
12386    (set (match_operand:DI 0 "register_operand" "=r")
12387         (zero_extend:DI(popcount:SI (match_dup 1))))]
12388   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12389 {
12390 #if TARGET_MACHO
12391   return "popcnt\t{%1, %0|%0, %1}";
12392 #else
12393   return "popcnt{l}\t{%1, %0|%0, %1}";
12394 #endif
12395 }
12396   [(set_attr "prefix_rep" "1")
12397    (set_attr "type" "bitmanip")
12398    (set_attr "mode" "SI")])
12399
12400 (define_expand "bswap<mode>2"
12401   [(set (match_operand:SWI48 0 "register_operand" "")
12402         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12403   ""
12404 {
12405   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12406     {
12407       rtx x = operands[0];
12408
12409       emit_move_insn (x, operands[1]);
12410       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12411       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12412       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12413       DONE;
12414     }
12415 })
12416
12417 (define_insn "*bswap<mode>2_movbe"
12418   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12419         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12420   "TARGET_MOVBE
12421    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12422   "@
12423     bswap\t%0
12424     movbe\t{%1, %0|%0, %1}
12425     movbe\t{%1, %0|%0, %1}"
12426   [(set_attr "type" "bitmanip,imov,imov")
12427    (set_attr "modrm" "0,1,1")
12428    (set_attr "prefix_0f" "*,1,1")
12429    (set_attr "prefix_extra" "*,1,1")
12430    (set_attr "mode" "<MODE>")])
12431
12432 (define_insn "*bswap<mode>2_1"
12433   [(set (match_operand:SWI48 0 "register_operand" "=r")
12434         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12435   "TARGET_BSWAP"
12436   "bswap\t%0"
12437   [(set_attr "type" "bitmanip")
12438    (set_attr "modrm" "0")
12439    (set_attr "mode" "<MODE>")])
12440
12441 (define_insn "*bswaphi_lowpart_1"
12442   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12443         (bswap:HI (match_dup 0)))
12444    (clobber (reg:CC FLAGS_REG))]
12445   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12446   "@
12447     xchg{b}\t{%h0, %b0|%b0, %h0}
12448     rol{w}\t{$8, %0|%0, 8}"
12449   [(set_attr "length" "2,4")
12450    (set_attr "mode" "QI,HI")])
12451
12452 (define_insn "bswaphi_lowpart"
12453   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12454         (bswap:HI (match_dup 0)))
12455    (clobber (reg:CC FLAGS_REG))]
12456   ""
12457   "rol{w}\t{$8, %0|%0, 8}"
12458   [(set_attr "length" "4")
12459    (set_attr "mode" "HI")])
12460
12461 (define_expand "paritydi2"
12462   [(set (match_operand:DI 0 "register_operand" "")
12463         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12464   "! TARGET_POPCNT"
12465 {
12466   rtx scratch = gen_reg_rtx (QImode);
12467   rtx cond;
12468
12469   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12470                                 NULL_RTX, operands[1]));
12471
12472   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12473                          gen_rtx_REG (CCmode, FLAGS_REG),
12474                          const0_rtx);
12475   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12476
12477   if (TARGET_64BIT)
12478     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12479   else
12480     {
12481       rtx tmp = gen_reg_rtx (SImode);
12482
12483       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12484       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12485     }
12486   DONE;
12487 })
12488
12489 (define_expand "paritysi2"
12490   [(set (match_operand:SI 0 "register_operand" "")
12491         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12492   "! TARGET_POPCNT"
12493 {
12494   rtx scratch = gen_reg_rtx (QImode);
12495   rtx cond;
12496
12497   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12498
12499   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12500                          gen_rtx_REG (CCmode, FLAGS_REG),
12501                          const0_rtx);
12502   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12503
12504   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12505   DONE;
12506 })
12507
12508 (define_insn_and_split "paritydi2_cmp"
12509   [(set (reg:CC FLAGS_REG)
12510         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12511                    UNSPEC_PARITY))
12512    (clobber (match_scratch:DI 0 "=r"))
12513    (clobber (match_scratch:SI 1 "=&r"))
12514    (clobber (match_scratch:HI 2 "=Q"))]
12515   "! TARGET_POPCNT"
12516   "#"
12517   "&& reload_completed"
12518   [(parallel
12519      [(set (match_dup 1)
12520            (xor:SI (match_dup 1) (match_dup 4)))
12521       (clobber (reg:CC FLAGS_REG))])
12522    (parallel
12523      [(set (reg:CC FLAGS_REG)
12524            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12525       (clobber (match_dup 1))
12526       (clobber (match_dup 2))])]
12527 {
12528   operands[4] = gen_lowpart (SImode, operands[3]);
12529
12530   if (TARGET_64BIT)
12531     {
12532       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12533       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12534     }
12535   else
12536     operands[1] = gen_highpart (SImode, operands[3]);
12537 })
12538
12539 (define_insn_and_split "paritysi2_cmp"
12540   [(set (reg:CC FLAGS_REG)
12541         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12542                    UNSPEC_PARITY))
12543    (clobber (match_scratch:SI 0 "=r"))
12544    (clobber (match_scratch:HI 1 "=&Q"))]
12545   "! TARGET_POPCNT"
12546   "#"
12547   "&& reload_completed"
12548   [(parallel
12549      [(set (match_dup 1)
12550            (xor:HI (match_dup 1) (match_dup 3)))
12551       (clobber (reg:CC FLAGS_REG))])
12552    (parallel
12553      [(set (reg:CC FLAGS_REG)
12554            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12555       (clobber (match_dup 1))])]
12556 {
12557   operands[3] = gen_lowpart (HImode, operands[2]);
12558
12559   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12560   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12561 })
12562
12563 (define_insn "*parityhi2_cmp"
12564   [(set (reg:CC FLAGS_REG)
12565         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12566                    UNSPEC_PARITY))
12567    (clobber (match_scratch:HI 0 "=Q"))]
12568   "! TARGET_POPCNT"
12569   "xor{b}\t{%h0, %b0|%b0, %h0}"
12570   [(set_attr "length" "2")
12571    (set_attr "mode" "HI")])
12572
12573 \f
12574 ;; Thread-local storage patterns for ELF.
12575 ;;
12576 ;; Note that these code sequences must appear exactly as shown
12577 ;; in order to allow linker relaxation.
12578
12579 (define_insn "*tls_global_dynamic_32_gnu"
12580   [(set (match_operand:SI 0 "register_operand" "=a")
12581         (unspec:SI
12582          [(match_operand:SI 1 "register_operand" "b")
12583           (match_operand:SI 2 "tls_symbolic_operand" "")
12584           (match_operand:SI 3 "constant_call_address_operand" "z")]
12585          UNSPEC_TLS_GD))
12586    (clobber (match_scratch:SI 4 "=d"))
12587    (clobber (match_scratch:SI 5 "=c"))
12588    (clobber (reg:CC FLAGS_REG))]
12589   "!TARGET_64BIT && TARGET_GNU_TLS"
12590 {
12591   output_asm_insn
12592     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12593   if (TARGET_SUN_TLS)
12594 #ifdef HAVE_AS_IX86_TLSGDPLT
12595     return "call\t%a2@tlsgdplt";
12596 #else
12597     return "call\t%p3@plt";
12598 #endif
12599   return "call\t%P3";
12600 }
12601   [(set_attr "type" "multi")
12602    (set_attr "length" "12")])
12603
12604 (define_expand "tls_global_dynamic_32"
12605   [(parallel
12606     [(set (match_operand:SI 0 "register_operand" "")
12607           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12608                       (match_operand:SI 1 "tls_symbolic_operand" "")
12609                       (match_operand:SI 3 "constant_call_address_operand" "")]
12610                      UNSPEC_TLS_GD))
12611      (clobber (match_scratch:SI 4 ""))
12612      (clobber (match_scratch:SI 5 ""))
12613      (clobber (reg:CC FLAGS_REG))])])
12614
12615 (define_insn "*tls_global_dynamic_64"
12616   [(set (match_operand:DI 0 "register_operand" "=a")
12617         (call:DI
12618          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12619          (match_operand:DI 3 "" "")))
12620    (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12621               UNSPEC_TLS_GD)]
12622   "TARGET_64BIT"
12623 {
12624   if (!TARGET_X32)
12625     fputs (ASM_BYTE "0x66\n", asm_out_file);
12626   output_asm_insn
12627     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12628   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12629   fputs ("\trex64\n", asm_out_file);
12630   if (TARGET_SUN_TLS)
12631     return "call\t%p2@plt";
12632   return "call\t%P2";
12633 }
12634   [(set_attr "type" "multi")
12635    (set (attr "length")
12636         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12637
12638 (define_expand "tls_global_dynamic_64"
12639   [(parallel
12640     [(set (match_operand:DI 0 "register_operand" "")
12641           (call:DI
12642            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12643            (const_int 0)))
12644      (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12645                 UNSPEC_TLS_GD)])])
12646
12647 (define_insn "*tls_local_dynamic_base_32_gnu"
12648   [(set (match_operand:SI 0 "register_operand" "=a")
12649         (unspec:SI
12650          [(match_operand:SI 1 "register_operand" "b")
12651           (match_operand:SI 2 "constant_call_address_operand" "z")]
12652          UNSPEC_TLS_LD_BASE))
12653    (clobber (match_scratch:SI 3 "=d"))
12654    (clobber (match_scratch:SI 4 "=c"))
12655    (clobber (reg:CC FLAGS_REG))]
12656   "!TARGET_64BIT && TARGET_GNU_TLS"
12657 {
12658   output_asm_insn
12659     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12660   if (TARGET_SUN_TLS)
12661 #ifdef HAVE_AS_IX86_TLSLDMPLT
12662     return "call\t%&@tlsldmplt";
12663 #else
12664     return "call\t%p2@plt";
12665 #endif
12666   return "call\t%P2";
12667 }
12668   [(set_attr "type" "multi")
12669    (set_attr "length" "11")])
12670
12671 (define_expand "tls_local_dynamic_base_32"
12672   [(parallel
12673      [(set (match_operand:SI 0 "register_operand" "")
12674            (unspec:SI
12675             [(match_operand:SI 1 "register_operand" "")
12676              (match_operand:SI 2 "constant_call_address_operand" "")]
12677             UNSPEC_TLS_LD_BASE))
12678       (clobber (match_scratch:SI 3 ""))
12679       (clobber (match_scratch:SI 4 ""))
12680       (clobber (reg:CC FLAGS_REG))])])
12681
12682 (define_insn "*tls_local_dynamic_base_64"
12683   [(set (match_operand:DI 0 "register_operand" "=a")
12684         (call:DI
12685          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12686          (match_operand:DI 2 "" "")))
12687    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12688   "TARGET_64BIT"
12689 {
12690   output_asm_insn
12691     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12692   if (TARGET_SUN_TLS)
12693     return "call\t%p1@plt";
12694   return "call\t%P1";
12695 }
12696   [(set_attr "type" "multi")
12697    (set_attr "length" "12")])
12698
12699 (define_expand "tls_local_dynamic_base_64"
12700   [(parallel
12701      [(set (match_operand:DI 0 "register_operand" "")
12702            (call:DI
12703             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12704             (const_int 0)))
12705       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12706
12707 ;; Local dynamic of a single variable is a lose.  Show combine how
12708 ;; to convert that back to global dynamic.
12709
12710 (define_insn_and_split "*tls_local_dynamic_32_once"
12711   [(set (match_operand:SI 0 "register_operand" "=a")
12712         (plus:SI
12713          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12714                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12715                     UNSPEC_TLS_LD_BASE)
12716          (const:SI (unspec:SI
12717                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12718                     UNSPEC_DTPOFF))))
12719    (clobber (match_scratch:SI 4 "=d"))
12720    (clobber (match_scratch:SI 5 "=c"))
12721    (clobber (reg:CC FLAGS_REG))]
12722   ""
12723   "#"
12724   ""
12725   [(parallel
12726      [(set (match_dup 0)
12727            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12728                       UNSPEC_TLS_GD))
12729       (clobber (match_dup 4))
12730       (clobber (match_dup 5))
12731       (clobber (reg:CC FLAGS_REG))])])
12732
12733 ;; Segment register for the thread base ptr load
12734 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12735
12736 ;; Load and add the thread base pointer from %<tp_seg>:0.
12737 (define_insn "*load_tp_x32"
12738   [(set (match_operand:SI 0 "register_operand" "=r")
12739         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12740   "TARGET_X32"
12741   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12742   [(set_attr "type" "imov")
12743    (set_attr "modrm" "0")
12744    (set_attr "length" "7")
12745    (set_attr "memory" "load")
12746    (set_attr "imm_disp" "false")])
12747
12748 (define_insn "*load_tp_x32_zext"
12749   [(set (match_operand:DI 0 "register_operand" "=r")
12750         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12751   "TARGET_X32"
12752   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12753   [(set_attr "type" "imov")
12754    (set_attr "modrm" "0")
12755    (set_attr "length" "7")
12756    (set_attr "memory" "load")
12757    (set_attr "imm_disp" "false")])
12758
12759 (define_insn "*load_tp_<mode>"
12760   [(set (match_operand:P 0 "register_operand" "=r")
12761         (unspec:P [(const_int 0)] UNSPEC_TP))]
12762   "!TARGET_X32"
12763   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12764   [(set_attr "type" "imov")
12765    (set_attr "modrm" "0")
12766    (set_attr "length" "7")
12767    (set_attr "memory" "load")
12768    (set_attr "imm_disp" "false")])
12769
12770 (define_insn "*add_tp_x32"
12771   [(set (match_operand:SI 0 "register_operand" "=r")
12772         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12773                  (match_operand:SI 1 "register_operand" "0")))
12774    (clobber (reg:CC FLAGS_REG))]
12775   "TARGET_X32"
12776   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12777   [(set_attr "type" "alu")
12778    (set_attr "modrm" "0")
12779    (set_attr "length" "7")
12780    (set_attr "memory" "load")
12781    (set_attr "imm_disp" "false")])
12782
12783 (define_insn "*add_tp_x32_zext"
12784   [(set (match_operand:DI 0 "register_operand" "=r")
12785         (zero_extend:DI
12786           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12787                    (match_operand:SI 1 "register_operand" "0"))))
12788    (clobber (reg:CC FLAGS_REG))]
12789   "TARGET_X32"
12790   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12791   [(set_attr "type" "alu")
12792    (set_attr "modrm" "0")
12793    (set_attr "length" "7")
12794    (set_attr "memory" "load")
12795    (set_attr "imm_disp" "false")])
12796
12797 (define_insn "*add_tp_<mode>"
12798   [(set (match_operand:P 0 "register_operand" "=r")
12799         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12800                 (match_operand:P 1 "register_operand" "0")))
12801    (clobber (reg:CC FLAGS_REG))]
12802   "!TARGET_X32"
12803   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12804   [(set_attr "type" "alu")
12805    (set_attr "modrm" "0")
12806    (set_attr "length" "7")
12807    (set_attr "memory" "load")
12808    (set_attr "imm_disp" "false")])
12809
12810 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12811 ;; %rax as destination of the initial executable code sequence.
12812 (define_insn "tls_initial_exec_64_sun"
12813   [(set (match_operand:DI 0 "register_operand" "=a")
12814         (unspec:DI
12815          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12816          UNSPEC_TLS_IE_SUN))
12817    (clobber (reg:CC FLAGS_REG))]
12818   "TARGET_64BIT && TARGET_SUN_TLS"
12819 {
12820   output_asm_insn
12821     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12822   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12823 }
12824   [(set_attr "type" "multi")])
12825
12826 ;; GNU2 TLS patterns can be split.
12827
12828 (define_expand "tls_dynamic_gnu2_32"
12829   [(set (match_dup 3)
12830         (plus:SI (match_operand:SI 2 "register_operand" "")
12831                  (const:SI
12832                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12833                              UNSPEC_TLSDESC))))
12834    (parallel
12835     [(set (match_operand:SI 0 "register_operand" "")
12836           (unspec:SI [(match_dup 1) (match_dup 3)
12837                       (match_dup 2) (reg:SI SP_REG)]
12838                       UNSPEC_TLSDESC))
12839      (clobber (reg:CC FLAGS_REG))])]
12840   "!TARGET_64BIT && TARGET_GNU2_TLS"
12841 {
12842   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12843   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12844 })
12845
12846 (define_insn "*tls_dynamic_gnu2_lea_32"
12847   [(set (match_operand:SI 0 "register_operand" "=r")
12848         (plus:SI (match_operand:SI 1 "register_operand" "b")
12849                  (const:SI
12850                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12851                               UNSPEC_TLSDESC))))]
12852   "!TARGET_64BIT && TARGET_GNU2_TLS"
12853   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12854   [(set_attr "type" "lea")
12855    (set_attr "mode" "SI")
12856    (set_attr "length" "6")
12857    (set_attr "length_address" "4")])
12858
12859 (define_insn "*tls_dynamic_gnu2_call_32"
12860   [(set (match_operand:SI 0 "register_operand" "=a")
12861         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12862                     (match_operand:SI 2 "register_operand" "0")
12863                     ;; we have to make sure %ebx still points to the GOT
12864                     (match_operand:SI 3 "register_operand" "b")
12865                     (reg:SI SP_REG)]
12866                    UNSPEC_TLSDESC))
12867    (clobber (reg:CC FLAGS_REG))]
12868   "!TARGET_64BIT && TARGET_GNU2_TLS"
12869   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12870   [(set_attr "type" "call")
12871    (set_attr "length" "2")
12872    (set_attr "length_address" "0")])
12873
12874 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12875   [(set (match_operand:SI 0 "register_operand" "=&a")
12876         (plus:SI
12877          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12878                      (match_operand:SI 4 "" "")
12879                      (match_operand:SI 2 "register_operand" "b")
12880                      (reg:SI SP_REG)]
12881                     UNSPEC_TLSDESC)
12882          (const:SI (unspec:SI
12883                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12884                     UNSPEC_DTPOFF))))
12885    (clobber (reg:CC FLAGS_REG))]
12886   "!TARGET_64BIT && TARGET_GNU2_TLS"
12887   "#"
12888   ""
12889   [(set (match_dup 0) (match_dup 5))]
12890 {
12891   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12892   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12893 })
12894
12895 (define_expand "tls_dynamic_gnu2_64"
12896   [(set (match_dup 2)
12897         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12898                    UNSPEC_TLSDESC))
12899    (parallel
12900     [(set (match_operand:DI 0 "register_operand" "")
12901           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12902                      UNSPEC_TLSDESC))
12903      (clobber (reg:CC FLAGS_REG))])]
12904   "TARGET_64BIT && TARGET_GNU2_TLS"
12905 {
12906   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12907   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12908 })
12909
12910 (define_insn "*tls_dynamic_gnu2_lea_64"
12911   [(set (match_operand:DI 0 "register_operand" "=r")
12912         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12913                    UNSPEC_TLSDESC))]
12914   "TARGET_64BIT && TARGET_GNU2_TLS"
12915   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12916   [(set_attr "type" "lea")
12917    (set_attr "mode" "DI")
12918    (set_attr "length" "7")
12919    (set_attr "length_address" "4")])
12920
12921 (define_insn "*tls_dynamic_gnu2_call_64"
12922   [(set (match_operand:DI 0 "register_operand" "=a")
12923         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12924                     (match_operand:DI 2 "register_operand" "0")
12925                     (reg:DI SP_REG)]
12926                    UNSPEC_TLSDESC))
12927    (clobber (reg:CC FLAGS_REG))]
12928   "TARGET_64BIT && TARGET_GNU2_TLS"
12929   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12930   [(set_attr "type" "call")
12931    (set_attr "length" "2")
12932    (set_attr "length_address" "0")])
12933
12934 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12935   [(set (match_operand:DI 0 "register_operand" "=&a")
12936         (plus:DI
12937          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12938                      (match_operand:DI 3 "" "")
12939                      (reg:DI SP_REG)]
12940                     UNSPEC_TLSDESC)
12941          (const:DI (unspec:DI
12942                     [(match_operand 1 "tls_symbolic_operand" "")]
12943                     UNSPEC_DTPOFF))))
12944    (clobber (reg:CC FLAGS_REG))]
12945   "TARGET_64BIT && TARGET_GNU2_TLS"
12946   "#"
12947   ""
12948   [(set (match_dup 0) (match_dup 4))]
12949 {
12950   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12951   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12952 })
12953 \f
12954 ;; These patterns match the binary 387 instructions for addM3, subM3,
12955 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12956 ;; SFmode.  The first is the normal insn, the second the same insn but
12957 ;; with one operand a conversion, and the third the same insn but with
12958 ;; the other operand a conversion.  The conversion may be SFmode or
12959 ;; SImode if the target mode DFmode, but only SImode if the target mode
12960 ;; is SFmode.
12961
12962 ;; Gcc is slightly more smart about handling normal two address instructions
12963 ;; so use special patterns for add and mull.
12964
12965 (define_insn "*fop_<mode>_comm_mixed"
12966   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12967         (match_operator:MODEF 3 "binary_fp_operator"
12968           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12969            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12970   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12971    && COMMUTATIVE_ARITH_P (operands[3])
12972    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12973   "* return output_387_binary_op (insn, operands);"
12974   [(set (attr "type")
12975         (if_then_else (eq_attr "alternative" "1,2")
12976            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12977               (const_string "ssemul")
12978               (const_string "sseadd"))
12979            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12980               (const_string "fmul")
12981               (const_string "fop"))))
12982    (set_attr "isa" "*,noavx,avx")
12983    (set_attr "prefix" "orig,orig,vex")
12984    (set_attr "mode" "<MODE>")])
12985
12986 (define_insn "*fop_<mode>_comm_sse"
12987   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12988         (match_operator:MODEF 3 "binary_fp_operator"
12989           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12990            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12991   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12992    && COMMUTATIVE_ARITH_P (operands[3])
12993    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12994   "* return output_387_binary_op (insn, operands);"
12995   [(set (attr "type")
12996         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12997            (const_string "ssemul")
12998            (const_string "sseadd")))
12999    (set_attr "isa" "noavx,avx")
13000    (set_attr "prefix" "orig,vex")
13001    (set_attr "mode" "<MODE>")])
13002
13003 (define_insn "*fop_<mode>_comm_i387"
13004   [(set (match_operand:MODEF 0 "register_operand" "=f")
13005         (match_operator:MODEF 3 "binary_fp_operator"
13006           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13007            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13008   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13009    && COMMUTATIVE_ARITH_P (operands[3])
13010    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13011   "* return output_387_binary_op (insn, operands);"
13012   [(set (attr "type")
13013         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13014            (const_string "fmul")
13015            (const_string "fop")))
13016    (set_attr "mode" "<MODE>")])
13017
13018 (define_insn "*fop_<mode>_1_mixed"
13019   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13020         (match_operator:MODEF 3 "binary_fp_operator"
13021           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13022            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13023   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13024    && !COMMUTATIVE_ARITH_P (operands[3])
13025    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13026   "* return output_387_binary_op (insn, operands);"
13027   [(set (attr "type")
13028         (cond [(and (eq_attr "alternative" "2,3")
13029                     (match_operand:MODEF 3 "mult_operator" ""))
13030                  (const_string "ssemul")
13031                (and (eq_attr "alternative" "2,3")
13032                     (match_operand:MODEF 3 "div_operator" ""))
13033                  (const_string "ssediv")
13034                (eq_attr "alternative" "2,3")
13035                  (const_string "sseadd")
13036                (match_operand:MODEF 3 "mult_operator" "")
13037                  (const_string "fmul")
13038                (match_operand:MODEF 3 "div_operator" "")
13039                  (const_string "fdiv")
13040               ]
13041               (const_string "fop")))
13042    (set_attr "isa" "*,*,noavx,avx")
13043    (set_attr "prefix" "orig,orig,orig,vex")
13044    (set_attr "mode" "<MODE>")])
13045
13046 (define_insn "*rcpsf2_sse"
13047   [(set (match_operand:SF 0 "register_operand" "=x")
13048         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13049                    UNSPEC_RCP))]
13050   "TARGET_SSE_MATH"
13051   "%vrcpss\t{%1, %d0|%d0, %1}"
13052   [(set_attr "type" "sse")
13053    (set_attr "atom_sse_attr" "rcp")
13054    (set_attr "prefix" "maybe_vex")
13055    (set_attr "mode" "SF")])
13056
13057 (define_insn "*fop_<mode>_1_sse"
13058   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13059         (match_operator:MODEF 3 "binary_fp_operator"
13060           [(match_operand:MODEF 1 "register_operand" "0,x")
13061            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13062   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13063    && !COMMUTATIVE_ARITH_P (operands[3])"
13064   "* return output_387_binary_op (insn, operands);"
13065   [(set (attr "type")
13066         (cond [(match_operand:MODEF 3 "mult_operator" "")
13067                  (const_string "ssemul")
13068                (match_operand:MODEF 3 "div_operator" "")
13069                  (const_string "ssediv")
13070               ]
13071               (const_string "sseadd")))
13072    (set_attr "isa" "noavx,avx")
13073    (set_attr "prefix" "orig,vex")
13074    (set_attr "mode" "<MODE>")])
13075
13076 ;; This pattern is not fully shadowed by the pattern above.
13077 (define_insn "*fop_<mode>_1_i387"
13078   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13079         (match_operator:MODEF 3 "binary_fp_operator"
13080           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13081            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13082   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13083    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13084    && !COMMUTATIVE_ARITH_P (operands[3])
13085    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13086   "* return output_387_binary_op (insn, operands);"
13087   [(set (attr "type")
13088         (cond [(match_operand:MODEF 3 "mult_operator" "")
13089                  (const_string "fmul")
13090                (match_operand:MODEF 3 "div_operator" "")
13091                  (const_string "fdiv")
13092               ]
13093               (const_string "fop")))
13094    (set_attr "mode" "<MODE>")])
13095
13096 ;; ??? Add SSE splitters for these!
13097 (define_insn "*fop_<MODEF:mode>_2_i387"
13098   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13099         (match_operator:MODEF 3 "binary_fp_operator"
13100           [(float:MODEF
13101              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13102            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13103   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13104    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13105    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13106   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13107   [(set (attr "type")
13108         (cond [(match_operand:MODEF 3 "mult_operator" "")
13109                  (const_string "fmul")
13110                (match_operand:MODEF 3 "div_operator" "")
13111                  (const_string "fdiv")
13112               ]
13113               (const_string "fop")))
13114    (set_attr "fp_int_src" "true")
13115    (set_attr "mode" "<SWI24:MODE>")])
13116
13117 (define_insn "*fop_<MODEF:mode>_3_i387"
13118   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13119         (match_operator:MODEF 3 "binary_fp_operator"
13120           [(match_operand:MODEF 1 "register_operand" "0,0")
13121            (float:MODEF
13122              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13123   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13124    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13125    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13126   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13127   [(set (attr "type")
13128         (cond [(match_operand:MODEF 3 "mult_operator" "")
13129                  (const_string "fmul")
13130                (match_operand:MODEF 3 "div_operator" "")
13131                  (const_string "fdiv")
13132               ]
13133               (const_string "fop")))
13134    (set_attr "fp_int_src" "true")
13135    (set_attr "mode" "<MODE>")])
13136
13137 (define_insn "*fop_df_4_i387"
13138   [(set (match_operand:DF 0 "register_operand" "=f,f")
13139         (match_operator:DF 3 "binary_fp_operator"
13140            [(float_extend:DF
13141              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13142             (match_operand:DF 2 "register_operand" "0,f")]))]
13143   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13144    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13145    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13146   "* return output_387_binary_op (insn, operands);"
13147   [(set (attr "type")
13148         (cond [(match_operand:DF 3 "mult_operator" "")
13149                  (const_string "fmul")
13150                (match_operand:DF 3 "div_operator" "")
13151                  (const_string "fdiv")
13152               ]
13153               (const_string "fop")))
13154    (set_attr "mode" "SF")])
13155
13156 (define_insn "*fop_df_5_i387"
13157   [(set (match_operand:DF 0 "register_operand" "=f,f")
13158         (match_operator:DF 3 "binary_fp_operator"
13159           [(match_operand:DF 1 "register_operand" "0,f")
13160            (float_extend:DF
13161             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13162   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13163    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13164   "* return output_387_binary_op (insn, operands);"
13165   [(set (attr "type")
13166         (cond [(match_operand:DF 3 "mult_operator" "")
13167                  (const_string "fmul")
13168                (match_operand:DF 3 "div_operator" "")
13169                  (const_string "fdiv")
13170               ]
13171               (const_string "fop")))
13172    (set_attr "mode" "SF")])
13173
13174 (define_insn "*fop_df_6_i387"
13175   [(set (match_operand:DF 0 "register_operand" "=f,f")
13176         (match_operator:DF 3 "binary_fp_operator"
13177           [(float_extend:DF
13178             (match_operand:SF 1 "register_operand" "0,f"))
13179            (float_extend:DF
13180             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13181   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13182    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13183   "* return output_387_binary_op (insn, operands);"
13184   [(set (attr "type")
13185         (cond [(match_operand:DF 3 "mult_operator" "")
13186                  (const_string "fmul")
13187                (match_operand:DF 3 "div_operator" "")
13188                  (const_string "fdiv")
13189               ]
13190               (const_string "fop")))
13191    (set_attr "mode" "SF")])
13192
13193 (define_insn "*fop_xf_comm_i387"
13194   [(set (match_operand:XF 0 "register_operand" "=f")
13195         (match_operator:XF 3 "binary_fp_operator"
13196                         [(match_operand:XF 1 "register_operand" "%0")
13197                          (match_operand:XF 2 "register_operand" "f")]))]
13198   "TARGET_80387
13199    && COMMUTATIVE_ARITH_P (operands[3])"
13200   "* return output_387_binary_op (insn, operands);"
13201   [(set (attr "type")
13202         (if_then_else (match_operand:XF 3 "mult_operator" "")
13203            (const_string "fmul")
13204            (const_string "fop")))
13205    (set_attr "mode" "XF")])
13206
13207 (define_insn "*fop_xf_1_i387"
13208   [(set (match_operand:XF 0 "register_operand" "=f,f")
13209         (match_operator:XF 3 "binary_fp_operator"
13210                         [(match_operand:XF 1 "register_operand" "0,f")
13211                          (match_operand:XF 2 "register_operand" "f,0")]))]
13212   "TARGET_80387
13213    && !COMMUTATIVE_ARITH_P (operands[3])"
13214   "* return output_387_binary_op (insn, operands);"
13215   [(set (attr "type")
13216         (cond [(match_operand:XF 3 "mult_operator" "")
13217                  (const_string "fmul")
13218                (match_operand:XF 3 "div_operator" "")
13219                  (const_string "fdiv")
13220               ]
13221               (const_string "fop")))
13222    (set_attr "mode" "XF")])
13223
13224 (define_insn "*fop_xf_2_i387"
13225   [(set (match_operand:XF 0 "register_operand" "=f,f")
13226         (match_operator:XF 3 "binary_fp_operator"
13227           [(float:XF
13228              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13229            (match_operand:XF 2 "register_operand" "0,0")]))]
13230   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13231   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13232   [(set (attr "type")
13233         (cond [(match_operand:XF 3 "mult_operator" "")
13234                  (const_string "fmul")
13235                (match_operand:XF 3 "div_operator" "")
13236                  (const_string "fdiv")
13237               ]
13238               (const_string "fop")))
13239    (set_attr "fp_int_src" "true")
13240    (set_attr "mode" "<MODE>")])
13241
13242 (define_insn "*fop_xf_3_i387"
13243   [(set (match_operand:XF 0 "register_operand" "=f,f")
13244         (match_operator:XF 3 "binary_fp_operator"
13245           [(match_operand:XF 1 "register_operand" "0,0")
13246            (float:XF
13247              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13248   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13249   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13250   [(set (attr "type")
13251         (cond [(match_operand:XF 3 "mult_operator" "")
13252                  (const_string "fmul")
13253                (match_operand:XF 3 "div_operator" "")
13254                  (const_string "fdiv")
13255               ]
13256               (const_string "fop")))
13257    (set_attr "fp_int_src" "true")
13258    (set_attr "mode" "<MODE>")])
13259
13260 (define_insn "*fop_xf_4_i387"
13261   [(set (match_operand:XF 0 "register_operand" "=f,f")
13262         (match_operator:XF 3 "binary_fp_operator"
13263            [(float_extend:XF
13264               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13265             (match_operand:XF 2 "register_operand" "0,f")]))]
13266   "TARGET_80387"
13267   "* return output_387_binary_op (insn, operands);"
13268   [(set (attr "type")
13269         (cond [(match_operand:XF 3 "mult_operator" "")
13270                  (const_string "fmul")
13271                (match_operand:XF 3 "div_operator" "")
13272                  (const_string "fdiv")
13273               ]
13274               (const_string "fop")))
13275    (set_attr "mode" "<MODE>")])
13276
13277 (define_insn "*fop_xf_5_i387"
13278   [(set (match_operand:XF 0 "register_operand" "=f,f")
13279         (match_operator:XF 3 "binary_fp_operator"
13280           [(match_operand:XF 1 "register_operand" "0,f")
13281            (float_extend:XF
13282              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13283   "TARGET_80387"
13284   "* return output_387_binary_op (insn, operands);"
13285   [(set (attr "type")
13286         (cond [(match_operand:XF 3 "mult_operator" "")
13287                  (const_string "fmul")
13288                (match_operand:XF 3 "div_operator" "")
13289                  (const_string "fdiv")
13290               ]
13291               (const_string "fop")))
13292    (set_attr "mode" "<MODE>")])
13293
13294 (define_insn "*fop_xf_6_i387"
13295   [(set (match_operand:XF 0 "register_operand" "=f,f")
13296         (match_operator:XF 3 "binary_fp_operator"
13297           [(float_extend:XF
13298              (match_operand:MODEF 1 "register_operand" "0,f"))
13299            (float_extend:XF
13300              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13301   "TARGET_80387"
13302   "* return output_387_binary_op (insn, operands);"
13303   [(set (attr "type")
13304         (cond [(match_operand:XF 3 "mult_operator" "")
13305                  (const_string "fmul")
13306                (match_operand:XF 3 "div_operator" "")
13307                  (const_string "fdiv")
13308               ]
13309               (const_string "fop")))
13310    (set_attr "mode" "<MODE>")])
13311
13312 (define_split
13313   [(set (match_operand 0 "register_operand" "")
13314         (match_operator 3 "binary_fp_operator"
13315            [(float (match_operand:SWI24 1 "register_operand" ""))
13316             (match_operand 2 "register_operand" "")]))]
13317   "reload_completed
13318    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13319    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13320   [(const_int 0)]
13321 {
13322   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13323   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13324   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13325                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13326                                           GET_MODE (operands[3]),
13327                                           operands[4],
13328                                           operands[2])));
13329   ix86_free_from_memory (GET_MODE (operands[1]));
13330   DONE;
13331 })
13332
13333 (define_split
13334   [(set (match_operand 0 "register_operand" "")
13335         (match_operator 3 "binary_fp_operator"
13336            [(match_operand 1 "register_operand" "")
13337             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13338   "reload_completed
13339    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13340    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13341   [(const_int 0)]
13342 {
13343   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13344   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13345   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13346                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13347                                           GET_MODE (operands[3]),
13348                                           operands[1],
13349                                           operands[4])));
13350   ix86_free_from_memory (GET_MODE (operands[2]));
13351   DONE;
13352 })
13353 \f
13354 ;; FPU special functions.
13355
13356 ;; This pattern implements a no-op XFmode truncation for
13357 ;; all fancy i386 XFmode math functions.
13358
13359 (define_insn "truncxf<mode>2_i387_noop_unspec"
13360   [(set (match_operand:MODEF 0 "register_operand" "=f")
13361         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13362         UNSPEC_TRUNC_NOOP))]
13363   "TARGET_USE_FANCY_MATH_387"
13364   "* return output_387_reg_move (insn, operands);"
13365   [(set_attr "type" "fmov")
13366    (set_attr "mode" "<MODE>")])
13367
13368 (define_insn "sqrtxf2"
13369   [(set (match_operand:XF 0 "register_operand" "=f")
13370         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13371   "TARGET_USE_FANCY_MATH_387"
13372   "fsqrt"
13373   [(set_attr "type" "fpspc")
13374    (set_attr "mode" "XF")
13375    (set_attr "athlon_decode" "direct")
13376    (set_attr "amdfam10_decode" "direct")
13377    (set_attr "bdver1_decode" "direct")])
13378
13379 (define_insn "sqrt_extend<mode>xf2_i387"
13380   [(set (match_operand:XF 0 "register_operand" "=f")
13381         (sqrt:XF
13382           (float_extend:XF
13383             (match_operand:MODEF 1 "register_operand" "0"))))]
13384   "TARGET_USE_FANCY_MATH_387"
13385   "fsqrt"
13386   [(set_attr "type" "fpspc")
13387    (set_attr "mode" "XF")
13388    (set_attr "athlon_decode" "direct")
13389    (set_attr "amdfam10_decode" "direct")
13390    (set_attr "bdver1_decode" "direct")])
13391
13392 (define_insn "*rsqrtsf2_sse"
13393   [(set (match_operand:SF 0 "register_operand" "=x")
13394         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13395                    UNSPEC_RSQRT))]
13396   "TARGET_SSE_MATH"
13397   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13398   [(set_attr "type" "sse")
13399    (set_attr "atom_sse_attr" "rcp")
13400    (set_attr "prefix" "maybe_vex")
13401    (set_attr "mode" "SF")])
13402
13403 (define_expand "rsqrtsf2"
13404   [(set (match_operand:SF 0 "register_operand" "")
13405         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13406                    UNSPEC_RSQRT))]
13407   "TARGET_SSE_MATH"
13408 {
13409   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13410   DONE;
13411 })
13412
13413 (define_insn "*sqrt<mode>2_sse"
13414   [(set (match_operand:MODEF 0 "register_operand" "=x")
13415         (sqrt:MODEF
13416           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13417   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13418   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13419   [(set_attr "type" "sse")
13420    (set_attr "atom_sse_attr" "sqrt")
13421    (set_attr "prefix" "maybe_vex")
13422    (set_attr "mode" "<MODE>")
13423    (set_attr "athlon_decode" "*")
13424    (set_attr "amdfam10_decode" "*")
13425    (set_attr "bdver1_decode" "*")])
13426
13427 (define_expand "sqrt<mode>2"
13428   [(set (match_operand:MODEF 0 "register_operand" "")
13429         (sqrt:MODEF
13430           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13431   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13432    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13433 {
13434   if (<MODE>mode == SFmode
13435       && TARGET_SSE_MATH
13436       && TARGET_RECIP_SQRT
13437       && !optimize_function_for_size_p (cfun)
13438       && flag_finite_math_only && !flag_trapping_math
13439       && flag_unsafe_math_optimizations)
13440     {
13441       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13442       DONE;
13443     }
13444
13445   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13446     {
13447       rtx op0 = gen_reg_rtx (XFmode);
13448       rtx op1 = force_reg (<MODE>mode, operands[1]);
13449
13450       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13451       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13452       DONE;
13453    }
13454 })
13455
13456 (define_insn "fpremxf4_i387"
13457   [(set (match_operand:XF 0 "register_operand" "=f")
13458         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13459                     (match_operand:XF 3 "register_operand" "1")]
13460                    UNSPEC_FPREM_F))
13461    (set (match_operand:XF 1 "register_operand" "=u")
13462         (unspec:XF [(match_dup 2) (match_dup 3)]
13463                    UNSPEC_FPREM_U))
13464    (set (reg:CCFP FPSR_REG)
13465         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13466                      UNSPEC_C2_FLAG))]
13467   "TARGET_USE_FANCY_MATH_387"
13468   "fprem"
13469   [(set_attr "type" "fpspc")
13470    (set_attr "mode" "XF")])
13471
13472 (define_expand "fmodxf3"
13473   [(use (match_operand:XF 0 "register_operand" ""))
13474    (use (match_operand:XF 1 "general_operand" ""))
13475    (use (match_operand:XF 2 "general_operand" ""))]
13476   "TARGET_USE_FANCY_MATH_387"
13477 {
13478   rtx label = gen_label_rtx ();
13479
13480   rtx op1 = gen_reg_rtx (XFmode);
13481   rtx op2 = gen_reg_rtx (XFmode);
13482
13483   emit_move_insn (op2, operands[2]);
13484   emit_move_insn (op1, operands[1]);
13485
13486   emit_label (label);
13487   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13488   ix86_emit_fp_unordered_jump (label);
13489   LABEL_NUSES (label) = 1;
13490
13491   emit_move_insn (operands[0], op1);
13492   DONE;
13493 })
13494
13495 (define_expand "fmod<mode>3"
13496   [(use (match_operand:MODEF 0 "register_operand" ""))
13497    (use (match_operand:MODEF 1 "general_operand" ""))
13498    (use (match_operand:MODEF 2 "general_operand" ""))]
13499   "TARGET_USE_FANCY_MATH_387"
13500 {
13501   rtx (*gen_truncxf) (rtx, rtx);
13502
13503   rtx label = gen_label_rtx ();
13504
13505   rtx op1 = gen_reg_rtx (XFmode);
13506   rtx op2 = gen_reg_rtx (XFmode);
13507
13508   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13509   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13510
13511   emit_label (label);
13512   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13513   ix86_emit_fp_unordered_jump (label);
13514   LABEL_NUSES (label) = 1;
13515
13516   /* Truncate the result properly for strict SSE math.  */
13517   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13518       && !TARGET_MIX_SSE_I387)
13519     gen_truncxf = gen_truncxf<mode>2;
13520   else
13521     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13522
13523   emit_insn (gen_truncxf (operands[0], op1));
13524   DONE;
13525 })
13526
13527 (define_insn "fprem1xf4_i387"
13528   [(set (match_operand:XF 0 "register_operand" "=f")
13529         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13530                     (match_operand:XF 3 "register_operand" "1")]
13531                    UNSPEC_FPREM1_F))
13532    (set (match_operand:XF 1 "register_operand" "=u")
13533         (unspec:XF [(match_dup 2) (match_dup 3)]
13534                    UNSPEC_FPREM1_U))
13535    (set (reg:CCFP FPSR_REG)
13536         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13537                      UNSPEC_C2_FLAG))]
13538   "TARGET_USE_FANCY_MATH_387"
13539   "fprem1"
13540   [(set_attr "type" "fpspc")
13541    (set_attr "mode" "XF")])
13542
13543 (define_expand "remainderxf3"
13544   [(use (match_operand:XF 0 "register_operand" ""))
13545    (use (match_operand:XF 1 "general_operand" ""))
13546    (use (match_operand:XF 2 "general_operand" ""))]
13547   "TARGET_USE_FANCY_MATH_387"
13548 {
13549   rtx label = gen_label_rtx ();
13550
13551   rtx op1 = gen_reg_rtx (XFmode);
13552   rtx op2 = gen_reg_rtx (XFmode);
13553
13554   emit_move_insn (op2, operands[2]);
13555   emit_move_insn (op1, operands[1]);
13556
13557   emit_label (label);
13558   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13559   ix86_emit_fp_unordered_jump (label);
13560   LABEL_NUSES (label) = 1;
13561
13562   emit_move_insn (operands[0], op1);
13563   DONE;
13564 })
13565
13566 (define_expand "remainder<mode>3"
13567   [(use (match_operand:MODEF 0 "register_operand" ""))
13568    (use (match_operand:MODEF 1 "general_operand" ""))
13569    (use (match_operand:MODEF 2 "general_operand" ""))]
13570   "TARGET_USE_FANCY_MATH_387"
13571 {
13572   rtx (*gen_truncxf) (rtx, rtx);
13573
13574   rtx label = gen_label_rtx ();
13575
13576   rtx op1 = gen_reg_rtx (XFmode);
13577   rtx op2 = gen_reg_rtx (XFmode);
13578
13579   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13580   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13581
13582   emit_label (label);
13583
13584   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13585   ix86_emit_fp_unordered_jump (label);
13586   LABEL_NUSES (label) = 1;
13587
13588   /* Truncate the result properly for strict SSE math.  */
13589   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13590       && !TARGET_MIX_SSE_I387)
13591     gen_truncxf = gen_truncxf<mode>2;
13592   else
13593     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13594
13595   emit_insn (gen_truncxf (operands[0], op1));
13596   DONE;
13597 })
13598
13599 (define_insn "*sinxf2_i387"
13600   [(set (match_operand:XF 0 "register_operand" "=f")
13601         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13602   "TARGET_USE_FANCY_MATH_387
13603    && flag_unsafe_math_optimizations"
13604   "fsin"
13605   [(set_attr "type" "fpspc")
13606    (set_attr "mode" "XF")])
13607
13608 (define_insn "*sin_extend<mode>xf2_i387"
13609   [(set (match_operand:XF 0 "register_operand" "=f")
13610         (unspec:XF [(float_extend:XF
13611                       (match_operand:MODEF 1 "register_operand" "0"))]
13612                    UNSPEC_SIN))]
13613   "TARGET_USE_FANCY_MATH_387
13614    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13615        || TARGET_MIX_SSE_I387)
13616    && flag_unsafe_math_optimizations"
13617   "fsin"
13618   [(set_attr "type" "fpspc")
13619    (set_attr "mode" "XF")])
13620
13621 (define_insn "*cosxf2_i387"
13622   [(set (match_operand:XF 0 "register_operand" "=f")
13623         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13624   "TARGET_USE_FANCY_MATH_387
13625    && flag_unsafe_math_optimizations"
13626   "fcos"
13627   [(set_attr "type" "fpspc")
13628    (set_attr "mode" "XF")])
13629
13630 (define_insn "*cos_extend<mode>xf2_i387"
13631   [(set (match_operand:XF 0 "register_operand" "=f")
13632         (unspec:XF [(float_extend:XF
13633                       (match_operand:MODEF 1 "register_operand" "0"))]
13634                    UNSPEC_COS))]
13635   "TARGET_USE_FANCY_MATH_387
13636    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13637        || TARGET_MIX_SSE_I387)
13638    && flag_unsafe_math_optimizations"
13639   "fcos"
13640   [(set_attr "type" "fpspc")
13641    (set_attr "mode" "XF")])
13642
13643 ;; When sincos pattern is defined, sin and cos builtin functions will be
13644 ;; expanded to sincos pattern with one of its outputs left unused.
13645 ;; CSE pass will figure out if two sincos patterns can be combined,
13646 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13647 ;; depending on the unused output.
13648
13649 (define_insn "sincosxf3"
13650   [(set (match_operand:XF 0 "register_operand" "=f")
13651         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13652                    UNSPEC_SINCOS_COS))
13653    (set (match_operand:XF 1 "register_operand" "=u")
13654         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13655   "TARGET_USE_FANCY_MATH_387
13656    && flag_unsafe_math_optimizations"
13657   "fsincos"
13658   [(set_attr "type" "fpspc")
13659    (set_attr "mode" "XF")])
13660
13661 (define_split
13662   [(set (match_operand:XF 0 "register_operand" "")
13663         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13664                    UNSPEC_SINCOS_COS))
13665    (set (match_operand:XF 1 "register_operand" "")
13666         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13667   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13668    && can_create_pseudo_p ()"
13669   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13670
13671 (define_split
13672   [(set (match_operand:XF 0 "register_operand" "")
13673         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13674                    UNSPEC_SINCOS_COS))
13675    (set (match_operand:XF 1 "register_operand" "")
13676         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13677   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13678    && can_create_pseudo_p ()"
13679   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13680
13681 (define_insn "sincos_extend<mode>xf3_i387"
13682   [(set (match_operand:XF 0 "register_operand" "=f")
13683         (unspec:XF [(float_extend:XF
13684                       (match_operand:MODEF 2 "register_operand" "0"))]
13685                    UNSPEC_SINCOS_COS))
13686    (set (match_operand:XF 1 "register_operand" "=u")
13687         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13688   "TARGET_USE_FANCY_MATH_387
13689    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13690        || TARGET_MIX_SSE_I387)
13691    && flag_unsafe_math_optimizations"
13692   "fsincos"
13693   [(set_attr "type" "fpspc")
13694    (set_attr "mode" "XF")])
13695
13696 (define_split
13697   [(set (match_operand:XF 0 "register_operand" "")
13698         (unspec:XF [(float_extend:XF
13699                       (match_operand:MODEF 2 "register_operand" ""))]
13700                    UNSPEC_SINCOS_COS))
13701    (set (match_operand:XF 1 "register_operand" "")
13702         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13703   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13704    && can_create_pseudo_p ()"
13705   [(set (match_dup 1)
13706         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13707
13708 (define_split
13709   [(set (match_operand:XF 0 "register_operand" "")
13710         (unspec:XF [(float_extend:XF
13711                       (match_operand:MODEF 2 "register_operand" ""))]
13712                    UNSPEC_SINCOS_COS))
13713    (set (match_operand:XF 1 "register_operand" "")
13714         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13715   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13716    && can_create_pseudo_p ()"
13717   [(set (match_dup 0)
13718         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13719
13720 (define_expand "sincos<mode>3"
13721   [(use (match_operand:MODEF 0 "register_operand" ""))
13722    (use (match_operand:MODEF 1 "register_operand" ""))
13723    (use (match_operand:MODEF 2 "register_operand" ""))]
13724   "TARGET_USE_FANCY_MATH_387
13725    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13726        || TARGET_MIX_SSE_I387)
13727    && flag_unsafe_math_optimizations"
13728 {
13729   rtx op0 = gen_reg_rtx (XFmode);
13730   rtx op1 = gen_reg_rtx (XFmode);
13731
13732   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13733   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13734   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13735   DONE;
13736 })
13737
13738 (define_insn "fptanxf4_i387"
13739   [(set (match_operand:XF 0 "register_operand" "=f")
13740         (match_operand:XF 3 "const_double_operand" "F"))
13741    (set (match_operand:XF 1 "register_operand" "=u")
13742         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13743                    UNSPEC_TAN))]
13744   "TARGET_USE_FANCY_MATH_387
13745    && flag_unsafe_math_optimizations
13746    && standard_80387_constant_p (operands[3]) == 2"
13747   "fptan"
13748   [(set_attr "type" "fpspc")
13749    (set_attr "mode" "XF")])
13750
13751 (define_insn "fptan_extend<mode>xf4_i387"
13752   [(set (match_operand:MODEF 0 "register_operand" "=f")
13753         (match_operand:MODEF 3 "const_double_operand" "F"))
13754    (set (match_operand:XF 1 "register_operand" "=u")
13755         (unspec:XF [(float_extend:XF
13756                       (match_operand:MODEF 2 "register_operand" "0"))]
13757                    UNSPEC_TAN))]
13758   "TARGET_USE_FANCY_MATH_387
13759    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13760        || TARGET_MIX_SSE_I387)
13761    && flag_unsafe_math_optimizations
13762    && standard_80387_constant_p (operands[3]) == 2"
13763   "fptan"
13764   [(set_attr "type" "fpspc")
13765    (set_attr "mode" "XF")])
13766
13767 (define_expand "tanxf2"
13768   [(use (match_operand:XF 0 "register_operand" ""))
13769    (use (match_operand:XF 1 "register_operand" ""))]
13770   "TARGET_USE_FANCY_MATH_387
13771    && flag_unsafe_math_optimizations"
13772 {
13773   rtx one = gen_reg_rtx (XFmode);
13774   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13775
13776   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13777   DONE;
13778 })
13779
13780 (define_expand "tan<mode>2"
13781   [(use (match_operand:MODEF 0 "register_operand" ""))
13782    (use (match_operand:MODEF 1 "register_operand" ""))]
13783   "TARGET_USE_FANCY_MATH_387
13784    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13785        || TARGET_MIX_SSE_I387)
13786    && flag_unsafe_math_optimizations"
13787 {
13788   rtx op0 = gen_reg_rtx (XFmode);
13789
13790   rtx one = gen_reg_rtx (<MODE>mode);
13791   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13792
13793   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13794                                              operands[1], op2));
13795   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13796   DONE;
13797 })
13798
13799 (define_insn "*fpatanxf3_i387"
13800   [(set (match_operand:XF 0 "register_operand" "=f")
13801         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13802                     (match_operand:XF 2 "register_operand" "u")]
13803                    UNSPEC_FPATAN))
13804    (clobber (match_scratch:XF 3 "=2"))]
13805   "TARGET_USE_FANCY_MATH_387
13806    && flag_unsafe_math_optimizations"
13807   "fpatan"
13808   [(set_attr "type" "fpspc")
13809    (set_attr "mode" "XF")])
13810
13811 (define_insn "fpatan_extend<mode>xf3_i387"
13812   [(set (match_operand:XF 0 "register_operand" "=f")
13813         (unspec:XF [(float_extend:XF
13814                       (match_operand:MODEF 1 "register_operand" "0"))
13815                     (float_extend:XF
13816                       (match_operand:MODEF 2 "register_operand" "u"))]
13817                    UNSPEC_FPATAN))
13818    (clobber (match_scratch:XF 3 "=2"))]
13819   "TARGET_USE_FANCY_MATH_387
13820    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13821        || TARGET_MIX_SSE_I387)
13822    && flag_unsafe_math_optimizations"
13823   "fpatan"
13824   [(set_attr "type" "fpspc")
13825    (set_attr "mode" "XF")])
13826
13827 (define_expand "atan2xf3"
13828   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13829                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13830                                (match_operand:XF 1 "register_operand" "")]
13831                               UNSPEC_FPATAN))
13832               (clobber (match_scratch:XF 3 ""))])]
13833   "TARGET_USE_FANCY_MATH_387
13834    && flag_unsafe_math_optimizations")
13835
13836 (define_expand "atan2<mode>3"
13837   [(use (match_operand:MODEF 0 "register_operand" ""))
13838    (use (match_operand:MODEF 1 "register_operand" ""))
13839    (use (match_operand:MODEF 2 "register_operand" ""))]
13840   "TARGET_USE_FANCY_MATH_387
13841    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13842        || TARGET_MIX_SSE_I387)
13843    && flag_unsafe_math_optimizations"
13844 {
13845   rtx op0 = gen_reg_rtx (XFmode);
13846
13847   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13848   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13849   DONE;
13850 })
13851
13852 (define_expand "atanxf2"
13853   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13854                    (unspec:XF [(match_dup 2)
13855                                (match_operand:XF 1 "register_operand" "")]
13856                               UNSPEC_FPATAN))
13857               (clobber (match_scratch:XF 3 ""))])]
13858   "TARGET_USE_FANCY_MATH_387
13859    && flag_unsafe_math_optimizations"
13860 {
13861   operands[2] = gen_reg_rtx (XFmode);
13862   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13863 })
13864
13865 (define_expand "atan<mode>2"
13866   [(use (match_operand:MODEF 0 "register_operand" ""))
13867    (use (match_operand:MODEF 1 "register_operand" ""))]
13868   "TARGET_USE_FANCY_MATH_387
13869    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13870        || TARGET_MIX_SSE_I387)
13871    && flag_unsafe_math_optimizations"
13872 {
13873   rtx op0 = gen_reg_rtx (XFmode);
13874
13875   rtx op2 = gen_reg_rtx (<MODE>mode);
13876   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13877
13878   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13879   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13880   DONE;
13881 })
13882
13883 (define_expand "asinxf2"
13884   [(set (match_dup 2)
13885         (mult:XF (match_operand:XF 1 "register_operand" "")
13886                  (match_dup 1)))
13887    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13888    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13889    (parallel [(set (match_operand:XF 0 "register_operand" "")
13890                    (unspec:XF [(match_dup 5) (match_dup 1)]
13891                               UNSPEC_FPATAN))
13892               (clobber (match_scratch:XF 6 ""))])]
13893   "TARGET_USE_FANCY_MATH_387
13894    && flag_unsafe_math_optimizations"
13895 {
13896   int i;
13897
13898   if (optimize_insn_for_size_p ())
13899     FAIL;
13900
13901   for (i = 2; i < 6; i++)
13902     operands[i] = gen_reg_rtx (XFmode);
13903
13904   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13905 })
13906
13907 (define_expand "asin<mode>2"
13908   [(use (match_operand:MODEF 0 "register_operand" ""))
13909    (use (match_operand:MODEF 1 "general_operand" ""))]
13910  "TARGET_USE_FANCY_MATH_387
13911    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13912        || TARGET_MIX_SSE_I387)
13913    && flag_unsafe_math_optimizations"
13914 {
13915   rtx op0 = gen_reg_rtx (XFmode);
13916   rtx op1 = gen_reg_rtx (XFmode);
13917
13918   if (optimize_insn_for_size_p ())
13919     FAIL;
13920
13921   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13922   emit_insn (gen_asinxf2 (op0, op1));
13923   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13924   DONE;
13925 })
13926
13927 (define_expand "acosxf2"
13928   [(set (match_dup 2)
13929         (mult:XF (match_operand:XF 1 "register_operand" "")
13930                  (match_dup 1)))
13931    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13932    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13933    (parallel [(set (match_operand:XF 0 "register_operand" "")
13934                    (unspec:XF [(match_dup 1) (match_dup 5)]
13935                               UNSPEC_FPATAN))
13936               (clobber (match_scratch:XF 6 ""))])]
13937   "TARGET_USE_FANCY_MATH_387
13938    && flag_unsafe_math_optimizations"
13939 {
13940   int i;
13941
13942   if (optimize_insn_for_size_p ())
13943     FAIL;
13944
13945   for (i = 2; i < 6; i++)
13946     operands[i] = gen_reg_rtx (XFmode);
13947
13948   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13949 })
13950
13951 (define_expand "acos<mode>2"
13952   [(use (match_operand:MODEF 0 "register_operand" ""))
13953    (use (match_operand:MODEF 1 "general_operand" ""))]
13954  "TARGET_USE_FANCY_MATH_387
13955    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13956        || TARGET_MIX_SSE_I387)
13957    && flag_unsafe_math_optimizations"
13958 {
13959   rtx op0 = gen_reg_rtx (XFmode);
13960   rtx op1 = gen_reg_rtx (XFmode);
13961
13962   if (optimize_insn_for_size_p ())
13963     FAIL;
13964
13965   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13966   emit_insn (gen_acosxf2 (op0, op1));
13967   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13968   DONE;
13969 })
13970
13971 (define_insn "fyl2xxf3_i387"
13972   [(set (match_operand:XF 0 "register_operand" "=f")
13973         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13974                     (match_operand:XF 2 "register_operand" "u")]
13975                    UNSPEC_FYL2X))
13976    (clobber (match_scratch:XF 3 "=2"))]
13977   "TARGET_USE_FANCY_MATH_387
13978    && flag_unsafe_math_optimizations"
13979   "fyl2x"
13980   [(set_attr "type" "fpspc")
13981    (set_attr "mode" "XF")])
13982
13983 (define_insn "fyl2x_extend<mode>xf3_i387"
13984   [(set (match_operand:XF 0 "register_operand" "=f")
13985         (unspec:XF [(float_extend:XF
13986                       (match_operand:MODEF 1 "register_operand" "0"))
13987                     (match_operand:XF 2 "register_operand" "u")]
13988                    UNSPEC_FYL2X))
13989    (clobber (match_scratch:XF 3 "=2"))]
13990   "TARGET_USE_FANCY_MATH_387
13991    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13992        || TARGET_MIX_SSE_I387)
13993    && flag_unsafe_math_optimizations"
13994   "fyl2x"
13995   [(set_attr "type" "fpspc")
13996    (set_attr "mode" "XF")])
13997
13998 (define_expand "logxf2"
13999   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14000                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14001                                (match_dup 2)] UNSPEC_FYL2X))
14002               (clobber (match_scratch:XF 3 ""))])]
14003   "TARGET_USE_FANCY_MATH_387
14004    && flag_unsafe_math_optimizations"
14005 {
14006   operands[2] = gen_reg_rtx (XFmode);
14007   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14008 })
14009
14010 (define_expand "log<mode>2"
14011   [(use (match_operand:MODEF 0 "register_operand" ""))
14012    (use (match_operand:MODEF 1 "register_operand" ""))]
14013   "TARGET_USE_FANCY_MATH_387
14014    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14015        || TARGET_MIX_SSE_I387)
14016    && flag_unsafe_math_optimizations"
14017 {
14018   rtx op0 = gen_reg_rtx (XFmode);
14019
14020   rtx op2 = gen_reg_rtx (XFmode);
14021   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14022
14023   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14024   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14025   DONE;
14026 })
14027
14028 (define_expand "log10xf2"
14029   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14030                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14031                                (match_dup 2)] UNSPEC_FYL2X))
14032               (clobber (match_scratch:XF 3 ""))])]
14033   "TARGET_USE_FANCY_MATH_387
14034    && flag_unsafe_math_optimizations"
14035 {
14036   operands[2] = gen_reg_rtx (XFmode);
14037   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14038 })
14039
14040 (define_expand "log10<mode>2"
14041   [(use (match_operand:MODEF 0 "register_operand" ""))
14042    (use (match_operand:MODEF 1 "register_operand" ""))]
14043   "TARGET_USE_FANCY_MATH_387
14044    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14045        || TARGET_MIX_SSE_I387)
14046    && flag_unsafe_math_optimizations"
14047 {
14048   rtx op0 = gen_reg_rtx (XFmode);
14049
14050   rtx op2 = gen_reg_rtx (XFmode);
14051   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14052
14053   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14054   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14055   DONE;
14056 })
14057
14058 (define_expand "log2xf2"
14059   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14060                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14061                                (match_dup 2)] UNSPEC_FYL2X))
14062               (clobber (match_scratch:XF 3 ""))])]
14063   "TARGET_USE_FANCY_MATH_387
14064    && flag_unsafe_math_optimizations"
14065 {
14066   operands[2] = gen_reg_rtx (XFmode);
14067   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14068 })
14069
14070 (define_expand "log2<mode>2"
14071   [(use (match_operand:MODEF 0 "register_operand" ""))
14072    (use (match_operand:MODEF 1 "register_operand" ""))]
14073   "TARGET_USE_FANCY_MATH_387
14074    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14075        || TARGET_MIX_SSE_I387)
14076    && flag_unsafe_math_optimizations"
14077 {
14078   rtx op0 = gen_reg_rtx (XFmode);
14079
14080   rtx op2 = gen_reg_rtx (XFmode);
14081   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14082
14083   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14084   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14085   DONE;
14086 })
14087
14088 (define_insn "fyl2xp1xf3_i387"
14089   [(set (match_operand:XF 0 "register_operand" "=f")
14090         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14091                     (match_operand:XF 2 "register_operand" "u")]
14092                    UNSPEC_FYL2XP1))
14093    (clobber (match_scratch:XF 3 "=2"))]
14094   "TARGET_USE_FANCY_MATH_387
14095    && flag_unsafe_math_optimizations"
14096   "fyl2xp1"
14097   [(set_attr "type" "fpspc")
14098    (set_attr "mode" "XF")])
14099
14100 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14101   [(set (match_operand:XF 0 "register_operand" "=f")
14102         (unspec:XF [(float_extend:XF
14103                       (match_operand:MODEF 1 "register_operand" "0"))
14104                     (match_operand:XF 2 "register_operand" "u")]
14105                    UNSPEC_FYL2XP1))
14106    (clobber (match_scratch:XF 3 "=2"))]
14107   "TARGET_USE_FANCY_MATH_387
14108    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14109        || TARGET_MIX_SSE_I387)
14110    && flag_unsafe_math_optimizations"
14111   "fyl2xp1"
14112   [(set_attr "type" "fpspc")
14113    (set_attr "mode" "XF")])
14114
14115 (define_expand "log1pxf2"
14116   [(use (match_operand:XF 0 "register_operand" ""))
14117    (use (match_operand:XF 1 "register_operand" ""))]
14118   "TARGET_USE_FANCY_MATH_387
14119    && flag_unsafe_math_optimizations"
14120 {
14121   if (optimize_insn_for_size_p ())
14122     FAIL;
14123
14124   ix86_emit_i387_log1p (operands[0], operands[1]);
14125   DONE;
14126 })
14127
14128 (define_expand "log1p<mode>2"
14129   [(use (match_operand:MODEF 0 "register_operand" ""))
14130    (use (match_operand:MODEF 1 "register_operand" ""))]
14131   "TARGET_USE_FANCY_MATH_387
14132    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14133        || TARGET_MIX_SSE_I387)
14134    && flag_unsafe_math_optimizations"
14135 {
14136   rtx op0;
14137
14138   if (optimize_insn_for_size_p ())
14139     FAIL;
14140
14141   op0 = gen_reg_rtx (XFmode);
14142
14143   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14144
14145   ix86_emit_i387_log1p (op0, operands[1]);
14146   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14147   DONE;
14148 })
14149
14150 (define_insn "fxtractxf3_i387"
14151   [(set (match_operand:XF 0 "register_operand" "=f")
14152         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14153                    UNSPEC_XTRACT_FRACT))
14154    (set (match_operand:XF 1 "register_operand" "=u")
14155         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14156   "TARGET_USE_FANCY_MATH_387
14157    && flag_unsafe_math_optimizations"
14158   "fxtract"
14159   [(set_attr "type" "fpspc")
14160    (set_attr "mode" "XF")])
14161
14162 (define_insn "fxtract_extend<mode>xf3_i387"
14163   [(set (match_operand:XF 0 "register_operand" "=f")
14164         (unspec:XF [(float_extend:XF
14165                       (match_operand:MODEF 2 "register_operand" "0"))]
14166                    UNSPEC_XTRACT_FRACT))
14167    (set (match_operand:XF 1 "register_operand" "=u")
14168         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14169   "TARGET_USE_FANCY_MATH_387
14170    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14171        || TARGET_MIX_SSE_I387)
14172    && flag_unsafe_math_optimizations"
14173   "fxtract"
14174   [(set_attr "type" "fpspc")
14175    (set_attr "mode" "XF")])
14176
14177 (define_expand "logbxf2"
14178   [(parallel [(set (match_dup 2)
14179                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14180                               UNSPEC_XTRACT_FRACT))
14181               (set (match_operand:XF 0 "register_operand" "")
14182                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14183   "TARGET_USE_FANCY_MATH_387
14184    && flag_unsafe_math_optimizations"
14185   "operands[2] = gen_reg_rtx (XFmode);")
14186
14187 (define_expand "logb<mode>2"
14188   [(use (match_operand:MODEF 0 "register_operand" ""))
14189    (use (match_operand:MODEF 1 "register_operand" ""))]
14190   "TARGET_USE_FANCY_MATH_387
14191    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14192        || TARGET_MIX_SSE_I387)
14193    && flag_unsafe_math_optimizations"
14194 {
14195   rtx op0 = gen_reg_rtx (XFmode);
14196   rtx op1 = gen_reg_rtx (XFmode);
14197
14198   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14199   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14200   DONE;
14201 })
14202
14203 (define_expand "ilogbxf2"
14204   [(use (match_operand:SI 0 "register_operand" ""))
14205    (use (match_operand:XF 1 "register_operand" ""))]
14206   "TARGET_USE_FANCY_MATH_387
14207    && flag_unsafe_math_optimizations"
14208 {
14209   rtx op0, op1;
14210
14211   if (optimize_insn_for_size_p ())
14212     FAIL;
14213
14214   op0 = gen_reg_rtx (XFmode);
14215   op1 = gen_reg_rtx (XFmode);
14216
14217   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14218   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14219   DONE;
14220 })
14221
14222 (define_expand "ilogb<mode>2"
14223   [(use (match_operand:SI 0 "register_operand" ""))
14224    (use (match_operand:MODEF 1 "register_operand" ""))]
14225   "TARGET_USE_FANCY_MATH_387
14226    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14227        || TARGET_MIX_SSE_I387)
14228    && flag_unsafe_math_optimizations"
14229 {
14230   rtx op0, op1;
14231
14232   if (optimize_insn_for_size_p ())
14233     FAIL;
14234
14235   op0 = gen_reg_rtx (XFmode);
14236   op1 = gen_reg_rtx (XFmode);
14237
14238   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14239   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14240   DONE;
14241 })
14242
14243 (define_insn "*f2xm1xf2_i387"
14244   [(set (match_operand:XF 0 "register_operand" "=f")
14245         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14246                    UNSPEC_F2XM1))]
14247   "TARGET_USE_FANCY_MATH_387
14248    && flag_unsafe_math_optimizations"
14249   "f2xm1"
14250   [(set_attr "type" "fpspc")
14251    (set_attr "mode" "XF")])
14252
14253 (define_insn "*fscalexf4_i387"
14254   [(set (match_operand:XF 0 "register_operand" "=f")
14255         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14256                     (match_operand:XF 3 "register_operand" "1")]
14257                    UNSPEC_FSCALE_FRACT))
14258    (set (match_operand:XF 1 "register_operand" "=u")
14259         (unspec:XF [(match_dup 2) (match_dup 3)]
14260                    UNSPEC_FSCALE_EXP))]
14261   "TARGET_USE_FANCY_MATH_387
14262    && flag_unsafe_math_optimizations"
14263   "fscale"
14264   [(set_attr "type" "fpspc")
14265    (set_attr "mode" "XF")])
14266
14267 (define_expand "expNcorexf3"
14268   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14269                                (match_operand:XF 2 "register_operand" "")))
14270    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14271    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14272    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14273    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14274    (parallel [(set (match_operand:XF 0 "register_operand" "")
14275                    (unspec:XF [(match_dup 8) (match_dup 4)]
14276                               UNSPEC_FSCALE_FRACT))
14277               (set (match_dup 9)
14278                    (unspec:XF [(match_dup 8) (match_dup 4)]
14279                               UNSPEC_FSCALE_EXP))])]
14280   "TARGET_USE_FANCY_MATH_387
14281    && flag_unsafe_math_optimizations"
14282 {
14283   int i;
14284
14285   if (optimize_insn_for_size_p ())
14286     FAIL;
14287
14288   for (i = 3; i < 10; i++)
14289     operands[i] = gen_reg_rtx (XFmode);
14290
14291   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14292 })
14293
14294 (define_expand "expxf2"
14295   [(use (match_operand:XF 0 "register_operand" ""))
14296    (use (match_operand:XF 1 "register_operand" ""))]
14297   "TARGET_USE_FANCY_MATH_387
14298    && flag_unsafe_math_optimizations"
14299 {
14300   rtx op2;
14301
14302   if (optimize_insn_for_size_p ())
14303     FAIL;
14304
14305   op2 = gen_reg_rtx (XFmode);
14306   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14307
14308   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14309   DONE;
14310 })
14311
14312 (define_expand "exp<mode>2"
14313   [(use (match_operand:MODEF 0 "register_operand" ""))
14314    (use (match_operand:MODEF 1 "general_operand" ""))]
14315  "TARGET_USE_FANCY_MATH_387
14316    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14317        || TARGET_MIX_SSE_I387)
14318    && flag_unsafe_math_optimizations"
14319 {
14320   rtx op0, op1;
14321
14322   if (optimize_insn_for_size_p ())
14323     FAIL;
14324
14325   op0 = gen_reg_rtx (XFmode);
14326   op1 = gen_reg_rtx (XFmode);
14327
14328   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14329   emit_insn (gen_expxf2 (op0, op1));
14330   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14331   DONE;
14332 })
14333
14334 (define_expand "exp10xf2"
14335   [(use (match_operand:XF 0 "register_operand" ""))
14336    (use (match_operand:XF 1 "register_operand" ""))]
14337   "TARGET_USE_FANCY_MATH_387
14338    && flag_unsafe_math_optimizations"
14339 {
14340   rtx op2;
14341
14342   if (optimize_insn_for_size_p ())
14343     FAIL;
14344
14345   op2 = gen_reg_rtx (XFmode);
14346   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14347
14348   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14349   DONE;
14350 })
14351
14352 (define_expand "exp10<mode>2"
14353   [(use (match_operand:MODEF 0 "register_operand" ""))
14354    (use (match_operand:MODEF 1 "general_operand" ""))]
14355  "TARGET_USE_FANCY_MATH_387
14356    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14357        || TARGET_MIX_SSE_I387)
14358    && flag_unsafe_math_optimizations"
14359 {
14360   rtx op0, op1;
14361
14362   if (optimize_insn_for_size_p ())
14363     FAIL;
14364
14365   op0 = gen_reg_rtx (XFmode);
14366   op1 = gen_reg_rtx (XFmode);
14367
14368   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14369   emit_insn (gen_exp10xf2 (op0, op1));
14370   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14371   DONE;
14372 })
14373
14374 (define_expand "exp2xf2"
14375   [(use (match_operand:XF 0 "register_operand" ""))
14376    (use (match_operand:XF 1 "register_operand" ""))]
14377   "TARGET_USE_FANCY_MATH_387
14378    && flag_unsafe_math_optimizations"
14379 {
14380   rtx op2;
14381
14382   if (optimize_insn_for_size_p ())
14383     FAIL;
14384
14385   op2 = gen_reg_rtx (XFmode);
14386   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14387
14388   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14389   DONE;
14390 })
14391
14392 (define_expand "exp2<mode>2"
14393   [(use (match_operand:MODEF 0 "register_operand" ""))
14394    (use (match_operand:MODEF 1 "general_operand" ""))]
14395  "TARGET_USE_FANCY_MATH_387
14396    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14397        || TARGET_MIX_SSE_I387)
14398    && flag_unsafe_math_optimizations"
14399 {
14400   rtx op0, op1;
14401
14402   if (optimize_insn_for_size_p ())
14403     FAIL;
14404
14405   op0 = gen_reg_rtx (XFmode);
14406   op1 = gen_reg_rtx (XFmode);
14407
14408   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14409   emit_insn (gen_exp2xf2 (op0, op1));
14410   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14411   DONE;
14412 })
14413
14414 (define_expand "expm1xf2"
14415   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14416                                (match_dup 2)))
14417    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14418    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14419    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14420    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14421    (parallel [(set (match_dup 7)
14422                    (unspec:XF [(match_dup 6) (match_dup 4)]
14423                               UNSPEC_FSCALE_FRACT))
14424               (set (match_dup 8)
14425                    (unspec:XF [(match_dup 6) (match_dup 4)]
14426                               UNSPEC_FSCALE_EXP))])
14427    (parallel [(set (match_dup 10)
14428                    (unspec:XF [(match_dup 9) (match_dup 8)]
14429                               UNSPEC_FSCALE_FRACT))
14430               (set (match_dup 11)
14431                    (unspec:XF [(match_dup 9) (match_dup 8)]
14432                               UNSPEC_FSCALE_EXP))])
14433    (set (match_dup 12) (minus:XF (match_dup 10)
14434                                  (float_extend:XF (match_dup 13))))
14435    (set (match_operand:XF 0 "register_operand" "")
14436         (plus:XF (match_dup 12) (match_dup 7)))]
14437   "TARGET_USE_FANCY_MATH_387
14438    && flag_unsafe_math_optimizations"
14439 {
14440   int i;
14441
14442   if (optimize_insn_for_size_p ())
14443     FAIL;
14444
14445   for (i = 2; i < 13; i++)
14446     operands[i] = gen_reg_rtx (XFmode);
14447
14448   operands[13]
14449     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14450
14451   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14452 })
14453
14454 (define_expand "expm1<mode>2"
14455   [(use (match_operand:MODEF 0 "register_operand" ""))
14456    (use (match_operand:MODEF 1 "general_operand" ""))]
14457  "TARGET_USE_FANCY_MATH_387
14458    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14459        || TARGET_MIX_SSE_I387)
14460    && flag_unsafe_math_optimizations"
14461 {
14462   rtx op0, op1;
14463
14464   if (optimize_insn_for_size_p ())
14465     FAIL;
14466
14467   op0 = gen_reg_rtx (XFmode);
14468   op1 = gen_reg_rtx (XFmode);
14469
14470   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14471   emit_insn (gen_expm1xf2 (op0, op1));
14472   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14473   DONE;
14474 })
14475
14476 (define_expand "ldexpxf3"
14477   [(set (match_dup 3)
14478         (float:XF (match_operand:SI 2 "register_operand" "")))
14479    (parallel [(set (match_operand:XF 0 " register_operand" "")
14480                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14481                                (match_dup 3)]
14482                               UNSPEC_FSCALE_FRACT))
14483               (set (match_dup 4)
14484                    (unspec:XF [(match_dup 1) (match_dup 3)]
14485                               UNSPEC_FSCALE_EXP))])]
14486   "TARGET_USE_FANCY_MATH_387
14487    && flag_unsafe_math_optimizations"
14488 {
14489   if (optimize_insn_for_size_p ())
14490     FAIL;
14491
14492   operands[3] = gen_reg_rtx (XFmode);
14493   operands[4] = gen_reg_rtx (XFmode);
14494 })
14495
14496 (define_expand "ldexp<mode>3"
14497   [(use (match_operand:MODEF 0 "register_operand" ""))
14498    (use (match_operand:MODEF 1 "general_operand" ""))
14499    (use (match_operand:SI 2 "register_operand" ""))]
14500  "TARGET_USE_FANCY_MATH_387
14501    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14502        || TARGET_MIX_SSE_I387)
14503    && flag_unsafe_math_optimizations"
14504 {
14505   rtx op0, op1;
14506
14507   if (optimize_insn_for_size_p ())
14508     FAIL;
14509
14510   op0 = gen_reg_rtx (XFmode);
14511   op1 = gen_reg_rtx (XFmode);
14512
14513   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14514   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14515   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14516   DONE;
14517 })
14518
14519 (define_expand "scalbxf3"
14520   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14521                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14522                                (match_operand:XF 2 "register_operand" "")]
14523                               UNSPEC_FSCALE_FRACT))
14524               (set (match_dup 3)
14525                    (unspec:XF [(match_dup 1) (match_dup 2)]
14526                               UNSPEC_FSCALE_EXP))])]
14527   "TARGET_USE_FANCY_MATH_387
14528    && flag_unsafe_math_optimizations"
14529 {
14530   if (optimize_insn_for_size_p ())
14531     FAIL;
14532
14533   operands[3] = gen_reg_rtx (XFmode);
14534 })
14535
14536 (define_expand "scalb<mode>3"
14537   [(use (match_operand:MODEF 0 "register_operand" ""))
14538    (use (match_operand:MODEF 1 "general_operand" ""))
14539    (use (match_operand:MODEF 2 "general_operand" ""))]
14540  "TARGET_USE_FANCY_MATH_387
14541    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14542        || TARGET_MIX_SSE_I387)
14543    && flag_unsafe_math_optimizations"
14544 {
14545   rtx op0, op1, op2;
14546
14547   if (optimize_insn_for_size_p ())
14548     FAIL;
14549
14550   op0 = gen_reg_rtx (XFmode);
14551   op1 = gen_reg_rtx (XFmode);
14552   op2 = gen_reg_rtx (XFmode);
14553
14554   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14555   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14556   emit_insn (gen_scalbxf3 (op0, op1, op2));
14557   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14558   DONE;
14559 })
14560
14561 (define_expand "significandxf2"
14562   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14563                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14564                               UNSPEC_XTRACT_FRACT))
14565               (set (match_dup 2)
14566                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14567   "TARGET_USE_FANCY_MATH_387
14568    && flag_unsafe_math_optimizations"
14569   "operands[2] = gen_reg_rtx (XFmode);")
14570
14571 (define_expand "significand<mode>2"
14572   [(use (match_operand:MODEF 0 "register_operand" ""))
14573    (use (match_operand:MODEF 1 "register_operand" ""))]
14574   "TARGET_USE_FANCY_MATH_387
14575    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14576        || TARGET_MIX_SSE_I387)
14577    && flag_unsafe_math_optimizations"
14578 {
14579   rtx op0 = gen_reg_rtx (XFmode);
14580   rtx op1 = gen_reg_rtx (XFmode);
14581
14582   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14583   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14584   DONE;
14585 })
14586 \f
14587
14588 (define_insn "sse4_1_round<mode>2"
14589   [(set (match_operand:MODEF 0 "register_operand" "=x")
14590         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14591                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14592                       UNSPEC_ROUND))]
14593   "TARGET_ROUND"
14594   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14595   [(set_attr "type" "ssecvt")
14596    (set_attr "prefix_extra" "1")
14597    (set_attr "prefix" "maybe_vex")
14598    (set_attr "mode" "<MODE>")])
14599
14600 (define_insn "rintxf2"
14601   [(set (match_operand:XF 0 "register_operand" "=f")
14602         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14603                    UNSPEC_FRNDINT))]
14604   "TARGET_USE_FANCY_MATH_387
14605    && flag_unsafe_math_optimizations"
14606   "frndint"
14607   [(set_attr "type" "fpspc")
14608    (set_attr "mode" "XF")])
14609
14610 (define_expand "rint<mode>2"
14611   [(use (match_operand:MODEF 0 "register_operand" ""))
14612    (use (match_operand:MODEF 1 "register_operand" ""))]
14613   "(TARGET_USE_FANCY_MATH_387
14614     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14615         || TARGET_MIX_SSE_I387)
14616     && flag_unsafe_math_optimizations)
14617    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14618        && !flag_trapping_math)"
14619 {
14620   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14621       && !flag_trapping_math)
14622     {
14623       if (TARGET_ROUND)
14624         emit_insn (gen_sse4_1_round<mode>2
14625                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14626       else if (optimize_insn_for_size_p ())
14627         FAIL;
14628       else
14629         ix86_expand_rint (operands[0], operands[1]);
14630     }
14631   else
14632     {
14633       rtx op0 = gen_reg_rtx (XFmode);
14634       rtx op1 = gen_reg_rtx (XFmode);
14635
14636       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14637       emit_insn (gen_rintxf2 (op0, op1));
14638
14639       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14640     }
14641   DONE;
14642 })
14643
14644 (define_expand "round<mode>2"
14645   [(match_operand:X87MODEF 0 "register_operand" "")
14646    (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14647   "(TARGET_USE_FANCY_MATH_387
14648     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14649         || TARGET_MIX_SSE_I387)
14650     && flag_unsafe_math_optimizations)
14651    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14652        && !flag_trapping_math && !flag_rounding_math)"
14653 {
14654   if (optimize_insn_for_size_p ())
14655     FAIL;
14656
14657   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14658       && !flag_trapping_math && !flag_rounding_math)
14659     {
14660       if (TARGET_ROUND)
14661         {
14662           operands[1] = force_reg (<MODE>mode, operands[1]);
14663           ix86_expand_round_sse4 (operands[0], operands[1]);
14664         }
14665       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14666         ix86_expand_round (operands[0], operands[1]);
14667       else
14668         ix86_expand_rounddf_32 (operands[0], operands[1]);
14669     }
14670   else
14671     {
14672       operands[1] = force_reg (<MODE>mode, operands[1]);
14673       ix86_emit_i387_round (operands[0], operands[1]);
14674     }
14675   DONE;
14676 })
14677
14678 (define_insn_and_split "*fistdi2_1"
14679   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14680         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14681                    UNSPEC_FIST))]
14682   "TARGET_USE_FANCY_MATH_387
14683    && can_create_pseudo_p ()"
14684   "#"
14685   "&& 1"
14686   [(const_int 0)]
14687 {
14688   if (memory_operand (operands[0], VOIDmode))
14689     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14690   else
14691     {
14692       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14693       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14694                                          operands[2]));
14695     }
14696   DONE;
14697 }
14698   [(set_attr "type" "fpspc")
14699    (set_attr "mode" "DI")])
14700
14701 (define_insn "fistdi2"
14702   [(set (match_operand:DI 0 "memory_operand" "=m")
14703         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14704                    UNSPEC_FIST))
14705    (clobber (match_scratch:XF 2 "=&1f"))]
14706   "TARGET_USE_FANCY_MATH_387"
14707   "* return output_fix_trunc (insn, operands, false);"
14708   [(set_attr "type" "fpspc")
14709    (set_attr "mode" "DI")])
14710
14711 (define_insn "fistdi2_with_temp"
14712   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14713         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14714                    UNSPEC_FIST))
14715    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14716    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14717   "TARGET_USE_FANCY_MATH_387"
14718   "#"
14719   [(set_attr "type" "fpspc")
14720    (set_attr "mode" "DI")])
14721
14722 (define_split
14723   [(set (match_operand:DI 0 "register_operand" "")
14724         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14725                    UNSPEC_FIST))
14726    (clobber (match_operand:DI 2 "memory_operand" ""))
14727    (clobber (match_scratch 3 ""))]
14728   "reload_completed"
14729   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14730               (clobber (match_dup 3))])
14731    (set (match_dup 0) (match_dup 2))])
14732
14733 (define_split
14734   [(set (match_operand:DI 0 "memory_operand" "")
14735         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14736                    UNSPEC_FIST))
14737    (clobber (match_operand:DI 2 "memory_operand" ""))
14738    (clobber (match_scratch 3 ""))]
14739   "reload_completed"
14740   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14741               (clobber (match_dup 3))])])
14742
14743 (define_insn_and_split "*fist<mode>2_1"
14744   [(set (match_operand:SWI24 0 "register_operand" "")
14745         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14746                       UNSPEC_FIST))]
14747   "TARGET_USE_FANCY_MATH_387
14748    && can_create_pseudo_p ()"
14749   "#"
14750   "&& 1"
14751   [(const_int 0)]
14752 {
14753   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14754   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14755                                         operands[2]));
14756   DONE;
14757 }
14758   [(set_attr "type" "fpspc")
14759    (set_attr "mode" "<MODE>")])
14760
14761 (define_insn "fist<mode>2"
14762   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14763         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14764                       UNSPEC_FIST))]
14765   "TARGET_USE_FANCY_MATH_387"
14766   "* return output_fix_trunc (insn, operands, false);"
14767   [(set_attr "type" "fpspc")
14768    (set_attr "mode" "<MODE>")])
14769
14770 (define_insn "fist<mode>2_with_temp"
14771   [(set (match_operand:SWI24 0 "register_operand" "=r")
14772         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14773                       UNSPEC_FIST))
14774    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14775   "TARGET_USE_FANCY_MATH_387"
14776   "#"
14777   [(set_attr "type" "fpspc")
14778    (set_attr "mode" "<MODE>")])
14779
14780 (define_split
14781   [(set (match_operand:SWI24 0 "register_operand" "")
14782         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14783                       UNSPEC_FIST))
14784    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14785   "reload_completed"
14786   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14787    (set (match_dup 0) (match_dup 2))])
14788
14789 (define_split
14790   [(set (match_operand:SWI24 0 "memory_operand" "")
14791         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14792                       UNSPEC_FIST))
14793    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14794   "reload_completed"
14795   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14796
14797 (define_expand "lrintxf<mode>2"
14798   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14799      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14800                      UNSPEC_FIST))]
14801   "TARGET_USE_FANCY_MATH_387")
14802
14803 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14804   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14805      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14806                         UNSPEC_FIX_NOTRUNC))]
14807   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14808    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14809
14810 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14811   [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14812    (match_operand:X87MODEF 1 "register_operand" "")]
14813   "(TARGET_USE_FANCY_MATH_387
14814     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14815         || TARGET_MIX_SSE_I387)
14816     && flag_unsafe_math_optimizations)
14817    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14818        && <SWI248x:MODE>mode != HImode 
14819        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14820        && !flag_trapping_math && !flag_rounding_math)"
14821 {
14822   if (optimize_insn_for_size_p ())
14823     FAIL;
14824
14825   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14826       && <SWI248x:MODE>mode != HImode
14827       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14828       && !flag_trapping_math && !flag_rounding_math)
14829     ix86_expand_lround (operands[0], operands[1]);
14830   else
14831     ix86_emit_i387_round (operands[0], operands[1]);
14832   DONE;
14833 })
14834
14835 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14836 (define_insn_and_split "frndintxf2_floor"
14837   [(set (match_operand:XF 0 "register_operand" "")
14838         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14839          UNSPEC_FRNDINT_FLOOR))
14840    (clobber (reg:CC FLAGS_REG))]
14841   "TARGET_USE_FANCY_MATH_387
14842    && flag_unsafe_math_optimizations
14843    && can_create_pseudo_p ()"
14844   "#"
14845   "&& 1"
14846   [(const_int 0)]
14847 {
14848   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14849
14850   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14851   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14852
14853   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14854                                         operands[2], operands[3]));
14855   DONE;
14856 }
14857   [(set_attr "type" "frndint")
14858    (set_attr "i387_cw" "floor")
14859    (set_attr "mode" "XF")])
14860
14861 (define_insn "frndintxf2_floor_i387"
14862   [(set (match_operand:XF 0 "register_operand" "=f")
14863         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14864          UNSPEC_FRNDINT_FLOOR))
14865    (use (match_operand:HI 2 "memory_operand" "m"))
14866    (use (match_operand:HI 3 "memory_operand" "m"))]
14867   "TARGET_USE_FANCY_MATH_387
14868    && flag_unsafe_math_optimizations"
14869   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14870   [(set_attr "type" "frndint")
14871    (set_attr "i387_cw" "floor")
14872    (set_attr "mode" "XF")])
14873
14874 (define_expand "floorxf2"
14875   [(use (match_operand:XF 0 "register_operand" ""))
14876    (use (match_operand:XF 1 "register_operand" ""))]
14877   "TARGET_USE_FANCY_MATH_387
14878    && flag_unsafe_math_optimizations"
14879 {
14880   if (optimize_insn_for_size_p ())
14881     FAIL;
14882   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14883   DONE;
14884 })
14885
14886 (define_expand "floor<mode>2"
14887   [(use (match_operand:MODEF 0 "register_operand" ""))
14888    (use (match_operand:MODEF 1 "register_operand" ""))]
14889   "(TARGET_USE_FANCY_MATH_387
14890     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14891         || TARGET_MIX_SSE_I387)
14892     && flag_unsafe_math_optimizations)
14893    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14894        && !flag_trapping_math)"
14895 {
14896   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14897       && !flag_trapping_math)
14898     {
14899       if (TARGET_ROUND)
14900         emit_insn (gen_sse4_1_round<mode>2
14901                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14902       else if (optimize_insn_for_size_p ())
14903         FAIL;
14904       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14905         ix86_expand_floorceil (operands[0], operands[1], true);
14906       else
14907         ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14908     }
14909   else
14910     {
14911       rtx op0, op1;
14912
14913       if (optimize_insn_for_size_p ())
14914         FAIL;
14915
14916       op0 = gen_reg_rtx (XFmode);
14917       op1 = gen_reg_rtx (XFmode);
14918       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14919       emit_insn (gen_frndintxf2_floor (op0, op1));
14920
14921       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14922     }
14923   DONE;
14924 })
14925
14926 (define_insn_and_split "*fist<mode>2_floor_1"
14927   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14928         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14929                         UNSPEC_FIST_FLOOR))
14930    (clobber (reg:CC FLAGS_REG))]
14931   "TARGET_USE_FANCY_MATH_387
14932    && flag_unsafe_math_optimizations
14933    && can_create_pseudo_p ()"
14934   "#"
14935   "&& 1"
14936   [(const_int 0)]
14937 {
14938   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14939
14940   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14941   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14942   if (memory_operand (operands[0], VOIDmode))
14943     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14944                                       operands[2], operands[3]));
14945   else
14946     {
14947       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14948       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14949                                                   operands[2], operands[3],
14950                                                   operands[4]));
14951     }
14952   DONE;
14953 }
14954   [(set_attr "type" "fistp")
14955    (set_attr "i387_cw" "floor")
14956    (set_attr "mode" "<MODE>")])
14957
14958 (define_insn "fistdi2_floor"
14959   [(set (match_operand:DI 0 "memory_operand" "=m")
14960         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14961                    UNSPEC_FIST_FLOOR))
14962    (use (match_operand:HI 2 "memory_operand" "m"))
14963    (use (match_operand:HI 3 "memory_operand" "m"))
14964    (clobber (match_scratch:XF 4 "=&1f"))]
14965   "TARGET_USE_FANCY_MATH_387
14966    && flag_unsafe_math_optimizations"
14967   "* return output_fix_trunc (insn, operands, false);"
14968   [(set_attr "type" "fistp")
14969    (set_attr "i387_cw" "floor")
14970    (set_attr "mode" "DI")])
14971
14972 (define_insn "fistdi2_floor_with_temp"
14973   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14974         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14975                    UNSPEC_FIST_FLOOR))
14976    (use (match_operand:HI 2 "memory_operand" "m,m"))
14977    (use (match_operand:HI 3 "memory_operand" "m,m"))
14978    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14979    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14980   "TARGET_USE_FANCY_MATH_387
14981    && flag_unsafe_math_optimizations"
14982   "#"
14983   [(set_attr "type" "fistp")
14984    (set_attr "i387_cw" "floor")
14985    (set_attr "mode" "DI")])
14986
14987 (define_split
14988   [(set (match_operand:DI 0 "register_operand" "")
14989         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14990                    UNSPEC_FIST_FLOOR))
14991    (use (match_operand:HI 2 "memory_operand" ""))
14992    (use (match_operand:HI 3 "memory_operand" ""))
14993    (clobber (match_operand:DI 4 "memory_operand" ""))
14994    (clobber (match_scratch 5 ""))]
14995   "reload_completed"
14996   [(parallel [(set (match_dup 4)
14997                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14998               (use (match_dup 2))
14999               (use (match_dup 3))
15000               (clobber (match_dup 5))])
15001    (set (match_dup 0) (match_dup 4))])
15002
15003 (define_split
15004   [(set (match_operand:DI 0 "memory_operand" "")
15005         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15006                    UNSPEC_FIST_FLOOR))
15007    (use (match_operand:HI 2 "memory_operand" ""))
15008    (use (match_operand:HI 3 "memory_operand" ""))
15009    (clobber (match_operand:DI 4 "memory_operand" ""))
15010    (clobber (match_scratch 5 ""))]
15011   "reload_completed"
15012   [(parallel [(set (match_dup 0)
15013                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15014               (use (match_dup 2))
15015               (use (match_dup 3))
15016               (clobber (match_dup 5))])])
15017
15018 (define_insn "fist<mode>2_floor"
15019   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15020         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15021                       UNSPEC_FIST_FLOOR))
15022    (use (match_operand:HI 2 "memory_operand" "m"))
15023    (use (match_operand:HI 3 "memory_operand" "m"))]
15024   "TARGET_USE_FANCY_MATH_387
15025    && flag_unsafe_math_optimizations"
15026   "* return output_fix_trunc (insn, operands, false);"
15027   [(set_attr "type" "fistp")
15028    (set_attr "i387_cw" "floor")
15029    (set_attr "mode" "<MODE>")])
15030
15031 (define_insn "fist<mode>2_floor_with_temp"
15032   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15033         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15034                       UNSPEC_FIST_FLOOR))
15035    (use (match_operand:HI 2 "memory_operand" "m,m"))
15036    (use (match_operand:HI 3 "memory_operand" "m,m"))
15037    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15038   "TARGET_USE_FANCY_MATH_387
15039    && flag_unsafe_math_optimizations"
15040   "#"
15041   [(set_attr "type" "fistp")
15042    (set_attr "i387_cw" "floor")
15043    (set_attr "mode" "<MODE>")])
15044
15045 (define_split
15046   [(set (match_operand:SWI24 0 "register_operand" "")
15047         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15048                       UNSPEC_FIST_FLOOR))
15049    (use (match_operand:HI 2 "memory_operand" ""))
15050    (use (match_operand:HI 3 "memory_operand" ""))
15051    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15052   "reload_completed"
15053   [(parallel [(set (match_dup 4)
15054                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15055               (use (match_dup 2))
15056               (use (match_dup 3))])
15057    (set (match_dup 0) (match_dup 4))])
15058
15059 (define_split
15060   [(set (match_operand:SWI24 0 "memory_operand" "")
15061         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15062                       UNSPEC_FIST_FLOOR))
15063    (use (match_operand:HI 2 "memory_operand" ""))
15064    (use (match_operand:HI 3 "memory_operand" ""))
15065    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15066   "reload_completed"
15067   [(parallel [(set (match_dup 0)
15068                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15069               (use (match_dup 2))
15070               (use (match_dup 3))])])
15071
15072 (define_expand "lfloorxf<mode>2"
15073   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15074                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15075                                    UNSPEC_FIST_FLOOR))
15076               (clobber (reg:CC FLAGS_REG))])]
15077   "TARGET_USE_FANCY_MATH_387
15078    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15079    && flag_unsafe_math_optimizations")
15080
15081 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15082   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15083    (match_operand:MODEF 1 "register_operand" "")]
15084   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15085    && !flag_trapping_math"
15086 {
15087   if (TARGET_64BIT && optimize_insn_for_size_p ())
15088     FAIL;
15089   ix86_expand_lfloorceil (operands[0], operands[1], true);
15090   DONE;
15091 })
15092
15093 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15094 (define_insn_and_split "frndintxf2_ceil"
15095   [(set (match_operand:XF 0 "register_operand" "")
15096         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15097          UNSPEC_FRNDINT_CEIL))
15098    (clobber (reg:CC FLAGS_REG))]
15099   "TARGET_USE_FANCY_MATH_387
15100    && flag_unsafe_math_optimizations
15101    && can_create_pseudo_p ()"
15102   "#"
15103   "&& 1"
15104   [(const_int 0)]
15105 {
15106   ix86_optimize_mode_switching[I387_CEIL] = 1;
15107
15108   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15109   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15110
15111   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15112                                        operands[2], operands[3]));
15113   DONE;
15114 }
15115   [(set_attr "type" "frndint")
15116    (set_attr "i387_cw" "ceil")
15117    (set_attr "mode" "XF")])
15118
15119 (define_insn "frndintxf2_ceil_i387"
15120   [(set (match_operand:XF 0 "register_operand" "=f")
15121         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15122          UNSPEC_FRNDINT_CEIL))
15123    (use (match_operand:HI 2 "memory_operand" "m"))
15124    (use (match_operand:HI 3 "memory_operand" "m"))]
15125   "TARGET_USE_FANCY_MATH_387
15126    && flag_unsafe_math_optimizations"
15127   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15128   [(set_attr "type" "frndint")
15129    (set_attr "i387_cw" "ceil")
15130    (set_attr "mode" "XF")])
15131
15132 (define_expand "ceilxf2"
15133   [(use (match_operand:XF 0 "register_operand" ""))
15134    (use (match_operand:XF 1 "register_operand" ""))]
15135   "TARGET_USE_FANCY_MATH_387
15136    && flag_unsafe_math_optimizations"
15137 {
15138   if (optimize_insn_for_size_p ())
15139     FAIL;
15140   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15141   DONE;
15142 })
15143
15144 (define_expand "ceil<mode>2"
15145   [(use (match_operand:MODEF 0 "register_operand" ""))
15146    (use (match_operand:MODEF 1 "register_operand" ""))]
15147   "(TARGET_USE_FANCY_MATH_387
15148     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15149         || TARGET_MIX_SSE_I387)
15150     && flag_unsafe_math_optimizations)
15151    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15152        && !flag_trapping_math)"
15153 {
15154   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15155       && !flag_trapping_math)
15156     {
15157       if (TARGET_ROUND)
15158         emit_insn (gen_sse4_1_round<mode>2
15159                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15160       else if (optimize_insn_for_size_p ())
15161         FAIL;
15162       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15163         ix86_expand_floorceil (operands[0], operands[1], false);
15164       else
15165         ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15166     }
15167   else
15168     {
15169       rtx op0, op1;
15170
15171       if (optimize_insn_for_size_p ())
15172         FAIL;
15173
15174       op0 = gen_reg_rtx (XFmode);
15175       op1 = gen_reg_rtx (XFmode);
15176       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15177       emit_insn (gen_frndintxf2_ceil (op0, op1));
15178
15179       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15180     }
15181   DONE;
15182 })
15183
15184 (define_insn_and_split "*fist<mode>2_ceil_1"
15185   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15186         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15187                         UNSPEC_FIST_CEIL))
15188    (clobber (reg:CC FLAGS_REG))]
15189   "TARGET_USE_FANCY_MATH_387
15190    && flag_unsafe_math_optimizations
15191    && can_create_pseudo_p ()"
15192   "#"
15193   "&& 1"
15194   [(const_int 0)]
15195 {
15196   ix86_optimize_mode_switching[I387_CEIL] = 1;
15197
15198   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15199   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15200   if (memory_operand (operands[0], VOIDmode))
15201     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15202                                      operands[2], operands[3]));
15203   else
15204     {
15205       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15206       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15207                                                  operands[2], operands[3],
15208                                                  operands[4]));
15209     }
15210   DONE;
15211 }
15212   [(set_attr "type" "fistp")
15213    (set_attr "i387_cw" "ceil")
15214    (set_attr "mode" "<MODE>")])
15215
15216 (define_insn "fistdi2_ceil"
15217   [(set (match_operand:DI 0 "memory_operand" "=m")
15218         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15219                    UNSPEC_FIST_CEIL))
15220    (use (match_operand:HI 2 "memory_operand" "m"))
15221    (use (match_operand:HI 3 "memory_operand" "m"))
15222    (clobber (match_scratch:XF 4 "=&1f"))]
15223   "TARGET_USE_FANCY_MATH_387
15224    && flag_unsafe_math_optimizations"
15225   "* return output_fix_trunc (insn, operands, false);"
15226   [(set_attr "type" "fistp")
15227    (set_attr "i387_cw" "ceil")
15228    (set_attr "mode" "DI")])
15229
15230 (define_insn "fistdi2_ceil_with_temp"
15231   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15232         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15233                    UNSPEC_FIST_CEIL))
15234    (use (match_operand:HI 2 "memory_operand" "m,m"))
15235    (use (match_operand:HI 3 "memory_operand" "m,m"))
15236    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15237    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15238   "TARGET_USE_FANCY_MATH_387
15239    && flag_unsafe_math_optimizations"
15240   "#"
15241   [(set_attr "type" "fistp")
15242    (set_attr "i387_cw" "ceil")
15243    (set_attr "mode" "DI")])
15244
15245 (define_split
15246   [(set (match_operand:DI 0 "register_operand" "")
15247         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15248                    UNSPEC_FIST_CEIL))
15249    (use (match_operand:HI 2 "memory_operand" ""))
15250    (use (match_operand:HI 3 "memory_operand" ""))
15251    (clobber (match_operand:DI 4 "memory_operand" ""))
15252    (clobber (match_scratch 5 ""))]
15253   "reload_completed"
15254   [(parallel [(set (match_dup 4)
15255                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15256               (use (match_dup 2))
15257               (use (match_dup 3))
15258               (clobber (match_dup 5))])
15259    (set (match_dup 0) (match_dup 4))])
15260
15261 (define_split
15262   [(set (match_operand:DI 0 "memory_operand" "")
15263         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15264                    UNSPEC_FIST_CEIL))
15265    (use (match_operand:HI 2 "memory_operand" ""))
15266    (use (match_operand:HI 3 "memory_operand" ""))
15267    (clobber (match_operand:DI 4 "memory_operand" ""))
15268    (clobber (match_scratch 5 ""))]
15269   "reload_completed"
15270   [(parallel [(set (match_dup 0)
15271                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15272               (use (match_dup 2))
15273               (use (match_dup 3))
15274               (clobber (match_dup 5))])])
15275
15276 (define_insn "fist<mode>2_ceil"
15277   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15278         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15279                       UNSPEC_FIST_CEIL))
15280    (use (match_operand:HI 2 "memory_operand" "m"))
15281    (use (match_operand:HI 3 "memory_operand" "m"))]
15282   "TARGET_USE_FANCY_MATH_387
15283    && flag_unsafe_math_optimizations"
15284   "* return output_fix_trunc (insn, operands, false);"
15285   [(set_attr "type" "fistp")
15286    (set_attr "i387_cw" "ceil")
15287    (set_attr "mode" "<MODE>")])
15288
15289 (define_insn "fist<mode>2_ceil_with_temp"
15290   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15291         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15292                       UNSPEC_FIST_CEIL))
15293    (use (match_operand:HI 2 "memory_operand" "m,m"))
15294    (use (match_operand:HI 3 "memory_operand" "m,m"))
15295    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15296   "TARGET_USE_FANCY_MATH_387
15297    && flag_unsafe_math_optimizations"
15298   "#"
15299   [(set_attr "type" "fistp")
15300    (set_attr "i387_cw" "ceil")
15301    (set_attr "mode" "<MODE>")])
15302
15303 (define_split
15304   [(set (match_operand:SWI24 0 "register_operand" "")
15305         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15306                       UNSPEC_FIST_CEIL))
15307    (use (match_operand:HI 2 "memory_operand" ""))
15308    (use (match_operand:HI 3 "memory_operand" ""))
15309    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15310   "reload_completed"
15311   [(parallel [(set (match_dup 4)
15312                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15313               (use (match_dup 2))
15314               (use (match_dup 3))])
15315    (set (match_dup 0) (match_dup 4))])
15316
15317 (define_split
15318   [(set (match_operand:SWI24 0 "memory_operand" "")
15319         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15320                       UNSPEC_FIST_CEIL))
15321    (use (match_operand:HI 2 "memory_operand" ""))
15322    (use (match_operand:HI 3 "memory_operand" ""))
15323    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15324   "reload_completed"
15325   [(parallel [(set (match_dup 0)
15326                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15327               (use (match_dup 2))
15328               (use (match_dup 3))])])
15329
15330 (define_expand "lceilxf<mode>2"
15331   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15332                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15333                                    UNSPEC_FIST_CEIL))
15334               (clobber (reg:CC FLAGS_REG))])]
15335   "TARGET_USE_FANCY_MATH_387
15336    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15337    && flag_unsafe_math_optimizations")
15338
15339 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15340   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15341    (match_operand:MODEF 1 "register_operand" "")]
15342   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15343    && !flag_trapping_math"
15344 {
15345   ix86_expand_lfloorceil (operands[0], operands[1], false);
15346   DONE;
15347 })
15348
15349 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15350 (define_insn_and_split "frndintxf2_trunc"
15351   [(set (match_operand:XF 0 "register_operand" "")
15352         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15353          UNSPEC_FRNDINT_TRUNC))
15354    (clobber (reg:CC FLAGS_REG))]
15355   "TARGET_USE_FANCY_MATH_387
15356    && flag_unsafe_math_optimizations
15357    && can_create_pseudo_p ()"
15358   "#"
15359   "&& 1"
15360   [(const_int 0)]
15361 {
15362   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15363
15364   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15365   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15366
15367   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15368                                         operands[2], operands[3]));
15369   DONE;
15370 }
15371   [(set_attr "type" "frndint")
15372    (set_attr "i387_cw" "trunc")
15373    (set_attr "mode" "XF")])
15374
15375 (define_insn "frndintxf2_trunc_i387"
15376   [(set (match_operand:XF 0 "register_operand" "=f")
15377         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15378          UNSPEC_FRNDINT_TRUNC))
15379    (use (match_operand:HI 2 "memory_operand" "m"))
15380    (use (match_operand:HI 3 "memory_operand" "m"))]
15381   "TARGET_USE_FANCY_MATH_387
15382    && flag_unsafe_math_optimizations"
15383   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15384   [(set_attr "type" "frndint")
15385    (set_attr "i387_cw" "trunc")
15386    (set_attr "mode" "XF")])
15387
15388 (define_expand "btruncxf2"
15389   [(use (match_operand:XF 0 "register_operand" ""))
15390    (use (match_operand:XF 1 "register_operand" ""))]
15391   "TARGET_USE_FANCY_MATH_387
15392    && flag_unsafe_math_optimizations"
15393 {
15394   if (optimize_insn_for_size_p ())
15395     FAIL;
15396   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15397   DONE;
15398 })
15399
15400 (define_expand "btrunc<mode>2"
15401   [(use (match_operand:MODEF 0 "register_operand" ""))
15402    (use (match_operand:MODEF 1 "register_operand" ""))]
15403   "(TARGET_USE_FANCY_MATH_387
15404     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15405         || TARGET_MIX_SSE_I387)
15406     && flag_unsafe_math_optimizations)
15407    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15408        && !flag_trapping_math)"
15409 {
15410   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15411       && !flag_trapping_math)
15412     {
15413       if (TARGET_ROUND)
15414         emit_insn (gen_sse4_1_round<mode>2
15415                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15416       else if (optimize_insn_for_size_p ())
15417         FAIL;
15418       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15419         ix86_expand_trunc (operands[0], operands[1]);
15420       else
15421         ix86_expand_truncdf_32 (operands[0], operands[1]);
15422     }
15423   else
15424     {
15425       rtx op0, op1;
15426
15427       if (optimize_insn_for_size_p ())
15428         FAIL;
15429
15430       op0 = gen_reg_rtx (XFmode);
15431       op1 = gen_reg_rtx (XFmode);
15432       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15433       emit_insn (gen_frndintxf2_trunc (op0, op1));
15434
15435       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15436     }
15437   DONE;
15438 })
15439
15440 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15441 (define_insn_and_split "frndintxf2_mask_pm"
15442   [(set (match_operand:XF 0 "register_operand" "")
15443         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15444          UNSPEC_FRNDINT_MASK_PM))
15445    (clobber (reg:CC FLAGS_REG))]
15446   "TARGET_USE_FANCY_MATH_387
15447    && flag_unsafe_math_optimizations
15448    && can_create_pseudo_p ()"
15449   "#"
15450   "&& 1"
15451   [(const_int 0)]
15452 {
15453   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15454
15455   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15456   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15457
15458   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15459                                           operands[2], operands[3]));
15460   DONE;
15461 }
15462   [(set_attr "type" "frndint")
15463    (set_attr "i387_cw" "mask_pm")
15464    (set_attr "mode" "XF")])
15465
15466 (define_insn "frndintxf2_mask_pm_i387"
15467   [(set (match_operand:XF 0 "register_operand" "=f")
15468         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15469          UNSPEC_FRNDINT_MASK_PM))
15470    (use (match_operand:HI 2 "memory_operand" "m"))
15471    (use (match_operand:HI 3 "memory_operand" "m"))]
15472   "TARGET_USE_FANCY_MATH_387
15473    && flag_unsafe_math_optimizations"
15474   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15475   [(set_attr "type" "frndint")
15476    (set_attr "i387_cw" "mask_pm")
15477    (set_attr "mode" "XF")])
15478
15479 (define_expand "nearbyintxf2"
15480   [(use (match_operand:XF 0 "register_operand" ""))
15481    (use (match_operand:XF 1 "register_operand" ""))]
15482   "TARGET_USE_FANCY_MATH_387
15483    && flag_unsafe_math_optimizations"
15484 {
15485   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15486   DONE;
15487 })
15488
15489 (define_expand "nearbyint<mode>2"
15490   [(use (match_operand:MODEF 0 "register_operand" ""))
15491    (use (match_operand:MODEF 1 "register_operand" ""))]
15492   "TARGET_USE_FANCY_MATH_387
15493    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15494        || TARGET_MIX_SSE_I387)
15495    && flag_unsafe_math_optimizations"
15496 {
15497   rtx op0 = gen_reg_rtx (XFmode);
15498   rtx op1 = gen_reg_rtx (XFmode);
15499
15500   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15501   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15502
15503   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15504   DONE;
15505 })
15506
15507 (define_insn "fxam<mode>2_i387"
15508   [(set (match_operand:HI 0 "register_operand" "=a")
15509         (unspec:HI
15510           [(match_operand:X87MODEF 1 "register_operand" "f")]
15511           UNSPEC_FXAM))]
15512   "TARGET_USE_FANCY_MATH_387"
15513   "fxam\n\tfnstsw\t%0"
15514   [(set_attr "type" "multi")
15515    (set_attr "length" "4")
15516    (set_attr "unit" "i387")
15517    (set_attr "mode" "<MODE>")])
15518
15519 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15520   [(set (match_operand:HI 0 "register_operand" "")
15521         (unspec:HI
15522           [(match_operand:MODEF 1 "memory_operand" "")]
15523           UNSPEC_FXAM_MEM))]
15524   "TARGET_USE_FANCY_MATH_387
15525    && can_create_pseudo_p ()"
15526   "#"
15527   "&& 1"
15528   [(set (match_dup 2)(match_dup 1))
15529    (set (match_dup 0)
15530         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15531 {
15532   operands[2] = gen_reg_rtx (<MODE>mode);
15533
15534   MEM_VOLATILE_P (operands[1]) = 1;
15535 }
15536   [(set_attr "type" "multi")
15537    (set_attr "unit" "i387")
15538    (set_attr "mode" "<MODE>")])
15539
15540 (define_expand "isinfxf2"
15541   [(use (match_operand:SI 0 "register_operand" ""))
15542    (use (match_operand:XF 1 "register_operand" ""))]
15543   "TARGET_USE_FANCY_MATH_387
15544    && TARGET_C99_FUNCTIONS"
15545 {
15546   rtx mask = GEN_INT (0x45);
15547   rtx val = GEN_INT (0x05);
15548
15549   rtx cond;
15550
15551   rtx scratch = gen_reg_rtx (HImode);
15552   rtx res = gen_reg_rtx (QImode);
15553
15554   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15555
15556   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15557   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15558   cond = gen_rtx_fmt_ee (EQ, QImode,
15559                          gen_rtx_REG (CCmode, FLAGS_REG),
15560                          const0_rtx);
15561   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15562   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15563   DONE;
15564 })
15565
15566 (define_expand "isinf<mode>2"
15567   [(use (match_operand:SI 0 "register_operand" ""))
15568    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15569   "TARGET_USE_FANCY_MATH_387
15570    && TARGET_C99_FUNCTIONS
15571    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15572 {
15573   rtx mask = GEN_INT (0x45);
15574   rtx val = GEN_INT (0x05);
15575
15576   rtx cond;
15577
15578   rtx scratch = gen_reg_rtx (HImode);
15579   rtx res = gen_reg_rtx (QImode);
15580
15581   /* Remove excess precision by forcing value through memory. */
15582   if (memory_operand (operands[1], VOIDmode))
15583     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15584   else
15585     {
15586       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15587
15588       emit_move_insn (temp, operands[1]);
15589       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15590     }
15591
15592   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15593   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15594   cond = gen_rtx_fmt_ee (EQ, QImode,
15595                          gen_rtx_REG (CCmode, FLAGS_REG),
15596                          const0_rtx);
15597   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15598   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15599   DONE;
15600 })
15601
15602 (define_expand "signbitxf2"
15603   [(use (match_operand:SI 0 "register_operand" ""))
15604    (use (match_operand:XF 1 "register_operand" ""))]
15605   "TARGET_USE_FANCY_MATH_387"
15606 {
15607   rtx scratch = gen_reg_rtx (HImode);
15608
15609   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15610   emit_insn (gen_andsi3 (operands[0],
15611              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15612   DONE;
15613 })
15614
15615 (define_insn "movmsk_df"
15616   [(set (match_operand:SI 0 "register_operand" "=r")
15617         (unspec:SI
15618           [(match_operand:DF 1 "register_operand" "x")]
15619           UNSPEC_MOVMSK))]
15620   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15621   "%vmovmskpd\t{%1, %0|%0, %1}"
15622   [(set_attr "type" "ssemov")
15623    (set_attr "prefix" "maybe_vex")
15624    (set_attr "mode" "DF")])
15625
15626 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15627 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15628 (define_expand "signbitdf2"
15629   [(use (match_operand:SI 0 "register_operand" ""))
15630    (use (match_operand:DF 1 "register_operand" ""))]
15631   "TARGET_USE_FANCY_MATH_387
15632    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15633 {
15634   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15635     {
15636       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15637       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15638     }
15639   else
15640     {
15641       rtx scratch = gen_reg_rtx (HImode);
15642
15643       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15644       emit_insn (gen_andsi3 (operands[0],
15645                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15646     }
15647   DONE;
15648 })
15649
15650 (define_expand "signbitsf2"
15651   [(use (match_operand:SI 0 "register_operand" ""))
15652    (use (match_operand:SF 1 "register_operand" ""))]
15653   "TARGET_USE_FANCY_MATH_387
15654    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15655 {
15656   rtx scratch = gen_reg_rtx (HImode);
15657
15658   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15659   emit_insn (gen_andsi3 (operands[0],
15660              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15661   DONE;
15662 })
15663 \f
15664 ;; Block operation instructions
15665
15666 (define_insn "cld"
15667   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15668   ""
15669   "cld"
15670   [(set_attr "length" "1")
15671    (set_attr "length_immediate" "0")
15672    (set_attr "modrm" "0")])
15673
15674 (define_expand "movmem<mode>"
15675   [(use (match_operand:BLK 0 "memory_operand" ""))
15676    (use (match_operand:BLK 1 "memory_operand" ""))
15677    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15678    (use (match_operand:SWI48 3 "const_int_operand" ""))
15679    (use (match_operand:SI 4 "const_int_operand" ""))
15680    (use (match_operand:SI 5 "const_int_operand" ""))]
15681   ""
15682 {
15683  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15684                          operands[4], operands[5]))
15685    DONE;
15686  else
15687    FAIL;
15688 })
15689
15690 ;; Most CPUs don't like single string operations
15691 ;; Handle this case here to simplify previous expander.
15692
15693 (define_expand "strmov"
15694   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15695    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15696    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15697               (clobber (reg:CC FLAGS_REG))])
15698    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15699               (clobber (reg:CC FLAGS_REG))])]
15700   ""
15701 {
15702   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15703
15704   /* If .md ever supports :P for Pmode, these can be directly
15705      in the pattern above.  */
15706   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15707   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15708
15709   /* Can't use this if the user has appropriated esi or edi.  */
15710   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15711       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15712     {
15713       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15714                                       operands[2], operands[3],
15715                                       operands[5], operands[6]));
15716       DONE;
15717     }
15718
15719   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15720 })
15721
15722 (define_expand "strmov_singleop"
15723   [(parallel [(set (match_operand 1 "memory_operand" "")
15724                    (match_operand 3 "memory_operand" ""))
15725               (set (match_operand 0 "register_operand" "")
15726                    (match_operand 4 "" ""))
15727               (set (match_operand 2 "register_operand" "")
15728                    (match_operand 5 "" ""))])]
15729   ""
15730   "ix86_current_function_needs_cld = 1;")
15731
15732 (define_insn "*strmovdi_rex_1"
15733   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15734         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15735    (set (match_operand:DI 0 "register_operand" "=D")
15736         (plus:DI (match_dup 2)
15737                  (const_int 8)))
15738    (set (match_operand:DI 1 "register_operand" "=S")
15739         (plus:DI (match_dup 3)
15740                  (const_int 8)))]
15741   "TARGET_64BIT
15742    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15743   "movsq"
15744   [(set_attr "type" "str")
15745    (set_attr "memory" "both")
15746    (set_attr "mode" "DI")])
15747
15748 (define_insn "*strmovsi_1"
15749   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15750         (mem:SI (match_operand:P 3 "register_operand" "1")))
15751    (set (match_operand:P 0 "register_operand" "=D")
15752         (plus:P (match_dup 2)
15753                 (const_int 4)))
15754    (set (match_operand:P 1 "register_operand" "=S")
15755         (plus:P (match_dup 3)
15756                 (const_int 4)))]
15757   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15758   "movs{l|d}"
15759   [(set_attr "type" "str")
15760    (set_attr "memory" "both")
15761    (set_attr "mode" "SI")])
15762
15763 (define_insn "*strmovhi_1"
15764   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15765         (mem:HI (match_operand:P 3 "register_operand" "1")))
15766    (set (match_operand:P 0 "register_operand" "=D")
15767         (plus:P (match_dup 2)
15768                 (const_int 2)))
15769    (set (match_operand:P 1 "register_operand" "=S")
15770         (plus:P (match_dup 3)
15771                 (const_int 2)))]
15772   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15773   "movsw"
15774   [(set_attr "type" "str")
15775    (set_attr "memory" "both")
15776    (set_attr "mode" "HI")])
15777
15778 (define_insn "*strmovqi_1"
15779   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15780         (mem:QI (match_operand:P 3 "register_operand" "1")))
15781    (set (match_operand:P 0 "register_operand" "=D")
15782         (plus:P (match_dup 2)
15783                 (const_int 1)))
15784    (set (match_operand:P 1 "register_operand" "=S")
15785         (plus:P (match_dup 3)
15786                 (const_int 1)))]
15787   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15788   "movsb"
15789   [(set_attr "type" "str")
15790    (set_attr "memory" "both")
15791    (set (attr "prefix_rex")
15792         (if_then_else
15793           (match_test "<P:MODE>mode == DImode")
15794           (const_string "0")
15795           (const_string "*")))
15796    (set_attr "mode" "QI")])
15797
15798 (define_expand "rep_mov"
15799   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15800               (set (match_operand 0 "register_operand" "")
15801                    (match_operand 5 "" ""))
15802               (set (match_operand 2 "register_operand" "")
15803                    (match_operand 6 "" ""))
15804               (set (match_operand 1 "memory_operand" "")
15805                    (match_operand 3 "memory_operand" ""))
15806               (use (match_dup 4))])]
15807   ""
15808   "ix86_current_function_needs_cld = 1;")
15809
15810 (define_insn "*rep_movdi_rex64"
15811   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15812    (set (match_operand:DI 0 "register_operand" "=D")
15813         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15814                             (const_int 3))
15815                  (match_operand:DI 3 "register_operand" "0")))
15816    (set (match_operand:DI 1 "register_operand" "=S")
15817         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15818                  (match_operand:DI 4 "register_operand" "1")))
15819    (set (mem:BLK (match_dup 3))
15820         (mem:BLK (match_dup 4)))
15821    (use (match_dup 5))]
15822   "TARGET_64BIT
15823    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15824   "rep{%;} movsq"
15825   [(set_attr "type" "str")
15826    (set_attr "prefix_rep" "1")
15827    (set_attr "memory" "both")
15828    (set_attr "mode" "DI")])
15829
15830 (define_insn "*rep_movsi"
15831   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15832    (set (match_operand:P 0 "register_operand" "=D")
15833         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15834                           (const_int 2))
15835                  (match_operand:P 3 "register_operand" "0")))
15836    (set (match_operand:P 1 "register_operand" "=S")
15837         (plus:P (ashift:P (match_dup 5) (const_int 2))
15838                 (match_operand:P 4 "register_operand" "1")))
15839    (set (mem:BLK (match_dup 3))
15840         (mem:BLK (match_dup 4)))
15841    (use (match_dup 5))]
15842   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15843   "rep{%;} movs{l|d}"
15844   [(set_attr "type" "str")
15845    (set_attr "prefix_rep" "1")
15846    (set_attr "memory" "both")
15847    (set_attr "mode" "SI")])
15848
15849 (define_insn "*rep_movqi"
15850   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15851    (set (match_operand:P 0 "register_operand" "=D")
15852         (plus:P (match_operand:P 3 "register_operand" "0")
15853                 (match_operand:P 5 "register_operand" "2")))
15854    (set (match_operand:P 1 "register_operand" "=S")
15855         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15856    (set (mem:BLK (match_dup 3))
15857         (mem:BLK (match_dup 4)))
15858    (use (match_dup 5))]
15859   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15860   "rep{%;} movsb"
15861   [(set_attr "type" "str")
15862    (set_attr "prefix_rep" "1")
15863    (set_attr "memory" "both")
15864    (set_attr "mode" "QI")])
15865
15866 (define_expand "setmem<mode>"
15867    [(use (match_operand:BLK 0 "memory_operand" ""))
15868     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15869     (use (match_operand:QI 2 "nonmemory_operand" ""))
15870     (use (match_operand 3 "const_int_operand" ""))
15871     (use (match_operand:SI 4 "const_int_operand" ""))
15872     (use (match_operand:SI 5 "const_int_operand" ""))]
15873   ""
15874 {
15875  if (ix86_expand_setmem (operands[0], operands[1],
15876                          operands[2], operands[3],
15877                          operands[4], operands[5]))
15878    DONE;
15879  else
15880    FAIL;
15881 })
15882
15883 ;; Most CPUs don't like single string operations
15884 ;; Handle this case here to simplify previous expander.
15885
15886 (define_expand "strset"
15887   [(set (match_operand 1 "memory_operand" "")
15888         (match_operand 2 "register_operand" ""))
15889    (parallel [(set (match_operand 0 "register_operand" "")
15890                    (match_dup 3))
15891               (clobber (reg:CC FLAGS_REG))])]
15892   ""
15893 {
15894   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15895     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15896
15897   /* If .md ever supports :P for Pmode, this can be directly
15898      in the pattern above.  */
15899   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15900                               GEN_INT (GET_MODE_SIZE (GET_MODE
15901                                                       (operands[2]))));
15902   /* Can't use this if the user has appropriated eax or edi.  */
15903   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15904       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15905     {
15906       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15907                                       operands[3]));
15908       DONE;
15909     }
15910 })
15911
15912 (define_expand "strset_singleop"
15913   [(parallel [(set (match_operand 1 "memory_operand" "")
15914                    (match_operand 2 "register_operand" ""))
15915               (set (match_operand 0 "register_operand" "")
15916                    (match_operand 3 "" ""))
15917               (unspec [(const_int 0)] UNSPEC_STOS)])]
15918   ""
15919   "ix86_current_function_needs_cld = 1;")
15920
15921 (define_insn "*strsetdi_rex_1"
15922   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15923         (match_operand:DI 2 "register_operand" "a"))
15924    (set (match_operand:DI 0 "register_operand" "=D")
15925         (plus:DI (match_dup 1)
15926                  (const_int 8)))
15927    (unspec [(const_int 0)] UNSPEC_STOS)]
15928   "TARGET_64BIT
15929    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15930   "stosq"
15931   [(set_attr "type" "str")
15932    (set_attr "memory" "store")
15933    (set_attr "mode" "DI")])
15934
15935 (define_insn "*strsetsi_1"
15936   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15937         (match_operand:SI 2 "register_operand" "a"))
15938    (set (match_operand:P 0 "register_operand" "=D")
15939         (plus:P (match_dup 1)
15940                 (const_int 4)))
15941    (unspec [(const_int 0)] UNSPEC_STOS)]
15942   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15943   "stos{l|d}"
15944   [(set_attr "type" "str")
15945    (set_attr "memory" "store")
15946    (set_attr "mode" "SI")])
15947
15948 (define_insn "*strsethi_1"
15949   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15950         (match_operand:HI 2 "register_operand" "a"))
15951    (set (match_operand:P 0 "register_operand" "=D")
15952         (plus:P (match_dup 1)
15953                 (const_int 2)))
15954    (unspec [(const_int 0)] UNSPEC_STOS)]
15955   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15956   "stosw"
15957   [(set_attr "type" "str")
15958    (set_attr "memory" "store")
15959    (set_attr "mode" "HI")])
15960
15961 (define_insn "*strsetqi_1"
15962   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15963         (match_operand:QI 2 "register_operand" "a"))
15964    (set (match_operand:P 0 "register_operand" "=D")
15965         (plus:P (match_dup 1)
15966                 (const_int 1)))
15967    (unspec [(const_int 0)] UNSPEC_STOS)]
15968   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15969   "stosb"
15970   [(set_attr "type" "str")
15971    (set_attr "memory" "store")
15972    (set (attr "prefix_rex")
15973         (if_then_else
15974           (match_test "<P:MODE>mode == DImode")
15975           (const_string "0")
15976           (const_string "*")))
15977    (set_attr "mode" "QI")])
15978
15979 (define_expand "rep_stos"
15980   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15981               (set (match_operand 0 "register_operand" "")
15982                    (match_operand 4 "" ""))
15983               (set (match_operand 2 "memory_operand" "") (const_int 0))
15984               (use (match_operand 3 "register_operand" ""))
15985               (use (match_dup 1))])]
15986   ""
15987   "ix86_current_function_needs_cld = 1;")
15988
15989 (define_insn "*rep_stosdi_rex64"
15990   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15991    (set (match_operand:DI 0 "register_operand" "=D")
15992         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15993                             (const_int 3))
15994                  (match_operand:DI 3 "register_operand" "0")))
15995    (set (mem:BLK (match_dup 3))
15996         (const_int 0))
15997    (use (match_operand:DI 2 "register_operand" "a"))
15998    (use (match_dup 4))]
15999   "TARGET_64BIT
16000    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16001   "rep{%;} stosq"
16002   [(set_attr "type" "str")
16003    (set_attr "prefix_rep" "1")
16004    (set_attr "memory" "store")
16005    (set_attr "mode" "DI")])
16006
16007 (define_insn "*rep_stossi"
16008   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16009    (set (match_operand:P 0 "register_operand" "=D")
16010         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16011                           (const_int 2))
16012                  (match_operand:P 3 "register_operand" "0")))
16013    (set (mem:BLK (match_dup 3))
16014         (const_int 0))
16015    (use (match_operand:SI 2 "register_operand" "a"))
16016    (use (match_dup 4))]
16017   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16018   "rep{%;} stos{l|d}"
16019   [(set_attr "type" "str")
16020    (set_attr "prefix_rep" "1")
16021    (set_attr "memory" "store")
16022    (set_attr "mode" "SI")])
16023
16024 (define_insn "*rep_stosqi"
16025   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16026    (set (match_operand:P 0 "register_operand" "=D")
16027         (plus:P (match_operand:P 3 "register_operand" "0")
16028                 (match_operand:P 4 "register_operand" "1")))
16029    (set (mem:BLK (match_dup 3))
16030         (const_int 0))
16031    (use (match_operand:QI 2 "register_operand" "a"))
16032    (use (match_dup 4))]
16033   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16034   "rep{%;} stosb"
16035   [(set_attr "type" "str")
16036    (set_attr "prefix_rep" "1")
16037    (set_attr "memory" "store")
16038    (set (attr "prefix_rex")
16039         (if_then_else
16040           (match_test "<P:MODE>mode == DImode")
16041           (const_string "0")
16042           (const_string "*")))
16043    (set_attr "mode" "QI")])
16044
16045 (define_expand "cmpstrnsi"
16046   [(set (match_operand:SI 0 "register_operand" "")
16047         (compare:SI (match_operand:BLK 1 "general_operand" "")
16048                     (match_operand:BLK 2 "general_operand" "")))
16049    (use (match_operand 3 "general_operand" ""))
16050    (use (match_operand 4 "immediate_operand" ""))]
16051   ""
16052 {
16053   rtx addr1, addr2, out, outlow, count, countreg, align;
16054
16055   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16056     FAIL;
16057
16058   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16059   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16060     FAIL;
16061
16062   out = operands[0];
16063   if (!REG_P (out))
16064     out = gen_reg_rtx (SImode);
16065
16066   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16067   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16068   if (addr1 != XEXP (operands[1], 0))
16069     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16070   if (addr2 != XEXP (operands[2], 0))
16071     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16072
16073   count = operands[3];
16074   countreg = ix86_zero_extend_to_Pmode (count);
16075
16076   /* %%% Iff we are testing strict equality, we can use known alignment
16077      to good advantage.  This may be possible with combine, particularly
16078      once cc0 is dead.  */
16079   align = operands[4];
16080
16081   if (CONST_INT_P (count))
16082     {
16083       if (INTVAL (count) == 0)
16084         {
16085           emit_move_insn (operands[0], const0_rtx);
16086           DONE;
16087         }
16088       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16089                                      operands[1], operands[2]));
16090     }
16091   else
16092     {
16093       rtx (*gen_cmp) (rtx, rtx);
16094
16095       gen_cmp = (TARGET_64BIT
16096                  ? gen_cmpdi_1 : gen_cmpsi_1);
16097
16098       emit_insn (gen_cmp (countreg, countreg));
16099       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16100                                   operands[1], operands[2]));
16101     }
16102
16103   outlow = gen_lowpart (QImode, out);
16104   emit_insn (gen_cmpintqi (outlow));
16105   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16106
16107   if (operands[0] != out)
16108     emit_move_insn (operands[0], out);
16109
16110   DONE;
16111 })
16112
16113 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16114
16115 (define_expand "cmpintqi"
16116   [(set (match_dup 1)
16117         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16118    (set (match_dup 2)
16119         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16120    (parallel [(set (match_operand:QI 0 "register_operand" "")
16121                    (minus:QI (match_dup 1)
16122                              (match_dup 2)))
16123               (clobber (reg:CC FLAGS_REG))])]
16124   ""
16125 {
16126   operands[1] = gen_reg_rtx (QImode);
16127   operands[2] = gen_reg_rtx (QImode);
16128 })
16129
16130 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16131 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16132
16133 (define_expand "cmpstrnqi_nz_1"
16134   [(parallel [(set (reg:CC FLAGS_REG)
16135                    (compare:CC (match_operand 4 "memory_operand" "")
16136                                (match_operand 5 "memory_operand" "")))
16137               (use (match_operand 2 "register_operand" ""))
16138               (use (match_operand:SI 3 "immediate_operand" ""))
16139               (clobber (match_operand 0 "register_operand" ""))
16140               (clobber (match_operand 1 "register_operand" ""))
16141               (clobber (match_dup 2))])]
16142   ""
16143   "ix86_current_function_needs_cld = 1;")
16144
16145 (define_insn "*cmpstrnqi_nz_1"
16146   [(set (reg:CC FLAGS_REG)
16147         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16148                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16149    (use (match_operand:P 6 "register_operand" "2"))
16150    (use (match_operand:SI 3 "immediate_operand" "i"))
16151    (clobber (match_operand:P 0 "register_operand" "=S"))
16152    (clobber (match_operand:P 1 "register_operand" "=D"))
16153    (clobber (match_operand:P 2 "register_operand" "=c"))]
16154   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16155   "repz{%;} cmpsb"
16156   [(set_attr "type" "str")
16157    (set_attr "mode" "QI")
16158    (set (attr "prefix_rex")
16159         (if_then_else
16160           (match_test "<P:MODE>mode == DImode")
16161           (const_string "0")
16162           (const_string "*")))
16163    (set_attr "prefix_rep" "1")])
16164
16165 ;; The same, but the count is not known to not be zero.
16166
16167 (define_expand "cmpstrnqi_1"
16168   [(parallel [(set (reg:CC FLAGS_REG)
16169                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16170                                      (const_int 0))
16171                   (compare:CC (match_operand 4 "memory_operand" "")
16172                               (match_operand 5 "memory_operand" ""))
16173                   (const_int 0)))
16174               (use (match_operand:SI 3 "immediate_operand" ""))
16175               (use (reg:CC FLAGS_REG))
16176               (clobber (match_operand 0 "register_operand" ""))
16177               (clobber (match_operand 1 "register_operand" ""))
16178               (clobber (match_dup 2))])]
16179   ""
16180   "ix86_current_function_needs_cld = 1;")
16181
16182 (define_insn "*cmpstrnqi_1"
16183   [(set (reg:CC FLAGS_REG)
16184         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16185                              (const_int 0))
16186           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16187                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16188           (const_int 0)))
16189    (use (match_operand:SI 3 "immediate_operand" "i"))
16190    (use (reg:CC FLAGS_REG))
16191    (clobber (match_operand:P 0 "register_operand" "=S"))
16192    (clobber (match_operand:P 1 "register_operand" "=D"))
16193    (clobber (match_operand:P 2 "register_operand" "=c"))]
16194   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16195   "repz{%;} cmpsb"
16196   [(set_attr "type" "str")
16197    (set_attr "mode" "QI")
16198    (set (attr "prefix_rex")
16199         (if_then_else
16200           (match_test "<P:MODE>mode == DImode")
16201           (const_string "0")
16202           (const_string "*")))
16203    (set_attr "prefix_rep" "1")])
16204
16205 (define_expand "strlen<mode>"
16206   [(set (match_operand:P 0 "register_operand" "")
16207         (unspec:P [(match_operand:BLK 1 "general_operand" "")
16208                    (match_operand:QI 2 "immediate_operand" "")
16209                    (match_operand 3 "immediate_operand" "")]
16210                   UNSPEC_SCAS))]
16211   ""
16212 {
16213  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16214    DONE;
16215  else
16216    FAIL;
16217 })
16218
16219 (define_expand "strlenqi_1"
16220   [(parallel [(set (match_operand 0 "register_operand" "")
16221                    (match_operand 2 "" ""))
16222               (clobber (match_operand 1 "register_operand" ""))
16223               (clobber (reg:CC FLAGS_REG))])]
16224   ""
16225   "ix86_current_function_needs_cld = 1;")
16226
16227 (define_insn "*strlenqi_1"
16228   [(set (match_operand:P 0 "register_operand" "=&c")
16229         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16230                    (match_operand:QI 2 "register_operand" "a")
16231                    (match_operand:P 3 "immediate_operand" "i")
16232                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16233    (clobber (match_operand:P 1 "register_operand" "=D"))
16234    (clobber (reg:CC FLAGS_REG))]
16235   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16236   "repnz{%;} scasb"
16237   [(set_attr "type" "str")
16238    (set_attr "mode" "QI")
16239    (set (attr "prefix_rex")
16240         (if_then_else
16241           (match_test "<P:MODE>mode == DImode")
16242           (const_string "0")
16243           (const_string "*")))
16244    (set_attr "prefix_rep" "1")])
16245
16246 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16247 ;; handled in combine, but it is not currently up to the task.
16248 ;; When used for their truth value, the cmpstrn* expanders generate
16249 ;; code like this:
16250 ;;
16251 ;;   repz cmpsb
16252 ;;   seta       %al
16253 ;;   setb       %dl
16254 ;;   cmpb       %al, %dl
16255 ;;   jcc        label
16256 ;;
16257 ;; The intermediate three instructions are unnecessary.
16258
16259 ;; This one handles cmpstrn*_nz_1...
16260 (define_peephole2
16261   [(parallel[
16262      (set (reg:CC FLAGS_REG)
16263           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16264                       (mem:BLK (match_operand 5 "register_operand" ""))))
16265      (use (match_operand 6 "register_operand" ""))
16266      (use (match_operand:SI 3 "immediate_operand" ""))
16267      (clobber (match_operand 0 "register_operand" ""))
16268      (clobber (match_operand 1 "register_operand" ""))
16269      (clobber (match_operand 2 "register_operand" ""))])
16270    (set (match_operand:QI 7 "register_operand" "")
16271         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16272    (set (match_operand:QI 8 "register_operand" "")
16273         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16274    (set (reg FLAGS_REG)
16275         (compare (match_dup 7) (match_dup 8)))
16276   ]
16277   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16278   [(parallel[
16279      (set (reg:CC FLAGS_REG)
16280           (compare:CC (mem:BLK (match_dup 4))
16281                       (mem:BLK (match_dup 5))))
16282      (use (match_dup 6))
16283      (use (match_dup 3))
16284      (clobber (match_dup 0))
16285      (clobber (match_dup 1))
16286      (clobber (match_dup 2))])])
16287
16288 ;; ...and this one handles cmpstrn*_1.
16289 (define_peephole2
16290   [(parallel[
16291      (set (reg:CC FLAGS_REG)
16292           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16293                                (const_int 0))
16294             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16295                         (mem:BLK (match_operand 5 "register_operand" "")))
16296             (const_int 0)))
16297      (use (match_operand:SI 3 "immediate_operand" ""))
16298      (use (reg:CC FLAGS_REG))
16299      (clobber (match_operand 0 "register_operand" ""))
16300      (clobber (match_operand 1 "register_operand" ""))
16301      (clobber (match_operand 2 "register_operand" ""))])
16302    (set (match_operand:QI 7 "register_operand" "")
16303         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16304    (set (match_operand:QI 8 "register_operand" "")
16305         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16306    (set (reg FLAGS_REG)
16307         (compare (match_dup 7) (match_dup 8)))
16308   ]
16309   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16310   [(parallel[
16311      (set (reg:CC FLAGS_REG)
16312           (if_then_else:CC (ne (match_dup 6)
16313                                (const_int 0))
16314             (compare:CC (mem:BLK (match_dup 4))
16315                         (mem:BLK (match_dup 5)))
16316             (const_int 0)))
16317      (use (match_dup 3))
16318      (use (reg:CC FLAGS_REG))
16319      (clobber (match_dup 0))
16320      (clobber (match_dup 1))
16321      (clobber (match_dup 2))])])
16322 \f
16323 ;; Conditional move instructions.
16324
16325 (define_expand "mov<mode>cc"
16326   [(set (match_operand:SWIM 0 "register_operand" "")
16327         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16328                            (match_operand:SWIM 2 "<general_operand>" "")
16329                            (match_operand:SWIM 3 "<general_operand>" "")))]
16330   ""
16331   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16332
16333 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16334 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16335 ;; So just document what we're doing explicitly.
16336
16337 (define_expand "x86_mov<mode>cc_0_m1"
16338   [(parallel
16339     [(set (match_operand:SWI48 0 "register_operand" "")
16340           (if_then_else:SWI48
16341             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16342              [(match_operand 1 "flags_reg_operand" "")
16343               (const_int 0)])
16344             (const_int -1)
16345             (const_int 0)))
16346      (clobber (reg:CC FLAGS_REG))])])
16347
16348 (define_insn "*x86_mov<mode>cc_0_m1"
16349   [(set (match_operand:SWI48 0 "register_operand" "=r")
16350         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16351                              [(reg FLAGS_REG) (const_int 0)])
16352           (const_int -1)
16353           (const_int 0)))
16354    (clobber (reg:CC FLAGS_REG))]
16355   ""
16356   "sbb{<imodesuffix>}\t%0, %0"
16357   ; Since we don't have the proper number of operands for an alu insn,
16358   ; fill in all the blanks.
16359   [(set_attr "type" "alu")
16360    (set_attr "use_carry" "1")
16361    (set_attr "pent_pair" "pu")
16362    (set_attr "memory" "none")
16363    (set_attr "imm_disp" "false")
16364    (set_attr "mode" "<MODE>")
16365    (set_attr "length_immediate" "0")])
16366
16367 (define_insn "*x86_mov<mode>cc_0_m1_se"
16368   [(set (match_operand:SWI48 0 "register_operand" "=r")
16369         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16370                              [(reg FLAGS_REG) (const_int 0)])
16371                             (const_int 1)
16372                             (const_int 0)))
16373    (clobber (reg:CC FLAGS_REG))]
16374   ""
16375   "sbb{<imodesuffix>}\t%0, %0"
16376   [(set_attr "type" "alu")
16377    (set_attr "use_carry" "1")
16378    (set_attr "pent_pair" "pu")
16379    (set_attr "memory" "none")
16380    (set_attr "imm_disp" "false")
16381    (set_attr "mode" "<MODE>")
16382    (set_attr "length_immediate" "0")])
16383
16384 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16385   [(set (match_operand:SWI48 0 "register_operand" "=r")
16386         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16387                     [(reg FLAGS_REG) (const_int 0)])))
16388    (clobber (reg:CC FLAGS_REG))]
16389   ""
16390   "sbb{<imodesuffix>}\t%0, %0"
16391   [(set_attr "type" "alu")
16392    (set_attr "use_carry" "1")
16393    (set_attr "pent_pair" "pu")
16394    (set_attr "memory" "none")
16395    (set_attr "imm_disp" "false")
16396    (set_attr "mode" "<MODE>")
16397    (set_attr "length_immediate" "0")])
16398
16399 (define_insn "*mov<mode>cc_noc"
16400   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16401         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16402                                [(reg FLAGS_REG) (const_int 0)])
16403           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16404           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16405   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16406   "@
16407    cmov%O2%C1\t{%2, %0|%0, %2}
16408    cmov%O2%c1\t{%3, %0|%0, %3}"
16409   [(set_attr "type" "icmov")
16410    (set_attr "mode" "<MODE>")])
16411
16412 (define_insn "*movqicc_noc"
16413   [(set (match_operand:QI 0 "register_operand" "=r,r")
16414         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16415                            [(reg FLAGS_REG) (const_int 0)])
16416                       (match_operand:QI 2 "register_operand" "r,0")
16417                       (match_operand:QI 3 "register_operand" "0,r")))]
16418   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16419   "#"
16420   [(set_attr "type" "icmov")
16421    (set_attr "mode" "QI")])
16422
16423 (define_split
16424   [(set (match_operand 0 "register_operand")
16425         (if_then_else (match_operator 1 "ix86_comparison_operator"
16426                         [(reg FLAGS_REG) (const_int 0)])
16427                       (match_operand 2 "register_operand")
16428                       (match_operand 3 "register_operand")))]
16429   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16430    && (GET_MODE (operands[0]) == QImode
16431        || GET_MODE (operands[0]) == HImode)
16432    && reload_completed"
16433   [(set (match_dup 0)
16434         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16435 {
16436   operands[0] = gen_lowpart (SImode, operands[0]);
16437   operands[2] = gen_lowpart (SImode, operands[2]);
16438   operands[3] = gen_lowpart (SImode, operands[3]);
16439 })
16440
16441 (define_expand "mov<mode>cc"
16442   [(set (match_operand:X87MODEF 0 "register_operand" "")
16443         (if_then_else:X87MODEF
16444           (match_operand 1 "ix86_fp_comparison_operator" "")
16445           (match_operand:X87MODEF 2 "register_operand" "")
16446           (match_operand:X87MODEF 3 "register_operand" "")))]
16447   "(TARGET_80387 && TARGET_CMOVE)
16448    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16449   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16450
16451 (define_insn "*movxfcc_1"
16452   [(set (match_operand:XF 0 "register_operand" "=f,f")
16453         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16454                                 [(reg FLAGS_REG) (const_int 0)])
16455                       (match_operand:XF 2 "register_operand" "f,0")
16456                       (match_operand:XF 3 "register_operand" "0,f")))]
16457   "TARGET_80387 && TARGET_CMOVE"
16458   "@
16459    fcmov%F1\t{%2, %0|%0, %2}
16460    fcmov%f1\t{%3, %0|%0, %3}"
16461   [(set_attr "type" "fcmov")
16462    (set_attr "mode" "XF")])
16463
16464 (define_insn "*movdfcc_1_rex64"
16465   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16466         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16467                                 [(reg FLAGS_REG) (const_int 0)])
16468                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16469                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16470   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16471    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16472   "@
16473    fcmov%F1\t{%2, %0|%0, %2}
16474    fcmov%f1\t{%3, %0|%0, %3}
16475    cmov%O2%C1\t{%2, %0|%0, %2}
16476    cmov%O2%c1\t{%3, %0|%0, %3}"
16477   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16478    (set_attr "mode" "DF,DF,DI,DI")])
16479
16480 (define_insn "*movdfcc_1"
16481   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16482         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16483                                 [(reg FLAGS_REG) (const_int 0)])
16484                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16485                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16486   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16487    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16488   "@
16489    fcmov%F1\t{%2, %0|%0, %2}
16490    fcmov%f1\t{%3, %0|%0, %3}
16491    #
16492    #"
16493   [(set_attr "type" "fcmov,fcmov,multi,multi")
16494    (set_attr "mode" "DF,DF,DI,DI")])
16495
16496 (define_split
16497   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16498         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16499                                 [(reg FLAGS_REG) (const_int 0)])
16500                       (match_operand:DF 2 "nonimmediate_operand")
16501                       (match_operand:DF 3 "nonimmediate_operand")))]
16502   "!TARGET_64BIT && reload_completed"
16503   [(set (match_dup 2)
16504         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16505    (set (match_dup 3)
16506         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16507 {
16508   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16509   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16510 })
16511
16512 (define_insn "*movsfcc_1_387"
16513   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16514         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16515                                 [(reg FLAGS_REG) (const_int 0)])
16516                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16517                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16518   "TARGET_80387 && TARGET_CMOVE
16519    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16520   "@
16521    fcmov%F1\t{%2, %0|%0, %2}
16522    fcmov%f1\t{%3, %0|%0, %3}
16523    cmov%O2%C1\t{%2, %0|%0, %2}
16524    cmov%O2%c1\t{%3, %0|%0, %3}"
16525   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16526    (set_attr "mode" "SF,SF,SI,SI")])
16527
16528 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16529 ;; the scalar versions to have only XMM registers as operands.
16530
16531 ;; XOP conditional move
16532 (define_insn "*xop_pcmov_<mode>"
16533   [(set (match_operand:MODEF 0 "register_operand" "=x")
16534         (if_then_else:MODEF
16535           (match_operand:MODEF 1 "register_operand" "x")
16536           (match_operand:MODEF 2 "register_operand" "x")
16537           (match_operand:MODEF 3 "register_operand" "x")))]
16538   "TARGET_XOP"
16539   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16540   [(set_attr "type" "sse4arg")])
16541
16542 ;; These versions of the min/max patterns are intentionally ignorant of
16543 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16544 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16545 ;; are undefined in this condition, we're certain this is correct.
16546
16547 (define_insn "<code><mode>3"
16548   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16549         (smaxmin:MODEF
16550           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16551           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16552   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16553   "@
16554    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16555    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16556   [(set_attr "isa" "noavx,avx")
16557    (set_attr "prefix" "orig,vex")
16558    (set_attr "type" "sseadd")
16559    (set_attr "mode" "<MODE>")])
16560
16561 ;; These versions of the min/max patterns implement exactly the operations
16562 ;;   min = (op1 < op2 ? op1 : op2)
16563 ;;   max = (!(op1 < op2) ? op1 : op2)
16564 ;; Their operands are not commutative, and thus they may be used in the
16565 ;; presence of -0.0 and NaN.
16566
16567 (define_insn "*ieee_smin<mode>3"
16568   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16569         (unspec:MODEF
16570           [(match_operand:MODEF 1 "register_operand" "0,x")
16571            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16572          UNSPEC_IEEE_MIN))]
16573   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16574   "@
16575    min<ssemodesuffix>\t{%2, %0|%0, %2}
16576    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16577   [(set_attr "isa" "noavx,avx")
16578    (set_attr "prefix" "orig,vex")
16579    (set_attr "type" "sseadd")
16580    (set_attr "mode" "<MODE>")])
16581
16582 (define_insn "*ieee_smax<mode>3"
16583   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16584         (unspec:MODEF
16585           [(match_operand:MODEF 1 "register_operand" "0,x")
16586            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16587          UNSPEC_IEEE_MAX))]
16588   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16589   "@
16590    max<ssemodesuffix>\t{%2, %0|%0, %2}
16591    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16592   [(set_attr "isa" "noavx,avx")
16593    (set_attr "prefix" "orig,vex")
16594    (set_attr "type" "sseadd")
16595    (set_attr "mode" "<MODE>")])
16596
16597 ;; Make two stack loads independent:
16598 ;;   fld aa              fld aa
16599 ;;   fld %st(0)     ->   fld bb
16600 ;;   fmul bb             fmul %st(1), %st
16601 ;;
16602 ;; Actually we only match the last two instructions for simplicity.
16603 (define_peephole2
16604   [(set (match_operand 0 "fp_register_operand" "")
16605         (match_operand 1 "fp_register_operand" ""))
16606    (set (match_dup 0)
16607         (match_operator 2 "binary_fp_operator"
16608            [(match_dup 0)
16609             (match_operand 3 "memory_operand" "")]))]
16610   "REGNO (operands[0]) != REGNO (operands[1])"
16611   [(set (match_dup 0) (match_dup 3))
16612    (set (match_dup 0) (match_dup 4))]
16613
16614   ;; The % modifier is not operational anymore in peephole2's, so we have to
16615   ;; swap the operands manually in the case of addition and multiplication.
16616 {
16617   rtx op0, op1;
16618
16619   if (COMMUTATIVE_ARITH_P (operands[2]))
16620     op0 = operands[0], op1 = operands[1];
16621   else
16622     op0 = operands[1], op1 = operands[0];
16623
16624   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16625                                 GET_MODE (operands[2]),
16626                                 op0, op1);
16627 })
16628
16629 ;; Conditional addition patterns
16630 (define_expand "add<mode>cc"
16631   [(match_operand:SWI 0 "register_operand" "")
16632    (match_operand 1 "ordered_comparison_operator" "")
16633    (match_operand:SWI 2 "register_operand" "")
16634    (match_operand:SWI 3 "const_int_operand" "")]
16635   ""
16636   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16637 \f
16638 ;; Misc patterns (?)
16639
16640 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16641 ;; Otherwise there will be nothing to keep
16642 ;;
16643 ;; [(set (reg ebp) (reg esp))]
16644 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16645 ;;  (clobber (eflags)]
16646 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16647 ;;
16648 ;; in proper program order.
16649
16650 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16651   [(set (match_operand:P 0 "register_operand" "=r,r")
16652         (plus:P (match_operand:P 1 "register_operand" "0,r")
16653                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16654    (clobber (reg:CC FLAGS_REG))
16655    (clobber (mem:BLK (scratch)))]
16656   ""
16657 {
16658   switch (get_attr_type (insn))
16659     {
16660     case TYPE_IMOV:
16661       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16662
16663     case TYPE_ALU:
16664       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16665       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16666         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16667
16668       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16669
16670     default:
16671       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16672       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16673     }
16674 }
16675   [(set (attr "type")
16676         (cond [(and (eq_attr "alternative" "0")
16677                     (not (match_test "TARGET_OPT_AGU")))
16678                  (const_string "alu")
16679                (match_operand:<MODE> 2 "const0_operand" "")
16680                  (const_string "imov")
16681               ]
16682               (const_string "lea")))
16683    (set (attr "length_immediate")
16684         (cond [(eq_attr "type" "imov")
16685                  (const_string "0")
16686                (and (eq_attr "type" "alu")
16687                     (match_operand 2 "const128_operand" ""))
16688                  (const_string "1")
16689               ]
16690               (const_string "*")))
16691    (set_attr "mode" "<MODE>")])
16692
16693 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16694   [(set (match_operand:P 0 "register_operand" "=r")
16695         (minus:P (match_operand:P 1 "register_operand" "0")
16696                  (match_operand:P 2 "register_operand" "r")))
16697    (clobber (reg:CC FLAGS_REG))
16698    (clobber (mem:BLK (scratch)))]
16699   ""
16700   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16701   [(set_attr "type" "alu")
16702    (set_attr "mode" "<MODE>")])
16703
16704 (define_insn "allocate_stack_worker_probe_<mode>"
16705   [(set (match_operand:P 0 "register_operand" "=a")
16706         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16707                             UNSPECV_STACK_PROBE))
16708    (clobber (reg:CC FLAGS_REG))]
16709   "ix86_target_stack_probe ()"
16710   "call\t___chkstk_ms"
16711   [(set_attr "type" "multi")
16712    (set_attr "length" "5")])
16713
16714 (define_expand "allocate_stack"
16715   [(match_operand 0 "register_operand" "")
16716    (match_operand 1 "general_operand" "")]
16717   "ix86_target_stack_probe ()"
16718 {
16719   rtx x;
16720
16721 #ifndef CHECK_STACK_LIMIT
16722 #define CHECK_STACK_LIMIT 0
16723 #endif
16724
16725   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16726       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16727     {
16728       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16729                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16730       if (x != stack_pointer_rtx)
16731         emit_move_insn (stack_pointer_rtx, x);
16732     }
16733   else
16734     {
16735       x = copy_to_mode_reg (Pmode, operands[1]);
16736       if (TARGET_64BIT)
16737         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16738       else
16739         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16740       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16741                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16742       if (x != stack_pointer_rtx)
16743         emit_move_insn (stack_pointer_rtx, x);
16744     }
16745
16746   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16747   DONE;
16748 })
16749
16750 ;; Use IOR for stack probes, this is shorter.
16751 (define_expand "probe_stack"
16752   [(match_operand 0 "memory_operand" "")]
16753   ""
16754 {
16755   rtx (*gen_ior3) (rtx, rtx, rtx);
16756
16757   gen_ior3 = (GET_MODE (operands[0]) == DImode
16758               ? gen_iordi3 : gen_iorsi3);
16759
16760   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16761   DONE;
16762 })
16763
16764 (define_insn "adjust_stack_and_probe<mode>"
16765   [(set (match_operand:P 0 "register_operand" "=r")
16766         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16767                             UNSPECV_PROBE_STACK_RANGE))
16768    (set (reg:P SP_REG)
16769         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16770    (clobber (reg:CC FLAGS_REG))
16771    (clobber (mem:BLK (scratch)))]
16772   ""
16773   "* return output_adjust_stack_and_probe (operands[0]);"
16774   [(set_attr "type" "multi")])
16775
16776 (define_insn "probe_stack_range<mode>"
16777   [(set (match_operand:P 0 "register_operand" "=r")
16778         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16779                             (match_operand:P 2 "const_int_operand" "n")]
16780                             UNSPECV_PROBE_STACK_RANGE))
16781    (clobber (reg:CC FLAGS_REG))]
16782   ""
16783   "* return output_probe_stack_range (operands[0], operands[2]);"
16784   [(set_attr "type" "multi")])
16785
16786 (define_expand "builtin_setjmp_receiver"
16787   [(label_ref (match_operand 0 "" ""))]
16788   "!TARGET_64BIT && flag_pic"
16789 {
16790 #if TARGET_MACHO
16791   if (TARGET_MACHO)
16792     {
16793       rtx xops[3];
16794       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16795       rtx label_rtx = gen_label_rtx ();
16796       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16797       xops[0] = xops[1] = picreg;
16798       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16799       ix86_expand_binary_operator (MINUS, SImode, xops);
16800     }
16801   else
16802 #endif
16803     emit_insn (gen_set_got (pic_offset_table_rtx));
16804   DONE;
16805 })
16806
16807 (define_insn_and_split "nonlocal_goto_receiver"
16808   [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16809   "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16810   "#"
16811   "&& reload_completed"
16812   [(const_int 0)]
16813 {
16814   if (crtl->uses_pic_offset_table)
16815     {
16816       rtx xops[3];
16817       rtx label_rtx = gen_label_rtx ();
16818       rtx tmp;
16819
16820       /* Get a new pic base.  */
16821       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16822       /* Correct this with the offset from the new to the old.  */
16823       xops[0] = xops[1] = pic_offset_table_rtx;
16824       label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16825       tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16826                             UNSPEC_MACHOPIC_OFFSET);
16827       xops[2] = gen_rtx_CONST (Pmode, tmp);
16828       ix86_expand_binary_operator (MINUS, SImode, xops);
16829     }
16830   else
16831     /* No pic reg restore needed.  */
16832     emit_note (NOTE_INSN_DELETED);
16833
16834   DONE;
16835 })
16836
16837 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16838
16839 (define_split
16840   [(set (match_operand 0 "register_operand" "")
16841         (match_operator 3 "promotable_binary_operator"
16842            [(match_operand 1 "register_operand" "")
16843             (match_operand 2 "aligned_operand" "")]))
16844    (clobber (reg:CC FLAGS_REG))]
16845   "! TARGET_PARTIAL_REG_STALL && reload_completed
16846    && ((GET_MODE (operands[0]) == HImode
16847         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16848             /* ??? next two lines just !satisfies_constraint_K (...) */
16849             || !CONST_INT_P (operands[2])
16850             || satisfies_constraint_K (operands[2])))
16851        || (GET_MODE (operands[0]) == QImode
16852            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16853   [(parallel [(set (match_dup 0)
16854                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16855               (clobber (reg:CC FLAGS_REG))])]
16856 {
16857   operands[0] = gen_lowpart (SImode, operands[0]);
16858   operands[1] = gen_lowpart (SImode, operands[1]);
16859   if (GET_CODE (operands[3]) != ASHIFT)
16860     operands[2] = gen_lowpart (SImode, operands[2]);
16861   PUT_MODE (operands[3], SImode);
16862 })
16863
16864 ; Promote the QImode tests, as i386 has encoding of the AND
16865 ; instruction with 32-bit sign-extended immediate and thus the
16866 ; instruction size is unchanged, except in the %eax case for
16867 ; which it is increased by one byte, hence the ! optimize_size.
16868 (define_split
16869   [(set (match_operand 0 "flags_reg_operand" "")
16870         (match_operator 2 "compare_operator"
16871           [(and (match_operand 3 "aligned_operand" "")
16872                 (match_operand 4 "const_int_operand" ""))
16873            (const_int 0)]))
16874    (set (match_operand 1 "register_operand" "")
16875         (and (match_dup 3) (match_dup 4)))]
16876   "! TARGET_PARTIAL_REG_STALL && reload_completed
16877    && optimize_insn_for_speed_p ()
16878    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16879        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16880    /* Ensure that the operand will remain sign-extended immediate.  */
16881    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16882   [(parallel [(set (match_dup 0)
16883                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16884                                     (const_int 0)]))
16885               (set (match_dup 1)
16886                    (and:SI (match_dup 3) (match_dup 4)))])]
16887 {
16888   operands[4]
16889     = gen_int_mode (INTVAL (operands[4])
16890                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16891   operands[1] = gen_lowpart (SImode, operands[1]);
16892   operands[3] = gen_lowpart (SImode, operands[3]);
16893 })
16894
16895 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16896 ; the TEST instruction with 32-bit sign-extended immediate and thus
16897 ; the instruction size would at least double, which is not what we
16898 ; want even with ! optimize_size.
16899 (define_split
16900   [(set (match_operand 0 "flags_reg_operand" "")
16901         (match_operator 1 "compare_operator"
16902           [(and (match_operand:HI 2 "aligned_operand" "")
16903                 (match_operand:HI 3 "const_int_operand" ""))
16904            (const_int 0)]))]
16905   "! TARGET_PARTIAL_REG_STALL && reload_completed
16906    && ! TARGET_FAST_PREFIX
16907    && optimize_insn_for_speed_p ()
16908    /* Ensure that the operand will remain sign-extended immediate.  */
16909    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16910   [(set (match_dup 0)
16911         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16912                          (const_int 0)]))]
16913 {
16914   operands[3]
16915     = gen_int_mode (INTVAL (operands[3])
16916                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16917   operands[2] = gen_lowpart (SImode, operands[2]);
16918 })
16919
16920 (define_split
16921   [(set (match_operand 0 "register_operand" "")
16922         (neg (match_operand 1 "register_operand" "")))
16923    (clobber (reg:CC FLAGS_REG))]
16924   "! TARGET_PARTIAL_REG_STALL && reload_completed
16925    && (GET_MODE (operands[0]) == HImode
16926        || (GET_MODE (operands[0]) == QImode
16927            && (TARGET_PROMOTE_QImode
16928                || optimize_insn_for_size_p ())))"
16929   [(parallel [(set (match_dup 0)
16930                    (neg:SI (match_dup 1)))
16931               (clobber (reg:CC FLAGS_REG))])]
16932 {
16933   operands[0] = gen_lowpart (SImode, operands[0]);
16934   operands[1] = gen_lowpart (SImode, operands[1]);
16935 })
16936
16937 (define_split
16938   [(set (match_operand 0 "register_operand" "")
16939         (not (match_operand 1 "register_operand" "")))]
16940   "! TARGET_PARTIAL_REG_STALL && reload_completed
16941    && (GET_MODE (operands[0]) == HImode
16942        || (GET_MODE (operands[0]) == QImode
16943            && (TARGET_PROMOTE_QImode
16944                || optimize_insn_for_size_p ())))"
16945   [(set (match_dup 0)
16946         (not:SI (match_dup 1)))]
16947 {
16948   operands[0] = gen_lowpart (SImode, operands[0]);
16949   operands[1] = gen_lowpart (SImode, operands[1]);
16950 })
16951 \f
16952 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16953 ;; transform a complex memory operation into two memory to register operations.
16954
16955 ;; Don't push memory operands
16956 (define_peephole2
16957   [(set (match_operand:SWI 0 "push_operand" "")
16958         (match_operand:SWI 1 "memory_operand" ""))
16959    (match_scratch:SWI 2 "<r>")]
16960   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16961    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16962   [(set (match_dup 2) (match_dup 1))
16963    (set (match_dup 0) (match_dup 2))])
16964
16965 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16966 ;; SImode pushes.
16967 (define_peephole2
16968   [(set (match_operand:SF 0 "push_operand" "")
16969         (match_operand:SF 1 "memory_operand" ""))
16970    (match_scratch:SF 2 "r")]
16971   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16972    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16973   [(set (match_dup 2) (match_dup 1))
16974    (set (match_dup 0) (match_dup 2))])
16975
16976 ;; Don't move an immediate directly to memory when the instruction
16977 ;; gets too big.
16978 (define_peephole2
16979   [(match_scratch:SWI124 1 "<r>")
16980    (set (match_operand:SWI124 0 "memory_operand" "")
16981         (const_int 0))]
16982   "optimize_insn_for_speed_p ()
16983    && !TARGET_USE_MOV0
16984    && TARGET_SPLIT_LONG_MOVES
16985    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16986    && peep2_regno_dead_p (0, FLAGS_REG)"
16987   [(parallel [(set (match_dup 2) (const_int 0))
16988               (clobber (reg:CC FLAGS_REG))])
16989    (set (match_dup 0) (match_dup 1))]
16990   "operands[2] = gen_lowpart (SImode, operands[1]);")
16991
16992 (define_peephole2
16993   [(match_scratch:SWI124 2 "<r>")
16994    (set (match_operand:SWI124 0 "memory_operand" "")
16995         (match_operand:SWI124 1 "immediate_operand" ""))]
16996   "optimize_insn_for_speed_p ()
16997    && TARGET_SPLIT_LONG_MOVES
16998    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16999   [(set (match_dup 2) (match_dup 1))
17000    (set (match_dup 0) (match_dup 2))])
17001
17002 ;; Don't compare memory with zero, load and use a test instead.
17003 (define_peephole2
17004   [(set (match_operand 0 "flags_reg_operand" "")
17005         (match_operator 1 "compare_operator"
17006           [(match_operand:SI 2 "memory_operand" "")
17007            (const_int 0)]))
17008    (match_scratch:SI 3 "r")]
17009   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17010   [(set (match_dup 3) (match_dup 2))
17011    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17012
17013 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17014 ;; Don't split NOTs with a displacement operand, because resulting XOR
17015 ;; will not be pairable anyway.
17016 ;;
17017 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17018 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17019 ;; so this split helps here as well.
17020 ;;
17021 ;; Note: Can't do this as a regular split because we can't get proper
17022 ;; lifetime information then.
17023
17024 (define_peephole2
17025   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17026         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17027   "optimize_insn_for_speed_p ()
17028    && ((TARGET_NOT_UNPAIRABLE
17029         && (!MEM_P (operands[0])
17030             || !memory_displacement_operand (operands[0], <MODE>mode)))
17031        || (TARGET_NOT_VECTORMODE
17032            && long_memory_operand (operands[0], <MODE>mode)))
17033    && peep2_regno_dead_p (0, FLAGS_REG)"
17034   [(parallel [(set (match_dup 0)
17035                    (xor:SWI124 (match_dup 1) (const_int -1)))
17036               (clobber (reg:CC FLAGS_REG))])])
17037
17038 ;; Non pairable "test imm, reg" instructions can be translated to
17039 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17040 ;; byte opcode instead of two, have a short form for byte operands),
17041 ;; so do it for other CPUs as well.  Given that the value was dead,
17042 ;; this should not create any new dependencies.  Pass on the sub-word
17043 ;; versions if we're concerned about partial register stalls.
17044
17045 (define_peephole2
17046   [(set (match_operand 0 "flags_reg_operand" "")
17047         (match_operator 1 "compare_operator"
17048           [(and:SI (match_operand:SI 2 "register_operand" "")
17049                    (match_operand:SI 3 "immediate_operand" ""))
17050            (const_int 0)]))]
17051   "ix86_match_ccmode (insn, CCNOmode)
17052    && (true_regnum (operands[2]) != AX_REG
17053        || satisfies_constraint_K (operands[3]))
17054    && peep2_reg_dead_p (1, operands[2])"
17055   [(parallel
17056      [(set (match_dup 0)
17057            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17058                             (const_int 0)]))
17059       (set (match_dup 2)
17060            (and:SI (match_dup 2) (match_dup 3)))])])
17061
17062 ;; We don't need to handle HImode case, because it will be promoted to SImode
17063 ;; on ! TARGET_PARTIAL_REG_STALL
17064
17065 (define_peephole2
17066   [(set (match_operand 0 "flags_reg_operand" "")
17067         (match_operator 1 "compare_operator"
17068           [(and:QI (match_operand:QI 2 "register_operand" "")
17069                    (match_operand:QI 3 "immediate_operand" ""))
17070            (const_int 0)]))]
17071   "! TARGET_PARTIAL_REG_STALL
17072    && ix86_match_ccmode (insn, CCNOmode)
17073    && true_regnum (operands[2]) != AX_REG
17074    && peep2_reg_dead_p (1, operands[2])"
17075   [(parallel
17076      [(set (match_dup 0)
17077            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17078                             (const_int 0)]))
17079       (set (match_dup 2)
17080            (and:QI (match_dup 2) (match_dup 3)))])])
17081
17082 (define_peephole2
17083   [(set (match_operand 0 "flags_reg_operand" "")
17084         (match_operator 1 "compare_operator"
17085           [(and:SI
17086              (zero_extract:SI
17087                (match_operand 2 "ext_register_operand" "")
17088                (const_int 8)
17089                (const_int 8))
17090              (match_operand 3 "const_int_operand" ""))
17091            (const_int 0)]))]
17092   "! TARGET_PARTIAL_REG_STALL
17093    && ix86_match_ccmode (insn, CCNOmode)
17094    && true_regnum (operands[2]) != AX_REG
17095    && peep2_reg_dead_p (1, operands[2])"
17096   [(parallel [(set (match_dup 0)
17097                    (match_op_dup 1
17098                      [(and:SI
17099                         (zero_extract:SI
17100                           (match_dup 2)
17101                           (const_int 8)
17102                           (const_int 8))
17103                         (match_dup 3))
17104                       (const_int 0)]))
17105               (set (zero_extract:SI (match_dup 2)
17106                                     (const_int 8)
17107                                     (const_int 8))
17108                    (and:SI
17109                      (zero_extract:SI
17110                        (match_dup 2)
17111                        (const_int 8)
17112                        (const_int 8))
17113                      (match_dup 3)))])])
17114
17115 ;; Don't do logical operations with memory inputs.
17116 (define_peephole2
17117   [(match_scratch:SI 2 "r")
17118    (parallel [(set (match_operand:SI 0 "register_operand" "")
17119                    (match_operator:SI 3 "arith_or_logical_operator"
17120                      [(match_dup 0)
17121                       (match_operand:SI 1 "memory_operand" "")]))
17122               (clobber (reg:CC FLAGS_REG))])]
17123   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17124   [(set (match_dup 2) (match_dup 1))
17125    (parallel [(set (match_dup 0)
17126                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17127               (clobber (reg:CC FLAGS_REG))])])
17128
17129 (define_peephole2
17130   [(match_scratch:SI 2 "r")
17131    (parallel [(set (match_operand:SI 0 "register_operand" "")
17132                    (match_operator:SI 3 "arith_or_logical_operator"
17133                      [(match_operand:SI 1 "memory_operand" "")
17134                       (match_dup 0)]))
17135               (clobber (reg:CC FLAGS_REG))])]
17136   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17137   [(set (match_dup 2) (match_dup 1))
17138    (parallel [(set (match_dup 0)
17139                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17140               (clobber (reg:CC FLAGS_REG))])])
17141
17142 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17143 ;; refers to the destination of the load!
17144
17145 (define_peephole2
17146   [(set (match_operand:SI 0 "register_operand" "")
17147         (match_operand:SI 1 "register_operand" ""))
17148    (parallel [(set (match_dup 0)
17149                    (match_operator:SI 3 "commutative_operator"
17150                      [(match_dup 0)
17151                       (match_operand:SI 2 "memory_operand" "")]))
17152               (clobber (reg:CC FLAGS_REG))])]
17153   "REGNO (operands[0]) != REGNO (operands[1])
17154    && GENERAL_REGNO_P (REGNO (operands[0]))
17155    && GENERAL_REGNO_P (REGNO (operands[1]))"
17156   [(set (match_dup 0) (match_dup 4))
17157    (parallel [(set (match_dup 0)
17158                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17159               (clobber (reg:CC FLAGS_REG))])]
17160   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17161
17162 (define_peephole2
17163   [(set (match_operand 0 "register_operand" "")
17164         (match_operand 1 "register_operand" ""))
17165    (set (match_dup 0)
17166                    (match_operator 3 "commutative_operator"
17167                      [(match_dup 0)
17168                       (match_operand 2 "memory_operand" "")]))]
17169   "REGNO (operands[0]) != REGNO (operands[1])
17170    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17171        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17172   [(set (match_dup 0) (match_dup 2))
17173    (set (match_dup 0)
17174         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17175
17176 ; Don't do logical operations with memory outputs
17177 ;
17178 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17179 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17180 ; the same decoder scheduling characteristics as the original.
17181
17182 (define_peephole2
17183   [(match_scratch:SI 2 "r")
17184    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17185                    (match_operator:SI 3 "arith_or_logical_operator"
17186                      [(match_dup 0)
17187                       (match_operand:SI 1 "nonmemory_operand" "")]))
17188               (clobber (reg:CC FLAGS_REG))])]
17189   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17190    /* Do not split stack checking probes.  */
17191    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17192   [(set (match_dup 2) (match_dup 0))
17193    (parallel [(set (match_dup 2)
17194                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17195               (clobber (reg:CC FLAGS_REG))])
17196    (set (match_dup 0) (match_dup 2))])
17197
17198 (define_peephole2
17199   [(match_scratch:SI 2 "r")
17200    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17201                    (match_operator:SI 3 "arith_or_logical_operator"
17202                      [(match_operand:SI 1 "nonmemory_operand" "")
17203                       (match_dup 0)]))
17204               (clobber (reg:CC FLAGS_REG))])]
17205   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17206    /* Do not split stack checking probes.  */
17207    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17208   [(set (match_dup 2) (match_dup 0))
17209    (parallel [(set (match_dup 2)
17210                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17211               (clobber (reg:CC FLAGS_REG))])
17212    (set (match_dup 0) (match_dup 2))])
17213
17214 ;; Attempt to use arith or logical operations with memory outputs with
17215 ;; setting of flags.
17216 (define_peephole2
17217   [(set (match_operand:SWI 0 "register_operand" "")
17218         (match_operand:SWI 1 "memory_operand" ""))
17219    (parallel [(set (match_dup 0)
17220                    (match_operator:SWI 3 "plusminuslogic_operator"
17221                      [(match_dup 0)
17222                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17223               (clobber (reg:CC FLAGS_REG))])
17224    (set (match_dup 1) (match_dup 0))
17225    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17226   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17227    && peep2_reg_dead_p (4, operands[0])
17228    && !reg_overlap_mentioned_p (operands[0], operands[1])
17229    && !reg_overlap_mentioned_p (operands[0], operands[2])
17230    && (<MODE>mode != QImode
17231        || immediate_operand (operands[2], QImode)
17232        || q_regs_operand (operands[2], QImode))
17233    && ix86_match_ccmode (peep2_next_insn (3),
17234                          (GET_CODE (operands[3]) == PLUS
17235                           || GET_CODE (operands[3]) == MINUS)
17236                          ? CCGOCmode : CCNOmode)"
17237   [(parallel [(set (match_dup 4) (match_dup 5))
17238               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17239                                                   (match_dup 2)]))])]
17240 {
17241   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17242   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17243                                 copy_rtx (operands[1]),
17244                                 copy_rtx (operands[2]));
17245   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17246                                  operands[5], const0_rtx);
17247 })
17248
17249 (define_peephole2
17250   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17251                    (match_operator:SWI 2 "plusminuslogic_operator"
17252                      [(match_dup 0)
17253                       (match_operand:SWI 1 "memory_operand" "")]))
17254               (clobber (reg:CC FLAGS_REG))])
17255    (set (match_dup 1) (match_dup 0))
17256    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17257   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17258    && GET_CODE (operands[2]) != MINUS
17259    && peep2_reg_dead_p (3, operands[0])
17260    && !reg_overlap_mentioned_p (operands[0], operands[1])
17261    && ix86_match_ccmode (peep2_next_insn (2),
17262                          GET_CODE (operands[2]) == PLUS
17263                          ? CCGOCmode : CCNOmode)"
17264   [(parallel [(set (match_dup 3) (match_dup 4))
17265               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17266                                                   (match_dup 0)]))])]
17267 {
17268   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17269   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17270                                 copy_rtx (operands[1]),
17271                                 copy_rtx (operands[0]));
17272   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17273                                  operands[4], const0_rtx);
17274 })
17275
17276 (define_peephole2
17277   [(set (match_operand:SWI12 0 "register_operand" "")
17278         (match_operand:SWI12 1 "memory_operand" ""))
17279    (parallel [(set (match_operand:SI 4 "register_operand" "")
17280                    (match_operator:SI 3 "plusminuslogic_operator"
17281                      [(match_dup 4)
17282                       (match_operand:SI 2 "nonmemory_operand" "")]))
17283               (clobber (reg:CC FLAGS_REG))])
17284    (set (match_dup 1) (match_dup 0))
17285    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17286   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17287    && REG_P (operands[0]) && REG_P (operands[4])
17288    && REGNO (operands[0]) == REGNO (operands[4])
17289    && peep2_reg_dead_p (4, operands[0])
17290    && (<MODE>mode != QImode
17291        || immediate_operand (operands[2], SImode)
17292        || q_regs_operand (operands[2], SImode))
17293    && !reg_overlap_mentioned_p (operands[0], operands[1])
17294    && !reg_overlap_mentioned_p (operands[0], operands[2])
17295    && ix86_match_ccmode (peep2_next_insn (3),
17296                          (GET_CODE (operands[3]) == PLUS
17297                           || GET_CODE (operands[3]) == MINUS)
17298                          ? CCGOCmode : CCNOmode)"
17299   [(parallel [(set (match_dup 4) (match_dup 5))
17300               (set (match_dup 1) (match_dup 6))])]
17301 {
17302   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17303   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17304   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17305                                 copy_rtx (operands[1]), operands[2]);
17306   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17307                                  operands[5], const0_rtx);
17308   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17309                                 copy_rtx (operands[1]),
17310                                 copy_rtx (operands[2]));
17311 })
17312
17313 ;; Attempt to always use XOR for zeroing registers.
17314 (define_peephole2
17315   [(set (match_operand 0 "register_operand" "")
17316         (match_operand 1 "const0_operand" ""))]
17317   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17318    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17319    && GENERAL_REG_P (operands[0])
17320    && peep2_regno_dead_p (0, FLAGS_REG)"
17321   [(parallel [(set (match_dup 0) (const_int 0))
17322               (clobber (reg:CC FLAGS_REG))])]
17323   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17324
17325 (define_peephole2
17326   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17327         (const_int 0))]
17328   "(GET_MODE (operands[0]) == QImode
17329     || GET_MODE (operands[0]) == HImode)
17330    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17331    && peep2_regno_dead_p (0, FLAGS_REG)"
17332   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17333               (clobber (reg:CC FLAGS_REG))])])
17334
17335 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17336 (define_peephole2
17337   [(set (match_operand:SWI248 0 "register_operand" "")
17338         (const_int -1))]
17339   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17340    && peep2_regno_dead_p (0, FLAGS_REG)"
17341   [(parallel [(set (match_dup 0) (const_int -1))
17342               (clobber (reg:CC FLAGS_REG))])]
17343 {
17344   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17345     operands[0] = gen_lowpart (SImode, operands[0]);
17346 })
17347
17348 ;; Attempt to convert simple lea to add/shift.
17349 ;; These can be created by move expanders.
17350
17351 (define_peephole2
17352   [(set (match_operand:SWI48 0 "register_operand" "")
17353         (plus:SWI48 (match_dup 0)
17354                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17355   "peep2_regno_dead_p (0, FLAGS_REG)"
17356   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17357               (clobber (reg:CC FLAGS_REG))])])
17358
17359 (define_peephole2
17360   [(set (match_operand:SI 0 "register_operand" "")
17361         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17362                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17363   "TARGET_64BIT
17364    && peep2_regno_dead_p (0, FLAGS_REG)
17365    && REGNO (operands[0]) == REGNO (operands[1])"
17366   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17367               (clobber (reg:CC FLAGS_REG))])]
17368   "operands[2] = gen_lowpart (SImode, operands[2]);")
17369
17370 (define_peephole2
17371   [(set (match_operand:SWI48 0 "register_operand" "")
17372         (mult:SWI48 (match_dup 0)
17373                     (match_operand:SWI48 1 "const_int_operand" "")))]
17374   "exact_log2 (INTVAL (operands[1])) >= 0
17375    && peep2_regno_dead_p (0, FLAGS_REG)"
17376   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17377               (clobber (reg:CC FLAGS_REG))])]
17378   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17379
17380 (define_peephole2
17381   [(set (match_operand:SI 0 "register_operand" "")
17382         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17383                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17384   "TARGET_64BIT
17385    && exact_log2 (INTVAL (operands[2])) >= 0
17386    && REGNO (operands[0]) == REGNO (operands[1])
17387    && peep2_regno_dead_p (0, FLAGS_REG)"
17388   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17389               (clobber (reg:CC FLAGS_REG))])]
17390   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17391
17392 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17393 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17394 ;; On many CPUs it is also faster, since special hardware to avoid esp
17395 ;; dependencies is present.
17396
17397 ;; While some of these conversions may be done using splitters, we use
17398 ;; peepholes in order to allow combine_stack_adjustments pass to see
17399 ;; nonobfuscated RTL.
17400
17401 ;; Convert prologue esp subtractions to push.
17402 ;; We need register to push.  In order to keep verify_flow_info happy we have
17403 ;; two choices
17404 ;; - use scratch and clobber it in order to avoid dependencies
17405 ;; - use already live register
17406 ;; We can't use the second way right now, since there is no reliable way how to
17407 ;; verify that given register is live.  First choice will also most likely in
17408 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17409 ;; call clobbered registers are dead.  We may want to use base pointer as an
17410 ;; alternative when no register is available later.
17411
17412 (define_peephole2
17413   [(match_scratch:P 1 "r")
17414    (parallel [(set (reg:P SP_REG)
17415                    (plus:P (reg:P SP_REG)
17416                            (match_operand:P 0 "const_int_operand" "")))
17417               (clobber (reg:CC FLAGS_REG))
17418               (clobber (mem:BLK (scratch)))])]
17419   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17420    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17421   [(clobber (match_dup 1))
17422    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17423               (clobber (mem:BLK (scratch)))])])
17424
17425 (define_peephole2
17426   [(match_scratch:P 1 "r")
17427    (parallel [(set (reg:P SP_REG)
17428                    (plus:P (reg:P SP_REG)
17429                            (match_operand:P 0 "const_int_operand" "")))
17430               (clobber (reg:CC FLAGS_REG))
17431               (clobber (mem:BLK (scratch)))])]
17432   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17433    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17434   [(clobber (match_dup 1))
17435    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17436    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17437               (clobber (mem:BLK (scratch)))])])
17438
17439 ;; Convert esp subtractions to push.
17440 (define_peephole2
17441   [(match_scratch:P 1 "r")
17442    (parallel [(set (reg:P SP_REG)
17443                    (plus:P (reg:P SP_REG)
17444                            (match_operand:P 0 "const_int_operand" "")))
17445               (clobber (reg:CC FLAGS_REG))])]
17446   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17447    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17448   [(clobber (match_dup 1))
17449    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17450
17451 (define_peephole2
17452   [(match_scratch:P 1 "r")
17453    (parallel [(set (reg:P SP_REG)
17454                    (plus:P (reg:P SP_REG)
17455                            (match_operand:P 0 "const_int_operand" "")))
17456               (clobber (reg:CC FLAGS_REG))])]
17457   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17458    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17459   [(clobber (match_dup 1))
17460    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17461    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17462
17463 ;; Convert epilogue deallocator to pop.
17464 (define_peephole2
17465   [(match_scratch:P 1 "r")
17466    (parallel [(set (reg:P SP_REG)
17467                    (plus:P (reg:P SP_REG)
17468                            (match_operand:P 0 "const_int_operand" "")))
17469               (clobber (reg:CC FLAGS_REG))
17470               (clobber (mem:BLK (scratch)))])]
17471   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17472    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17473   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17474               (clobber (mem:BLK (scratch)))])])
17475
17476 ;; Two pops case is tricky, since pop causes dependency
17477 ;; on destination register.  We use two registers if available.
17478 (define_peephole2
17479   [(match_scratch:P 1 "r")
17480    (match_scratch:P 2 "r")
17481    (parallel [(set (reg:P SP_REG)
17482                    (plus:P (reg:P SP_REG)
17483                            (match_operand:P 0 "const_int_operand" "")))
17484               (clobber (reg:CC FLAGS_REG))
17485               (clobber (mem:BLK (scratch)))])]
17486   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17487    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17488   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17489               (clobber (mem:BLK (scratch)))])
17490    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17491
17492 (define_peephole2
17493   [(match_scratch:P 1 "r")
17494    (parallel [(set (reg:P SP_REG)
17495                    (plus:P (reg:P SP_REG)
17496                            (match_operand:P 0 "const_int_operand" "")))
17497               (clobber (reg:CC FLAGS_REG))
17498               (clobber (mem:BLK (scratch)))])]
17499   "optimize_insn_for_size_p ()
17500    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17501   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17502               (clobber (mem:BLK (scratch)))])
17503    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17504
17505 ;; Convert esp additions to pop.
17506 (define_peephole2
17507   [(match_scratch:P 1 "r")
17508    (parallel [(set (reg:P SP_REG)
17509                    (plus:P (reg:P SP_REG)
17510                            (match_operand:P 0 "const_int_operand" "")))
17511               (clobber (reg:CC FLAGS_REG))])]
17512   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17513   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17514
17515 ;; Two pops case is tricky, since pop causes dependency
17516 ;; on destination register.  We use two registers if available.
17517 (define_peephole2
17518   [(match_scratch:P 1 "r")
17519    (match_scratch:P 2 "r")
17520    (parallel [(set (reg:P SP_REG)
17521                    (plus:P (reg:P SP_REG)
17522                            (match_operand:P 0 "const_int_operand" "")))
17523               (clobber (reg:CC FLAGS_REG))])]
17524   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17525   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17526    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17527
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   "optimize_insn_for_size_p ()
17535    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17536   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17537    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17538 \f
17539 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17540 ;; required and register dies.  Similarly for 128 to -128.
17541 (define_peephole2
17542   [(set (match_operand 0 "flags_reg_operand" "")
17543         (match_operator 1 "compare_operator"
17544           [(match_operand 2 "register_operand" "")
17545            (match_operand 3 "const_int_operand" "")]))]
17546   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17547      && incdec_operand (operands[3], GET_MODE (operands[3])))
17548     || (!TARGET_FUSE_CMP_AND_BRANCH
17549         && INTVAL (operands[3]) == 128))
17550    && ix86_match_ccmode (insn, CCGCmode)
17551    && peep2_reg_dead_p (1, operands[2])"
17552   [(parallel [(set (match_dup 0)
17553                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17554               (clobber (match_dup 2))])])
17555 \f
17556 ;; Convert imul by three, five and nine into lea
17557 (define_peephole2
17558   [(parallel
17559     [(set (match_operand:SWI48 0 "register_operand" "")
17560           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17561                       (match_operand:SWI48 2 "const359_operand" "")))
17562      (clobber (reg:CC FLAGS_REG))])]
17563   "!TARGET_PARTIAL_REG_STALL
17564    || <MODE>mode == SImode
17565    || optimize_function_for_size_p (cfun)"
17566   [(set (match_dup 0)
17567         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17568                     (match_dup 1)))]
17569   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17570
17571 (define_peephole2
17572   [(parallel
17573     [(set (match_operand:SWI48 0 "register_operand" "")
17574           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17575                       (match_operand:SWI48 2 "const359_operand" "")))
17576      (clobber (reg:CC FLAGS_REG))])]
17577   "optimize_insn_for_speed_p ()
17578    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17579   [(set (match_dup 0) (match_dup 1))
17580    (set (match_dup 0)
17581         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17582                     (match_dup 0)))]
17583   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17584
17585 ;; imul $32bit_imm, mem, reg is vector decoded, while
17586 ;; imul $32bit_imm, reg, reg is direct decoded.
17587 (define_peephole2
17588   [(match_scratch:SWI48 3 "r")
17589    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17590                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17591                                (match_operand:SWI48 2 "immediate_operand" "")))
17592               (clobber (reg:CC FLAGS_REG))])]
17593   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17594    && !satisfies_constraint_K (operands[2])"
17595   [(set (match_dup 3) (match_dup 1))
17596    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17597               (clobber (reg:CC FLAGS_REG))])])
17598
17599 (define_peephole2
17600   [(match_scratch:SI 3 "r")
17601    (parallel [(set (match_operand:DI 0 "register_operand" "")
17602                    (zero_extend:DI
17603                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17604                               (match_operand:SI 2 "immediate_operand" ""))))
17605               (clobber (reg:CC FLAGS_REG))])]
17606   "TARGET_64BIT
17607    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17608    && !satisfies_constraint_K (operands[2])"
17609   [(set (match_dup 3) (match_dup 1))
17610    (parallel [(set (match_dup 0)
17611                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17612               (clobber (reg:CC FLAGS_REG))])])
17613
17614 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17615 ;; Convert it into imul reg, reg
17616 ;; It would be better to force assembler to encode instruction using long
17617 ;; immediate, but there is apparently no way to do so.
17618 (define_peephole2
17619   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17620                    (mult:SWI248
17621                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17622                     (match_operand:SWI248 2 "const_int_operand" "")))
17623               (clobber (reg:CC FLAGS_REG))])
17624    (match_scratch:SWI248 3 "r")]
17625   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17626    && satisfies_constraint_K (operands[2])"
17627   [(set (match_dup 3) (match_dup 2))
17628    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17629               (clobber (reg:CC FLAGS_REG))])]
17630 {
17631   if (!rtx_equal_p (operands[0], operands[1]))
17632     emit_move_insn (operands[0], operands[1]);
17633 })
17634
17635 ;; After splitting up read-modify operations, array accesses with memory
17636 ;; operands might end up in form:
17637 ;;  sall    $2, %eax
17638 ;;  movl    4(%esp), %edx
17639 ;;  addl    %edx, %eax
17640 ;; instead of pre-splitting:
17641 ;;  sall    $2, %eax
17642 ;;  addl    4(%esp), %eax
17643 ;; Turn it into:
17644 ;;  movl    4(%esp), %edx
17645 ;;  leal    (%edx,%eax,4), %eax
17646
17647 (define_peephole2
17648   [(match_scratch:P 5 "r")
17649    (parallel [(set (match_operand 0 "register_operand" "")
17650                    (ashift (match_operand 1 "register_operand" "")
17651                            (match_operand 2 "const_int_operand" "")))
17652                (clobber (reg:CC FLAGS_REG))])
17653    (parallel [(set (match_operand 3 "register_operand" "")
17654                    (plus (match_dup 0)
17655                          (match_operand 4 "x86_64_general_operand" "")))
17656                    (clobber (reg:CC FLAGS_REG))])]
17657   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17658    /* Validate MODE for lea.  */
17659    && ((!TARGET_PARTIAL_REG_STALL
17660         && (GET_MODE (operands[0]) == QImode
17661             || GET_MODE (operands[0]) == HImode))
17662        || GET_MODE (operands[0]) == SImode
17663        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17664    && (rtx_equal_p (operands[0], operands[3])
17665        || peep2_reg_dead_p (2, operands[0]))
17666    /* We reorder load and the shift.  */
17667    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17668   [(set (match_dup 5) (match_dup 4))
17669    (set (match_dup 0) (match_dup 1))]
17670 {
17671   enum machine_mode op1mode = GET_MODE (operands[1]);
17672   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17673   int scale = 1 << INTVAL (operands[2]);
17674   rtx index = gen_lowpart (Pmode, operands[1]);
17675   rtx base = gen_lowpart (Pmode, operands[5]);
17676   rtx dest = gen_lowpart (mode, operands[3]);
17677
17678   operands[1] = gen_rtx_PLUS (Pmode, base,
17679                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17680   operands[5] = base;
17681   if (mode != Pmode)
17682     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17683   if (op1mode != Pmode)
17684     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17685   operands[0] = dest;
17686 })
17687 \f
17688 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17689 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17690 ;; caught for use by garbage collectors and the like.  Using an insn that
17691 ;; maps to SIGILL makes it more likely the program will rightfully die.
17692 ;; Keeping with tradition, "6" is in honor of #UD.
17693 (define_insn "trap"
17694   [(trap_if (const_int 1) (const_int 6))]
17695   ""
17696   { return ASM_SHORT "0x0b0f"; }
17697   [(set_attr "length" "2")])
17698
17699 (define_expand "prefetch"
17700   [(prefetch (match_operand 0 "address_operand" "")
17701              (match_operand:SI 1 "const_int_operand" "")
17702              (match_operand:SI 2 "const_int_operand" ""))]
17703   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17704 {
17705   int rw = INTVAL (operands[1]);
17706   int locality = INTVAL (operands[2]);
17707
17708   gcc_assert (rw == 0 || rw == 1);
17709   gcc_assert (IN_RANGE (locality, 0, 3));
17710
17711   if (TARGET_PREFETCHW && rw)
17712     operands[2] = GEN_INT (3);
17713   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17714      supported by SSE counterpart or the SSE prefetch is not available
17715      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17716      of locality.  */
17717   else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17718     operands[2] = GEN_INT (3);
17719   else
17720     operands[1] = const0_rtx;
17721 })
17722
17723 (define_insn "*prefetch_sse"
17724   [(prefetch (match_operand 0 "address_operand" "p")
17725              (const_int 0)
17726              (match_operand:SI 1 "const_int_operand" ""))]
17727   "TARGET_PREFETCH_SSE"
17728 {
17729   static const char * const patterns[4] = {
17730    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17731   };
17732
17733   int locality = INTVAL (operands[1]);
17734   gcc_assert (IN_RANGE (locality, 0, 3));
17735
17736   return patterns[locality];
17737 }
17738   [(set_attr "type" "sse")
17739    (set_attr "atom_sse_attr" "prefetch")
17740    (set (attr "length_address")
17741         (symbol_ref "memory_address_length (operands[0], false)"))
17742    (set_attr "memory" "none")])
17743
17744 (define_insn "*prefetch_3dnow"
17745   [(prefetch (match_operand 0 "address_operand" "p")
17746              (match_operand:SI 1 "const_int_operand" "n")
17747              (const_int 3))]
17748   "TARGET_3DNOW || TARGET_PREFETCHW"
17749 {
17750   if (INTVAL (operands[1]) == 0)
17751     return "prefetch\t%a0";
17752   else
17753     return "prefetchw\t%a0";
17754 }
17755   [(set_attr "type" "mmx")
17756    (set (attr "length_address")
17757         (symbol_ref "memory_address_length (operands[0], false)"))
17758    (set_attr "memory" "none")])
17759
17760 (define_expand "stack_protect_set"
17761   [(match_operand 0 "memory_operand" "")
17762    (match_operand 1 "memory_operand" "")]
17763   "!TARGET_HAS_BIONIC"
17764 {
17765   rtx (*insn)(rtx, rtx);
17766
17767 #ifdef TARGET_THREAD_SSP_OFFSET
17768   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17769   insn = (TARGET_LP64
17770           ? gen_stack_tls_protect_set_di
17771           : gen_stack_tls_protect_set_si);
17772 #else
17773   insn = (TARGET_LP64
17774           ? gen_stack_protect_set_di
17775           : gen_stack_protect_set_si);
17776 #endif
17777
17778   emit_insn (insn (operands[0], operands[1]));
17779   DONE;
17780 })
17781
17782 (define_insn "stack_protect_set_<mode>"
17783   [(set (match_operand:PTR 0 "memory_operand" "=m")
17784         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17785                     UNSPEC_SP_SET))
17786    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17787    (clobber (reg:CC FLAGS_REG))]
17788   "!TARGET_HAS_BIONIC"
17789   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17790   [(set_attr "type" "multi")])
17791
17792 (define_insn "stack_tls_protect_set_<mode>"
17793   [(set (match_operand:PTR 0 "memory_operand" "=m")
17794         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17795                     UNSPEC_SP_TLS_SET))
17796    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17797    (clobber (reg:CC FLAGS_REG))]
17798   ""
17799   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17800   [(set_attr "type" "multi")])
17801
17802 (define_expand "stack_protect_test"
17803   [(match_operand 0 "memory_operand" "")
17804    (match_operand 1 "memory_operand" "")
17805    (match_operand 2 "" "")]
17806   "!TARGET_HAS_BIONIC"
17807 {
17808   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17809
17810   rtx (*insn)(rtx, rtx, rtx);
17811
17812 #ifdef TARGET_THREAD_SSP_OFFSET
17813   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17814   insn = (TARGET_LP64
17815           ? gen_stack_tls_protect_test_di
17816           : gen_stack_tls_protect_test_si);
17817 #else
17818   insn = (TARGET_LP64
17819           ? gen_stack_protect_test_di
17820           : gen_stack_protect_test_si);
17821 #endif
17822
17823   emit_insn (insn (flags, operands[0], operands[1]));
17824
17825   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17826                                   flags, const0_rtx, operands[2]));
17827   DONE;
17828 })
17829
17830 (define_insn "stack_protect_test_<mode>"
17831   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17832         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17833                      (match_operand:PTR 2 "memory_operand" "m")]
17834                     UNSPEC_SP_TEST))
17835    (clobber (match_scratch:PTR 3 "=&r"))]
17836   "!TARGET_HAS_BIONIC"
17837   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17838   [(set_attr "type" "multi")])
17839
17840 (define_insn "stack_tls_protect_test_<mode>"
17841   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17842         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17843                      (match_operand:PTR 2 "const_int_operand" "i")]
17844                     UNSPEC_SP_TLS_TEST))
17845    (clobber (match_scratch:PTR 3 "=r"))]
17846   ""
17847   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17848   [(set_attr "type" "multi")])
17849
17850 (define_insn "sse4_2_crc32<mode>"
17851   [(set (match_operand:SI 0 "register_operand" "=r")
17852         (unspec:SI
17853           [(match_operand:SI 1 "register_operand" "0")
17854            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17855           UNSPEC_CRC32))]
17856   "TARGET_SSE4_2 || TARGET_CRC32"
17857   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17858   [(set_attr "type" "sselog1")
17859    (set_attr "prefix_rep" "1")
17860    (set_attr "prefix_extra" "1")
17861    (set (attr "prefix_data16")
17862      (if_then_else (match_operand:HI 2 "" "")
17863        (const_string "1")
17864        (const_string "*")))
17865    (set (attr "prefix_rex")
17866      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17867        (const_string "1")
17868        (const_string "*")))
17869    (set_attr "mode" "SI")])
17870
17871 (define_insn "sse4_2_crc32di"
17872   [(set (match_operand:DI 0 "register_operand" "=r")
17873         (unspec:DI
17874           [(match_operand:DI 1 "register_operand" "0")
17875            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17876           UNSPEC_CRC32))]
17877   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17878   "crc32{q}\t{%2, %0|%0, %2}"
17879   [(set_attr "type" "sselog1")
17880    (set_attr "prefix_rep" "1")
17881    (set_attr "prefix_extra" "1")
17882    (set_attr "mode" "DI")])
17883
17884 (define_expand "rdpmc"
17885   [(match_operand:DI 0 "register_operand" "")
17886    (match_operand:SI 1 "register_operand" "")]
17887   ""
17888 {
17889   rtx reg = gen_reg_rtx (DImode);
17890   rtx si;
17891
17892   /* Force operand 1 into ECX.  */
17893   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17894   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17895   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17896                                 UNSPECV_RDPMC);
17897
17898   if (TARGET_64BIT)
17899     {
17900       rtvec vec = rtvec_alloc (2);
17901       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17902       rtx upper = gen_reg_rtx (DImode);
17903       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17904                                         gen_rtvec (1, const0_rtx),
17905                                         UNSPECV_RDPMC);
17906       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17907       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17908       emit_insn (load);
17909       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17910                                    NULL, 1, OPTAB_DIRECT);
17911       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17912                                  OPTAB_DIRECT);
17913     }
17914   else
17915     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17916   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17917   DONE;
17918 })
17919
17920 (define_insn "*rdpmc"
17921   [(set (match_operand:DI 0 "register_operand" "=A")
17922         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17923                             UNSPECV_RDPMC))]
17924   "!TARGET_64BIT"
17925   "rdpmc"
17926   [(set_attr "type" "other")
17927    (set_attr "length" "2")])
17928
17929 (define_insn "*rdpmc_rex64"
17930   [(set (match_operand:DI 0 "register_operand" "=a")
17931         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17932                             UNSPECV_RDPMC))
17933   (set (match_operand:DI 1 "register_operand" "=d")
17934        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17935   "TARGET_64BIT"
17936   "rdpmc"
17937   [(set_attr "type" "other")
17938    (set_attr "length" "2")])
17939
17940 (define_expand "rdtsc"
17941   [(set (match_operand:DI 0 "register_operand" "")
17942         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17943   ""
17944 {
17945   if (TARGET_64BIT)
17946     {
17947       rtvec vec = rtvec_alloc (2);
17948       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17949       rtx upper = gen_reg_rtx (DImode);
17950       rtx lower = gen_reg_rtx (DImode);
17951       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17952                                          gen_rtvec (1, const0_rtx),
17953                                          UNSPECV_RDTSC);
17954       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17955       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17956       emit_insn (load);
17957       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17958                                    NULL, 1, OPTAB_DIRECT);
17959       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17960                                    OPTAB_DIRECT);
17961       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17962       DONE;
17963     }
17964 })
17965
17966 (define_insn "*rdtsc"
17967   [(set (match_operand:DI 0 "register_operand" "=A")
17968         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17969   "!TARGET_64BIT"
17970   "rdtsc"
17971   [(set_attr "type" "other")
17972    (set_attr "length" "2")])
17973
17974 (define_insn "*rdtsc_rex64"
17975   [(set (match_operand:DI 0 "register_operand" "=a")
17976         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17977    (set (match_operand:DI 1 "register_operand" "=d")
17978         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17979   "TARGET_64BIT"
17980   "rdtsc"
17981   [(set_attr "type" "other")
17982    (set_attr "length" "2")])
17983
17984 (define_expand "rdtscp"
17985   [(match_operand:DI 0 "register_operand" "")
17986    (match_operand:SI 1 "memory_operand" "")]
17987   ""
17988 {
17989   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17990                                     gen_rtvec (1, const0_rtx),
17991                                     UNSPECV_RDTSCP);
17992   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17993                                     gen_rtvec (1, const0_rtx),
17994                                     UNSPECV_RDTSCP);
17995   rtx reg = gen_reg_rtx (DImode);
17996   rtx tmp = gen_reg_rtx (SImode);
17997
17998   if (TARGET_64BIT)
17999     {
18000       rtvec vec = rtvec_alloc (3);
18001       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18002       rtx upper = gen_reg_rtx (DImode);
18003       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18004       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18005       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18006       emit_insn (load);
18007       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18008                                    NULL, 1, OPTAB_DIRECT);
18009       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18010                                  OPTAB_DIRECT);
18011     }
18012   else
18013     {
18014       rtvec vec = rtvec_alloc (2);
18015       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18016       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18017       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18018       emit_insn (load);
18019     }
18020   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18021   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18022   DONE;
18023 })
18024
18025 (define_insn "*rdtscp"
18026   [(set (match_operand:DI 0 "register_operand" "=A")
18027         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18028    (set (match_operand:SI 1 "register_operand" "=c")
18029         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18030   "!TARGET_64BIT"
18031   "rdtscp"
18032   [(set_attr "type" "other")
18033    (set_attr "length" "3")])
18034
18035 (define_insn "*rdtscp_rex64"
18036   [(set (match_operand:DI 0 "register_operand" "=a")
18037         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18038    (set (match_operand:DI 1 "register_operand" "=d")
18039         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18040    (set (match_operand:SI 2 "register_operand" "=c")
18041         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18042   "TARGET_64BIT"
18043   "rdtscp"
18044   [(set_attr "type" "other")
18045    (set_attr "length" "3")])
18046
18047 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18048 ;;
18049 ;; LWP instructions
18050 ;;
18051 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18052
18053 (define_expand "lwp_llwpcb"
18054   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18055                     UNSPECV_LLWP_INTRINSIC)]
18056   "TARGET_LWP")
18057
18058 (define_insn "*lwp_llwpcb<mode>1"
18059   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18060                     UNSPECV_LLWP_INTRINSIC)]
18061   "TARGET_LWP"
18062   "llwpcb\t%0"
18063   [(set_attr "type" "lwp")
18064    (set_attr "mode" "<MODE>")
18065    (set_attr "length" "5")])
18066
18067 (define_expand "lwp_slwpcb"
18068   [(set (match_operand 0 "register_operand" "=r")
18069         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18070   "TARGET_LWP"
18071 {
18072   rtx (*insn)(rtx);
18073
18074   insn = (TARGET_64BIT
18075           ? gen_lwp_slwpcbdi
18076           : gen_lwp_slwpcbsi);
18077
18078   emit_insn (insn (operands[0]));
18079   DONE;
18080 })
18081
18082 (define_insn "lwp_slwpcb<mode>"
18083   [(set (match_operand:P 0 "register_operand" "=r")
18084         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18085   "TARGET_LWP"
18086   "slwpcb\t%0"
18087   [(set_attr "type" "lwp")
18088    (set_attr "mode" "<MODE>")
18089    (set_attr "length" "5")])
18090
18091 (define_expand "lwp_lwpval<mode>3"
18092   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18093                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18094                      (match_operand:SI 3 "const_int_operand" "i")]
18095                     UNSPECV_LWPVAL_INTRINSIC)]
18096   "TARGET_LWP"
18097   ;; Avoid unused variable warning.
18098   "(void) operands[0];")
18099
18100 (define_insn "*lwp_lwpval<mode>3_1"
18101   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18102                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18103                      (match_operand:SI 2 "const_int_operand" "i")]
18104                     UNSPECV_LWPVAL_INTRINSIC)]
18105   "TARGET_LWP"
18106   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18107   [(set_attr "type" "lwp")
18108    (set_attr "mode" "<MODE>")
18109    (set (attr "length")
18110         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18111
18112 (define_expand "lwp_lwpins<mode>3"
18113   [(set (reg:CCC FLAGS_REG)
18114         (unspec_volatile:CCC [(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_LWPINS_INTRINSIC))
18118    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18119         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18120   "TARGET_LWP")
18121
18122 (define_insn "*lwp_lwpins<mode>3_1"
18123   [(set (reg:CCC FLAGS_REG)
18124         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18125                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18126                               (match_operand:SI 2 "const_int_operand" "i")]
18127                              UNSPECV_LWPINS_INTRINSIC))]
18128   "TARGET_LWP"
18129   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18130   [(set_attr "type" "lwp")
18131    (set_attr "mode" "<MODE>")
18132    (set (attr "length")
18133         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18134
18135 (define_insn "rdfsbase<mode>"
18136   [(set (match_operand:SWI48 0 "register_operand" "=r")
18137         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18138   "TARGET_64BIT && TARGET_FSGSBASE"
18139   "rdfsbase %0"
18140   [(set_attr "type" "other")
18141    (set_attr "prefix_extra" "2")])
18142
18143 (define_insn "rdgsbase<mode>"
18144   [(set (match_operand:SWI48 0 "register_operand" "=r")
18145         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18146   "TARGET_64BIT && TARGET_FSGSBASE"
18147   "rdgsbase %0"
18148   [(set_attr "type" "other")
18149    (set_attr "prefix_extra" "2")])
18150
18151 (define_insn "wrfsbase<mode>"
18152   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18153                     UNSPECV_WRFSBASE)]
18154   "TARGET_64BIT && TARGET_FSGSBASE"
18155   "wrfsbase %0"
18156   [(set_attr "type" "other")
18157    (set_attr "prefix_extra" "2")])
18158
18159 (define_insn "wrgsbase<mode>"
18160   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18161                     UNSPECV_WRGSBASE)]
18162   "TARGET_64BIT && TARGET_FSGSBASE"
18163   "wrgsbase %0"
18164   [(set_attr "type" "other")
18165    (set_attr "prefix_extra" "2")])
18166
18167 (define_insn "rdrand<mode>_1"
18168   [(set (match_operand:SWI248 0 "register_operand" "=r")
18169         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18170    (set (reg:CCC FLAGS_REG)
18171         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18172   "TARGET_RDRND"
18173   "rdrand\t%0"
18174   [(set_attr "type" "other")
18175    (set_attr "prefix_extra" "1")])
18176
18177 (define_expand "pause"
18178   [(set (match_dup 0)
18179         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18180   ""
18181 {
18182   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18183   MEM_VOLATILE_P (operands[0]) = 1;
18184 })
18185
18186 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18187 ;; They have the same encoding.
18188 (define_insn "*pause"
18189   [(set (match_operand:BLK 0 "" "")
18190         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18191   ""
18192   "rep; nop"
18193   [(set_attr "length" "2")
18194    (set_attr "memory" "unknown")])
18195
18196 (include "mmx.md")
18197 (include "sse.md")
18198 (include "sync.md")