* config/i386/i386.c (get_thread_pointer): Add tp_mode argument.
[official-gcc.git] / gcc / config / i386 / i386.md
blob8e8eb7fda703446eb5060823c7e2fe313091ddd9
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.
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.
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/>.  */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
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 "i" if TARGET_AVX2, "f" otherwise.
65 ;; @ -- print a segment register of thread base pointer load
66 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
68 (define_c_enum "unspec" [
69   ;; Relocation specifiers
70   UNSPEC_GOT
71   UNSPEC_GOTOFF
72   UNSPEC_GOTPCREL
73   UNSPEC_GOTTPOFF
74   UNSPEC_TPOFF
75   UNSPEC_NTPOFF
76   UNSPEC_DTPOFF
77   UNSPEC_GOTNTPOFF
78   UNSPEC_INDNTPOFF
79   UNSPEC_PLTOFF
80   UNSPEC_MACHOPIC_OFFSET
81   UNSPEC_PCREL
83   ;; Prologue support
84   UNSPEC_STACK_ALLOC
85   UNSPEC_SET_GOT
86   UNSPEC_REG_SAVE
87   UNSPEC_DEF_CFA
88   UNSPEC_SET_RIP
89   UNSPEC_SET_GOT_OFFSET
90   UNSPEC_MEMORY_BLOCKAGE
91   UNSPEC_STACK_CHECK
93   ;; TLS support
94   UNSPEC_TP
95   UNSPEC_TLS_GD
96   UNSPEC_TLS_LD_BASE
97   UNSPEC_TLSDESC
98   UNSPEC_TLS_IE_SUN
100   ;; Other random patterns
101   UNSPEC_SCAS
102   UNSPEC_FNSTSW
103   UNSPEC_SAHF
104   UNSPEC_PARITY
105   UNSPEC_FSTCW
106   UNSPEC_ADD_CARRY
107   UNSPEC_FLDCW
108   UNSPEC_REP
109   UNSPEC_LD_MPIC        ; load_macho_picbase
110   UNSPEC_TRUNC_NOOP
111   UNSPEC_DIV_ALREADY_SPLIT
112   UNSPEC_MS_TO_SYSV_CALL
113   UNSPEC_CALL_NEEDS_VZEROUPPER
114   UNSPEC_PAUSE
115   UNSPEC_LEA_ADDR
116   UNSPEC_XBEGIN_ABORT
118   ;; For SSE/MMX support:
119   UNSPEC_FIX_NOTRUNC
120   UNSPEC_MASKMOV
121   UNSPEC_MOVMSK
122   UNSPEC_RCP
123   UNSPEC_RSQRT
124   UNSPEC_PSADBW
126   ;; Generic math support
127   UNSPEC_COPYSIGN
128   UNSPEC_IEEE_MIN       ; not commutative
129   UNSPEC_IEEE_MAX       ; not commutative
131   ;; x87 Floating point
132   UNSPEC_SIN
133   UNSPEC_COS
134   UNSPEC_FPATAN
135   UNSPEC_FYL2X
136   UNSPEC_FYL2XP1
137   UNSPEC_FRNDINT
138   UNSPEC_FIST
139   UNSPEC_F2XM1
140   UNSPEC_TAN
141   UNSPEC_FXAM
143   ;; x87 Rounding
144   UNSPEC_FRNDINT_FLOOR
145   UNSPEC_FRNDINT_CEIL
146   UNSPEC_FRNDINT_TRUNC
147   UNSPEC_FRNDINT_MASK_PM
148   UNSPEC_FIST_FLOOR
149   UNSPEC_FIST_CEIL
151   ;; x87 Double output FP
152   UNSPEC_SINCOS_COS
153   UNSPEC_SINCOS_SIN
154   UNSPEC_XTRACT_FRACT
155   UNSPEC_XTRACT_EXP
156   UNSPEC_FSCALE_FRACT
157   UNSPEC_FSCALE_EXP
158   UNSPEC_FPREM_F
159   UNSPEC_FPREM_U
160   UNSPEC_FPREM1_F
161   UNSPEC_FPREM1_U
163   UNSPEC_C2_FLAG
164   UNSPEC_FXAM_MEM
166   ;; SSP patterns
167   UNSPEC_SP_SET
168   UNSPEC_SP_TEST
169   UNSPEC_SP_TLS_SET
170   UNSPEC_SP_TLS_TEST
172   ;; For ROUND support
173   UNSPEC_ROUND
175   ;; For CRC32 support
176   UNSPEC_CRC32
178   ;; For RDRAND support
179   UNSPEC_RDRAND
181   ;; For BMI support
182   UNSPEC_BEXTR
184   ;; For BMI2 support
185   UNSPEC_PDEP
186   UNSPEC_PEXT
189 (define_c_enum "unspecv" [
190   UNSPECV_BLOCKAGE
191   UNSPECV_STACK_PROBE
192   UNSPECV_PROBE_STACK_RANGE
193   UNSPECV_ALIGN
194   UNSPECV_PROLOGUE_USE
195   UNSPECV_SPLIT_STACK_RETURN
196   UNSPECV_CLD
197   UNSPECV_NOPS
198   UNSPECV_RDTSC
199   UNSPECV_RDTSCP
200   UNSPECV_RDPMC
201   UNSPECV_LLWP_INTRINSIC
202   UNSPECV_SLWP_INTRINSIC
203   UNSPECV_LWPVAL_INTRINSIC
204   UNSPECV_LWPINS_INTRINSIC
205   UNSPECV_RDFSBASE
206   UNSPECV_RDGSBASE
207   UNSPECV_WRFSBASE
208   UNSPECV_WRGSBASE
210   ;; For RTM support
211   UNSPECV_XBEGIN
212   UNSPECV_XEND
213   UNSPECV_XABORT
214   UNSPECV_XTEST
217 ;; Constants to represent rounding modes in the ROUND instruction
218 (define_constants
219   [(ROUND_FLOOR                 0x1)
220    (ROUND_CEIL                  0x2)
221    (ROUND_TRUNC                 0x3)
222    (ROUND_MXCSR                 0x4)
223    (ROUND_NO_EXC                0x8)
224   ])
226 ;; Constants to represent pcomtrue/pcomfalse variants
227 (define_constants
228   [(PCOM_FALSE                  0)
229    (PCOM_TRUE                   1)
230    (COM_FALSE_S                 2)
231    (COM_FALSE_P                 3)
232    (COM_TRUE_S                  4)
233    (COM_TRUE_P                  5)
234   ])
236 ;; Constants used in the XOP pperm instruction
237 (define_constants
238   [(PPERM_SRC                   0x00)   /* copy source */
239    (PPERM_INVERT                0x20)   /* invert source */
240    (PPERM_REVERSE               0x40)   /* bit reverse source */
241    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
242    (PPERM_ZERO                  0x80)   /* all 0's */
243    (PPERM_ONES                  0xa0)   /* all 1's */
244    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
245    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
246    (PPERM_SRC1                  0x00)   /* use first source byte */
247    (PPERM_SRC2                  0x10)   /* use second source byte */
248    ])
250 ;; Registers by name.
251 (define_constants
252   [(AX_REG                       0)
253    (DX_REG                       1)
254    (CX_REG                       2)
255    (BX_REG                       3)
256    (SI_REG                       4)
257    (DI_REG                       5)
258    (BP_REG                       6)
259    (SP_REG                       7)
260    (ST0_REG                      8)
261    (ST1_REG                      9)
262    (ST2_REG                     10)
263    (ST3_REG                     11)
264    (ST4_REG                     12)
265    (ST5_REG                     13)
266    (ST6_REG                     14)
267    (ST7_REG                     15)
268    (FLAGS_REG                   17)
269    (FPSR_REG                    18)
270    (FPCR_REG                    19)
271    (XMM0_REG                    21)
272    (XMM1_REG                    22)
273    (XMM2_REG                    23)
274    (XMM3_REG                    24)
275    (XMM4_REG                    25)
276    (XMM5_REG                    26)
277    (XMM6_REG                    27)
278    (XMM7_REG                    28)
279    (MM0_REG                     29)
280    (MM1_REG                     30)
281    (MM2_REG                     31)
282    (MM3_REG                     32)
283    (MM4_REG                     33)
284    (MM5_REG                     34)
285    (MM6_REG                     35)
286    (MM7_REG                     36)
287    (R8_REG                      37)
288    (R9_REG                      38)
289    (R10_REG                     39)
290    (R11_REG                     40)
291    (R12_REG                     41)
292    (R13_REG                     42)
293    (XMM8_REG                    45)
294    (XMM9_REG                    46)
295    (XMM10_REG                   47)
296    (XMM11_REG                   48)
297    (XMM12_REG                   49)
298    (XMM13_REG                   50)
299    (XMM14_REG                   51)
300    (XMM15_REG                   52)
301   ])
303 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
304 ;; from i386.c.
306 ;; In C guard expressions, put expressions which may be compile-time
307 ;; constants first.  This allows for better optimization.  For
308 ;; example, write "TARGET_64BIT && reload_completed", not
309 ;; "reload_completed && TARGET_64BIT".
312 ;; Processor type.
313 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
314                     atom,generic64,amdfam10,bdver1,bdver2,btver1"
315   (const (symbol_ref "ix86_schedule")))
317 ;; A basic instruction type.  Refinements due to arguments to be
318 ;; provided in other attributes.
319 (define_attr "type"
320   "other,multi,
321    alu,alu1,negnot,imov,imovx,lea,
322    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
323    icmp,test,ibr,setcc,icmov,
324    push,pop,call,callv,leave,
325    str,bitmanip,
326    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
327    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
328    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
329    ssemuladd,sse4arg,lwp,
330    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
331   (const_string "other"))
333 ;; Main data type used by the insn
334 (define_attr "mode"
335   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
336   (const_string "unknown"))
338 ;; The CPU unit operations uses.
339 (define_attr "unit" "integer,i387,sse,mmx,unknown"
340   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
341            (const_string "i387")
342          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
343                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
344                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
345            (const_string "sse")
346          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
347            (const_string "mmx")
348          (eq_attr "type" "other")
349            (const_string "unknown")]
350          (const_string "integer")))
352 ;; The (bounding maximum) length of an instruction immediate.
353 (define_attr "length_immediate" ""
354   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
355                           bitmanip,imulx")
356            (const_int 0)
357          (eq_attr "unit" "i387,sse,mmx")
358            (const_int 0)
359          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
360                           rotate,rotatex,rotate1,imul,icmp,push,pop")
361            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
362          (eq_attr "type" "imov,test")
363            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
364          (eq_attr "type" "call")
365            (if_then_else (match_operand 0 "constant_call_address_operand")
366              (const_int 4)
367              (const_int 0))
368          (eq_attr "type" "callv")
369            (if_then_else (match_operand 1 "constant_call_address_operand")
370              (const_int 4)
371              (const_int 0))
372          ;; We don't know the size before shorten_branches.  Expect
373          ;; the instruction to fit for better scheduling.
374          (eq_attr "type" "ibr")
375            (const_int 1)
376          ]
377          (symbol_ref "/* Update immediate_length and other attributes! */
378                       gcc_unreachable (),1")))
380 ;; The (bounding maximum) length of an instruction address.
381 (define_attr "length_address" ""
382   (cond [(eq_attr "type" "str,other,multi,fxch")
383            (const_int 0)
384          (and (eq_attr "type" "call")
385               (match_operand 0 "constant_call_address_operand"))
386              (const_int 0)
387          (and (eq_attr "type" "callv")
388               (match_operand 1 "constant_call_address_operand"))
389              (const_int 0)
390          ]
391          (symbol_ref "ix86_attr_length_address_default (insn)")))
393 ;; Set when length prefix is used.
394 (define_attr "prefix_data16" ""
395   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
396            (const_int 0)
397          (eq_attr "mode" "HI")
398            (const_int 1)
399          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
400            (const_int 1)
401         ]
402         (const_int 0)))
404 ;; Set when string REP prefix is used.
405 (define_attr "prefix_rep" ""
406   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
407            (const_int 0)
408          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
409            (const_int 1)
410         ]
411         (const_int 0)))
413 ;; Set when 0f opcode prefix is used.
414 (define_attr "prefix_0f" ""
415   (if_then_else
416     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
417          (eq_attr "unit" "sse,mmx"))
418     (const_int 1)
419     (const_int 0)))
421 ;; Set when REX opcode prefix is used.
422 (define_attr "prefix_rex" ""
423   (cond [(not (match_test "TARGET_64BIT"))
424            (const_int 0)
425          (and (eq_attr "mode" "DI")
426               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
427                    (eq_attr "unit" "!mmx")))
428            (const_int 1)
429          (and (eq_attr "mode" "QI")
430               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
431            (const_int 1)
432          (match_test "x86_extended_reg_mentioned_p (insn)")
433            (const_int 1)
434          (and (eq_attr "type" "imovx")
435               (match_operand:QI 1 "ext_QIreg_operand"))
436            (const_int 1)
437         ]
438         (const_int 0)))
440 ;; There are also additional prefixes in 3DNOW, SSSE3.
441 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
442 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
443 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
444 (define_attr "prefix_extra" ""
445   (cond [(eq_attr "type" "ssemuladd,sse4arg")
446            (const_int 2)
447          (eq_attr "type" "sseiadd1,ssecvt1")
448            (const_int 1)
449         ]
450         (const_int 0)))
452 ;; Prefix used: original, VEX or maybe VEX.
453 (define_attr "prefix" "orig,vex,maybe_vex"
454   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
455     (const_string "vex")
456     (const_string "orig")))
458 ;; VEX W bit is used.
459 (define_attr "prefix_vex_w" "" (const_int 0))
461 ;; The length of VEX prefix
462 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
463 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
464 ;; still prefix_0f 1, with prefix_extra 1.
465 (define_attr "length_vex" ""
466   (if_then_else (and (eq_attr "prefix_0f" "1")
467                      (eq_attr "prefix_extra" "0"))
468     (if_then_else (eq_attr "prefix_vex_w" "1")
469       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
470       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
471     (if_then_else (eq_attr "prefix_vex_w" "1")
472       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
473       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
475 ;; Set when modrm byte is used.
476 (define_attr "modrm" ""
477   (cond [(eq_attr "type" "str,leave")
478            (const_int 0)
479          (eq_attr "unit" "i387")
480            (const_int 0)
481          (and (eq_attr "type" "incdec")
482               (and (not (match_test "TARGET_64BIT"))
483                    (ior (match_operand:SI 1 "register_operand")
484                         (match_operand:HI 1 "register_operand"))))
485            (const_int 0)
486          (and (eq_attr "type" "push")
487               (not (match_operand 1 "memory_operand")))
488            (const_int 0)
489          (and (eq_attr "type" "pop")
490               (not (match_operand 0 "memory_operand")))
491            (const_int 0)
492          (and (eq_attr "type" "imov")
493               (and (not (eq_attr "mode" "DI"))
494                    (ior (and (match_operand 0 "register_operand")
495                              (match_operand 1 "immediate_operand"))
496                         (ior (and (match_operand 0 "ax_reg_operand")
497                                   (match_operand 1 "memory_displacement_only_operand"))
498                              (and (match_operand 0 "memory_displacement_only_operand")
499                                   (match_operand 1 "ax_reg_operand"))))))
500            (const_int 0)
501          (and (eq_attr "type" "call")
502               (match_operand 0 "constant_call_address_operand"))
503              (const_int 0)
504          (and (eq_attr "type" "callv")
505               (match_operand 1 "constant_call_address_operand"))
506              (const_int 0)
507          (and (eq_attr "type" "alu,alu1,icmp,test")
508               (match_operand 0 "ax_reg_operand"))
509              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
510          ]
511          (const_int 1)))
513 ;; The (bounding maximum) length of an instruction in bytes.
514 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
515 ;; Later we may want to split them and compute proper length as for
516 ;; other insns.
517 (define_attr "length" ""
518   (cond [(eq_attr "type" "other,multi,fistp,frndint")
519            (const_int 16)
520          (eq_attr "type" "fcmp")
521            (const_int 4)
522          (eq_attr "unit" "i387")
523            (plus (const_int 2)
524                  (plus (attr "prefix_data16")
525                        (attr "length_address")))
526          (ior (eq_attr "prefix" "vex")
527               (and (eq_attr "prefix" "maybe_vex")
528                    (match_test "TARGET_AVX")))
529            (plus (attr "length_vex")
530                  (plus (attr "length_immediate")
531                        (plus (attr "modrm")
532                              (attr "length_address"))))]
533          (plus (plus (attr "modrm")
534                      (plus (attr "prefix_0f")
535                            (plus (attr "prefix_rex")
536                                  (plus (attr "prefix_extra")
537                                        (const_int 1)))))
538                (plus (attr "prefix_rep")
539                      (plus (attr "prefix_data16")
540                            (plus (attr "length_immediate")
541                                  (attr "length_address")))))))
543 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
544 ;; `store' if there is a simple memory reference therein, or `unknown'
545 ;; if the instruction is complex.
547 (define_attr "memory" "none,load,store,both,unknown"
548   (cond [(eq_attr "type" "other,multi,str,lwp")
549            (const_string "unknown")
550          (eq_attr "type" "lea,fcmov,fpspc")
551            (const_string "none")
552          (eq_attr "type" "fistp,leave")
553            (const_string "both")
554          (eq_attr "type" "frndint")
555            (const_string "load")
556          (eq_attr "type" "push")
557            (if_then_else (match_operand 1 "memory_operand")
558              (const_string "both")
559              (const_string "store"))
560          (eq_attr "type" "pop")
561            (if_then_else (match_operand 0 "memory_operand")
562              (const_string "both")
563              (const_string "load"))
564          (eq_attr "type" "setcc")
565            (if_then_else (match_operand 0 "memory_operand")
566              (const_string "store")
567              (const_string "none"))
568          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
569            (if_then_else (ior (match_operand 0 "memory_operand")
570                               (match_operand 1 "memory_operand"))
571              (const_string "load")
572              (const_string "none"))
573          (eq_attr "type" "ibr")
574            (if_then_else (match_operand 0 "memory_operand")
575              (const_string "load")
576              (const_string "none"))
577          (eq_attr "type" "call")
578            (if_then_else (match_operand 0 "constant_call_address_operand")
579              (const_string "none")
580              (const_string "load"))
581          (eq_attr "type" "callv")
582            (if_then_else (match_operand 1 "constant_call_address_operand")
583              (const_string "none")
584              (const_string "load"))
585          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
586               (match_operand 1 "memory_operand"))
587            (const_string "both")
588          (and (match_operand 0 "memory_operand")
589               (match_operand 1 "memory_operand"))
590            (const_string "both")
591          (match_operand 0 "memory_operand")
592            (const_string "store")
593          (match_operand 1 "memory_operand")
594            (const_string "load")
595          (and (eq_attr "type"
596                  "!alu1,negnot,ishift1,
597                    imov,imovx,icmp,test,bitmanip,
598                    fmov,fcmp,fsgn,
599                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
600                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
601               (match_operand 2 "memory_operand"))
602            (const_string "load")
603          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
604               (match_operand 3 "memory_operand"))
605            (const_string "load")
606         ]
607         (const_string "none")))
609 ;; Indicates if an instruction has both an immediate and a displacement.
611 (define_attr "imm_disp" "false,true,unknown"
612   (cond [(eq_attr "type" "other,multi")
613            (const_string "unknown")
614          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
615               (and (match_operand 0 "memory_displacement_operand")
616                    (match_operand 1 "immediate_operand")))
617            (const_string "true")
618          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
619               (and (match_operand 0 "memory_displacement_operand")
620                    (match_operand 2 "immediate_operand")))
621            (const_string "true")
622         ]
623         (const_string "false")))
625 ;; Indicates if an FP operation has an integer source.
627 (define_attr "fp_int_src" "false,true"
628   (const_string "false"))
630 ;; Defines rounding mode of an FP operation.
632 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
633   (const_string "any"))
635 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
636 (define_attr "use_carry" "0,1" (const_string "0"))
638 ;; Define attribute to indicate unaligned ssemov insns
639 (define_attr "movu" "0,1" (const_string "0"))
641 ;; Used to control the "enabled" attribute on a per-instruction basis.
642 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
643   (const_string "base"))
645 (define_attr "enabled" ""
646   (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
647          (eq_attr "isa" "sse2_noavx")
648            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
649          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
650          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
651          (eq_attr "isa" "sse4_noavx")
652            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
653          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
654          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
655          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
656         ]
657         (const_int 1)))
659 ;; Describe a user's asm statement.
660 (define_asm_attributes
661   [(set_attr "length" "128")
662    (set_attr "type" "multi")])
664 (define_code_iterator plusminus [plus minus])
666 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
668 ;; Base name for define_insn
669 (define_code_attr plusminus_insn
670   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
671    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
673 ;; Base name for insn mnemonic.
674 (define_code_attr plusminus_mnemonic
675   [(plus "add") (ss_plus "adds") (us_plus "addus")
676    (minus "sub") (ss_minus "subs") (us_minus "subus")])
677 (define_code_attr plusminus_carry_mnemonic
678   [(plus "adc") (minus "sbb")])
680 ;; Mark commutative operators as such in constraints.
681 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
682                         (minus "") (ss_minus "") (us_minus "")])
684 ;; Mapping of max and min
685 (define_code_iterator maxmin [smax smin umax umin])
687 ;; Mapping of signed max and min
688 (define_code_iterator smaxmin [smax smin])
690 ;; Mapping of unsigned max and min
691 (define_code_iterator umaxmin [umax umin])
693 ;; Base name for integer and FP insn mnemonic
694 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
695                               (umax "maxu") (umin "minu")])
696 (define_code_attr maxmin_float [(smax "max") (smin "min")])
698 ;; Mapping of logic operators
699 (define_code_iterator any_logic [and ior xor])
700 (define_code_iterator any_or [ior xor])
702 ;; Base name for insn mnemonic.
703 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
705 ;; Mapping of logic-shift operators
706 (define_code_iterator any_lshift [ashift lshiftrt])
708 ;; Mapping of shift-right operators
709 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
711 ;; Base name for define_insn
712 (define_code_attr shift_insn
713   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
715 ;; Base name for insn mnemonic.
716 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
717 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
719 ;; Mapping of rotate operators
720 (define_code_iterator any_rotate [rotate rotatert])
722 ;; Base name for define_insn
723 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
725 ;; Base name for insn mnemonic.
726 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
728 ;; Mapping of abs neg operators
729 (define_code_iterator absneg [abs neg])
731 ;; Base name for x87 insn mnemonic.
732 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
734 ;; Used in signed and unsigned widening multiplications.
735 (define_code_iterator any_extend [sign_extend zero_extend])
737 ;; Prefix for insn menmonic.
738 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
740 ;; Prefix for define_insn
741 (define_code_attr u [(sign_extend "") (zero_extend "u")])
742 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
744 ;; All integer modes.
745 (define_mode_iterator SWI1248x [QI HI SI DI])
747 ;; All integer modes without QImode.
748 (define_mode_iterator SWI248x [HI SI DI])
750 ;; All integer modes without QImode and HImode.
751 (define_mode_iterator SWI48x [SI DI])
753 ;; All integer modes without SImode and DImode.
754 (define_mode_iterator SWI12 [QI HI])
756 ;; All integer modes without DImode.
757 (define_mode_iterator SWI124 [QI HI SI])
759 ;; All integer modes without QImode and DImode.
760 (define_mode_iterator SWI24 [HI SI])
762 ;; Single word integer modes.
763 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
765 ;; Single word integer modes without QImode.
766 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
768 ;; Single word integer modes without QImode and HImode.
769 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
771 ;; All math-dependant single and double word integer modes.
772 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
773                              (HI "TARGET_HIMODE_MATH")
774                              SI DI (TI "TARGET_64BIT")])
776 ;; Math-dependant single word integer modes.
777 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
778                             (HI "TARGET_HIMODE_MATH")
779                             SI (DI "TARGET_64BIT")])
781 ;; Math-dependant integer modes without DImode.
782 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
783                                (HI "TARGET_HIMODE_MATH")
784                                SI])
786 ;; Math-dependant single word integer modes without QImode.
787 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
788                                SI (DI "TARGET_64BIT")])
790 ;; Double word integer modes.
791 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
792                            (TI "TARGET_64BIT")])
794 ;; Double word integer modes as mode attribute.
795 (define_mode_attr DWI [(SI "DI") (DI "TI")])
796 (define_mode_attr dwi [(SI "di") (DI "ti")])
798 ;; Half mode for double word integer modes.
799 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
800                             (DI "TARGET_64BIT")])
802 ;; Instruction suffix for integer modes.
803 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
805 ;; Pointer size prefix for integer modes (Intel asm dialect)
806 (define_mode_attr iptrsize [(QI "BYTE")
807                             (HI "WORD")
808                             (SI "DWORD")
809                             (DI "QWORD")])
811 ;; Register class for integer modes.
812 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
814 ;; Immediate operand constraint for integer modes.
815 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
817 ;; General operand constraint for word modes.
818 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
820 ;; Immediate operand constraint for double integer modes.
821 (define_mode_attr di [(SI "nF") (DI "e")])
823 ;; Immediate operand constraint for shifts.
824 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
826 ;; General operand predicate for integer modes.
827 (define_mode_attr general_operand
828         [(QI "general_operand")
829          (HI "general_operand")
830          (SI "x86_64_general_operand")
831          (DI "x86_64_general_operand")
832          (TI "x86_64_general_operand")])
834 ;; General sign/zero extend operand predicate for integer modes.
835 (define_mode_attr general_szext_operand
836         [(QI "general_operand")
837          (HI "general_operand")
838          (SI "x86_64_szext_general_operand")
839          (DI "x86_64_szext_general_operand")])
841 ;; Immediate operand predicate for integer modes.
842 (define_mode_attr immediate_operand
843         [(QI "immediate_operand")
844          (HI "immediate_operand")
845          (SI "x86_64_immediate_operand")
846          (DI "x86_64_immediate_operand")])
848 ;; Nonmemory operand predicate for integer modes.
849 (define_mode_attr nonmemory_operand
850         [(QI "nonmemory_operand")
851          (HI "nonmemory_operand")
852          (SI "x86_64_nonmemory_operand")
853          (DI "x86_64_nonmemory_operand")])
855 ;; Operand predicate for shifts.
856 (define_mode_attr shift_operand
857         [(QI "nonimmediate_operand")
858          (HI "nonimmediate_operand")
859          (SI "nonimmediate_operand")
860          (DI "shiftdi_operand")
861          (TI "register_operand")])
863 ;; Operand predicate for shift argument.
864 (define_mode_attr shift_immediate_operand
865         [(QI "const_1_to_31_operand")
866          (HI "const_1_to_31_operand")
867          (SI "const_1_to_31_operand")
868          (DI "const_1_to_63_operand")])
870 ;; Input operand predicate for arithmetic left shifts.
871 (define_mode_attr ashl_input_operand
872         [(QI "nonimmediate_operand")
873          (HI "nonimmediate_operand")
874          (SI "nonimmediate_operand")
875          (DI "ashldi_input_operand")
876          (TI "reg_or_pm1_operand")])
878 ;; SSE and x87 SFmode and DFmode floating point modes
879 (define_mode_iterator MODEF [SF DF])
881 ;; All x87 floating point modes
882 (define_mode_iterator X87MODEF [SF DF XF])
884 ;; SSE instruction suffix for various modes
885 (define_mode_attr ssemodesuffix
886   [(SF "ss") (DF "sd")
887    (V8SF "ps") (V4DF "pd")
888    (V4SF "ps") (V2DF "pd")
889    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
890    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
892 ;; SSE vector suffix for floating point modes
893 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
895 ;; SSE vector mode corresponding to a scalar mode
896 (define_mode_attr ssevecmode
897   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
899 ;; Instruction suffix for REX 64bit operators.
900 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
902 ;; This mode iterator allows :P to be used for patterns that operate on
903 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
904 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
906 ;; This mode iterator allows :W to be used for patterns that operate on
907 ;; word_mode sized quantities.
908 (define_mode_iterator W
909   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
911 ;; This mode iterator allows :PTR to be used for patterns that operate on
912 ;; ptr_mode sized quantities.
913 (define_mode_iterator PTR
914   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
916 ;; Scheduling descriptions
918 (include "pentium.md")
919 (include "ppro.md")
920 (include "k6.md")
921 (include "athlon.md")
922 (include "bdver1.md")
923 (include "geode.md")
924 (include "atom.md")
925 (include "core2.md")
928 ;; Operand and operator predicates and constraints
930 (include "predicates.md")
931 (include "constraints.md")
934 ;; Compare and branch/compare and store instructions.
936 (define_expand "cbranch<mode>4"
937   [(set (reg:CC FLAGS_REG)
938         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
939                     (match_operand:SDWIM 2 "<general_operand>")))
940    (set (pc) (if_then_else
941                (match_operator 0 "ordered_comparison_operator"
942                 [(reg:CC FLAGS_REG) (const_int 0)])
943                (label_ref (match_operand 3))
944                (pc)))]
945   ""
947   if (MEM_P (operands[1]) && MEM_P (operands[2]))
948     operands[1] = force_reg (<MODE>mode, operands[1]);
949   ix86_expand_branch (GET_CODE (operands[0]),
950                       operands[1], operands[2], operands[3]);
951   DONE;
954 (define_expand "cstore<mode>4"
955   [(set (reg:CC FLAGS_REG)
956         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
957                     (match_operand:SWIM 3 "<general_operand>")))
958    (set (match_operand:QI 0 "register_operand")
959         (match_operator 1 "ordered_comparison_operator"
960           [(reg:CC FLAGS_REG) (const_int 0)]))]
961   ""
963   if (MEM_P (operands[2]) && MEM_P (operands[3]))
964     operands[2] = force_reg (<MODE>mode, operands[2]);
965   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
966                      operands[2], operands[3]);
967   DONE;
970 (define_expand "cmp<mode>_1"
971   [(set (reg:CC FLAGS_REG)
972         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
973                     (match_operand:SWI48 1 "<general_operand>")))])
975 (define_insn "*cmp<mode>_ccno_1"
976   [(set (reg FLAGS_REG)
977         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
978                  (match_operand:SWI 1 "const0_operand")))]
979   "ix86_match_ccmode (insn, CCNOmode)"
980   "@
981    test{<imodesuffix>}\t%0, %0
982    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
983   [(set_attr "type" "test,icmp")
984    (set_attr "length_immediate" "0,1")
985    (set_attr "mode" "<MODE>")])
987 (define_insn "*cmp<mode>_1"
988   [(set (reg FLAGS_REG)
989         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
990                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
991   "ix86_match_ccmode (insn, CCmode)"
992   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
993   [(set_attr "type" "icmp")
994    (set_attr "mode" "<MODE>")])
996 (define_insn "*cmp<mode>_minus_1"
997   [(set (reg FLAGS_REG)
998         (compare
999           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1000                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1001           (const_int 0)))]
1002   "ix86_match_ccmode (insn, CCGOCmode)"
1003   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1004   [(set_attr "type" "icmp")
1005    (set_attr "mode" "<MODE>")])
1007 (define_insn "*cmpqi_ext_1"
1008   [(set (reg FLAGS_REG)
1009         (compare
1010           (match_operand:QI 0 "general_operand" "Qm")
1011           (subreg:QI
1012             (zero_extract:SI
1013               (match_operand 1 "ext_register_operand" "Q")
1014               (const_int 8)
1015               (const_int 8)) 0)))]
1016   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1017   "cmp{b}\t{%h1, %0|%0, %h1}"
1018   [(set_attr "type" "icmp")
1019    (set_attr "mode" "QI")])
1021 (define_insn "*cmpqi_ext_1_rex64"
1022   [(set (reg FLAGS_REG)
1023         (compare
1024           (match_operand:QI 0 "register_operand" "Q")
1025           (subreg:QI
1026             (zero_extract:SI
1027               (match_operand 1 "ext_register_operand" "Q")
1028               (const_int 8)
1029               (const_int 8)) 0)))]
1030   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1031   "cmp{b}\t{%h1, %0|%0, %h1}"
1032   [(set_attr "type" "icmp")
1033    (set_attr "mode" "QI")])
1035 (define_insn "*cmpqi_ext_2"
1036   [(set (reg FLAGS_REG)
1037         (compare
1038           (subreg:QI
1039             (zero_extract:SI
1040               (match_operand 0 "ext_register_operand" "Q")
1041               (const_int 8)
1042               (const_int 8)) 0)
1043           (match_operand:QI 1 "const0_operand")))]
1044   "ix86_match_ccmode (insn, CCNOmode)"
1045   "test{b}\t%h0, %h0"
1046   [(set_attr "type" "test")
1047    (set_attr "length_immediate" "0")
1048    (set_attr "mode" "QI")])
1050 (define_expand "cmpqi_ext_3"
1051   [(set (reg:CC FLAGS_REG)
1052         (compare:CC
1053           (subreg:QI
1054             (zero_extract:SI
1055               (match_operand 0 "ext_register_operand")
1056               (const_int 8)
1057               (const_int 8)) 0)
1058           (match_operand:QI 1 "immediate_operand")))])
1060 (define_insn "*cmpqi_ext_3_insn"
1061   [(set (reg FLAGS_REG)
1062         (compare
1063           (subreg:QI
1064             (zero_extract:SI
1065               (match_operand 0 "ext_register_operand" "Q")
1066               (const_int 8)
1067               (const_int 8)) 0)
1068           (match_operand:QI 1 "general_operand" "Qmn")))]
1069   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1070   "cmp{b}\t{%1, %h0|%h0, %1}"
1071   [(set_attr "type" "icmp")
1072    (set_attr "modrm" "1")
1073    (set_attr "mode" "QI")])
1075 (define_insn "*cmpqi_ext_3_insn_rex64"
1076   [(set (reg FLAGS_REG)
1077         (compare
1078           (subreg:QI
1079             (zero_extract:SI
1080               (match_operand 0 "ext_register_operand" "Q")
1081               (const_int 8)
1082               (const_int 8)) 0)
1083           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1084   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1085   "cmp{b}\t{%1, %h0|%h0, %1}"
1086   [(set_attr "type" "icmp")
1087    (set_attr "modrm" "1")
1088    (set_attr "mode" "QI")])
1090 (define_insn "*cmpqi_ext_4"
1091   [(set (reg FLAGS_REG)
1092         (compare
1093           (subreg:QI
1094             (zero_extract:SI
1095               (match_operand 0 "ext_register_operand" "Q")
1096               (const_int 8)
1097               (const_int 8)) 0)
1098           (subreg:QI
1099             (zero_extract:SI
1100               (match_operand 1 "ext_register_operand" "Q")
1101               (const_int 8)
1102               (const_int 8)) 0)))]
1103   "ix86_match_ccmode (insn, CCmode)"
1104   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1105   [(set_attr "type" "icmp")
1106    (set_attr "mode" "QI")])
1108 ;; These implement float point compares.
1109 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1110 ;; which would allow mix and match FP modes on the compares.  Which is what
1111 ;; the old patterns did, but with many more of them.
1113 (define_expand "cbranchxf4"
1114   [(set (reg:CC FLAGS_REG)
1115         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1116                     (match_operand:XF 2 "nonmemory_operand")))
1117    (set (pc) (if_then_else
1118               (match_operator 0 "ix86_fp_comparison_operator"
1119                [(reg:CC FLAGS_REG)
1120                 (const_int 0)])
1121               (label_ref (match_operand 3))
1122               (pc)))]
1123   "TARGET_80387"
1125   ix86_expand_branch (GET_CODE (operands[0]),
1126                       operands[1], operands[2], operands[3]);
1127   DONE;
1130 (define_expand "cstorexf4"
1131   [(set (reg:CC FLAGS_REG)
1132         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1133                     (match_operand:XF 3 "nonmemory_operand")))
1134    (set (match_operand:QI 0 "register_operand")
1135               (match_operator 1 "ix86_fp_comparison_operator"
1136                [(reg:CC FLAGS_REG)
1137                 (const_int 0)]))]
1138   "TARGET_80387"
1140   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1141                      operands[2], operands[3]);
1142   DONE;
1145 (define_expand "cbranch<mode>4"
1146   [(set (reg:CC FLAGS_REG)
1147         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1148                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1149    (set (pc) (if_then_else
1150               (match_operator 0 "ix86_fp_comparison_operator"
1151                [(reg:CC FLAGS_REG)
1152                 (const_int 0)])
1153               (label_ref (match_operand 3))
1154               (pc)))]
1155   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1157   ix86_expand_branch (GET_CODE (operands[0]),
1158                       operands[1], operands[2], operands[3]);
1159   DONE;
1162 (define_expand "cstore<mode>4"
1163   [(set (reg:CC FLAGS_REG)
1164         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1165                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1166    (set (match_operand:QI 0 "register_operand")
1167               (match_operator 1 "ix86_fp_comparison_operator"
1168                [(reg:CC FLAGS_REG)
1169                 (const_int 0)]))]
1170   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1172   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1173                      operands[2], operands[3]);
1174   DONE;
1177 (define_expand "cbranchcc4"
1178   [(set (pc) (if_then_else
1179               (match_operator 0 "comparison_operator"
1180                [(match_operand 1 "flags_reg_operand")
1181                 (match_operand 2 "const0_operand")])
1182               (label_ref (match_operand 3))
1183               (pc)))]
1184   ""
1186   ix86_expand_branch (GET_CODE (operands[0]),
1187                       operands[1], operands[2], operands[3]);
1188   DONE;
1191 (define_expand "cstorecc4"
1192   [(set (match_operand:QI 0 "register_operand")
1193               (match_operator 1 "comparison_operator"
1194                [(match_operand 2 "flags_reg_operand")
1195                 (match_operand 3 "const0_operand")]))]
1196   ""
1198   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1199                      operands[2], operands[3]);
1200   DONE;
1204 ;; FP compares, step 1:
1205 ;; Set the FP condition codes.
1207 ;; CCFPmode     compare with exceptions
1208 ;; CCFPUmode    compare with no exceptions
1210 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1211 ;; used to manage the reg stack popping would not be preserved.
1213 (define_insn "*cmpfp_0"
1214   [(set (match_operand:HI 0 "register_operand" "=a")
1215         (unspec:HI
1216           [(compare:CCFP
1217              (match_operand 1 "register_operand" "f")
1218              (match_operand 2 "const0_operand"))]
1219         UNSPEC_FNSTSW))]
1220   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1221    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1222   "* return output_fp_compare (insn, operands, false, false);"
1223   [(set_attr "type" "multi")
1224    (set_attr "unit" "i387")
1225    (set (attr "mode")
1226      (cond [(match_operand:SF 1)
1227               (const_string "SF")
1228             (match_operand:DF 1)
1229               (const_string "DF")
1230            ]
1231            (const_string "XF")))])
1233 (define_insn_and_split "*cmpfp_0_cc"
1234   [(set (reg:CCFP FLAGS_REG)
1235         (compare:CCFP
1236           (match_operand 1 "register_operand" "f")
1237           (match_operand 2 "const0_operand")))
1238    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1239   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1240    && TARGET_SAHF && !TARGET_CMOVE
1241    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1242   "#"
1243   "&& reload_completed"
1244   [(set (match_dup 0)
1245         (unspec:HI
1246           [(compare:CCFP (match_dup 1)(match_dup 2))]
1247         UNSPEC_FNSTSW))
1248    (set (reg:CC FLAGS_REG)
1249         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1250   ""
1251   [(set_attr "type" "multi")
1252    (set_attr "unit" "i387")
1253    (set (attr "mode")
1254      (cond [(match_operand:SF 1)
1255               (const_string "SF")
1256             (match_operand:DF 1)
1257               (const_string "DF")
1258            ]
1259            (const_string "XF")))])
1261 (define_insn "*cmpfp_xf"
1262   [(set (match_operand:HI 0 "register_operand" "=a")
1263         (unspec:HI
1264           [(compare:CCFP
1265              (match_operand:XF 1 "register_operand" "f")
1266              (match_operand:XF 2 "register_operand" "f"))]
1267           UNSPEC_FNSTSW))]
1268   "TARGET_80387"
1269   "* return output_fp_compare (insn, operands, false, false);"
1270   [(set_attr "type" "multi")
1271    (set_attr "unit" "i387")
1272    (set_attr "mode" "XF")])
1274 (define_insn_and_split "*cmpfp_xf_cc"
1275   [(set (reg:CCFP FLAGS_REG)
1276         (compare:CCFP
1277           (match_operand:XF 1 "register_operand" "f")
1278           (match_operand:XF 2 "register_operand" "f")))
1279    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1280   "TARGET_80387
1281    && TARGET_SAHF && !TARGET_CMOVE"
1282   "#"
1283   "&& reload_completed"
1284   [(set (match_dup 0)
1285         (unspec:HI
1286           [(compare:CCFP (match_dup 1)(match_dup 2))]
1287         UNSPEC_FNSTSW))
1288    (set (reg:CC FLAGS_REG)
1289         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1290   ""
1291   [(set_attr "type" "multi")
1292    (set_attr "unit" "i387")
1293    (set_attr "mode" "XF")])
1295 (define_insn "*cmpfp_<mode>"
1296   [(set (match_operand:HI 0 "register_operand" "=a")
1297         (unspec:HI
1298           [(compare:CCFP
1299              (match_operand:MODEF 1 "register_operand" "f")
1300              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1301           UNSPEC_FNSTSW))]
1302   "TARGET_80387"
1303   "* return output_fp_compare (insn, operands, false, false);"
1304   [(set_attr "type" "multi")
1305    (set_attr "unit" "i387")
1306    (set_attr "mode" "<MODE>")])
1308 (define_insn_and_split "*cmpfp_<mode>_cc"
1309   [(set (reg:CCFP FLAGS_REG)
1310         (compare:CCFP
1311           (match_operand:MODEF 1 "register_operand" "f")
1312           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1313    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1314   "TARGET_80387
1315    && TARGET_SAHF && !TARGET_CMOVE"
1316   "#"
1317   "&& reload_completed"
1318   [(set (match_dup 0)
1319         (unspec:HI
1320           [(compare:CCFP (match_dup 1)(match_dup 2))]
1321         UNSPEC_FNSTSW))
1322    (set (reg:CC FLAGS_REG)
1323         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1324   ""
1325   [(set_attr "type" "multi")
1326    (set_attr "unit" "i387")
1327    (set_attr "mode" "<MODE>")])
1329 (define_insn "*cmpfp_u"
1330   [(set (match_operand:HI 0 "register_operand" "=a")
1331         (unspec:HI
1332           [(compare:CCFPU
1333              (match_operand 1 "register_operand" "f")
1334              (match_operand 2 "register_operand" "f"))]
1335           UNSPEC_FNSTSW))]
1336   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1337    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1338   "* return output_fp_compare (insn, operands, false, true);"
1339   [(set_attr "type" "multi")
1340    (set_attr "unit" "i387")
1341    (set (attr "mode")
1342      (cond [(match_operand:SF 1)
1343               (const_string "SF")
1344             (match_operand:DF 1)
1345               (const_string "DF")
1346            ]
1347            (const_string "XF")))])
1349 (define_insn_and_split "*cmpfp_u_cc"
1350   [(set (reg:CCFPU FLAGS_REG)
1351         (compare:CCFPU
1352           (match_operand 1 "register_operand" "f")
1353           (match_operand 2 "register_operand" "f")))
1354    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1355   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1356    && TARGET_SAHF && !TARGET_CMOVE
1357    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1358   "#"
1359   "&& reload_completed"
1360   [(set (match_dup 0)
1361         (unspec:HI
1362           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1363         UNSPEC_FNSTSW))
1364    (set (reg:CC FLAGS_REG)
1365         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1366   ""
1367   [(set_attr "type" "multi")
1368    (set_attr "unit" "i387")
1369    (set (attr "mode")
1370      (cond [(match_operand:SF 1)
1371               (const_string "SF")
1372             (match_operand:DF 1)
1373               (const_string "DF")
1374            ]
1375            (const_string "XF")))])
1377 (define_insn "*cmpfp_<mode>"
1378   [(set (match_operand:HI 0 "register_operand" "=a")
1379         (unspec:HI
1380           [(compare:CCFP
1381              (match_operand 1 "register_operand" "f")
1382              (match_operator 3 "float_operator"
1383                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1384           UNSPEC_FNSTSW))]
1385   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1386    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1387    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1388   "* return output_fp_compare (insn, operands, false, false);"
1389   [(set_attr "type" "multi")
1390    (set_attr "unit" "i387")
1391    (set_attr "fp_int_src" "true")
1392    (set_attr "mode" "<MODE>")])
1394 (define_insn_and_split "*cmpfp_<mode>_cc"
1395   [(set (reg:CCFP FLAGS_REG)
1396         (compare:CCFP
1397           (match_operand 1 "register_operand" "f")
1398           (match_operator 3 "float_operator"
1399             [(match_operand:SWI24 2 "memory_operand" "m")])))
1400    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1401   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1402    && TARGET_SAHF && !TARGET_CMOVE
1403    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1404    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1405   "#"
1406   "&& reload_completed"
1407   [(set (match_dup 0)
1408         (unspec:HI
1409           [(compare:CCFP
1410              (match_dup 1)
1411              (match_op_dup 3 [(match_dup 2)]))]
1412         UNSPEC_FNSTSW))
1413    (set (reg:CC FLAGS_REG)
1414         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1415   ""
1416   [(set_attr "type" "multi")
1417    (set_attr "unit" "i387")
1418    (set_attr "fp_int_src" "true")
1419    (set_attr "mode" "<MODE>")])
1421 ;; FP compares, step 2
1422 ;; Move the fpsw to ax.
1424 (define_insn "x86_fnstsw_1"
1425   [(set (match_operand:HI 0 "register_operand" "=a")
1426         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1427   "TARGET_80387"
1428   "fnstsw\t%0"
1429   [(set (attr "length")
1430         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1431    (set_attr "mode" "SI")
1432    (set_attr "unit" "i387")])
1434 ;; FP compares, step 3
1435 ;; Get ax into flags, general case.
1437 (define_insn "x86_sahf_1"
1438   [(set (reg:CC FLAGS_REG)
1439         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1440                    UNSPEC_SAHF))]
1441   "TARGET_SAHF"
1443 #ifndef HAVE_AS_IX86_SAHF
1444   if (TARGET_64BIT)
1445     return ASM_BYTE "0x9e";
1446   else
1447 #endif
1448   return "sahf";
1450   [(set_attr "length" "1")
1451    (set_attr "athlon_decode" "vector")
1452    (set_attr "amdfam10_decode" "direct")
1453    (set_attr "bdver1_decode" "direct")
1454    (set_attr "mode" "SI")])
1456 ;; Pentium Pro can do steps 1 through 3 in one go.
1457 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1458 ;; (these i387 instructions set flags directly)
1459 (define_insn "*cmpfp_i_mixed"
1460   [(set (reg:CCFP FLAGS_REG)
1461         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1462                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1463   "TARGET_MIX_SSE_I387
1464    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1465    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1466   "* return output_fp_compare (insn, operands, true, false);"
1467   [(set_attr "type" "fcmp,ssecomi")
1468    (set_attr "prefix" "orig,maybe_vex")
1469    (set (attr "mode")
1470      (if_then_else (match_operand:SF 1)
1471         (const_string "SF")
1472         (const_string "DF")))
1473    (set (attr "prefix_rep")
1474         (if_then_else (eq_attr "type" "ssecomi")
1475                       (const_string "0")
1476                       (const_string "*")))
1477    (set (attr "prefix_data16")
1478         (cond [(eq_attr "type" "fcmp")
1479                  (const_string "*")
1480                (eq_attr "mode" "DF")
1481                  (const_string "1")
1482               ]
1483               (const_string "0")))
1484    (set_attr "athlon_decode" "vector")
1485    (set_attr "amdfam10_decode" "direct")
1486    (set_attr "bdver1_decode" "double")])
1488 (define_insn "*cmpfp_i_sse"
1489   [(set (reg:CCFP FLAGS_REG)
1490         (compare:CCFP (match_operand 0 "register_operand" "x")
1491                       (match_operand 1 "nonimmediate_operand" "xm")))]
1492   "TARGET_SSE_MATH
1493    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1494    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1495   "* return output_fp_compare (insn, operands, true, false);"
1496   [(set_attr "type" "ssecomi")
1497    (set_attr "prefix" "maybe_vex")
1498    (set (attr "mode")
1499      (if_then_else (match_operand:SF 1)
1500         (const_string "SF")
1501         (const_string "DF")))
1502    (set_attr "prefix_rep" "0")
1503    (set (attr "prefix_data16")
1504         (if_then_else (eq_attr "mode" "DF")
1505                       (const_string "1")
1506                       (const_string "0")))
1507    (set_attr "athlon_decode" "vector")
1508    (set_attr "amdfam10_decode" "direct")
1509    (set_attr "bdver1_decode" "double")])
1511 (define_insn "*cmpfp_i_i387"
1512   [(set (reg:CCFP FLAGS_REG)
1513         (compare:CCFP (match_operand 0 "register_operand" "f")
1514                       (match_operand 1 "register_operand" "f")))]
1515   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1516    && TARGET_CMOVE
1517    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1518    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1519   "* return output_fp_compare (insn, operands, true, false);"
1520   [(set_attr "type" "fcmp")
1521    (set (attr "mode")
1522      (cond [(match_operand:SF 1)
1523               (const_string "SF")
1524             (match_operand:DF 1)
1525               (const_string "DF")
1526            ]
1527            (const_string "XF")))
1528    (set_attr "athlon_decode" "vector")
1529    (set_attr "amdfam10_decode" "direct")
1530    (set_attr "bdver1_decode" "double")])
1532 (define_insn "*cmpfp_iu_mixed"
1533   [(set (reg:CCFPU FLAGS_REG)
1534         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1535                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1536   "TARGET_MIX_SSE_I387
1537    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1538    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1539   "* return output_fp_compare (insn, operands, true, true);"
1540   [(set_attr "type" "fcmp,ssecomi")
1541    (set_attr "prefix" "orig,maybe_vex")
1542    (set (attr "mode")
1543      (if_then_else (match_operand:SF 1)
1544         (const_string "SF")
1545         (const_string "DF")))
1546    (set (attr "prefix_rep")
1547         (if_then_else (eq_attr "type" "ssecomi")
1548                       (const_string "0")
1549                       (const_string "*")))
1550    (set (attr "prefix_data16")
1551         (cond [(eq_attr "type" "fcmp")
1552                  (const_string "*")
1553                (eq_attr "mode" "DF")
1554                  (const_string "1")
1555               ]
1556               (const_string "0")))
1557    (set_attr "athlon_decode" "vector")
1558    (set_attr "amdfam10_decode" "direct")
1559    (set_attr "bdver1_decode" "double")])
1561 (define_insn "*cmpfp_iu_sse"
1562   [(set (reg:CCFPU FLAGS_REG)
1563         (compare:CCFPU (match_operand 0 "register_operand" "x")
1564                        (match_operand 1 "nonimmediate_operand" "xm")))]
1565   "TARGET_SSE_MATH
1566    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1567    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1568   "* return output_fp_compare (insn, operands, true, true);"
1569   [(set_attr "type" "ssecomi")
1570    (set_attr "prefix" "maybe_vex")
1571    (set (attr "mode")
1572      (if_then_else (match_operand:SF 1)
1573         (const_string "SF")
1574         (const_string "DF")))
1575    (set_attr "prefix_rep" "0")
1576    (set (attr "prefix_data16")
1577         (if_then_else (eq_attr "mode" "DF")
1578                       (const_string "1")
1579                       (const_string "0")))
1580    (set_attr "athlon_decode" "vector")
1581    (set_attr "amdfam10_decode" "direct")
1582    (set_attr "bdver1_decode" "double")])
1584 (define_insn "*cmpfp_iu_387"
1585   [(set (reg:CCFPU FLAGS_REG)
1586         (compare:CCFPU (match_operand 0 "register_operand" "f")
1587                        (match_operand 1 "register_operand" "f")))]
1588   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1589    && TARGET_CMOVE
1590    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1591    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1592   "* return output_fp_compare (insn, operands, true, true);"
1593   [(set_attr "type" "fcmp")
1594    (set (attr "mode")
1595      (cond [(match_operand:SF 1)
1596               (const_string "SF")
1597             (match_operand:DF 1)
1598               (const_string "DF")
1599            ]
1600            (const_string "XF")))
1601    (set_attr "athlon_decode" "vector")
1602    (set_attr "amdfam10_decode" "direct")
1603    (set_attr "bdver1_decode" "direct")])
1605 ;; Push/pop instructions.
1607 (define_insn "*push<mode>2"
1608   [(set (match_operand:DWI 0 "push_operand" "=<")
1609         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1610   ""
1611   "#"
1612   [(set_attr "type" "multi")
1613    (set_attr "mode" "<MODE>")])
1615 (define_split
1616   [(set (match_operand:TI 0 "push_operand")
1617         (match_operand:TI 1 "general_operand"))]
1618   "TARGET_64BIT && reload_completed
1619    && !SSE_REG_P (operands[1])"
1620   [(const_int 0)]
1621   "ix86_split_long_move (operands); DONE;")
1623 (define_insn "*pushdi2_rex64"
1624   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1625         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1626   "TARGET_64BIT"
1627   "@
1628    push{q}\t%1
1629    #"
1630   [(set_attr "type" "push,multi")
1631    (set_attr "mode" "DI")])
1633 ;; Convert impossible pushes of immediate to existing instructions.
1634 ;; First try to get scratch register and go through it.  In case this
1635 ;; fails, push sign extended lower part first and then overwrite
1636 ;; upper part by 32bit move.
1637 (define_peephole2
1638   [(match_scratch:DI 2 "r")
1639    (set (match_operand:DI 0 "push_operand")
1640         (match_operand:DI 1 "immediate_operand"))]
1641   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1642    && !x86_64_immediate_operand (operands[1], DImode)"
1643   [(set (match_dup 2) (match_dup 1))
1644    (set (match_dup 0) (match_dup 2))])
1646 ;; We need to define this as both peepholer and splitter for case
1647 ;; peephole2 pass is not run.
1648 ;; "&& 1" is needed to keep it from matching the previous pattern.
1649 (define_peephole2
1650   [(set (match_operand:DI 0 "push_operand")
1651         (match_operand:DI 1 "immediate_operand"))]
1652   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1653    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1654   [(set (match_dup 0) (match_dup 1))
1655    (set (match_dup 2) (match_dup 3))]
1657   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1659   operands[1] = gen_lowpart (DImode, operands[2]);
1660   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1661                                                    GEN_INT (4)));
1664 (define_split
1665   [(set (match_operand:DI 0 "push_operand")
1666         (match_operand:DI 1 "immediate_operand"))]
1667   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1668                     ? epilogue_completed : reload_completed)
1669    && !symbolic_operand (operands[1], DImode)
1670    && !x86_64_immediate_operand (operands[1], DImode)"
1671   [(set (match_dup 0) (match_dup 1))
1672    (set (match_dup 2) (match_dup 3))]
1674   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1676   operands[1] = gen_lowpart (DImode, operands[2]);
1677   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1678                                                    GEN_INT (4)));
1681 (define_split
1682   [(set (match_operand:DI 0 "push_operand")
1683         (match_operand:DI 1 "general_operand"))]
1684   "!TARGET_64BIT && reload_completed
1685    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1686   [(const_int 0)]
1687   "ix86_split_long_move (operands); DONE;")
1689 (define_insn "*pushsi2"
1690   [(set (match_operand:SI 0 "push_operand" "=<")
1691         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1692   "!TARGET_64BIT"
1693   "push{l}\t%1"
1694   [(set_attr "type" "push")
1695    (set_attr "mode" "SI")])
1697 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1698 ;; "push a byte/word".  But actually we use pushl, which has the effect
1699 ;; of rounding the amount pushed up to a word.
1701 ;; For TARGET_64BIT we always round up to 8 bytes.
1702 (define_insn "*push<mode>2_rex64"
1703   [(set (match_operand:SWI124 0 "push_operand" "=X")
1704         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1705   "TARGET_64BIT"
1706   "push{q}\t%q1"
1707   [(set_attr "type" "push")
1708    (set_attr "mode" "DI")])
1710 (define_insn "*push<mode>2"
1711   [(set (match_operand:SWI12 0 "push_operand" "=X")
1712         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1713   "!TARGET_64BIT"
1714   "push{l}\t%k1"
1715   [(set_attr "type" "push")
1716    (set_attr "mode" "SI")])
1718 (define_insn "*push<mode>2_prologue"
1719   [(set (match_operand:W 0 "push_operand" "=<")
1720         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1721    (clobber (mem:BLK (scratch)))]
1722   ""
1723   "push{<imodesuffix>}\t%1"
1724   [(set_attr "type" "push")
1725    (set_attr "mode" "<MODE>")])
1727 (define_insn "*pop<mode>1"
1728   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1729         (match_operand:W 1 "pop_operand" ">"))]
1730   ""
1731   "pop{<imodesuffix>}\t%0"
1732   [(set_attr "type" "pop")
1733    (set_attr "mode" "<MODE>")])
1735 (define_insn "*pop<mode>1_epilogue"
1736   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1737         (match_operand:W 1 "pop_operand" ">"))
1738    (clobber (mem:BLK (scratch)))]
1739   ""
1740   "pop{<imodesuffix>}\t%0"
1741   [(set_attr "type" "pop")
1742    (set_attr "mode" "<MODE>")])
1744 ;; Move instructions.
1746 (define_expand "movoi"
1747   [(set (match_operand:OI 0 "nonimmediate_operand")
1748         (match_operand:OI 1 "general_operand"))]
1749   "TARGET_AVX"
1750   "ix86_expand_move (OImode, operands); DONE;")
1752 (define_expand "movti"
1753   [(set (match_operand:TI 0 "nonimmediate_operand")
1754         (match_operand:TI 1 "nonimmediate_operand"))]
1755   "TARGET_64BIT || TARGET_SSE"
1757   if (TARGET_64BIT)
1758     ix86_expand_move (TImode, operands);
1759   else if (push_operand (operands[0], TImode))
1760     ix86_expand_push (TImode, operands[1]);
1761   else
1762     ix86_expand_vector_move (TImode, operands);
1763   DONE;
1766 ;; This expands to what emit_move_complex would generate if we didn't
1767 ;; have a movti pattern.  Having this avoids problems with reload on
1768 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1769 ;; to have around all the time.
1770 (define_expand "movcdi"
1771   [(set (match_operand:CDI 0 "nonimmediate_operand")
1772         (match_operand:CDI 1 "general_operand"))]
1773   ""
1775   if (push_operand (operands[0], CDImode))
1776     emit_move_complex_push (CDImode, operands[0], operands[1]);
1777   else
1778     emit_move_complex_parts (operands[0], operands[1]);
1779   DONE;
1782 (define_expand "mov<mode>"
1783   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1784         (match_operand:SWI1248x 1 "general_operand"))]
1785   ""
1786   "ix86_expand_move (<MODE>mode, operands); DONE;")
1788 (define_insn "*mov<mode>_xor"
1789   [(set (match_operand:SWI48 0 "register_operand" "=r")
1790         (match_operand:SWI48 1 "const0_operand"))
1791    (clobber (reg:CC FLAGS_REG))]
1792   "reload_completed"
1793   "xor{l}\t%k0, %k0"
1794   [(set_attr "type" "alu1")
1795    (set_attr "mode" "SI")
1796    (set_attr "length_immediate" "0")])
1798 (define_insn "*mov<mode>_or"
1799   [(set (match_operand:SWI48 0 "register_operand" "=r")
1800         (match_operand:SWI48 1 "const_int_operand"))
1801    (clobber (reg:CC FLAGS_REG))]
1802   "reload_completed
1803    && operands[1] == constm1_rtx"
1804   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1805   [(set_attr "type" "alu1")
1806    (set_attr "mode" "<MODE>")
1807    (set_attr "length_immediate" "1")])
1809 (define_insn "*movoi_internal_avx"
1810   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1811         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1812   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1814   switch (which_alternative)
1815     {
1816     case 0:
1817       return standard_sse_constant_opcode (insn, operands[1]);
1818     case 1:
1819     case 2:
1820       if (misaligned_operand (operands[0], OImode)
1821           || misaligned_operand (operands[1], OImode))
1822         return "vmovdqu\t{%1, %0|%0, %1}";
1823       else
1824         return "vmovdqa\t{%1, %0|%0, %1}";
1825     default:
1826       gcc_unreachable ();
1827     }
1829   [(set_attr "type" "sselog1,ssemov,ssemov")
1830    (set_attr "prefix" "vex")
1831    (set_attr "mode" "OI")])
1833 (define_insn "*movti_internal_rex64"
1834   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1835         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1836   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1838   switch (which_alternative)
1839     {
1840     case 0:
1841     case 1:
1842       return "#";
1843     case 2:
1844       return standard_sse_constant_opcode (insn, operands[1]);
1845     case 3:
1846     case 4:
1847       /* TDmode values are passed as TImode on the stack.  Moving them
1848          to stack may result in unaligned memory access.  */
1849       if (misaligned_operand (operands[0], TImode)
1850           || misaligned_operand (operands[1], TImode))
1851         {
1852           if (get_attr_mode (insn) == MODE_V4SF)
1853             return "%vmovups\t{%1, %0|%0, %1}";
1854           else
1855             return "%vmovdqu\t{%1, %0|%0, %1}";
1856         }
1857       else
1858         {
1859           if (get_attr_mode (insn) == MODE_V4SF)
1860             return "%vmovaps\t{%1, %0|%0, %1}";
1861           else
1862             return "%vmovdqa\t{%1, %0|%0, %1}";
1863         }
1864     default:
1865       gcc_unreachable ();
1866     }
1868   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1869    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1870    (set (attr "mode")
1871         (cond [(eq_attr "alternative" "2,3")
1872                  (if_then_else
1873                    (match_test "optimize_function_for_size_p (cfun)")
1874                    (const_string "V4SF")
1875                    (const_string "TI"))
1876                (eq_attr "alternative" "4")
1877                  (if_then_else
1878                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1879                         (match_test "optimize_function_for_size_p (cfun)"))
1880                    (const_string "V4SF")
1881                    (const_string "TI"))]
1882                (const_string "DI")))])
1884 (define_split
1885   [(set (match_operand:TI 0 "nonimmediate_operand")
1886         (match_operand:TI 1 "general_operand"))]
1887   "reload_completed
1888    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1889   [(const_int 0)]
1890   "ix86_split_long_move (operands); DONE;")
1892 (define_insn "*movti_internal_sse"
1893   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1894         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1895   "TARGET_SSE && !TARGET_64BIT
1896    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1898   switch (which_alternative)
1899     {
1900     case 0:
1901       return standard_sse_constant_opcode (insn, operands[1]);
1902     case 1:
1903     case 2:
1904       /* TDmode values are passed as TImode on the stack.  Moving them
1905          to stack may result in unaligned memory access.  */
1906       if (misaligned_operand (operands[0], TImode)
1907           || misaligned_operand (operands[1], TImode))
1908         {
1909           if (get_attr_mode (insn) == MODE_V4SF)
1910             return "%vmovups\t{%1, %0|%0, %1}";
1911           else
1912             return "%vmovdqu\t{%1, %0|%0, %1}";
1913         }
1914       else
1915         {
1916           if (get_attr_mode (insn) == MODE_V4SF)
1917             return "%vmovaps\t{%1, %0|%0, %1}";
1918           else
1919             return "%vmovdqa\t{%1, %0|%0, %1}";
1920         }
1921     default:
1922       gcc_unreachable ();
1923     }
1925   [(set_attr "type" "sselog1,ssemov,ssemov")
1926    (set_attr "prefix" "maybe_vex")
1927    (set (attr "mode")
1928         (cond [(ior (not (match_test "TARGET_SSE2"))
1929                     (match_test "optimize_function_for_size_p (cfun)"))
1930                  (const_string "V4SF")
1931                (and (eq_attr "alternative" "2")
1932                     (match_test "TARGET_SSE_TYPELESS_STORES"))
1933                  (const_string "V4SF")]
1934               (const_string "TI")))])
1936 (define_insn "*movdi_internal_rex64"
1937   [(set (match_operand:DI 0 "nonimmediate_operand"
1938           "=r,r  ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1939         (match_operand:DI 1 "general_operand"
1940           "Z ,rem,i,re,n ,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1941   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943   switch (get_attr_type (insn))
1944     {
1945     case TYPE_SSECVT:
1946       if (SSE_REG_P (operands[0]))
1947         return "movq2dq\t{%1, %0|%0, %1}";
1948       else
1949         return "movdq2q\t{%1, %0|%0, %1}";
1951     case TYPE_SSEMOV:
1952       if (get_attr_mode (insn) == MODE_TI)
1953         return "%vmovdqa\t{%1, %0|%0, %1}";
1954       /* Handle broken assemblers that require movd instead of movq.  */
1955       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1956         return "%vmovd\t{%1, %0|%0, %1}";
1957       else
1958         return "%vmovq\t{%1, %0|%0, %1}";
1960     case TYPE_MMXMOV:
1961       /* Handle broken assemblers that require movd instead of movq.  */
1962       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1963         return "movd\t{%1, %0|%0, %1}";
1964       else
1965         return "movq\t{%1, %0|%0, %1}";
1967     case TYPE_SSELOG1:
1968       return standard_sse_constant_opcode (insn, operands[1]);
1970     case TYPE_MMX:
1971       return "pxor\t%0, %0";
1973     case TYPE_MULTI:
1974       return "#";
1976     case TYPE_LEA:
1977       return "lea{q}\t{%E1, %0|%0, %E1}";
1979     default:
1980       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1981       if (get_attr_mode (insn) == MODE_SI)
1982         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1983       else if (which_alternative == 2)
1984         return "movabs{q}\t{%1, %0|%0, %1}";
1985       else if (ix86_use_lea_for_mov (insn, operands))
1986         return "lea{q}\t{%E1, %0|%0, %E1}";
1987       else
1988         return "mov{q}\t{%1, %0|%0, %1}";
1989     }
1991   [(set (attr "type")
1992      (cond [(eq_attr "alternative" "4")
1993               (const_string "multi")
1994             (eq_attr "alternative" "5")
1995               (const_string "mmx")
1996             (eq_attr "alternative" "6,7,8,9")
1997               (const_string "mmxmov")
1998             (eq_attr "alternative" "10")
1999               (const_string "sselog1")
2000             (eq_attr "alternative" "11,12,13,14,15")
2001               (const_string "ssemov")
2002             (eq_attr "alternative" "16,17")
2003               (const_string "ssecvt")
2004             (match_operand 1 "pic_32bit_operand")
2005               (const_string "lea")
2006            ]
2007            (const_string "imov")))
2008    (set (attr "modrm")
2009      (if_then_else
2010        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2011          (const_string "0")
2012          (const_string "*")))
2013    (set (attr "length_immediate")
2014      (if_then_else
2015        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2016          (const_string "8")
2017          (const_string "*")))
2018    (set (attr "prefix_rex")
2019      (if_then_else (eq_attr "alternative" "8,9")
2020        (const_string "1")
2021        (const_string "*")))
2022    (set (attr "prefix_data16")
2023      (if_then_else (eq_attr "alternative" "11")
2024        (const_string "1")
2025        (const_string "*")))
2026    (set (attr "prefix")
2027      (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2028        (const_string "maybe_vex")
2029        (const_string "orig")))
2030    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2032 ;; Reload patterns to support multi-word load/store
2033 ;; with non-offsetable address.
2034 (define_expand "reload_noff_store"
2035   [(parallel [(match_operand 0 "memory_operand" "=m")
2036               (match_operand 1 "register_operand" "r")
2037               (match_operand:DI 2 "register_operand" "=&r")])]
2038   "TARGET_64BIT"
2040   rtx mem = operands[0];
2041   rtx addr = XEXP (mem, 0);
2043   emit_move_insn (operands[2], addr);
2044   mem = replace_equiv_address_nv (mem, operands[2]);
2046   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2047   DONE;
2050 (define_expand "reload_noff_load"
2051   [(parallel [(match_operand 0 "register_operand" "=r")
2052               (match_operand 1 "memory_operand" "m")
2053               (match_operand:DI 2 "register_operand" "=r")])]
2054   "TARGET_64BIT"
2056   rtx mem = operands[1];
2057   rtx addr = XEXP (mem, 0);
2059   emit_move_insn (operands[2], addr);
2060   mem = replace_equiv_address_nv (mem, operands[2]);
2062   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2063   DONE;
2066 ;; Convert impossible stores of immediate to existing instructions.
2067 ;; First try to get scratch register and go through it.  In case this
2068 ;; fails, move by 32bit parts.
2069 (define_peephole2
2070   [(match_scratch:DI 2 "r")
2071    (set (match_operand:DI 0 "memory_operand")
2072         (match_operand:DI 1 "immediate_operand"))]
2073   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2074    && !x86_64_immediate_operand (operands[1], DImode)"
2075   [(set (match_dup 2) (match_dup 1))
2076    (set (match_dup 0) (match_dup 2))])
2078 ;; We need to define this as both peepholer and splitter for case
2079 ;; peephole2 pass is not run.
2080 ;; "&& 1" is needed to keep it from matching the previous pattern.
2081 (define_peephole2
2082   [(set (match_operand:DI 0 "memory_operand")
2083         (match_operand:DI 1 "immediate_operand"))]
2084   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2085    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2086   [(set (match_dup 2) (match_dup 3))
2087    (set (match_dup 4) (match_dup 5))]
2088   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2090 (define_split
2091   [(set (match_operand:DI 0 "memory_operand")
2092         (match_operand:DI 1 "immediate_operand"))]
2093   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2094                     ? epilogue_completed : reload_completed)
2095    && !symbolic_operand (operands[1], DImode)
2096    && !x86_64_immediate_operand (operands[1], DImode)"
2097   [(set (match_dup 2) (match_dup 3))
2098    (set (match_dup 4) (match_dup 5))]
2099   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2101 (define_insn "*movdi_internal"
2102   [(set (match_operand:DI 0 "nonimmediate_operand"
2103           "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2104         (match_operand:DI 1 "general_operand"
2105           "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2106   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2108   switch (get_attr_type (insn))
2109     {
2110     case TYPE_SSECVT:
2111       if (SSE_REG_P (operands[0]))
2112         return "movq2dq\t{%1, %0|%0, %1}";
2113       else
2114         return "movdq2q\t{%1, %0|%0, %1}";
2116     case TYPE_SSEMOV:
2117       switch (get_attr_mode (insn))
2118         {
2119         case MODE_TI:
2120           return "%vmovdqa\t{%1, %0|%0, %1}";
2121         case MODE_DI:
2122            return "%vmovq\t{%1, %0|%0, %1}";
2123         case MODE_V4SF:
2124           return "movaps\t{%1, %0|%0, %1}";
2125         case MODE_V2SF:
2126           return "movlps\t{%1, %0|%0, %1}";
2127         default:
2128           gcc_unreachable ();
2129         }
2131     case TYPE_MMXMOV:
2132       return "movq\t{%1, %0|%0, %1}";
2134     case TYPE_SSELOG1:
2135       return standard_sse_constant_opcode (insn, operands[1]);
2137     case TYPE_MMX:
2138       return "pxor\t%0, %0";
2140     case TYPE_MULTI:
2141       return "#";
2143     default:
2144       gcc_unreachable ();
2145     }
2147   [(set (attr "isa")
2148      (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2149               (const_string "sse2")
2150             (eq_attr "alternative" "9,10,11,12")
2151               (const_string "noavx")
2152            ]
2153            (const_string "*")))
2154    (set (attr "type")
2155      (cond [(eq_attr "alternative" "0,1")
2156               (const_string "multi")
2157             (eq_attr "alternative" "2")
2158               (const_string "mmx")
2159             (eq_attr "alternative" "3,4")
2160               (const_string "mmxmov")
2161             (eq_attr "alternative" "5,9")
2162               (const_string "sselog1")
2163             (eq_attr "alternative" "13,14")
2164               (const_string "ssecvt")
2165            ]
2166            (const_string "ssemov")))
2167    (set (attr "prefix")
2168      (if_then_else (eq_attr "alternative" "5,6,7,8")
2169        (const_string "maybe_vex")
2170        (const_string "orig")))
2171    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2173 (define_split
2174   [(set (match_operand:DI 0 "nonimmediate_operand")
2175         (match_operand:DI 1 "general_operand"))]
2176   "!TARGET_64BIT && reload_completed
2177    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2178    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2179   [(const_int 0)]
2180   "ix86_split_long_move (operands); DONE;")
2182 (define_insn "*movsi_internal"
2183   [(set (match_operand:SI 0 "nonimmediate_operand"
2184                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2185         (match_operand:SI 1 "general_operand"
2186                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2187   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189   switch (get_attr_type (insn))
2190     {
2191     case TYPE_SSELOG1:
2192       return standard_sse_constant_opcode (insn, operands[1]);
2194     case TYPE_SSEMOV:
2195       switch (get_attr_mode (insn))
2196         {
2197         case MODE_TI:
2198           return "%vmovdqa\t{%1, %0|%0, %1}";
2199         case MODE_V4SF:
2200           return "%vmovaps\t{%1, %0|%0, %1}";
2201         case MODE_SI:
2202           return "%vmovd\t{%1, %0|%0, %1}";
2203         case MODE_SF:
2204           return "%vmovss\t{%1, %0|%0, %1}";
2205         default:
2206           gcc_unreachable ();
2207         }
2209     case TYPE_MMX:
2210       return "pxor\t%0, %0";
2212     case TYPE_MMXMOV:
2213       if (get_attr_mode (insn) == MODE_DI)
2214         return "movq\t{%1, %0|%0, %1}";
2215       return "movd\t{%1, %0|%0, %1}";
2217     case TYPE_LEA:
2218       return "lea{l}\t{%E1, %0|%0, %E1}";
2220     default:
2221       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2222       if (ix86_use_lea_for_mov (insn, operands))
2223         return "lea{l}\t{%E1, %0|%0, %E1}";
2224       else
2225         return "mov{l}\t{%1, %0|%0, %1}";
2226     }
2228   [(set (attr "type")
2229      (cond [(eq_attr "alternative" "2")
2230               (const_string "mmx")
2231             (eq_attr "alternative" "3,4,5")
2232               (const_string "mmxmov")
2233             (eq_attr "alternative" "6")
2234               (const_string "sselog1")
2235             (eq_attr "alternative" "7,8,9,10,11")
2236               (const_string "ssemov")
2237             (match_operand 1 "pic_32bit_operand")
2238               (const_string "lea")
2239            ]
2240            (const_string "imov")))
2241    (set (attr "prefix")
2242      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2243        (const_string "orig")
2244        (const_string "maybe_vex")))
2245    (set (attr "prefix_data16")
2246      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2247        (const_string "1")
2248        (const_string "*")))
2249    (set (attr "mode")
2250      (cond [(eq_attr "alternative" "2,3")
2251               (const_string "DI")
2252             (eq_attr "alternative" "6,7")
2253               (if_then_else
2254                 (not (match_test "TARGET_SSE2"))
2255                 (const_string "V4SF")
2256                 (const_string "TI"))
2257             (and (eq_attr "alternative" "8,9,10,11")
2258                  (not (match_test "TARGET_SSE2")))
2259               (const_string "SF")
2260            ]
2261            (const_string "SI")))])
2263 (define_insn "*movhi_internal"
2264   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2265         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2266   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2268   switch (get_attr_type (insn))
2269     {
2270     case TYPE_IMOVX:
2271       /* movzwl is faster than movw on p2 due to partial word stalls,
2272          though not as fast as an aligned movl.  */
2273       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2274     default:
2275       if (get_attr_mode (insn) == MODE_SI)
2276         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2277       else
2278         return "mov{w}\t{%1, %0|%0, %1}";
2279     }
2281   [(set (attr "type")
2282      (cond [(match_test "optimize_function_for_size_p (cfun)")
2283               (const_string "imov")
2284             (and (eq_attr "alternative" "0")
2285                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2286                       (not (match_test "TARGET_HIMODE_MATH"))))
2287               (const_string "imov")
2288             (and (eq_attr "alternative" "1,2")
2289                  (match_operand:HI 1 "aligned_operand"))
2290               (const_string "imov")
2291             (and (match_test "TARGET_MOVX")
2292                  (eq_attr "alternative" "0,2"))
2293               (const_string "imovx")
2294            ]
2295            (const_string "imov")))
2296     (set (attr "mode")
2297       (cond [(eq_attr "type" "imovx")
2298                (const_string "SI")
2299              (and (eq_attr "alternative" "1,2")
2300                   (match_operand:HI 1 "aligned_operand"))
2301                (const_string "SI")
2302              (and (eq_attr "alternative" "0")
2303                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2304                        (not (match_test "TARGET_HIMODE_MATH"))))
2305                (const_string "SI")
2306             ]
2307             (const_string "HI")))])
2309 ;; Situation is quite tricky about when to choose full sized (SImode) move
2310 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2311 ;; partial register dependency machines (such as AMD Athlon), where QImode
2312 ;; moves issue extra dependency and for partial register stalls machines
2313 ;; that don't use QImode patterns (and QImode move cause stall on the next
2314 ;; instruction).
2316 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2317 ;; register stall machines with, where we use QImode instructions, since
2318 ;; partial register stall can be caused there.  Then we use movzx.
2319 (define_insn "*movqi_internal"
2320   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2321         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2322   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2324   switch (get_attr_type (insn))
2325     {
2326     case TYPE_IMOVX:
2327       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2328       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2329     default:
2330       if (get_attr_mode (insn) == MODE_SI)
2331         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2332       else
2333         return "mov{b}\t{%1, %0|%0, %1}";
2334     }
2336   [(set (attr "type")
2337      (cond [(and (eq_attr "alternative" "5")
2338                  (not (match_operand:QI 1 "aligned_operand")))
2339               (const_string "imovx")
2340             (match_test "optimize_function_for_size_p (cfun)")
2341               (const_string "imov")
2342             (and (eq_attr "alternative" "3")
2343                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2344                       (not (match_test "TARGET_QIMODE_MATH"))))
2345               (const_string "imov")
2346             (eq_attr "alternative" "3,5")
2347               (const_string "imovx")
2348             (and (match_test "TARGET_MOVX")
2349                  (eq_attr "alternative" "2"))
2350               (const_string "imovx")
2351            ]
2352            (const_string "imov")))
2353    (set (attr "mode")
2354       (cond [(eq_attr "alternative" "3,4,5")
2355                (const_string "SI")
2356              (eq_attr "alternative" "6")
2357                (const_string "QI")
2358              (eq_attr "type" "imovx")
2359                (const_string "SI")
2360              (and (eq_attr "type" "imov")
2361                   (and (eq_attr "alternative" "0,1")
2362                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2363                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2364                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2365                (const_string "SI")
2366              ;; Avoid partial register stalls when not using QImode arithmetic
2367              (and (eq_attr "type" "imov")
2368                   (and (eq_attr "alternative" "0,1")
2369                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2370                             (not (match_test "TARGET_QIMODE_MATH")))))
2371                (const_string "SI")
2372            ]
2373            (const_string "QI")))])
2375 ;; Stores and loads of ax to arbitrary constant address.
2376 ;; We fake an second form of instruction to force reload to load address
2377 ;; into register when rax is not available
2378 (define_insn "*movabs<mode>_1"
2379   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2380         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2381   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2382   "@
2383    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2384    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2385   [(set_attr "type" "imov")
2386    (set_attr "modrm" "0,*")
2387    (set_attr "length_address" "8,0")
2388    (set_attr "length_immediate" "0,*")
2389    (set_attr "memory" "store")
2390    (set_attr "mode" "<MODE>")])
2392 (define_insn "*movabs<mode>_2"
2393   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2394         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2395   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2396   "@
2397    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2398    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2399   [(set_attr "type" "imov")
2400    (set_attr "modrm" "0,*")
2401    (set_attr "length_address" "8,0")
2402    (set_attr "length_immediate" "0")
2403    (set_attr "memory" "load")
2404    (set_attr "mode" "<MODE>")])
2406 (define_insn "*swap<mode>"
2407   [(set (match_operand:SWI48 0 "register_operand" "+r")
2408         (match_operand:SWI48 1 "register_operand" "+r"))
2409    (set (match_dup 1)
2410         (match_dup 0))]
2411   ""
2412   "xchg{<imodesuffix>}\t%1, %0"
2413   [(set_attr "type" "imov")
2414    (set_attr "mode" "<MODE>")
2415    (set_attr "pent_pair" "np")
2416    (set_attr "athlon_decode" "vector")
2417    (set_attr "amdfam10_decode" "double")
2418    (set_attr "bdver1_decode" "double")])
2420 (define_insn "*swap<mode>_1"
2421   [(set (match_operand:SWI12 0 "register_operand" "+r")
2422         (match_operand:SWI12 1 "register_operand" "+r"))
2423    (set (match_dup 1)
2424         (match_dup 0))]
2425   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2426   "xchg{l}\t%k1, %k0"
2427   [(set_attr "type" "imov")
2428    (set_attr "mode" "SI")
2429    (set_attr "pent_pair" "np")
2430    (set_attr "athlon_decode" "vector")
2431    (set_attr "amdfam10_decode" "double")
2432    (set_attr "bdver1_decode" "double")])
2434 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2435 ;; is disabled for AMDFAM10
2436 (define_insn "*swap<mode>_2"
2437   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2438         (match_operand:SWI12 1 "register_operand" "+<r>"))
2439    (set (match_dup 1)
2440         (match_dup 0))]
2441   "TARGET_PARTIAL_REG_STALL"
2442   "xchg{<imodesuffix>}\t%1, %0"
2443   [(set_attr "type" "imov")
2444    (set_attr "mode" "<MODE>")
2445    (set_attr "pent_pair" "np")
2446    (set_attr "athlon_decode" "vector")])
2448 (define_expand "movstrict<mode>"
2449   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2450         (match_operand:SWI12 1 "general_operand"))]
2451   ""
2453   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2454     FAIL;
2455   if (GET_CODE (operands[0]) == SUBREG
2456       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2457     FAIL;
2458   /* Don't generate memory->memory moves, go through a register */
2459   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2460     operands[1] = force_reg (<MODE>mode, operands[1]);
2463 (define_insn "*movstrict<mode>_1"
2464   [(set (strict_low_part
2465           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2466         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2467   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2468    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2469   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2470   [(set_attr "type" "imov")
2471    (set_attr "mode" "<MODE>")])
2473 (define_insn "*movstrict<mode>_xor"
2474   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2475         (match_operand:SWI12 1 "const0_operand"))
2476    (clobber (reg:CC FLAGS_REG))]
2477   "reload_completed"
2478   "xor{<imodesuffix>}\t%0, %0"
2479   [(set_attr "type" "alu1")
2480    (set_attr "mode" "<MODE>")
2481    (set_attr "length_immediate" "0")])
2483 (define_insn "*mov<mode>_extv_1"
2484   [(set (match_operand:SWI24 0 "register_operand" "=R")
2485         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2486                             (const_int 8)
2487                             (const_int 8)))]
2488   ""
2489   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2490   [(set_attr "type" "imovx")
2491    (set_attr "mode" "SI")])
2493 (define_insn "*movqi_extv_1_rex64"
2494   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2495         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2496                          (const_int 8)
2497                          (const_int 8)))]
2498   "TARGET_64BIT"
2500   switch (get_attr_type (insn))
2501     {
2502     case TYPE_IMOVX:
2503       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2504     default:
2505       return "mov{b}\t{%h1, %0|%0, %h1}";
2506     }
2508   [(set (attr "type")
2509      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2510                         (match_test "TARGET_MOVX"))
2511         (const_string "imovx")
2512         (const_string "imov")))
2513    (set (attr "mode")
2514      (if_then_else (eq_attr "type" "imovx")
2515         (const_string "SI")
2516         (const_string "QI")))])
2518 (define_insn "*movqi_extv_1"
2519   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2520         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2521                          (const_int 8)
2522                          (const_int 8)))]
2523   "!TARGET_64BIT"
2525   switch (get_attr_type (insn))
2526     {
2527     case TYPE_IMOVX:
2528       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2529     default:
2530       return "mov{b}\t{%h1, %0|%0, %h1}";
2531     }
2533   [(set (attr "type")
2534      (if_then_else (and (match_operand:QI 0 "register_operand")
2535                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2536                              (match_test "TARGET_MOVX")))
2537         (const_string "imovx")
2538         (const_string "imov")))
2539    (set (attr "mode")
2540      (if_then_else (eq_attr "type" "imovx")
2541         (const_string "SI")
2542         (const_string "QI")))])
2544 (define_insn "*mov<mode>_extzv_1"
2545   [(set (match_operand:SWI48 0 "register_operand" "=R")
2546         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2547                             (const_int 8)
2548                             (const_int 8)))]
2549   ""
2550   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2551   [(set_attr "type" "imovx")
2552    (set_attr "mode" "SI")])
2554 (define_insn "*movqi_extzv_2_rex64"
2555   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2556         (subreg:QI
2557           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2558                            (const_int 8)
2559                            (const_int 8)) 0))]
2560   "TARGET_64BIT"
2562   switch (get_attr_type (insn))
2563     {
2564     case TYPE_IMOVX:
2565       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2566     default:
2567       return "mov{b}\t{%h1, %0|%0, %h1}";
2568     }
2570   [(set (attr "type")
2571      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2572                         (match_test "TARGET_MOVX"))
2573         (const_string "imovx")
2574         (const_string "imov")))
2575    (set (attr "mode")
2576      (if_then_else (eq_attr "type" "imovx")
2577         (const_string "SI")
2578         (const_string "QI")))])
2580 (define_insn "*movqi_extzv_2"
2581   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2582         (subreg:QI
2583           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2584                            (const_int 8)
2585                            (const_int 8)) 0))]
2586   "!TARGET_64BIT"
2588   switch (get_attr_type (insn))
2589     {
2590     case TYPE_IMOVX:
2591       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2592     default:
2593       return "mov{b}\t{%h1, %0|%0, %h1}";
2594     }
2596   [(set (attr "type")
2597      (if_then_else (and (match_operand:QI 0 "register_operand")
2598                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2599                              (match_test "TARGET_MOVX")))
2600         (const_string "imovx")
2601         (const_string "imov")))
2602    (set (attr "mode")
2603      (if_then_else (eq_attr "type" "imovx")
2604         (const_string "SI")
2605         (const_string "QI")))])
2607 (define_expand "mov<mode>_insv_1"
2608   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2609                             (const_int 8)
2610                             (const_int 8))
2611         (match_operand:SWI48 1 "nonmemory_operand"))])
2613 (define_insn "*mov<mode>_insv_1_rex64"
2614   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2615                              (const_int 8)
2616                              (const_int 8))
2617         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2618   "TARGET_64BIT"
2619   "mov{b}\t{%b1, %h0|%h0, %b1}"
2620   [(set_attr "type" "imov")
2621    (set_attr "mode" "QI")])
2623 (define_insn "*movsi_insv_1"
2624   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2625                          (const_int 8)
2626                          (const_int 8))
2627         (match_operand:SI 1 "general_operand" "Qmn"))]
2628   "!TARGET_64BIT"
2629   "mov{b}\t{%b1, %h0|%h0, %b1}"
2630   [(set_attr "type" "imov")
2631    (set_attr "mode" "QI")])
2633 (define_insn "*movqi_insv_2"
2634   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2635                          (const_int 8)
2636                          (const_int 8))
2637         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2638                      (const_int 8)))]
2639   ""
2640   "mov{b}\t{%h1, %h0|%h0, %h1}"
2641   [(set_attr "type" "imov")
2642    (set_attr "mode" "QI")])
2644 ;; Floating point push instructions.
2646 (define_insn "*pushtf"
2647   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2648         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2649   "TARGET_SSE2"
2651   /* This insn should be already split before reg-stack.  */
2652   gcc_unreachable ();
2654   [(set_attr "type" "multi")
2655    (set_attr "unit" "sse,*,*")
2656    (set_attr "mode" "TF,SI,SI")])
2658 ;; %%% Kill this when call knows how to work this out.
2659 (define_split
2660   [(set (match_operand:TF 0 "push_operand")
2661         (match_operand:TF 1 "sse_reg_operand"))]
2662   "TARGET_SSE2 && reload_completed"
2663   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2664    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2666 (define_insn "*pushxf"
2667   [(set (match_operand:XF 0 "push_operand" "=<,<")
2668         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2669   "optimize_function_for_speed_p (cfun)"
2671   /* This insn should be already split before reg-stack.  */
2672   gcc_unreachable ();
2674   [(set_attr "type" "multi")
2675    (set_attr "unit" "i387,*")
2676    (set_attr "mode" "XF,SI")])
2678 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2679 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2680 ;; Pushing using integer instructions is longer except for constants
2681 ;; and direct memory references (assuming that any given constant is pushed
2682 ;; only once, but this ought to be handled elsewhere).
2684 (define_insn "*pushxf_nointeger"
2685   [(set (match_operand:XF 0 "push_operand" "=<,<")
2686         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2687   "optimize_function_for_size_p (cfun)"
2689   /* This insn should be already split before reg-stack.  */
2690   gcc_unreachable ();
2692   [(set_attr "type" "multi")
2693    (set_attr "unit" "i387,*")
2694    (set_attr "mode" "XF,SI")])
2696 ;; %%% Kill this when call knows how to work this out.
2697 (define_split
2698   [(set (match_operand:XF 0 "push_operand")
2699         (match_operand:XF 1 "fp_register_operand"))]
2700   "reload_completed"
2701   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2702    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2703   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2705 (define_insn "*pushdf_rex64"
2706   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2707         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2708   "TARGET_64BIT"
2710   /* This insn should be already split before reg-stack.  */
2711   gcc_unreachable ();
2713   [(set_attr "type" "multi")
2714    (set_attr "unit" "i387,*,*")
2715    (set_attr "mode" "DF,DI,DF")])
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2719 ;; On the average, pushdf using integers can be still shorter.
2721 (define_insn "*pushdf"
2722   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2723         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2724   "!TARGET_64BIT"
2726   /* This insn should be already split before reg-stack.  */
2727   gcc_unreachable ();
2729   [(set_attr "isa" "*,*,sse2")
2730    (set_attr "type" "multi")
2731    (set_attr "unit" "i387,*,*")
2732    (set_attr "mode" "DF,DI,DF")])
2734 ;; %%% Kill this when call knows how to work this out.
2735 (define_split
2736   [(set (match_operand:DF 0 "push_operand")
2737         (match_operand:DF 1 "any_fp_register_operand"))]
2738   "reload_completed"
2739   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2740    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2742 (define_insn "*pushsf_rex64"
2743   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2744         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2745   "TARGET_64BIT"
2747   /* Anything else should be already split before reg-stack.  */
2748   gcc_assert (which_alternative == 1);
2749   return "push{q}\t%q1";
2751   [(set_attr "type" "multi,push,multi")
2752    (set_attr "unit" "i387,*,*")
2753    (set_attr "mode" "SF,DI,SF")])
2755 (define_insn "*pushsf"
2756   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2757         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2758   "!TARGET_64BIT"
2760   /* Anything else should be already split before reg-stack.  */
2761   gcc_assert (which_alternative == 1);
2762   return "push{l}\t%1";
2764   [(set_attr "type" "multi,push,multi")
2765    (set_attr "unit" "i387,*,*")
2766    (set_attr "mode" "SF,SI,SF")])
2768 ;; %%% Kill this when call knows how to work this out.
2769 (define_split
2770   [(set (match_operand:SF 0 "push_operand")
2771         (match_operand:SF 1 "any_fp_register_operand"))]
2772   "reload_completed"
2773   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2774    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2775   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2777 (define_split
2778   [(set (match_operand:SF 0 "push_operand")
2779         (match_operand:SF 1 "memory_operand"))]
2780   "reload_completed
2781    && (operands[2] = find_constant_src (insn))"
2782   [(set (match_dup 0) (match_dup 2))])
2784 (define_split
2785   [(set (match_operand 0 "push_operand")
2786         (match_operand 1 "general_operand"))]
2787   "reload_completed
2788    && (GET_MODE (operands[0]) == TFmode
2789        || GET_MODE (operands[0]) == XFmode
2790        || GET_MODE (operands[0]) == DFmode)
2791    && !ANY_FP_REG_P (operands[1])"
2792   [(const_int 0)]
2793   "ix86_split_long_move (operands); DONE;")
2795 ;; Floating point move instructions.
2797 (define_expand "movtf"
2798   [(set (match_operand:TF 0 "nonimmediate_operand")
2799         (match_operand:TF 1 "nonimmediate_operand"))]
2800   "TARGET_SSE2"
2802   ix86_expand_move (TFmode, operands);
2803   DONE;
2806 (define_expand "mov<mode>"
2807   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2808         (match_operand:X87MODEF 1 "general_operand"))]
2809   ""
2810   "ix86_expand_move (<MODE>mode, operands); DONE;")
2812 (define_insn "*movtf_internal"
2813   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2814         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,F*r"))]
2815   "TARGET_SSE2
2816    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2817    && (!can_create_pseudo_p ()
2818        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2819        || GET_CODE (operands[1]) != CONST_DOUBLE
2820        || (optimize_function_for_size_p (cfun)
2821            && standard_sse_constant_p (operands[1])
2822            && !memory_operand (operands[0], TFmode))
2823        || (!TARGET_MEMORY_MISMATCH_STALL
2824            && memory_operand (operands[0], TFmode)))"
2826   switch (which_alternative)
2827     {
2828     case 0:
2829     case 1:
2830       /* Handle misaligned load/store since we
2831          don't have movmisaligntf pattern. */
2832       if (misaligned_operand (operands[0], TFmode)
2833           || misaligned_operand (operands[1], TFmode))
2834         {
2835           if (get_attr_mode (insn) == MODE_V4SF)
2836             return "%vmovups\t{%1, %0|%0, %1}";
2837           else
2838             return "%vmovdqu\t{%1, %0|%0, %1}";
2839         }
2840       else
2841         {
2842           if (get_attr_mode (insn) == MODE_V4SF)
2843             return "%vmovaps\t{%1, %0|%0, %1}";
2844           else
2845             return "%vmovdqa\t{%1, %0|%0, %1}";
2846         }
2848     case 2:
2849       return standard_sse_constant_opcode (insn, operands[1]);
2851     case 3:
2852     case 4:
2853         return "#";
2855     default:
2856       gcc_unreachable ();
2857     }
2859   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2860    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2861    (set (attr "mode")
2862         (cond [(eq_attr "alternative" "0,2")
2863                  (if_then_else
2864                    (match_test "optimize_function_for_size_p (cfun)")
2865                    (const_string "V4SF")
2866                    (const_string "TI"))
2867                (eq_attr "alternative" "1")
2868                  (if_then_else
2869                    (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2870                         (match_test "optimize_function_for_size_p (cfun)"))
2871                    (const_string "V4SF")
2872                    (const_string "TI"))]
2873                (const_string "DI")))])
2875 ;; Possible store forwarding (partial memory) stall in alternative 4.
2876 (define_insn "*movxf_internal"
2877   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2878         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2879   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2880    && (!can_create_pseudo_p ()
2881        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2882        || GET_CODE (operands[1]) != CONST_DOUBLE
2883        || (optimize_function_for_size_p (cfun)
2884            && standard_80387_constant_p (operands[1]) > 0
2885            && !memory_operand (operands[0], XFmode))
2886        || (!TARGET_MEMORY_MISMATCH_STALL
2887            && memory_operand (operands[0], XFmode)))"
2889   switch (which_alternative)
2890     {
2891     case 0:
2892     case 1:
2893       return output_387_reg_move (insn, operands);
2895     case 2:
2896       return standard_80387_constant_opcode (operands[1]);
2898     case 3:
2899     case 4:
2900       return "#";
2902     default:
2903       gcc_unreachable ();
2904     }
2906   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2907    (set_attr "mode" "XF,XF,XF,SI,SI")])
2909 (define_insn "*movdf_internal_rex64"
2910   [(set (match_operand:DF 0 "nonimmediate_operand"
2911                 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2912         (match_operand:DF 1 "general_operand"
2913                 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2914   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2915    && (!can_create_pseudo_p ()
2916        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2917        || GET_CODE (operands[1]) != CONST_DOUBLE
2918        || (optimize_function_for_size_p (cfun)
2919            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2920                 && standard_80387_constant_p (operands[1]) > 0)
2921                || (TARGET_SSE2 && TARGET_SSE_MATH
2922                    && standard_sse_constant_p (operands[1]))))
2923        || memory_operand (operands[0], DFmode))"
2925   switch (which_alternative)
2926     {
2927     case 0:
2928     case 1:
2929       return output_387_reg_move (insn, operands);
2931     case 2:
2932       return standard_80387_constant_opcode (operands[1]);
2934     case 3:
2935     case 4:
2936       return "mov{q}\t{%1, %0|%0, %1}";
2938     case 5:
2939       return "movabs{q}\t{%1, %0|%0, %1}";
2941     case 6:
2942       return "#";
2944     case 7:
2945       return standard_sse_constant_opcode (insn, operands[1]);
2947     case 8:
2948     case 9:
2949     case 10:
2950       switch (get_attr_mode (insn))
2951         {
2952         case MODE_V2DF:
2953           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2954             return "%vmovapd\t{%1, %0|%0, %1}";
2955         case MODE_V4SF:
2956           return "%vmovaps\t{%1, %0|%0, %1}";
2958         case MODE_DI:
2959           return "%vmovq\t{%1, %0|%0, %1}";
2960         case MODE_DF:
2961           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2962             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2963           return "%vmovsd\t{%1, %0|%0, %1}";
2964         case MODE_V1DF:
2965           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2966         case MODE_V2SF:
2967           return "%vmovlps\t{%1, %d0|%d0, %1}";
2968         default:
2969           gcc_unreachable ();
2970         }
2972     case 11:
2973     case 12:
2974       /* Handle broken assemblers that require movd instead of movq.  */
2975       return "%vmovd\t{%1, %0|%0, %1}";
2977     default:
2978       gcc_unreachable();
2979     }
2981   [(set (attr "type")
2982         (cond [(eq_attr "alternative" "0,1,2")
2983                  (const_string "fmov")
2984                (eq_attr "alternative" "3,4,5")
2985                  (const_string "imov")
2986                (eq_attr "alternative" "6")
2987                  (const_string "multi")
2988                (eq_attr "alternative" "7")
2989                  (const_string "sselog1")
2990               ]
2991               (const_string "ssemov")))
2992    (set (attr "modrm")
2993      (if_then_else
2994        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2995          (const_string "0")
2996          (const_string "*")))
2997    (set (attr "length_immediate")
2998      (if_then_else
2999        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3000          (const_string "8")
3001          (const_string "*")))
3002    (set (attr "prefix")
3003      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3004        (const_string "orig")
3005        (const_string "maybe_vex")))
3006    (set (attr "prefix_data16")
3007      (if_then_else (eq_attr "mode" "V1DF")
3008        (const_string "1")
3009        (const_string "*")))
3010    (set (attr "mode")
3011         (cond [(eq_attr "alternative" "0,1,2")
3012                  (const_string "DF")
3013                (eq_attr "alternative" "3,4,5,6,11,12")
3014                  (const_string "DI")
3016                /* xorps is one byte shorter.  */
3017                (eq_attr "alternative" "7")
3018                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3019                           (const_string "V4SF")
3020                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3021                           (const_string "TI")
3022                        ]
3023                        (const_string "V2DF"))
3025                /* For architectures resolving dependencies on
3026                   whole SSE registers use APD move to break dependency
3027                   chains, otherwise use short move to avoid extra work.
3029                   movaps encodes one byte shorter.  */
3030                (eq_attr "alternative" "8")
3031                  (cond
3032                    [(match_test "optimize_function_for_size_p (cfun)")
3033                       (const_string "V4SF")
3034                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3035                       (const_string "V2DF")
3036                    ]
3037                    (const_string "DF"))
3038                /* For architectures resolving dependencies on register
3039                   parts we may avoid extra work to zero out upper part
3040                   of register.  */
3041                (eq_attr "alternative" "9")
3042                  (if_then_else
3043                    (match_test "TARGET_SSE_SPLIT_REGS")
3044                    (const_string "V1DF")
3045                    (const_string "DF"))
3046               ]
3047               (const_string "DF")))])
3049 ;; Possible store forwarding (partial memory) stall in alternative 4.
3050 (define_insn "*movdf_internal"
3051   [(set (match_operand:DF 0 "nonimmediate_operand"
3052                 "=f,m,f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3053         (match_operand:DF 1 "general_operand"
3054                 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3055   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3056    && (!can_create_pseudo_p ()
3057        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3058        || GET_CODE (operands[1]) != CONST_DOUBLE
3059        || (optimize_function_for_size_p (cfun)
3060            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3061                 && standard_80387_constant_p (operands[1]) > 0)
3062                || (TARGET_SSE2 && TARGET_SSE_MATH
3063                    && standard_sse_constant_p (operands[1])))
3064            && !memory_operand (operands[0], DFmode))
3065        || (!TARGET_MEMORY_MISMATCH_STALL
3066            && memory_operand (operands[0], DFmode)))"
3068   switch (which_alternative)
3069     {
3070     case 0:
3071     case 1:
3072       return output_387_reg_move (insn, operands);
3074     case 2:
3075       return standard_80387_constant_opcode (operands[1]);
3077     case 3:
3078     case 4:
3079       return "#";
3081     case 5:
3082     case 9:
3083       return standard_sse_constant_opcode (insn, operands[1]);
3085     case 6:
3086     case 7:
3087     case 8:
3088     case 10:
3089     case 11:
3090     case 12:
3091       switch (get_attr_mode (insn))
3092         {
3093         case MODE_V2DF:
3094           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3095             return "%vmovapd\t{%1, %0|%0, %1}";
3096         case MODE_V4SF:
3097           return "%vmovaps\t{%1, %0|%0, %1}";
3099         case MODE_DI:
3100           return "%vmovq\t{%1, %0|%0, %1}";
3101         case MODE_DF:
3102           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3103             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3104           return "%vmovsd\t{%1, %0|%0, %1}";
3105         case MODE_V1DF:
3106           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3107         case MODE_V2SF:
3108           return "%vmovlps\t{%1, %d0|%d0, %1}";
3109         default:
3110           gcc_unreachable ();
3111         }
3113     default:
3114       gcc_unreachable ();
3115     }
3117   [(set (attr "isa")
3118      (if_then_else (eq_attr "alternative" "5,6,7,8")
3119        (const_string "sse2")
3120        (const_string "*")))
3121    (set (attr "type")
3122         (cond [(eq_attr "alternative" "0,1,2")
3123                  (const_string "fmov")
3124                (eq_attr "alternative" "3,4")
3125                  (const_string "multi")
3126                (eq_attr "alternative" "5,9")
3127                  (const_string "sselog1")
3128               ]
3129               (const_string "ssemov")))
3130    (set (attr "prefix")
3131      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3132        (const_string "orig")
3133        (const_string "maybe_vex")))
3134    (set (attr "prefix_data16")
3135      (if_then_else (eq_attr "mode" "V1DF")
3136        (const_string "1")
3137        (const_string "*")))
3138    (set (attr "mode")
3139         (cond [(eq_attr "alternative" "0,1,2")
3140                  (const_string "DF")
3141                (eq_attr "alternative" "3,4")
3142                  (const_string "SI")
3144                /* For SSE1, we have many fewer alternatives.  */
3145                (not (match_test "TARGET_SSE2"))
3146                  (if_then_else
3147                    (eq_attr "alternative" "5,6,9,10")
3148                    (const_string "V4SF")
3149                    (const_string "V2SF"))
3151                /* xorps is one byte shorter.  */
3152                (eq_attr "alternative" "5,9")
3153                  (cond [(match_test "optimize_function_for_size_p (cfun)")
3154                           (const_string "V4SF")
3155                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3156                           (const_string "TI")
3157                        ]
3158                        (const_string "V2DF"))
3160                /* For architectures resolving dependencies on
3161                   whole SSE registers use APD move to break dependency
3162                   chains, otherwise use short move to avoid extra work.
3164                   movaps encodes one byte shorter.  */
3165                (eq_attr "alternative" "6,10")
3166                  (cond
3167                    [(match_test "optimize_function_for_size_p (cfun)")
3168                       (const_string "V4SF")
3169                     (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3170                       (const_string "V2DF")
3171                    ]
3172                    (const_string "DF"))
3173                /* For architectures resolving dependencies on register
3174                   parts we may avoid extra work to zero out upper part
3175                   of register.  */
3176                (eq_attr "alternative" "7,11")
3177                  (if_then_else
3178                    (match_test "TARGET_SSE_SPLIT_REGS")
3179                    (const_string "V1DF")
3180                    (const_string "DF"))
3181               ]
3182               (const_string "DF")))])
3184 (define_insn "*movsf_internal"
3185   [(set (match_operand:SF 0 "nonimmediate_operand"
3186           "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3187         (match_operand:SF 1 "general_operand"
3188           "fm,f,G,rmF,Fr,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3189   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3190    && (!can_create_pseudo_p ()
3191        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3192        || GET_CODE (operands[1]) != CONST_DOUBLE
3193        || (optimize_function_for_size_p (cfun)
3194            && ((!TARGET_SSE_MATH
3195                 && standard_80387_constant_p (operands[1]) > 0)
3196                || (TARGET_SSE_MATH
3197                    && standard_sse_constant_p (operands[1]))))
3198        || memory_operand (operands[0], SFmode))"
3200   switch (which_alternative)
3201     {
3202     case 0:
3203     case 1:
3204       return output_387_reg_move (insn, operands);
3206     case 2:
3207       return standard_80387_constant_opcode (operands[1]);
3209     case 3:
3210     case 4:
3211       return "mov{l}\t{%1, %0|%0, %1}";
3213     case 5:
3214       return standard_sse_constant_opcode (insn, operands[1]);
3216     case 6:
3217       if (get_attr_mode (insn) == MODE_V4SF)
3218         return "%vmovaps\t{%1, %0|%0, %1}";
3219       if (TARGET_AVX)
3220         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3222     case 7:
3223     case 8:
3224       return "%vmovss\t{%1, %0|%0, %1}";
3226     case 9:
3227     case 10:
3228     case 14:
3229     case 15:
3230       return "movd\t{%1, %0|%0, %1}";
3232     case 11:
3233       return "movq\t{%1, %0|%0, %1}";
3235     case 12:
3236     case 13:
3237       return "%vmovd\t{%1, %0|%0, %1}";
3239     default:
3240       gcc_unreachable ();
3241     }
3243   [(set (attr "type")
3244         (cond [(eq_attr "alternative" "0,1,2")
3245                  (const_string "fmov")
3246                (eq_attr "alternative" "3,4")
3247                  (const_string "multi")
3248                (eq_attr "alternative" "5")
3249                  (const_string "sselog1")
3250                (eq_attr "alternative" "9,10,11,14,15")
3251                  (const_string "mmxmov")
3252               ]
3253               (const_string "ssemov")))
3254    (set (attr "prefix")
3255      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3256        (const_string "maybe_vex")
3257        (const_string "orig")))
3258    (set (attr "mode")
3259         (cond [(eq_attr "alternative" "3,4,9,10")
3260                  (const_string "SI")
3261                (eq_attr "alternative" "5")
3262                  (if_then_else
3263                    (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3264                              (match_test "TARGET_SSE2"))
3265                         (not (match_test "optimize_function_for_size_p (cfun)")))
3266                    (const_string "TI")
3267                    (const_string "V4SF"))
3268                /* For architectures resolving dependencies on
3269                   whole SSE registers use APS move to break dependency
3270                   chains, otherwise use short move to avoid extra work.
3272                   Do the same for architectures resolving dependencies on
3273                   the parts.  While in DF mode it is better to always handle
3274                   just register parts, the SF mode is different due to lack
3275                   of instructions to load just part of the register.  It is
3276                   better to maintain the whole registers in single format
3277                   to avoid problems on using packed logical operations.  */
3278                (eq_attr "alternative" "6")
3279                  (if_then_else
3280                    (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3281                         (match_test "TARGET_SSE_SPLIT_REGS"))
3282                    (const_string "V4SF")
3283                    (const_string "SF"))
3284                (eq_attr "alternative" "11")
3285                  (const_string "DI")]
3286                (const_string "SF")))])
3288 (define_split
3289   [(set (match_operand 0 "any_fp_register_operand")
3290         (match_operand 1 "memory_operand"))]
3291   "reload_completed
3292    && (GET_MODE (operands[0]) == TFmode
3293        || GET_MODE (operands[0]) == XFmode
3294        || GET_MODE (operands[0]) == DFmode
3295        || GET_MODE (operands[0]) == SFmode)
3296    && (operands[2] = find_constant_src (insn))"
3297   [(set (match_dup 0) (match_dup 2))]
3299   rtx c = operands[2];
3300   int r = REGNO (operands[0]);
3302   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3303       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3304     FAIL;
3307 (define_split
3308   [(set (match_operand 0 "any_fp_register_operand")
3309         (float_extend (match_operand 1 "memory_operand")))]
3310   "reload_completed
3311    && (GET_MODE (operands[0]) == TFmode
3312        || GET_MODE (operands[0]) == XFmode
3313        || GET_MODE (operands[0]) == DFmode)
3314    && (operands[2] = find_constant_src (insn))"
3315   [(set (match_dup 0) (match_dup 2))]
3317   rtx c = operands[2];
3318   int r = REGNO (operands[0]);
3320   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3321       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3322     FAIL;
3325 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3326 (define_split
3327   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3328         (match_operand:X87MODEF 1 "immediate_operand"))]
3329   "reload_completed
3330    && (standard_80387_constant_p (operands[1]) == 8
3331        || standard_80387_constant_p (operands[1]) == 9)"
3332   [(set (match_dup 0)(match_dup 1))
3333    (set (match_dup 0)
3334         (neg:X87MODEF (match_dup 0)))]
3336   REAL_VALUE_TYPE r;
3338   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3339   if (real_isnegzero (&r))
3340     operands[1] = CONST0_RTX (<MODE>mode);
3341   else
3342     operands[1] = CONST1_RTX (<MODE>mode);
3345 (define_split
3346   [(set (match_operand 0 "nonimmediate_operand")
3347         (match_operand 1 "general_operand"))]
3348   "reload_completed
3349    && (GET_MODE (operands[0]) == TFmode
3350        || GET_MODE (operands[0]) == XFmode
3351        || GET_MODE (operands[0]) == DFmode)
3352    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3353   [(const_int 0)]
3354   "ix86_split_long_move (operands); DONE;")
3356 (define_insn "swapxf"
3357   [(set (match_operand:XF 0 "register_operand" "+f")
3358         (match_operand:XF 1 "register_operand" "+f"))
3359    (set (match_dup 1)
3360         (match_dup 0))]
3361   "TARGET_80387"
3363   if (STACK_TOP_P (operands[0]))
3364     return "fxch\t%1";
3365   else
3366     return "fxch\t%0";
3368   [(set_attr "type" "fxch")
3369    (set_attr "mode" "XF")])
3371 (define_insn "*swap<mode>"
3372   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3373         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3374    (set (match_dup 1)
3375         (match_dup 0))]
3376   "TARGET_80387 || reload_completed"
3378   if (STACK_TOP_P (operands[0]))
3379     return "fxch\t%1";
3380   else
3381     return "fxch\t%0";
3383   [(set_attr "type" "fxch")
3384    (set_attr "mode" "<MODE>")])
3386 ;; Zero extension instructions
3388 (define_expand "zero_extendsidi2"
3389   [(set (match_operand:DI 0 "nonimmediate_operand")
3390         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3392 (define_insn "*zero_extendsidi2_rex64"
3393   [(set (match_operand:DI 0 "nonimmediate_operand"
3394                         "=r ,o,?*Ym,?*y,?*Yi,!*x")
3395         (zero_extend:DI
3396          (match_operand:SI 1 "x86_64_zext_general_operand"
3397                         "rmZ,0,r   ,m  ,r   ,m*x")))]
3398   "TARGET_64BIT"
3399   "@
3400    mov{l}\t{%1, %k0|%k0, %1}
3401    #
3402    movd\t{%1, %0|%0, %1}
3403    movd\t{%1, %0|%0, %1}
3404    %vmovd\t{%1, %0|%0, %1}
3405    %vmovd\t{%1, %0|%0, %1}"
3406   [(set_attr "isa" "*,*,*,*,*,sse2")
3407    (set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3408    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3409    (set_attr "prefix_0f" "0,*,*,*,*,*")
3410    (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3412 (define_insn "*zero_extendsidi2"
3413   [(set (match_operand:DI 0 "nonimmediate_operand"
3414                         "=ro,?r,?o,?*Ym,?*y,?*Yi,!*x")
3415         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3416                         "0  ,rm,r ,r   ,m  ,r   ,m*x")))]
3417   "!TARGET_64BIT"
3418   "@
3419    #
3420    #
3421    #
3422    movd\t{%1, %0|%0, %1}
3423    movd\t{%1, %0|%0, %1}
3424    %vmovd\t{%1, %0|%0, %1}
3425    %vmovd\t{%1, %0|%0, %1}"
3426   [(set_attr "isa" "*,*,*,*,*,*,sse2")
3427    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3428    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3429    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3431 (define_split
3432   [(set (match_operand:DI 0 "memory_operand")
3433         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3434   "reload_completed"
3435   [(set (match_dup 4) (const_int 0))]
3436   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3438 (define_split
3439   [(set (match_operand:DI 0 "register_operand")
3440         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3441   "!TARGET_64BIT && reload_completed
3442    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3443    && true_regnum (operands[0]) == true_regnum (operands[1])"
3444   [(set (match_dup 4) (const_int 0))]
3445   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3447 (define_split
3448   [(set (match_operand:DI 0 "nonimmediate_operand")
3449         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3450   "!TARGET_64BIT && reload_completed
3451    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3452    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3453   [(set (match_dup 3) (match_dup 1))
3454    (set (match_dup 4) (const_int 0))]
3455   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3457 (define_insn "zero_extend<mode>di2"
3458   [(set (match_operand:DI 0 "register_operand" "=r")
3459         (zero_extend:DI
3460          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3461   "TARGET_64BIT"
3462   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3463   [(set_attr "type" "imovx")
3464    (set_attr "mode" "SI")])
3466 (define_expand "zero_extend<mode>si2"
3467   [(set (match_operand:SI 0 "register_operand")
3468         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3469   ""
3471   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3472     {
3473       operands[1] = force_reg (<MODE>mode, operands[1]);
3474       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3475       DONE;
3476     }
3479 (define_insn_and_split "zero_extend<mode>si2_and"
3480   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3481         (zero_extend:SI
3482           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3483    (clobber (reg:CC FLAGS_REG))]
3484   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3485   "#"
3486   "&& reload_completed"
3487   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3488               (clobber (reg:CC FLAGS_REG))])]
3490   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3491     {
3492       ix86_expand_clear (operands[0]);
3494       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3495       emit_insn (gen_movstrict<mode>
3496                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3497       DONE;
3498     }
3500   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3502   [(set_attr "type" "alu1")
3503    (set_attr "mode" "SI")])
3505 (define_insn "*zero_extend<mode>si2"
3506   [(set (match_operand:SI 0 "register_operand" "=r")
3507         (zero_extend:SI
3508           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3509   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3510   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3511   [(set_attr "type" "imovx")
3512    (set_attr "mode" "SI")])
3514 (define_expand "zero_extendqihi2"
3515   [(set (match_operand:HI 0 "register_operand")
3516         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3517   ""
3519   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3520     {
3521       operands[1] = force_reg (QImode, operands[1]);
3522       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3523       DONE;
3524     }
3527 (define_insn_and_split "zero_extendqihi2_and"
3528   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3529         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3530    (clobber (reg:CC FLAGS_REG))]
3531   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3532   "#"
3533   "&& reload_completed"
3534   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3535               (clobber (reg:CC FLAGS_REG))])]
3537   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3538     {
3539       ix86_expand_clear (operands[0]);
3541       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3542       emit_insn (gen_movstrictqi
3543                   (gen_lowpart (QImode, operands[0]), operands[1]));
3544       DONE;
3545     }
3547   operands[0] = gen_lowpart (SImode, operands[0]);
3549   [(set_attr "type" "alu1")
3550    (set_attr "mode" "SI")])
3552 ; zero extend to SImode to avoid partial register stalls
3553 (define_insn "*zero_extendqihi2"
3554   [(set (match_operand:HI 0 "register_operand" "=r")
3555         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3556   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3557   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3558   [(set_attr "type" "imovx")
3559    (set_attr "mode" "SI")])
3561 ;; Sign extension instructions
3563 (define_expand "extendsidi2"
3564   [(set (match_operand:DI 0 "register_operand")
3565         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3566   ""
3568   if (!TARGET_64BIT)
3569     {
3570       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3571       DONE;
3572     }
3575 (define_insn "*extendsidi2_rex64"
3576   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3577         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3578   "TARGET_64BIT"
3579   "@
3580    {cltq|cdqe}
3581    movs{lq|x}\t{%1, %0|%0, %1}"
3582   [(set_attr "type" "imovx")
3583    (set_attr "mode" "DI")
3584    (set_attr "prefix_0f" "0")
3585    (set_attr "modrm" "0,1")])
3587 (define_insn "extendsidi2_1"
3588   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3589         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3590    (clobber (reg:CC FLAGS_REG))
3591    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3592   "!TARGET_64BIT"
3593   "#")
3595 ;; Extend to memory case when source register does die.
3596 (define_split
3597   [(set (match_operand:DI 0 "memory_operand")
3598         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3599    (clobber (reg:CC FLAGS_REG))
3600    (clobber (match_operand:SI 2 "register_operand"))]
3601   "(reload_completed
3602     && dead_or_set_p (insn, operands[1])
3603     && !reg_mentioned_p (operands[1], operands[0]))"
3604   [(set (match_dup 3) (match_dup 1))
3605    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3606               (clobber (reg:CC FLAGS_REG))])
3607    (set (match_dup 4) (match_dup 1))]
3608   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3610 ;; Extend to memory case when source register does not die.
3611 (define_split
3612   [(set (match_operand:DI 0 "memory_operand")
3613         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3614    (clobber (reg:CC FLAGS_REG))
3615    (clobber (match_operand:SI 2 "register_operand"))]
3616   "reload_completed"
3617   [(const_int 0)]
3619   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3621   emit_move_insn (operands[3], operands[1]);
3623   /* Generate a cltd if possible and doing so it profitable.  */
3624   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3625       && true_regnum (operands[1]) == AX_REG
3626       && true_regnum (operands[2]) == DX_REG)
3627     {
3628       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3629     }
3630   else
3631     {
3632       emit_move_insn (operands[2], operands[1]);
3633       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3634     }
3635   emit_move_insn (operands[4], operands[2]);
3636   DONE;
3639 ;; Extend to register case.  Optimize case where source and destination
3640 ;; registers match and cases where we can use cltd.
3641 (define_split
3642   [(set (match_operand:DI 0 "register_operand")
3643         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3644    (clobber (reg:CC FLAGS_REG))
3645    (clobber (match_scratch:SI 2))]
3646   "reload_completed"
3647   [(const_int 0)]
3649   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3651   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3652     emit_move_insn (operands[3], operands[1]);
3654   /* Generate a cltd if possible and doing so it profitable.  */
3655   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3656       && true_regnum (operands[3]) == AX_REG
3657       && true_regnum (operands[4]) == DX_REG)
3658     {
3659       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3660       DONE;
3661     }
3663   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3664     emit_move_insn (operands[4], operands[1]);
3666   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3667   DONE;
3670 (define_insn "extend<mode>di2"
3671   [(set (match_operand:DI 0 "register_operand" "=r")
3672         (sign_extend:DI
3673          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3674   "TARGET_64BIT"
3675   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3676   [(set_attr "type" "imovx")
3677    (set_attr "mode" "DI")])
3679 (define_insn "extendhisi2"
3680   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3681         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3682   ""
3684   switch (get_attr_prefix_0f (insn))
3685     {
3686     case 0:
3687       return "{cwtl|cwde}";
3688     default:
3689       return "movs{wl|x}\t{%1, %0|%0, %1}";
3690     }
3692   [(set_attr "type" "imovx")
3693    (set_attr "mode" "SI")
3694    (set (attr "prefix_0f")
3695      ;; movsx is short decodable while cwtl is vector decoded.
3696      (if_then_else (and (eq_attr "cpu" "!k6")
3697                         (eq_attr "alternative" "0"))
3698         (const_string "0")
3699         (const_string "1")))
3700    (set (attr "modrm")
3701      (if_then_else (eq_attr "prefix_0f" "0")
3702         (const_string "0")
3703         (const_string "1")))])
3705 (define_insn "*extendhisi2_zext"
3706   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3707         (zero_extend:DI
3708          (sign_extend:SI
3709           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3710   "TARGET_64BIT"
3712   switch (get_attr_prefix_0f (insn))
3713     {
3714     case 0:
3715       return "{cwtl|cwde}";
3716     default:
3717       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3718     }
3720   [(set_attr "type" "imovx")
3721    (set_attr "mode" "SI")
3722    (set (attr "prefix_0f")
3723      ;; movsx is short decodable while cwtl is vector decoded.
3724      (if_then_else (and (eq_attr "cpu" "!k6")
3725                         (eq_attr "alternative" "0"))
3726         (const_string "0")
3727         (const_string "1")))
3728    (set (attr "modrm")
3729      (if_then_else (eq_attr "prefix_0f" "0")
3730         (const_string "0")
3731         (const_string "1")))])
3733 (define_insn "extendqisi2"
3734   [(set (match_operand:SI 0 "register_operand" "=r")
3735         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3736   ""
3737   "movs{bl|x}\t{%1, %0|%0, %1}"
3738    [(set_attr "type" "imovx")
3739     (set_attr "mode" "SI")])
3741 (define_insn "*extendqisi2_zext"
3742   [(set (match_operand:DI 0 "register_operand" "=r")
3743         (zero_extend:DI
3744           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3745   "TARGET_64BIT"
3746   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3747    [(set_attr "type" "imovx")
3748     (set_attr "mode" "SI")])
3750 (define_insn "extendqihi2"
3751   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3752         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3753   ""
3755   switch (get_attr_prefix_0f (insn))
3756     {
3757     case 0:
3758       return "{cbtw|cbw}";
3759     default:
3760       return "movs{bw|x}\t{%1, %0|%0, %1}";
3761     }
3763   [(set_attr "type" "imovx")
3764    (set_attr "mode" "HI")
3765    (set (attr "prefix_0f")
3766      ;; movsx is short decodable while cwtl is vector decoded.
3767      (if_then_else (and (eq_attr "cpu" "!k6")
3768                         (eq_attr "alternative" "0"))
3769         (const_string "0")
3770         (const_string "1")))
3771    (set (attr "modrm")
3772      (if_then_else (eq_attr "prefix_0f" "0")
3773         (const_string "0")
3774         (const_string "1")))])
3776 ;; Conversions between float and double.
3778 ;; These are all no-ops in the model used for the 80387.
3779 ;; So just emit moves.
3781 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3782 (define_split
3783   [(set (match_operand:DF 0 "push_operand")
3784         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3785   "reload_completed"
3786   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3787    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3789 (define_split
3790   [(set (match_operand:XF 0 "push_operand")
3791         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3792   "reload_completed"
3793   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3794    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3795   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3797 (define_expand "extendsfdf2"
3798   [(set (match_operand:DF 0 "nonimmediate_operand")
3799         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3800   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3802   /* ??? Needed for compress_float_constant since all fp constants
3803      are TARGET_LEGITIMATE_CONSTANT_P.  */
3804   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3805     {
3806       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3807           && standard_80387_constant_p (operands[1]) > 0)
3808         {
3809           operands[1] = simplify_const_unary_operation
3810             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3811           emit_move_insn_1 (operands[0], operands[1]);
3812           DONE;
3813         }
3814       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3815     }
3818 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3819    cvtss2sd:
3820       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3821       cvtps2pd xmm2,xmm1
3822    We do the conversion post reload to avoid producing of 128bit spills
3823    that might lead to ICE on 32bit target.  The sequence unlikely combine
3824    anyway.  */
3825 (define_split
3826   [(set (match_operand:DF 0 "register_operand")
3827         (float_extend:DF
3828           (match_operand:SF 1 "nonimmediate_operand")))]
3829   "TARGET_USE_VECTOR_FP_CONVERTS
3830    && optimize_insn_for_speed_p ()
3831    && reload_completed && SSE_REG_P (operands[0])"
3832    [(set (match_dup 2)
3833          (float_extend:V2DF
3834            (vec_select:V2SF
3835              (match_dup 3)
3836              (parallel [(const_int 0) (const_int 1)]))))]
3838   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3839   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3840   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3841      Try to avoid move when unpacking can be done in source.  */
3842   if (REG_P (operands[1]))
3843     {
3844       /* If it is unsafe to overwrite upper half of source, we need
3845          to move to destination and unpack there.  */
3846       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3847            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3848           && true_regnum (operands[0]) != true_regnum (operands[1]))
3849         {
3850           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3851           emit_move_insn (tmp, operands[1]);
3852         }
3853       else
3854         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3855       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3856                                              operands[3]));
3857     }
3858   else
3859     emit_insn (gen_vec_setv4sf_0 (operands[3],
3860                                   CONST0_RTX (V4SFmode), operands[1]));
3863 (define_insn "*extendsfdf2_mixed"
3864   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3865         (float_extend:DF
3866           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3867   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3869   switch (which_alternative)
3870     {
3871     case 0:
3872     case 1:
3873       return output_387_reg_move (insn, operands);
3875     case 2:
3876       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3878     default:
3879       gcc_unreachable ();
3880     }
3882   [(set_attr "type" "fmov,fmov,ssecvt")
3883    (set_attr "prefix" "orig,orig,maybe_vex")
3884    (set_attr "mode" "SF,XF,DF")])
3886 (define_insn "*extendsfdf2_sse"
3887   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3888         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3889   "TARGET_SSE2 && TARGET_SSE_MATH"
3890   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3891   [(set_attr "type" "ssecvt")
3892    (set_attr "prefix" "maybe_vex")
3893    (set_attr "mode" "DF")])
3895 (define_insn "*extendsfdf2_i387"
3896   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3897         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3898   "TARGET_80387"
3899   "* return output_387_reg_move (insn, operands);"
3900   [(set_attr "type" "fmov")
3901    (set_attr "mode" "SF,XF")])
3903 (define_expand "extend<mode>xf2"
3904   [(set (match_operand:XF 0 "nonimmediate_operand")
3905         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3906   "TARGET_80387"
3908   /* ??? Needed for compress_float_constant since all fp constants
3909      are TARGET_LEGITIMATE_CONSTANT_P.  */
3910   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3911     {
3912       if (standard_80387_constant_p (operands[1]) > 0)
3913         {
3914           operands[1] = simplify_const_unary_operation
3915             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3916           emit_move_insn_1 (operands[0], operands[1]);
3917           DONE;
3918         }
3919       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3920     }
3923 (define_insn "*extend<mode>xf2_i387"
3924   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3925         (float_extend:XF
3926           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3927   "TARGET_80387"
3928   "* return output_387_reg_move (insn, operands);"
3929   [(set_attr "type" "fmov")
3930    (set_attr "mode" "<MODE>,XF")])
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case.  Otherwise this is just like a simple move
3935 ;; insn.  So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3938 ;; Conversion from DFmode to SFmode.
3940 (define_expand "truncdfsf2"
3941   [(set (match_operand:SF 0 "nonimmediate_operand")
3942         (float_truncate:SF
3943           (match_operand:DF 1 "nonimmediate_operand")))]
3944   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3946   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3947     ;
3948   else if (flag_unsafe_math_optimizations)
3949     ;
3950   else
3951     {
3952       enum ix86_stack_slot slot = (virtuals_instantiated
3953                                    ? SLOT_TEMP
3954                                    : SLOT_VIRTUAL);
3955       rtx temp = assign_386_stack_local (SFmode, slot);
3956       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3957       DONE;
3958     }
3961 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3962    cvtsd2ss:
3963       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3964       cvtpd2ps xmm2,xmm1
3965    We do the conversion post reload to avoid producing of 128bit spills
3966    that might lead to ICE on 32bit target.  The sequence unlikely combine
3967    anyway.  */
3968 (define_split
3969   [(set (match_operand:SF 0 "register_operand")
3970         (float_truncate:SF
3971           (match_operand:DF 1 "nonimmediate_operand")))]
3972   "TARGET_USE_VECTOR_FP_CONVERTS
3973    && optimize_insn_for_speed_p ()
3974    && reload_completed && SSE_REG_P (operands[0])"
3975    [(set (match_dup 2)
3976          (vec_concat:V4SF
3977            (float_truncate:V2SF
3978              (match_dup 4))
3979            (match_dup 3)))]
3981   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3982   operands[3] = CONST0_RTX (V2SFmode);
3983   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3984   /* Use movsd for loading from memory, unpcklpd for registers.
3985      Try to avoid move when unpacking can be done in source, or SSE3
3986      movddup is available.  */
3987   if (REG_P (operands[1]))
3988     {
3989       if (!TARGET_SSE3
3990           && true_regnum (operands[0]) != true_regnum (operands[1])
3991           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3992               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3993         {
3994           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3995           emit_move_insn (tmp, operands[1]);
3996           operands[1] = tmp;
3997         }
3998       else if (!TARGET_SSE3)
3999         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4000       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4001     }
4002   else
4003     emit_insn (gen_sse2_loadlpd (operands[4],
4004                                  CONST0_RTX (V2DFmode), operands[1]));
4007 (define_expand "truncdfsf2_with_temp"
4008   [(parallel [(set (match_operand:SF 0)
4009                    (float_truncate:SF (match_operand:DF 1)))
4010               (clobber (match_operand:SF 2))])])
4012 (define_insn "*truncdfsf_fast_mixed"
4013   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4014         (float_truncate:SF
4015           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4016   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4018   switch (which_alternative)
4019     {
4020     case 0:
4021       return output_387_reg_move (insn, operands);
4022     case 1:
4023       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4024     default:
4025       gcc_unreachable ();
4026     }
4028   [(set_attr "type" "fmov,ssecvt")
4029    (set_attr "prefix" "orig,maybe_vex")
4030    (set_attr "mode" "SF")])
4032 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4033 ;; because nothing we do here is unsafe.
4034 (define_insn "*truncdfsf_fast_sse"
4035   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4036         (float_truncate:SF
4037           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4038   "TARGET_SSE2 && TARGET_SSE_MATH"
4039   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4040   [(set_attr "type" "ssecvt")
4041    (set_attr "prefix" "maybe_vex")
4042    (set_attr "mode" "SF")])
4044 (define_insn "*truncdfsf_fast_i387"
4045   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4046         (float_truncate:SF
4047           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4048   "TARGET_80387 && flag_unsafe_math_optimizations"
4049   "* return output_387_reg_move (insn, operands);"
4050   [(set_attr "type" "fmov")
4051    (set_attr "mode" "SF")])
4053 (define_insn "*truncdfsf_mixed"
4054   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4055         (float_truncate:SF
4056           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4057    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4058   "TARGET_MIX_SSE_I387"
4060   switch (which_alternative)
4061     {
4062     case 0:
4063       return output_387_reg_move (insn, operands);
4064     case 1:
4065       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4067     default:
4068       return "#";
4069     }
4071   [(set_attr "isa" "*,sse2,*,*,*")
4072    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4073    (set_attr "unit" "*,*,i387,i387,i387")
4074    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4075    (set_attr "mode" "SF")])
4077 (define_insn "*truncdfsf_i387"
4078   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4079         (float_truncate:SF
4080           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4081    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4082   "TARGET_80387"
4084   switch (which_alternative)
4085     {
4086     case 0:
4087       return output_387_reg_move (insn, operands);
4089     default:
4090       return "#";
4091     }
4093   [(set_attr "type" "fmov,multi,multi,multi")
4094    (set_attr "unit" "*,i387,i387,i387")
4095    (set_attr "mode" "SF")])
4097 (define_insn "*truncdfsf2_i387_1"
4098   [(set (match_operand:SF 0 "memory_operand" "=m")
4099         (float_truncate:SF
4100           (match_operand:DF 1 "register_operand" "f")))]
4101   "TARGET_80387
4102    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4103    && !TARGET_MIX_SSE_I387"
4104   "* return output_387_reg_move (insn, operands);"
4105   [(set_attr "type" "fmov")
4106    (set_attr "mode" "SF")])
4108 (define_split
4109   [(set (match_operand:SF 0 "register_operand")
4110         (float_truncate:SF
4111          (match_operand:DF 1 "fp_register_operand")))
4112    (clobber (match_operand 2))]
4113   "reload_completed"
4114   [(set (match_dup 2) (match_dup 1))
4115    (set (match_dup 0) (match_dup 2))]
4116   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4118 ;; Conversion from XFmode to {SF,DF}mode
4120 (define_expand "truncxf<mode>2"
4121   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4122                    (float_truncate:MODEF
4123                      (match_operand:XF 1 "register_operand")))
4124               (clobber (match_dup 2))])]
4125   "TARGET_80387"
4127   if (flag_unsafe_math_optimizations)
4128     {
4129       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4130       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4131       if (reg != operands[0])
4132         emit_move_insn (operands[0], reg);
4133       DONE;
4134     }
4135   else
4136     {
4137       enum ix86_stack_slot slot = (virtuals_instantiated
4138                                    ? SLOT_TEMP
4139                                    : SLOT_VIRTUAL);
4140       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4141     }
4144 (define_insn "*truncxfsf2_mixed"
4145   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4146         (float_truncate:SF
4147           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4148    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4149   "TARGET_80387"
4151   gcc_assert (!which_alternative);
4152   return output_387_reg_move (insn, operands);
4154   [(set_attr "type" "fmov,multi,multi,multi")
4155    (set_attr "unit" "*,i387,i387,i387")
4156    (set_attr "mode" "SF")])
4158 (define_insn "*truncxfdf2_mixed"
4159   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4160         (float_truncate:DF
4161           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4162    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4163   "TARGET_80387"
4165   gcc_assert (!which_alternative);
4166   return output_387_reg_move (insn, operands);
4168   [(set_attr "isa" "*,*,sse2,*")
4169    (set_attr "type" "fmov,multi,multi,multi")
4170    (set_attr "unit" "*,i387,i387,i387")
4171    (set_attr "mode" "DF")])
4173 (define_insn "truncxf<mode>2_i387_noop"
4174   [(set (match_operand:MODEF 0 "register_operand" "=f")
4175         (float_truncate:MODEF
4176           (match_operand:XF 1 "register_operand" "f")))]
4177   "TARGET_80387 && flag_unsafe_math_optimizations"
4178   "* return output_387_reg_move (insn, operands);"
4179   [(set_attr "type" "fmov")
4180    (set_attr "mode" "<MODE>")])
4182 (define_insn "*truncxf<mode>2_i387"
4183   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4184         (float_truncate:MODEF
4185           (match_operand:XF 1 "register_operand" "f")))]
4186   "TARGET_80387"
4187   "* return output_387_reg_move (insn, operands);"
4188   [(set_attr "type" "fmov")
4189    (set_attr "mode" "<MODE>")])
4191 (define_split
4192   [(set (match_operand:MODEF 0 "register_operand")
4193         (float_truncate:MODEF
4194           (match_operand:XF 1 "register_operand")))
4195    (clobber (match_operand:MODEF 2 "memory_operand"))]
4196   "TARGET_80387 && reload_completed"
4197   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4198    (set (match_dup 0) (match_dup 2))])
4200 (define_split
4201   [(set (match_operand:MODEF 0 "memory_operand")
4202         (float_truncate:MODEF
4203           (match_operand:XF 1 "register_operand")))
4204    (clobber (match_operand:MODEF 2 "memory_operand"))]
4205   "TARGET_80387"
4206   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4208 ;; Signed conversion to DImode.
4210 (define_expand "fix_truncxfdi2"
4211   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4212                    (fix:DI (match_operand:XF 1 "register_operand")))
4213               (clobber (reg:CC FLAGS_REG))])]
4214   "TARGET_80387"
4216   if (TARGET_FISTTP)
4217    {
4218      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4219      DONE;
4220    }
4223 (define_expand "fix_trunc<mode>di2"
4224   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4225                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4226               (clobber (reg:CC FLAGS_REG))])]
4227   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4229   if (TARGET_FISTTP
4230       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4231    {
4232      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4233      DONE;
4234    }
4235   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4236    {
4237      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4238      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4239      if (out != operands[0])
4240         emit_move_insn (operands[0], out);
4241      DONE;
4242    }
4245 ;; Signed conversion to SImode.
4247 (define_expand "fix_truncxfsi2"
4248   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4249                    (fix:SI (match_operand:XF 1 "register_operand")))
4250               (clobber (reg:CC FLAGS_REG))])]
4251   "TARGET_80387"
4253   if (TARGET_FISTTP)
4254    {
4255      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4256      DONE;
4257    }
4260 (define_expand "fix_trunc<mode>si2"
4261   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4262                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4263               (clobber (reg:CC FLAGS_REG))])]
4264   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4266   if (TARGET_FISTTP
4267       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4268    {
4269      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4270      DONE;
4271    }
4272   if (SSE_FLOAT_MODE_P (<MODE>mode))
4273    {
4274      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4275      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4276      if (out != operands[0])
4277         emit_move_insn (operands[0], out);
4278      DONE;
4279    }
4282 ;; Signed conversion to HImode.
4284 (define_expand "fix_trunc<mode>hi2"
4285   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4286                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4287               (clobber (reg:CC FLAGS_REG))])]
4288   "TARGET_80387
4289    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4291   if (TARGET_FISTTP)
4292    {
4293      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4294      DONE;
4295    }
4298 ;; Unsigned conversion to SImode.
4300 (define_expand "fixuns_trunc<mode>si2"
4301   [(parallel
4302     [(set (match_operand:SI 0 "register_operand")
4303           (unsigned_fix:SI
4304             (match_operand:MODEF 1 "nonimmediate_operand")))
4305      (use (match_dup 2))
4306      (clobber (match_scratch:<ssevecmode> 3))
4307      (clobber (match_scratch:<ssevecmode> 4))])]
4308   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4310   enum machine_mode mode = <MODE>mode;
4311   enum machine_mode vecmode = <ssevecmode>mode;
4312   REAL_VALUE_TYPE TWO31r;
4313   rtx two31;
4315   if (optimize_insn_for_size_p ())
4316     FAIL;
4318   real_ldexp (&TWO31r, &dconst1, 31);
4319   two31 = const_double_from_real_value (TWO31r, mode);
4320   two31 = ix86_build_const_vector (vecmode, true, two31);
4321   operands[2] = force_reg (vecmode, two31);
4324 (define_insn_and_split "*fixuns_trunc<mode>_1"
4325   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4326         (unsigned_fix:SI
4327           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4328    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4329    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4330    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4331   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4332    && optimize_function_for_speed_p (cfun)"
4333   "#"
4334   "&& reload_completed"
4335   [(const_int 0)]
4337   ix86_split_convert_uns_si_sse (operands);
4338   DONE;
4341 ;; Unsigned conversion to HImode.
4342 ;; Without these patterns, we'll try the unsigned SI conversion which
4343 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4345 (define_expand "fixuns_trunc<mode>hi2"
4346   [(set (match_dup 2)
4347         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4348    (set (match_operand:HI 0 "nonimmediate_operand")
4349         (subreg:HI (match_dup 2) 0))]
4350   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4351   "operands[2] = gen_reg_rtx (SImode);")
4353 ;; When SSE is available, it is always faster to use it!
4354 (define_insn "fix_trunc<mode>di_sse"
4355   [(set (match_operand:DI 0 "register_operand" "=r,r")
4356         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4357   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4358    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4359   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4360   [(set_attr "type" "sseicvt")
4361    (set_attr "prefix" "maybe_vex")
4362    (set_attr "prefix_rex" "1")
4363    (set_attr "mode" "<MODE>")
4364    (set_attr "athlon_decode" "double,vector")
4365    (set_attr "amdfam10_decode" "double,double")
4366    (set_attr "bdver1_decode" "double,double")])
4368 (define_insn "fix_trunc<mode>si_sse"
4369   [(set (match_operand:SI 0 "register_operand" "=r,r")
4370         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4371   "SSE_FLOAT_MODE_P (<MODE>mode)
4372    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4373   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4374   [(set_attr "type" "sseicvt")
4375    (set_attr "prefix" "maybe_vex")
4376    (set_attr "mode" "<MODE>")
4377    (set_attr "athlon_decode" "double,vector")
4378    (set_attr "amdfam10_decode" "double,double")
4379    (set_attr "bdver1_decode" "double,double")])
4381 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4382 (define_peephole2
4383   [(set (match_operand:MODEF 0 "register_operand")
4384         (match_operand:MODEF 1 "memory_operand"))
4385    (set (match_operand:SWI48x 2 "register_operand")
4386         (fix:SWI48x (match_dup 0)))]
4387   "TARGET_SHORTEN_X87_SSE
4388    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4389    && peep2_reg_dead_p (2, operands[0])"
4390   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4392 ;; Avoid vector decoded forms of the instruction.
4393 (define_peephole2
4394   [(match_scratch:DF 2 "x")
4395    (set (match_operand:SWI48x 0 "register_operand")
4396         (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4397   "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4398   [(set (match_dup 2) (match_dup 1))
4399    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4401 (define_peephole2
4402   [(match_scratch:SF 2 "x")
4403    (set (match_operand:SWI48x 0 "register_operand")
4404         (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4405   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4406   [(set (match_dup 2) (match_dup 1))
4407    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4409 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4410   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4411         (fix:SWI248x (match_operand 1 "register_operand")))]
4412   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4413    && TARGET_FISTTP
4414    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4415          && (TARGET_64BIT || <MODE>mode != DImode))
4416         && TARGET_SSE_MATH)
4417    && can_create_pseudo_p ()"
4418   "#"
4419   "&& 1"
4420   [(const_int 0)]
4422   if (memory_operand (operands[0], VOIDmode))
4423     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4424   else
4425     {
4426       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4427       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4428                                                             operands[1],
4429                                                             operands[2]));
4430     }
4431   DONE;
4433   [(set_attr "type" "fisttp")
4434    (set_attr "mode" "<MODE>")])
4436 (define_insn "fix_trunc<mode>_i387_fisttp"
4437   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4438         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4439    (clobber (match_scratch:XF 2 "=&1f"))]
4440   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4441    && TARGET_FISTTP
4442    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4443          && (TARGET_64BIT || <MODE>mode != DImode))
4444         && TARGET_SSE_MATH)"
4445   "* return output_fix_trunc (insn, operands, true);"
4446   [(set_attr "type" "fisttp")
4447    (set_attr "mode" "<MODE>")])
4449 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4450   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4451         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4452    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4453    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4454   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4455    && TARGET_FISTTP
4456    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4457         && (TARGET_64BIT || <MODE>mode != DImode))
4458         && TARGET_SSE_MATH)"
4459   "#"
4460   [(set_attr "type" "fisttp")
4461    (set_attr "mode" "<MODE>")])
4463 (define_split
4464   [(set (match_operand:SWI248x 0 "register_operand")
4465         (fix:SWI248x (match_operand 1 "register_operand")))
4466    (clobber (match_operand:SWI248x 2 "memory_operand"))
4467    (clobber (match_scratch 3))]
4468   "reload_completed"
4469   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4470               (clobber (match_dup 3))])
4471    (set (match_dup 0) (match_dup 2))])
4473 (define_split
4474   [(set (match_operand:SWI248x 0 "memory_operand")
4475         (fix:SWI248x (match_operand 1 "register_operand")))
4476    (clobber (match_operand:SWI248x 2 "memory_operand"))
4477    (clobber (match_scratch 3))]
4478   "reload_completed"
4479   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4480               (clobber (match_dup 3))])])
4482 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4483 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4484 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4485 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4486 ;; function in i386.c.
4487 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4488   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4489         (fix:SWI248x (match_operand 1 "register_operand")))
4490    (clobber (reg:CC FLAGS_REG))]
4491   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4492    && !TARGET_FISTTP
4493    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4494          && (TARGET_64BIT || <MODE>mode != DImode))
4495    && can_create_pseudo_p ()"
4496   "#"
4497   "&& 1"
4498   [(const_int 0)]
4500   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4502   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4503   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4504   if (memory_operand (operands[0], VOIDmode))
4505     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4506                                          operands[2], operands[3]));
4507   else
4508     {
4509       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4510       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4511                                                      operands[2], operands[3],
4512                                                      operands[4]));
4513     }
4514   DONE;
4516   [(set_attr "type" "fistp")
4517    (set_attr "i387_cw" "trunc")
4518    (set_attr "mode" "<MODE>")])
4520 (define_insn "fix_truncdi_i387"
4521   [(set (match_operand:DI 0 "memory_operand" "=m")
4522         (fix:DI (match_operand 1 "register_operand" "f")))
4523    (use (match_operand:HI 2 "memory_operand" "m"))
4524    (use (match_operand:HI 3 "memory_operand" "m"))
4525    (clobber (match_scratch:XF 4 "=&1f"))]
4526   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4527    && !TARGET_FISTTP
4528    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4529   "* return output_fix_trunc (insn, operands, false);"
4530   [(set_attr "type" "fistp")
4531    (set_attr "i387_cw" "trunc")
4532    (set_attr "mode" "DI")])
4534 (define_insn "fix_truncdi_i387_with_temp"
4535   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4536         (fix:DI (match_operand 1 "register_operand" "f,f")))
4537    (use (match_operand:HI 2 "memory_operand" "m,m"))
4538    (use (match_operand:HI 3 "memory_operand" "m,m"))
4539    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4540    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4541   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4542    && !TARGET_FISTTP
4543    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4544   "#"
4545   [(set_attr "type" "fistp")
4546    (set_attr "i387_cw" "trunc")
4547    (set_attr "mode" "DI")])
4549 (define_split
4550   [(set (match_operand:DI 0 "register_operand")
4551         (fix:DI (match_operand 1 "register_operand")))
4552    (use (match_operand:HI 2 "memory_operand"))
4553    (use (match_operand:HI 3 "memory_operand"))
4554    (clobber (match_operand:DI 4 "memory_operand"))
4555    (clobber (match_scratch 5))]
4556   "reload_completed"
4557   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4558               (use (match_dup 2))
4559               (use (match_dup 3))
4560               (clobber (match_dup 5))])
4561    (set (match_dup 0) (match_dup 4))])
4563 (define_split
4564   [(set (match_operand:DI 0 "memory_operand")
4565         (fix:DI (match_operand 1 "register_operand")))
4566    (use (match_operand:HI 2 "memory_operand"))
4567    (use (match_operand:HI 3 "memory_operand"))
4568    (clobber (match_operand:DI 4 "memory_operand"))
4569    (clobber (match_scratch 5))]
4570   "reload_completed"
4571   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4572               (use (match_dup 2))
4573               (use (match_dup 3))
4574               (clobber (match_dup 5))])])
4576 (define_insn "fix_trunc<mode>_i387"
4577   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4578         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4579    (use (match_operand:HI 2 "memory_operand" "m"))
4580    (use (match_operand:HI 3 "memory_operand" "m"))]
4581   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4582    && !TARGET_FISTTP
4583    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4584   "* return output_fix_trunc (insn, operands, false);"
4585   [(set_attr "type" "fistp")
4586    (set_attr "i387_cw" "trunc")
4587    (set_attr "mode" "<MODE>")])
4589 (define_insn "fix_trunc<mode>_i387_with_temp"
4590   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4591         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4592    (use (match_operand:HI 2 "memory_operand" "m,m"))
4593    (use (match_operand:HI 3 "memory_operand" "m,m"))
4594    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4595   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4596    && !TARGET_FISTTP
4597    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4598   "#"
4599   [(set_attr "type" "fistp")
4600    (set_attr "i387_cw" "trunc")
4601    (set_attr "mode" "<MODE>")])
4603 (define_split
4604   [(set (match_operand:SWI24 0 "register_operand")
4605         (fix:SWI24 (match_operand 1 "register_operand")))
4606    (use (match_operand:HI 2 "memory_operand"))
4607    (use (match_operand:HI 3 "memory_operand"))
4608    (clobber (match_operand:SWI24 4 "memory_operand"))]
4609   "reload_completed"
4610   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4611               (use (match_dup 2))
4612               (use (match_dup 3))])
4613    (set (match_dup 0) (match_dup 4))])
4615 (define_split
4616   [(set (match_operand:SWI24 0 "memory_operand")
4617         (fix:SWI24 (match_operand 1 "register_operand")))
4618    (use (match_operand:HI 2 "memory_operand"))
4619    (use (match_operand:HI 3 "memory_operand"))
4620    (clobber (match_operand:SWI24 4 "memory_operand"))]
4621   "reload_completed"
4622   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4623               (use (match_dup 2))
4624               (use (match_dup 3))])])
4626 (define_insn "x86_fnstcw_1"
4627   [(set (match_operand:HI 0 "memory_operand" "=m")
4628         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4629   "TARGET_80387"
4630   "fnstcw\t%0"
4631   [(set (attr "length")
4632         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4633    (set_attr "mode" "HI")
4634    (set_attr "unit" "i387")
4635    (set_attr "bdver1_decode" "vector")])
4637 (define_insn "x86_fldcw_1"
4638   [(set (reg:HI FPCR_REG)
4639         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4640   "TARGET_80387"
4641   "fldcw\t%0"
4642   [(set (attr "length")
4643         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4644    (set_attr "mode" "HI")
4645    (set_attr "unit" "i387")
4646    (set_attr "athlon_decode" "vector")
4647    (set_attr "amdfam10_decode" "vector")
4648    (set_attr "bdver1_decode" "vector")])
4650 ;; Conversion between fixed point and floating point.
4652 ;; Even though we only accept memory inputs, the backend _really_
4653 ;; wants to be able to do this between registers.
4655 (define_expand "floathi<mode>2"
4656   [(set (match_operand:X87MODEF 0 "register_operand")
4657         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4658   "TARGET_80387
4659    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4660        || TARGET_MIX_SSE_I387)")
4662 ;; Pre-reload splitter to add memory clobber to the pattern.
4663 (define_insn_and_split "*floathi<mode>2_1"
4664   [(set (match_operand:X87MODEF 0 "register_operand")
4665         (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4666   "TARGET_80387
4667    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4668        || TARGET_MIX_SSE_I387)
4669    && can_create_pseudo_p ()"
4670   "#"
4671   "&& 1"
4672   [(parallel [(set (match_dup 0)
4673               (float:X87MODEF (match_dup 1)))
4674    (clobber (match_dup 2))])]
4675   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4677 (define_insn "*floathi<mode>2_i387_with_temp"
4678   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4679         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4680   (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4681   "TARGET_80387
4682    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4683        || TARGET_MIX_SSE_I387)"
4684   "#"
4685   [(set_attr "type" "fmov,multi")
4686    (set_attr "mode" "<MODE>")
4687    (set_attr "unit" "*,i387")
4688    (set_attr "fp_int_src" "true")])
4690 (define_insn "*floathi<mode>2_i387"
4691   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4692         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4693   "TARGET_80387
4694    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4695        || TARGET_MIX_SSE_I387)"
4696   "fild%Z1\t%1"
4697   [(set_attr "type" "fmov")
4698    (set_attr "mode" "<MODE>")
4699    (set_attr "fp_int_src" "true")])
4701 (define_split
4702   [(set (match_operand:X87MODEF 0 "register_operand")
4703         (float:X87MODEF (match_operand:HI 1 "register_operand")))
4704    (clobber (match_operand:HI 2 "memory_operand"))]
4705   "TARGET_80387
4706    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4707        || TARGET_MIX_SSE_I387)
4708    && reload_completed"
4709   [(set (match_dup 2) (match_dup 1))
4710    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4712 (define_split
4713   [(set (match_operand:X87MODEF 0 "register_operand")
4714         (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4715    (clobber (match_operand:HI 2 "memory_operand"))]
4716    "TARGET_80387
4717     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4718         || TARGET_MIX_SSE_I387)
4719     && reload_completed"
4720   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4722 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4723   [(set (match_operand:X87MODEF 0 "register_operand")
4724         (float:X87MODEF
4725           (match_operand:SWI48x 1 "nonimmediate_operand")))]
4726   "TARGET_80387
4727    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4728        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4730   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4731         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4732       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4733     {
4734       rtx reg = gen_reg_rtx (XFmode);
4735       rtx (*insn)(rtx, rtx);
4737       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4739       if (<X87MODEF:MODE>mode == SFmode)
4740         insn = gen_truncxfsf2;
4741       else if (<X87MODEF:MODE>mode == DFmode)
4742         insn = gen_truncxfdf2;
4743       else
4744         gcc_unreachable ();
4746       emit_insn (insn (operands[0], reg));
4747       DONE;
4748     }
4751 ;; Pre-reload splitter to add memory clobber to the pattern.
4752 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4753   [(set (match_operand:X87MODEF 0 "register_operand")
4754         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4755   "((TARGET_80387
4756      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4757      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4758            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4759          || TARGET_MIX_SSE_I387))
4760     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4761         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4762         && ((<SWI48x:MODE>mode == SImode
4763              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4764              && optimize_function_for_speed_p (cfun)
4765              && flag_trapping_math)
4766             || !(TARGET_INTER_UNIT_CONVERSIONS
4767                  || optimize_function_for_size_p (cfun)))))
4768    && can_create_pseudo_p ()"
4769   "#"
4770   "&& 1"
4771   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4772               (clobber (match_dup 2))])]
4774   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4776   /* Avoid store forwarding (partial memory) stall penalty
4777      by passing DImode value through XMM registers.  */
4778   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4779       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4780       && optimize_function_for_speed_p (cfun))
4781     {
4782       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4783                                                             operands[1],
4784                                                             operands[2]));
4785       DONE;
4786     }
4789 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4790   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4791         (float:MODEF
4792           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4793    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4794   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4795    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4796   "#"
4797   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4798    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4799    (set_attr "unit" "*,i387,*,*,*")
4800    (set_attr "athlon_decode" "*,*,double,direct,double")
4801    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4802    (set_attr "bdver1_decode" "*,*,double,direct,double")
4803    (set_attr "fp_int_src" "true")])
4805 (define_insn "*floatsi<mode>2_vector_mixed"
4806   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4807         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4808   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4809    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4810   "@
4811    fild%Z1\t%1
4812    #"
4813   [(set_attr "type" "fmov,sseicvt")
4814    (set_attr "mode" "<MODE>,<ssevecmode>")
4815    (set_attr "unit" "i387,*")
4816    (set_attr "athlon_decode" "*,direct")
4817    (set_attr "amdfam10_decode" "*,double")
4818    (set_attr "bdver1_decode" "*,direct")
4819    (set_attr "fp_int_src" "true")])
4821 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4822   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4823         (float:MODEF
4824           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4825    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4826   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4827    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4828   "#"
4829   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4830    (set_attr "mode" "<MODEF:MODE>")
4831    (set_attr "unit" "*,i387,*,*")
4832    (set_attr "athlon_decode" "*,*,double,direct")
4833    (set_attr "amdfam10_decode" "*,*,vector,double")
4834    (set_attr "bdver1_decode" "*,*,double,direct")
4835    (set_attr "fp_int_src" "true")])
4837 (define_split
4838   [(set (match_operand:MODEF 0 "register_operand")
4839         (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4840    (clobber (match_operand:SWI48x 2 "memory_operand"))]
4841   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4842    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4843    && TARGET_INTER_UNIT_CONVERSIONS
4844    && reload_completed
4845    && (SSE_REG_P (operands[0])
4846        || (GET_CODE (operands[0]) == SUBREG
4847            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4848   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4850 (define_split
4851   [(set (match_operand:MODEF 0 "register_operand")
4852         (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4853    (clobber (match_operand:SWI48x 2 "memory_operand"))]
4854   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4855    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4856    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4857    && reload_completed
4858    && (SSE_REG_P (operands[0])
4859        || (GET_CODE (operands[0]) == SUBREG
4860            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4861   [(set (match_dup 2) (match_dup 1))
4862    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4864 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4865   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4866         (float:MODEF
4867           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4868   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4869    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4870    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4871   "@
4872    fild%Z1\t%1
4873    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4874    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4875   [(set_attr "type" "fmov,sseicvt,sseicvt")
4876    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4877    (set_attr "mode" "<MODEF:MODE>")
4878    (set (attr "prefix_rex")
4879      (if_then_else
4880        (and (eq_attr "prefix" "maybe_vex")
4881             (match_test "<SWI48x:MODE>mode == DImode"))
4882        (const_string "1")
4883        (const_string "*")))
4884    (set_attr "unit" "i387,*,*")
4885    (set_attr "athlon_decode" "*,double,direct")
4886    (set_attr "amdfam10_decode" "*,vector,double")
4887    (set_attr "bdver1_decode" "*,double,direct")
4888    (set_attr "fp_int_src" "true")])
4890 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4891   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4892         (float:MODEF
4893           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4894   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4895    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4896    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4897   "@
4898    fild%Z1\t%1
4899    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4900   [(set_attr "type" "fmov,sseicvt")
4901    (set_attr "prefix" "orig,maybe_vex")
4902    (set_attr "mode" "<MODEF:MODE>")
4903    (set (attr "prefix_rex")
4904      (if_then_else
4905        (and (eq_attr "prefix" "maybe_vex")
4906             (match_test "<SWI48x:MODE>mode == DImode"))
4907        (const_string "1")
4908        (const_string "*")))
4909    (set_attr "athlon_decode" "*,direct")
4910    (set_attr "amdfam10_decode" "*,double")
4911    (set_attr "bdver1_decode" "*,direct")
4912    (set_attr "fp_int_src" "true")])
4914 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4915   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4916         (float:MODEF
4917           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4918    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4919   "TARGET_SSE2 && TARGET_SSE_MATH
4920    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4921   "#"
4922   [(set_attr "type" "sseicvt")
4923    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4924    (set_attr "athlon_decode" "double,direct,double")
4925    (set_attr "amdfam10_decode" "vector,double,double")
4926    (set_attr "bdver1_decode" "double,direct,double")
4927    (set_attr "fp_int_src" "true")])
4929 (define_insn "*floatsi<mode>2_vector_sse"
4930   [(set (match_operand:MODEF 0 "register_operand" "=x")
4931         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4932   "TARGET_SSE2 && TARGET_SSE_MATH
4933    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4934   "#"
4935   [(set_attr "type" "sseicvt")
4936    (set_attr "mode" "<MODE>")
4937    (set_attr "athlon_decode" "direct")
4938    (set_attr "amdfam10_decode" "double")
4939    (set_attr "bdver1_decode" "direct")
4940    (set_attr "fp_int_src" "true")])
4942 (define_split
4943   [(set (match_operand:MODEF 0 "register_operand")
4944         (float:MODEF (match_operand:SI 1 "register_operand")))
4945    (clobber (match_operand:SI 2 "memory_operand"))]
4946   "TARGET_SSE2 && TARGET_SSE_MATH
4947    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4948    && reload_completed
4949    && (SSE_REG_P (operands[0])
4950        || (GET_CODE (operands[0]) == SUBREG
4951            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4952   [(const_int 0)]
4954   rtx op1 = operands[1];
4956   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4957                                      <MODE>mode, 0);
4958   if (GET_CODE (op1) == SUBREG)
4959     op1 = SUBREG_REG (op1);
4961   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4962     {
4963       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4964       emit_insn (gen_sse2_loadld (operands[4],
4965                                   CONST0_RTX (V4SImode), operands[1]));
4966     }
4967   /* We can ignore possible trapping value in the
4968      high part of SSE register for non-trapping math. */
4969   else if (SSE_REG_P (op1) && !flag_trapping_math)
4970     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4971   else
4972     {
4973       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4974       emit_move_insn (operands[2], operands[1]);
4975       emit_insn (gen_sse2_loadld (operands[4],
4976                                   CONST0_RTX (V4SImode), operands[2]));
4977     }
4978   if (<ssevecmode>mode == V4SFmode)
4979     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4980   else
4981     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4982   DONE;
4985 (define_split
4986   [(set (match_operand:MODEF 0 "register_operand")
4987         (float:MODEF (match_operand:SI 1 "memory_operand")))
4988    (clobber (match_operand:SI 2 "memory_operand"))]
4989   "TARGET_SSE2 && TARGET_SSE_MATH
4990    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4991    && reload_completed
4992    && (SSE_REG_P (operands[0])
4993        || (GET_CODE (operands[0]) == SUBREG
4994            && SSE_REG_P (SUBREG_REG (operands[0]))))"
4995   [(const_int 0)]
4997   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4998                                      <MODE>mode, 0);
4999   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5001   emit_insn (gen_sse2_loadld (operands[4],
5002                               CONST0_RTX (V4SImode), operands[1]));
5003   if (<ssevecmode>mode == V4SFmode)
5004     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5005   else
5006     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5007   DONE;
5010 (define_split
5011   [(set (match_operand:MODEF 0 "register_operand")
5012         (float:MODEF (match_operand:SI 1 "register_operand")))]
5013   "TARGET_SSE2 && TARGET_SSE_MATH
5014    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5015    && reload_completed
5016    && (SSE_REG_P (operands[0])
5017        || (GET_CODE (operands[0]) == SUBREG
5018            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5019   [(const_int 0)]
5021   rtx op1 = operands[1];
5023   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5024                                      <MODE>mode, 0);
5025   if (GET_CODE (op1) == SUBREG)
5026     op1 = SUBREG_REG (op1);
5028   if (GENERAL_REG_P (op1))
5029     {
5030       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5031       if (TARGET_INTER_UNIT_MOVES)
5032         emit_insn (gen_sse2_loadld (operands[4],
5033                                     CONST0_RTX (V4SImode), operands[1]));
5034       else
5035         {
5036           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5037                                               operands[1]);
5038           emit_insn (gen_sse2_loadld (operands[4],
5039                                       CONST0_RTX (V4SImode), operands[5]));
5040           ix86_free_from_memory (GET_MODE (operands[1]));
5041         }
5042     }
5043   /* We can ignore possible trapping value in the
5044      high part of SSE register for non-trapping math. */
5045   else if (SSE_REG_P (op1) && !flag_trapping_math)
5046     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5047   else
5048     gcc_unreachable ();
5049   if (<ssevecmode>mode == V4SFmode)
5050     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5051   else
5052     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5053   DONE;
5056 (define_split
5057   [(set (match_operand:MODEF 0 "register_operand")
5058         (float:MODEF (match_operand:SI 1 "memory_operand")))]
5059   "TARGET_SSE2 && TARGET_SSE_MATH
5060    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5061    && reload_completed
5062    && (SSE_REG_P (operands[0])
5063        || (GET_CODE (operands[0]) == SUBREG
5064            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5065   [(const_int 0)]
5067   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5068                                      <MODE>mode, 0);
5069   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5071   emit_insn (gen_sse2_loadld (operands[4],
5072                               CONST0_RTX (V4SImode), operands[1]));
5073   if (<ssevecmode>mode == V4SFmode)
5074     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5075   else
5076     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5077   DONE;
5080 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5081   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5082         (float:MODEF
5083           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5084   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5085   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5086    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5087   "#"
5088   [(set_attr "type" "sseicvt")
5089    (set_attr "mode" "<MODEF:MODE>")
5090    (set_attr "athlon_decode" "double,direct")
5091    (set_attr "amdfam10_decode" "vector,double")
5092    (set_attr "bdver1_decode" "double,direct")
5093    (set_attr "fp_int_src" "true")])
5095 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5096   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5097         (float:MODEF
5098           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5099   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5100    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5101    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5102   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5103   [(set_attr "type" "sseicvt")
5104    (set_attr "prefix" "maybe_vex")
5105    (set_attr "mode" "<MODEF:MODE>")
5106    (set (attr "prefix_rex")
5107      (if_then_else
5108        (and (eq_attr "prefix" "maybe_vex")
5109             (match_test "<SWI48x:MODE>mode == DImode"))
5110        (const_string "1")
5111        (const_string "*")))
5112    (set_attr "athlon_decode" "double,direct")
5113    (set_attr "amdfam10_decode" "vector,double")
5114    (set_attr "bdver1_decode" "double,direct")
5115    (set_attr "fp_int_src" "true")])
5117 (define_split
5118   [(set (match_operand:MODEF 0 "register_operand")
5119         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5120    (clobber (match_operand:SWI48x 2 "memory_operand"))]
5121   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5122    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5123    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5124    && reload_completed
5125    && (SSE_REG_P (operands[0])
5126        || (GET_CODE (operands[0]) == SUBREG
5127            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5128   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5130 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5131   [(set (match_operand:MODEF 0 "register_operand" "=x")
5132         (float:MODEF
5133           (match_operand:SWI48x 1 "memory_operand" "m")))]
5134   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5135    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5136    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5137   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5138   [(set_attr "type" "sseicvt")
5139    (set_attr "prefix" "maybe_vex")
5140    (set_attr "mode" "<MODEF:MODE>")
5141    (set (attr "prefix_rex")
5142      (if_then_else
5143        (and (eq_attr "prefix" "maybe_vex")
5144             (match_test "<SWI48x:MODE>mode == DImode"))
5145        (const_string "1")
5146        (const_string "*")))
5147    (set_attr "athlon_decode" "direct")
5148    (set_attr "amdfam10_decode" "double")
5149    (set_attr "bdver1_decode" "direct")
5150    (set_attr "fp_int_src" "true")])
5152 (define_split
5153   [(set (match_operand:MODEF 0 "register_operand")
5154         (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5155    (clobber (match_operand:SWI48x 2 "memory_operand"))]
5156   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5157    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5158    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5159    && reload_completed
5160    && (SSE_REG_P (operands[0])
5161        || (GET_CODE (operands[0]) == SUBREG
5162            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5163   [(set (match_dup 2) (match_dup 1))
5164    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5166 (define_split
5167   [(set (match_operand:MODEF 0 "register_operand")
5168         (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5169    (clobber (match_operand:SWI48x 2 "memory_operand"))]
5170   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5171    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5172    && reload_completed
5173    && (SSE_REG_P (operands[0])
5174        || (GET_CODE (operands[0]) == SUBREG
5175            && SSE_REG_P (SUBREG_REG (operands[0]))))"
5176   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5178 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5179   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5180         (float:X87MODEF
5181           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5182   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5183   "TARGET_80387
5184    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5185   "@
5186    fild%Z1\t%1
5187    #"
5188   [(set_attr "type" "fmov,multi")
5189    (set_attr "mode" "<X87MODEF:MODE>")
5190    (set_attr "unit" "*,i387")
5191    (set_attr "fp_int_src" "true")])
5193 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5194   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5195         (float:X87MODEF
5196           (match_operand:SWI48x 1 "memory_operand" "m")))]
5197   "TARGET_80387
5198    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5199   "fild%Z1\t%1"
5200   [(set_attr "type" "fmov")
5201    (set_attr "mode" "<X87MODEF:MODE>")
5202    (set_attr "fp_int_src" "true")])
5204 (define_split
5205   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5206         (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5207    (clobber (match_operand:SWI48x 2 "memory_operand"))]
5208   "TARGET_80387
5209    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5210    && reload_completed"
5211   [(set (match_dup 2) (match_dup 1))
5212    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5214 (define_split
5215   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5216         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5217    (clobber (match_operand:SWI48x 2 "memory_operand"))]
5218   "TARGET_80387
5219    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5220    && reload_completed"
5221   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5223 ;; Avoid store forwarding (partial memory) stall penalty
5224 ;; by passing DImode value through XMM registers.  */
5226 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5227   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5228         (float:X87MODEF
5229           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5230    (clobber (match_scratch:V4SI 3 "=X,x"))
5231    (clobber (match_scratch:V4SI 4 "=X,x"))
5232    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5233   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5234    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5235    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5236   "#"
5237   [(set_attr "type" "multi")
5238    (set_attr "mode" "<X87MODEF:MODE>")
5239    (set_attr "unit" "i387")
5240    (set_attr "fp_int_src" "true")])
5242 (define_split
5243   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5244         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5245    (clobber (match_scratch:V4SI 3))
5246    (clobber (match_scratch:V4SI 4))
5247    (clobber (match_operand:DI 2 "memory_operand"))]
5248   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5249    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5250    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5251    && reload_completed"
5252   [(set (match_dup 2) (match_dup 3))
5253    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5255   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5256      Assemble the 64-bit DImode value in an xmm register.  */
5257   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5258                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5259   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5260                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5261   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5262                                          operands[4]));
5264   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5267 (define_split
5268   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5269         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5270    (clobber (match_scratch:V4SI 3))
5271    (clobber (match_scratch:V4SI 4))
5272    (clobber (match_operand:DI 2 "memory_operand"))]
5273   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5274    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5275    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5276    && reload_completed"
5277   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5279 ;; Avoid store forwarding (partial memory) stall penalty by extending
5280 ;; SImode value to DImode through XMM register instead of pushing two
5281 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5282 ;; targets benefit from this optimization. Also note that fild
5283 ;; loads from memory only.
5285 (define_insn "*floatunssi<mode>2_1"
5286   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5287         (unsigned_float:X87MODEF
5288           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5289    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5290    (clobber (match_scratch:SI 3 "=X,x"))]
5291   "!TARGET_64BIT
5292    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5293    && TARGET_SSE"
5294   "#"
5295   [(set_attr "type" "multi")
5296    (set_attr "mode" "<MODE>")])
5298 (define_split
5299   [(set (match_operand:X87MODEF 0 "register_operand")
5300         (unsigned_float:X87MODEF
5301           (match_operand:SI 1 "register_operand")))
5302    (clobber (match_operand:DI 2 "memory_operand"))
5303    (clobber (match_scratch:SI 3))]
5304   "!TARGET_64BIT
5305    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5306    && TARGET_SSE
5307    && reload_completed"
5308   [(set (match_dup 2) (match_dup 1))
5309    (set (match_dup 0)
5310         (float:X87MODEF (match_dup 2)))]
5311   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5313 (define_split
5314   [(set (match_operand:X87MODEF 0 "register_operand")
5315         (unsigned_float:X87MODEF
5316           (match_operand:SI 1 "memory_operand")))
5317    (clobber (match_operand:DI 2 "memory_operand"))
5318    (clobber (match_scratch:SI 3))]
5319   "!TARGET_64BIT
5320    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5321    && TARGET_SSE
5322    && reload_completed"
5323   [(set (match_dup 2) (match_dup 3))
5324    (set (match_dup 0)
5325         (float:X87MODEF (match_dup 2)))]
5327   emit_move_insn (operands[3], operands[1]);
5328   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5331 (define_expand "floatunssi<mode>2"
5332   [(parallel
5333      [(set (match_operand:X87MODEF 0 "register_operand")
5334            (unsigned_float:X87MODEF
5335              (match_operand:SI 1 "nonimmediate_operand")))
5336       (clobber (match_dup 2))
5337       (clobber (match_scratch:SI 3))])]
5338   "!TARGET_64BIT
5339    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5340         && TARGET_SSE)
5341        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5343   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5344     {
5345       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5346       DONE;
5347     }
5348   else
5349     {
5350       enum ix86_stack_slot slot = (virtuals_instantiated
5351                                    ? SLOT_TEMP
5352                                    : SLOT_VIRTUAL);
5353       operands[2] = assign_386_stack_local (DImode, slot);
5354     }
5357 (define_expand "floatunsdisf2"
5358   [(use (match_operand:SF 0 "register_operand"))
5359    (use (match_operand:DI 1 "nonimmediate_operand"))]
5360   "TARGET_64BIT && TARGET_SSE_MATH"
5361   "x86_emit_floatuns (operands); DONE;")
5363 (define_expand "floatunsdidf2"
5364   [(use (match_operand:DF 0 "register_operand"))
5365    (use (match_operand:DI 1 "nonimmediate_operand"))]
5366   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5367    && TARGET_SSE2 && TARGET_SSE_MATH"
5369   if (TARGET_64BIT)
5370     x86_emit_floatuns (operands);
5371   else
5372     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5373   DONE;
5376 ;; Add instructions
5378 (define_expand "add<mode>3"
5379   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5380         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5381                     (match_operand:SDWIM 2 "<general_operand>")))]
5382   ""
5383   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5385 (define_insn_and_split "*add<dwi>3_doubleword"
5386   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5387         (plus:<DWI>
5388           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5389           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5390    (clobber (reg:CC FLAGS_REG))]
5391   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5392   "#"
5393   "reload_completed"
5394   [(parallel [(set (reg:CC FLAGS_REG)
5395                    (unspec:CC [(match_dup 1) (match_dup 2)]
5396                               UNSPEC_ADD_CARRY))
5397               (set (match_dup 0)
5398                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5399    (parallel [(set (match_dup 3)
5400                    (plus:DWIH
5401                      (match_dup 4)
5402                      (plus:DWIH
5403                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5404                        (match_dup 5))))
5405               (clobber (reg:CC FLAGS_REG))])]
5406   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5408 (define_insn "*add<mode>3_cc"
5409   [(set (reg:CC FLAGS_REG)
5410         (unspec:CC
5411           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5412            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5413           UNSPEC_ADD_CARRY))
5414    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5415         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5416   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5417   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5418   [(set_attr "type" "alu")
5419    (set_attr "mode" "<MODE>")])
5421 (define_insn "addqi3_cc"
5422   [(set (reg:CC FLAGS_REG)
5423         (unspec:CC
5424           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5425            (match_operand:QI 2 "general_operand" "qn,qm")]
5426           UNSPEC_ADD_CARRY))
5427    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5428         (plus:QI (match_dup 1) (match_dup 2)))]
5429   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5430   "add{b}\t{%2, %0|%0, %2}"
5431   [(set_attr "type" "alu")
5432    (set_attr "mode" "QI")])
5434 (define_insn_and_split "*lea_1"
5435   [(set (match_operand:SI 0 "register_operand" "=r")
5436         (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5437   "TARGET_64BIT"
5438   "lea{l}\t{%E1, %0|%0, %E1}"
5439   "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5440   [(const_int 0)]
5442   ix86_split_lea_for_addr (operands, SImode);
5443   DONE;
5445   [(set_attr "type" "lea")
5446    (set_attr "mode" "SI")])
5448 (define_insn_and_split "*lea<mode>_2"
5449   [(set (match_operand:SWI48 0 "register_operand" "=r")
5450         (match_operand:SWI48 1 "lea_address_operand" "p"))]
5451   ""
5452   "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5453   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5454   [(const_int 0)]
5456   ix86_split_lea_for_addr (operands, <MODE>mode);
5457   DONE;
5459   [(set_attr "type" "lea")
5460    (set_attr "mode" "<MODE>")])
5462 (define_insn "*lea_3_zext"
5463   [(set (match_operand:DI 0 "register_operand" "=r")
5464         (zero_extend:DI
5465           (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5466   "TARGET_64BIT"
5467   "lea{l}\t{%E1, %k0|%k0, %E1}"
5468   [(set_attr "type" "lea")
5469    (set_attr "mode" "SI")])
5471 (define_insn "*lea_4_zext"
5472   [(set (match_operand:DI 0 "register_operand" "=r")
5473         (zero_extend:DI
5474           (match_operand:SI 1 "lea_address_operand" "j")))]
5475   "TARGET_64BIT"
5476   "lea{l}\t{%E1, %k0|%k0, %E1}"
5477   [(set_attr "type" "lea")
5478    (set_attr "mode" "SI")])
5480 (define_insn "*lea_5_zext"
5481   [(set (match_operand:DI 0 "register_operand" "=r")
5482         (and:DI
5483           (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5484           (match_operand:DI 2 "const_32bit_mask" "n")))]
5485   "TARGET_64BIT"
5486   "lea{l}\t{%E1, %k0|%k0, %E1}"
5487   [(set_attr "type" "lea")
5488    (set_attr "mode" "SI")])
5490 (define_insn "*lea_6_zext"
5491   [(set (match_operand:DI 0 "register_operand" "=r")
5492         (and:DI
5493           (match_operand:DI 1 "lea_address_operand" "p")
5494           (match_operand:DI 2 "const_32bit_mask" "n")))]
5495   "TARGET_64BIT"
5496   "lea{l}\t{%E1, %k0|%k0, %E1}"
5497   [(set_attr "type" "lea")
5498    (set_attr "mode" "SI")])
5500 (define_insn "*add<mode>_1"
5501   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5502         (plus:SWI48
5503           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5504           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5505    (clobber (reg:CC FLAGS_REG))]
5506   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5508   switch (get_attr_type (insn))
5509     {
5510     case TYPE_LEA:
5511       return "#";
5513     case TYPE_INCDEC:
5514       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515       if (operands[2] == const1_rtx)
5516         return "inc{<imodesuffix>}\t%0";
5517       else
5518         {
5519           gcc_assert (operands[2] == constm1_rtx);
5520           return "dec{<imodesuffix>}\t%0";
5521         }
5523     default:
5524       /* For most processors, ADD is faster than LEA.  This alternative
5525          was added to use ADD as much as possible.  */
5526       if (which_alternative == 2)
5527         {
5528           rtx tmp;
5529           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5530         }
5531         
5532       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5533       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5534         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5536       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5537     }
5539   [(set (attr "type")
5540      (cond [(eq_attr "alternative" "3")
5541               (const_string "lea")
5542             (match_operand:SWI48 2 "incdec_operand")
5543               (const_string "incdec")
5544            ]
5545            (const_string "alu")))
5546    (set (attr "length_immediate")
5547       (if_then_else
5548         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5549         (const_string "1")
5550         (const_string "*")))
5551    (set_attr "mode" "<MODE>")])
5553 ;; It may seem that nonimmediate operand is proper one for operand 1.
5554 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5555 ;; we take care in ix86_binary_operator_ok to not allow two memory
5556 ;; operands so proper swapping will be done in reload.  This allow
5557 ;; patterns constructed from addsi_1 to match.
5559 (define_insn "addsi_1_zext"
5560   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5561         (zero_extend:DI
5562           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5563                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5564    (clobber (reg:CC FLAGS_REG))]
5565   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5567   switch (get_attr_type (insn))
5568     {
5569     case TYPE_LEA:
5570       return "#";
5572     case TYPE_INCDEC:
5573       if (operands[2] == const1_rtx)
5574         return "inc{l}\t%k0";
5575       else
5576         {
5577           gcc_assert (operands[2] == constm1_rtx);
5578           return "dec{l}\t%k0";
5579         }
5581     default:
5582       /* For most processors, ADD is faster than LEA.  This alternative
5583          was added to use ADD as much as possible.  */
5584       if (which_alternative == 1)
5585         {
5586           rtx tmp;
5587           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5588         }
5590       if (x86_maybe_negate_const_int (&operands[2], SImode))
5591         return "sub{l}\t{%2, %k0|%k0, %2}";
5593       return "add{l}\t{%2, %k0|%k0, %2}";
5594     }
5596   [(set (attr "type")
5597      (cond [(eq_attr "alternative" "2")
5598               (const_string "lea")
5599             (match_operand:SI 2 "incdec_operand")
5600               (const_string "incdec")
5601            ]
5602            (const_string "alu")))
5603    (set (attr "length_immediate")
5604       (if_then_else
5605         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5606         (const_string "1")
5607         (const_string "*")))
5608    (set_attr "mode" "SI")])
5610 (define_insn "*addhi_1"
5611   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5612         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5613                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5614    (clobber (reg:CC FLAGS_REG))]
5615   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5617   switch (get_attr_type (insn))
5618     {
5619     case TYPE_LEA:
5620       return "#";
5622     case TYPE_INCDEC:
5623       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5624       if (operands[2] == const1_rtx)
5625         return "inc{w}\t%0";
5626       else
5627         {
5628           gcc_assert (operands[2] == constm1_rtx);
5629           return "dec{w}\t%0";
5630         }
5632     default:
5633       /* For most processors, ADD is faster than LEA.  This alternative
5634          was added to use ADD as much as possible.  */
5635       if (which_alternative == 2)
5636         {
5637           rtx tmp;
5638           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5639         }
5641       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642       if (x86_maybe_negate_const_int (&operands[2], HImode))
5643         return "sub{w}\t{%2, %0|%0, %2}";
5645       return "add{w}\t{%2, %0|%0, %2}";
5646     }
5648   [(set (attr "type")
5649      (cond [(eq_attr "alternative" "3")
5650               (const_string "lea")
5651             (match_operand:HI 2 "incdec_operand")
5652               (const_string "incdec")
5653            ]
5654            (const_string "alu")))
5655    (set (attr "length_immediate")
5656       (if_then_else
5657         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5658         (const_string "1")
5659         (const_string "*")))
5660    (set_attr "mode" "HI,HI,HI,SI")])
5662 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5663 (define_insn "*addqi_1"
5664   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5665         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5666                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5667    (clobber (reg:CC FLAGS_REG))]
5668   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5670   bool widen = (which_alternative == 3 || which_alternative == 4);
5672   switch (get_attr_type (insn))
5673     {
5674     case TYPE_LEA:
5675       return "#";
5677     case TYPE_INCDEC:
5678       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5679       if (operands[2] == const1_rtx)
5680         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5681       else
5682         {
5683           gcc_assert (operands[2] == constm1_rtx);
5684           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5685         }
5687     default:
5688       /* For most processors, ADD is faster than LEA.  These alternatives
5689          were added to use ADD as much as possible.  */
5690       if (which_alternative == 2 || which_alternative == 4)
5691         {
5692           rtx tmp;
5693           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5694         }
5696       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5697       if (x86_maybe_negate_const_int (&operands[2], QImode))
5698         {
5699           if (widen)
5700             return "sub{l}\t{%2, %k0|%k0, %2}";
5701           else
5702             return "sub{b}\t{%2, %0|%0, %2}";
5703         }
5704       if (widen)
5705         return "add{l}\t{%k2, %k0|%k0, %k2}";
5706       else
5707         return "add{b}\t{%2, %0|%0, %2}";
5708     }
5710   [(set (attr "type")
5711      (cond [(eq_attr "alternative" "5")
5712               (const_string "lea")
5713             (match_operand:QI 2 "incdec_operand")
5714               (const_string "incdec")
5715            ]
5716            (const_string "alu")))
5717    (set (attr "length_immediate")
5718       (if_then_else
5719         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5720         (const_string "1")
5721         (const_string "*")))
5722    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5724 (define_insn "*addqi_1_slp"
5725   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5726         (plus:QI (match_dup 0)
5727                  (match_operand:QI 1 "general_operand" "qn,qm")))
5728    (clobber (reg:CC FLAGS_REG))]
5729   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5730    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5732   switch (get_attr_type (insn))
5733     {
5734     case TYPE_INCDEC:
5735       if (operands[1] == const1_rtx)
5736         return "inc{b}\t%0";
5737       else
5738         {
5739           gcc_assert (operands[1] == constm1_rtx);
5740           return "dec{b}\t%0";
5741         }
5743     default:
5744       if (x86_maybe_negate_const_int (&operands[1], QImode))
5745         return "sub{b}\t{%1, %0|%0, %1}";
5747       return "add{b}\t{%1, %0|%0, %1}";
5748     }
5750   [(set (attr "type")
5751      (if_then_else (match_operand:QI 1 "incdec_operand")
5752         (const_string "incdec")
5753         (const_string "alu1")))
5754    (set (attr "memory")
5755      (if_then_else (match_operand 1 "memory_operand")
5756         (const_string "load")
5757         (const_string "none")))
5758    (set_attr "mode" "QI")])
5760 ;; Split non destructive adds if we cannot use lea.
5761 (define_split
5762   [(set (match_operand:SWI48 0 "register_operand")
5763         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5764               (match_operand:SWI48 2 "nonmemory_operand")))
5765    (clobber (reg:CC FLAGS_REG))]
5766   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5767   [(set (match_dup 0) (match_dup 1))
5768    (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5769               (clobber (reg:CC FLAGS_REG))])])
5771 ;; Convert add to the lea pattern to avoid flags dependency.
5772 (define_split
5773   [(set (match_operand:SWI 0 "register_operand")
5774         (plus:SWI (match_operand:SWI 1 "register_operand")
5775                   (match_operand:SWI 2 "<nonmemory_operand>")))
5776    (clobber (reg:CC FLAGS_REG))]
5777   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5778   [(const_int 0)]
5780   enum machine_mode mode = <MODE>mode;
5781   rtx pat;
5783   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5784     { 
5785       mode = SImode; 
5786       operands[0] = gen_lowpart (mode, operands[0]);
5787       operands[1] = gen_lowpart (mode, operands[1]);
5788       operands[2] = gen_lowpart (mode, operands[2]);
5789     }
5791   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5793   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5794   DONE;
5797 ;; Convert add to the lea pattern to avoid flags dependency.
5798 (define_split
5799   [(set (match_operand:DI 0 "register_operand")
5800         (zero_extend:DI
5801           (plus:SI (match_operand:SI 1 "register_operand")
5802                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5803    (clobber (reg:CC FLAGS_REG))]
5804   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5805   [(set (match_dup 0)
5806         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5808 (define_insn "*add<mode>_2"
5809   [(set (reg FLAGS_REG)
5810         (compare
5811           (plus:SWI
5812             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5813             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5814           (const_int 0)))
5815    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5816         (plus:SWI (match_dup 1) (match_dup 2)))]
5817   "ix86_match_ccmode (insn, CCGOCmode)
5818    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5820   switch (get_attr_type (insn))
5821     {
5822     case TYPE_INCDEC:
5823       if (operands[2] == const1_rtx)
5824         return "inc{<imodesuffix>}\t%0";
5825       else
5826         {
5827           gcc_assert (operands[2] == constm1_rtx);
5828           return "dec{<imodesuffix>}\t%0";
5829         }
5831     default:
5832       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5833         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5835       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5836     }
5838   [(set (attr "type")
5839      (if_then_else (match_operand:SWI 2 "incdec_operand")
5840         (const_string "incdec")
5841         (const_string "alu")))
5842    (set (attr "length_immediate")
5843       (if_then_else
5844         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5845         (const_string "1")
5846         (const_string "*")))
5847    (set_attr "mode" "<MODE>")])
5849 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5850 (define_insn "*addsi_2_zext"
5851   [(set (reg FLAGS_REG)
5852         (compare
5853           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5854                    (match_operand:SI 2 "x86_64_general_operand" "rme"))
5855           (const_int 0)))
5856    (set (match_operand:DI 0 "register_operand" "=r")
5857         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5858   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5859    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5861   switch (get_attr_type (insn))
5862     {
5863     case TYPE_INCDEC:
5864       if (operands[2] == const1_rtx)
5865         return "inc{l}\t%k0";
5866       else
5867         {
5868           gcc_assert (operands[2] == constm1_rtx);
5869           return "dec{l}\t%k0";
5870         }
5872     default:
5873       if (x86_maybe_negate_const_int (&operands[2], SImode))
5874         return "sub{l}\t{%2, %k0|%k0, %2}";
5876       return "add{l}\t{%2, %k0|%k0, %2}";
5877     }
5879   [(set (attr "type")
5880      (if_then_else (match_operand:SI 2 "incdec_operand")
5881         (const_string "incdec")
5882         (const_string "alu")))
5883    (set (attr "length_immediate")
5884       (if_then_else
5885         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5886         (const_string "1")
5887         (const_string "*")))
5888    (set_attr "mode" "SI")])
5890 (define_insn "*add<mode>_3"
5891   [(set (reg FLAGS_REG)
5892         (compare
5893           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5894           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5895    (clobber (match_scratch:SWI 0 "=<r>"))]
5896   "ix86_match_ccmode (insn, CCZmode)
5897    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5899   switch (get_attr_type (insn))
5900     {
5901     case TYPE_INCDEC:
5902       if (operands[2] == const1_rtx)
5903         return "inc{<imodesuffix>}\t%0";
5904       else
5905         {
5906           gcc_assert (operands[2] == constm1_rtx);
5907           return "dec{<imodesuffix>}\t%0";
5908         }
5910     default:
5911       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5912         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5914       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5915     }
5917   [(set (attr "type")
5918      (if_then_else (match_operand:SWI 2 "incdec_operand")
5919         (const_string "incdec")
5920         (const_string "alu")))
5921    (set (attr "length_immediate")
5922       (if_then_else
5923         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5924         (const_string "1")
5925         (const_string "*")))
5926    (set_attr "mode" "<MODE>")])
5928 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5929 (define_insn "*addsi_3_zext"
5930   [(set (reg FLAGS_REG)
5931         (compare
5932           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5933           (match_operand:SI 1 "nonimmediate_operand" "%0")))
5934    (set (match_operand:DI 0 "register_operand" "=r")
5935         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5936   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5937    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5939   switch (get_attr_type (insn))
5940     {
5941     case TYPE_INCDEC:
5942       if (operands[2] == const1_rtx)
5943         return "inc{l}\t%k0";
5944       else
5945         {
5946           gcc_assert (operands[2] == constm1_rtx);
5947           return "dec{l}\t%k0";
5948         }
5950     default:
5951       if (x86_maybe_negate_const_int (&operands[2], SImode))
5952         return "sub{l}\t{%2, %k0|%k0, %2}";
5954       return "add{l}\t{%2, %k0|%k0, %2}";
5955     }
5957   [(set (attr "type")
5958      (if_then_else (match_operand:SI 2 "incdec_operand")
5959         (const_string "incdec")
5960         (const_string "alu")))
5961    (set (attr "length_immediate")
5962       (if_then_else
5963         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5964         (const_string "1")
5965         (const_string "*")))
5966    (set_attr "mode" "SI")])
5968 ; For comparisons against 1, -1 and 128, we may generate better code
5969 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5970 ; is matched then.  We can't accept general immediate, because for
5971 ; case of overflows,  the result is messed up.
5972 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5973 ; only for comparisons not depending on it.
5975 (define_insn "*adddi_4"
5976   [(set (reg FLAGS_REG)
5977         (compare
5978           (match_operand:DI 1 "nonimmediate_operand" "0")
5979           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5980    (clobber (match_scratch:DI 0 "=rm"))]
5981   "TARGET_64BIT
5982    && ix86_match_ccmode (insn, CCGCmode)"
5984   switch (get_attr_type (insn))
5985     {
5986     case TYPE_INCDEC:
5987       if (operands[2] == constm1_rtx)
5988         return "inc{q}\t%0";
5989       else
5990         {
5991           gcc_assert (operands[2] == const1_rtx);
5992           return "dec{q}\t%0";
5993         }
5995     default:
5996       if (x86_maybe_negate_const_int (&operands[2], DImode))
5997         return "add{q}\t{%2, %0|%0, %2}";
5999       return "sub{q}\t{%2, %0|%0, %2}";
6000     }
6002   [(set (attr "type")
6003      (if_then_else (match_operand:DI 2 "incdec_operand")
6004         (const_string "incdec")
6005         (const_string "alu")))
6006    (set (attr "length_immediate")
6007       (if_then_else
6008         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6009         (const_string "1")
6010         (const_string "*")))
6011    (set_attr "mode" "DI")])
6013 ; For comparisons against 1, -1 and 128, we may generate better code
6014 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6015 ; is matched then.  We can't accept general immediate, because for
6016 ; case of overflows,  the result is messed up.
6017 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6018 ; only for comparisons not depending on it.
6020 (define_insn "*add<mode>_4"
6021   [(set (reg FLAGS_REG)
6022         (compare
6023           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6024           (match_operand:SWI124 2 "const_int_operand" "n")))
6025    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6026   "ix86_match_ccmode (insn, CCGCmode)"
6028   switch (get_attr_type (insn))
6029     {
6030     case TYPE_INCDEC:
6031       if (operands[2] == constm1_rtx)
6032         return "inc{<imodesuffix>}\t%0";
6033       else
6034         {
6035           gcc_assert (operands[2] == const1_rtx);
6036           return "dec{<imodesuffix>}\t%0";
6037         }
6039     default:
6040       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6041         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6043       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6044     }
6046   [(set (attr "type")
6047      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6048         (const_string "incdec")
6049         (const_string "alu")))
6050    (set (attr "length_immediate")
6051       (if_then_else
6052         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6053         (const_string "1")
6054         (const_string "*")))
6055    (set_attr "mode" "<MODE>")])
6057 (define_insn "*add<mode>_5"
6058   [(set (reg FLAGS_REG)
6059         (compare
6060           (plus:SWI
6061             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6062             (match_operand:SWI 2 "<general_operand>" "<g>"))
6063           (const_int 0)))
6064    (clobber (match_scratch:SWI 0 "=<r>"))]
6065   "ix86_match_ccmode (insn, CCGOCmode)
6066    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6068   switch (get_attr_type (insn))
6069     {
6070     case TYPE_INCDEC:
6071       if (operands[2] == const1_rtx)
6072         return "inc{<imodesuffix>}\t%0";
6073       else
6074         {
6075           gcc_assert (operands[2] == constm1_rtx);
6076           return "dec{<imodesuffix>}\t%0";
6077         }
6079     default:
6080       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6081         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6083       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6084     }
6086   [(set (attr "type")
6087      (if_then_else (match_operand:SWI 2 "incdec_operand")
6088         (const_string "incdec")
6089         (const_string "alu")))
6090    (set (attr "length_immediate")
6091       (if_then_else
6092         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6093         (const_string "1")
6094         (const_string "*")))
6095    (set_attr "mode" "<MODE>")])
6097 (define_insn "*addqi_ext_1_rex64"
6098   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6099                          (const_int 8)
6100                          (const_int 8))
6101         (plus:SI
6102           (zero_extract:SI
6103             (match_operand 1 "ext_register_operand" "0")
6104             (const_int 8)
6105             (const_int 8))
6106           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6107    (clobber (reg:CC FLAGS_REG))]
6108   "TARGET_64BIT"
6110   switch (get_attr_type (insn))
6111     {
6112     case TYPE_INCDEC:
6113       if (operands[2] == const1_rtx)
6114         return "inc{b}\t%h0";
6115       else
6116         {
6117           gcc_assert (operands[2] == constm1_rtx);
6118           return "dec{b}\t%h0";
6119         }
6121     default:
6122       return "add{b}\t{%2, %h0|%h0, %2}";
6123     }
6125   [(set (attr "type")
6126      (if_then_else (match_operand:QI 2 "incdec_operand")
6127         (const_string "incdec")
6128         (const_string "alu")))
6129    (set_attr "modrm" "1")
6130    (set_attr "mode" "QI")])
6132 (define_insn "addqi_ext_1"
6133   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6134                          (const_int 8)
6135                          (const_int 8))
6136         (plus:SI
6137           (zero_extract:SI
6138             (match_operand 1 "ext_register_operand" "0")
6139             (const_int 8)
6140             (const_int 8))
6141           (match_operand:QI 2 "general_operand" "Qmn")))
6142    (clobber (reg:CC FLAGS_REG))]
6143   "!TARGET_64BIT"
6145   switch (get_attr_type (insn))
6146     {
6147     case TYPE_INCDEC:
6148       if (operands[2] == const1_rtx)
6149         return "inc{b}\t%h0";
6150       else
6151         {
6152           gcc_assert (operands[2] == constm1_rtx);
6153           return "dec{b}\t%h0";
6154         }
6156     default:
6157       return "add{b}\t{%2, %h0|%h0, %2}";
6158     }
6160   [(set (attr "type")
6161      (if_then_else (match_operand:QI 2 "incdec_operand")
6162         (const_string "incdec")
6163         (const_string "alu")))
6164    (set_attr "modrm" "1")
6165    (set_attr "mode" "QI")])
6167 (define_insn "*addqi_ext_2"
6168   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6169                          (const_int 8)
6170                          (const_int 8))
6171         (plus:SI
6172           (zero_extract:SI
6173             (match_operand 1 "ext_register_operand" "%0")
6174             (const_int 8)
6175             (const_int 8))
6176           (zero_extract:SI
6177             (match_operand 2 "ext_register_operand" "Q")
6178             (const_int 8)
6179             (const_int 8))))
6180    (clobber (reg:CC FLAGS_REG))]
6181   ""
6182   "add{b}\t{%h2, %h0|%h0, %h2}"
6183   [(set_attr "type" "alu")
6184    (set_attr "mode" "QI")])
6186 ;; The lea patterns for modes less than 32 bits need to be matched by
6187 ;; several insns converted to real lea by splitters.
6189 (define_insn_and_split "*lea_general_1"
6190   [(set (match_operand 0 "register_operand" "=r")
6191         (plus (plus (match_operand 1 "index_register_operand" "l")
6192                     (match_operand 2 "register_operand" "r"))
6193               (match_operand 3 "immediate_operand" "i")))]
6194   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6195    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6196    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6197    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6198    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6199        || GET_MODE (operands[3]) == VOIDmode)"
6200   "#"
6201   "&& reload_completed"
6202   [(const_int 0)]
6204   enum machine_mode mode = SImode;
6205   rtx pat;
6207   operands[0] = gen_lowpart (mode, operands[0]);
6208   operands[1] = gen_lowpart (mode, operands[1]);
6209   operands[2] = gen_lowpart (mode, operands[2]);
6210   operands[3] = gen_lowpart (mode, operands[3]);
6212   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6213                       operands[3]);
6215   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6216   DONE;
6218   [(set_attr "type" "lea")
6219    (set_attr "mode" "SI")])
6221 (define_insn_and_split "*lea_general_2"
6222   [(set (match_operand 0 "register_operand" "=r")
6223         (plus (mult (match_operand 1 "index_register_operand" "l")
6224                     (match_operand 2 "const248_operand" "n"))
6225               (match_operand 3 "nonmemory_operand" "ri")))]
6226   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6227    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6228    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6229    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6230        || GET_MODE (operands[3]) == VOIDmode)"
6231   "#"
6232   "&& reload_completed"
6233   [(const_int 0)]
6235   enum machine_mode mode = SImode;
6236   rtx pat;
6238   operands[0] = gen_lowpart (mode, operands[0]);
6239   operands[1] = gen_lowpart (mode, operands[1]);
6240   operands[3] = gen_lowpart (mode, operands[3]);
6242   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6243                       operands[3]);
6245   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6246   DONE;
6248   [(set_attr "type" "lea")
6249    (set_attr "mode" "SI")])
6251 (define_insn_and_split "*lea_general_3"
6252   [(set (match_operand 0 "register_operand" "=r")
6253         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6254                           (match_operand 2 "const248_operand" "n"))
6255                     (match_operand 3 "register_operand" "r"))
6256               (match_operand 4 "immediate_operand" "i")))]
6257   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6258    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6259    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6260    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6261   "#"
6262   "&& reload_completed"
6263   [(const_int 0)]
6265   enum machine_mode mode = SImode;
6266   rtx pat;
6268   operands[0] = gen_lowpart (mode, operands[0]);
6269   operands[1] = gen_lowpart (mode, operands[1]);
6270   operands[3] = gen_lowpart (mode, operands[3]);
6271   operands[4] = gen_lowpart (mode, operands[4]);
6273   pat = gen_rtx_PLUS (mode,
6274                       gen_rtx_PLUS (mode,
6275                                     gen_rtx_MULT (mode, operands[1],
6276                                                         operands[2]),
6277                                     operands[3]),
6278                       operands[4]);
6280   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6281   DONE;
6283   [(set_attr "type" "lea")
6284    (set_attr "mode" "SI")])
6286 (define_insn_and_split "*lea_general_4"
6287   [(set (match_operand 0 "register_operand" "=r")
6288         (any_or (ashift
6289                   (match_operand 1 "index_register_operand" "l")
6290                   (match_operand 2 "const_int_operand" "n"))
6291                 (match_operand 3 "const_int_operand" "n")))]
6292   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6293       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6294     || GET_MODE (operands[0]) == SImode
6295     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6296    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6297    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6298    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6299        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6300   "#"
6301   "&& reload_completed"
6302   [(const_int 0)]
6304   enum machine_mode mode = GET_MODE (operands[0]);
6305   rtx pat;
6307   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6308     { 
6309       mode = SImode; 
6310       operands[0] = gen_lowpart (mode, operands[0]);
6311       operands[1] = gen_lowpart (mode, operands[1]);
6312     }
6314   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6316   pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6317                        INTVAL (operands[3]));
6319   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6320   DONE;
6322   [(set_attr "type" "lea")
6323    (set (attr "mode")
6324       (if_then_else (match_operand:DI 0)
6325         (const_string "DI")
6326         (const_string "SI")))])
6328 ;; Subtract instructions
6330 (define_expand "sub<mode>3"
6331   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6332         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6333                      (match_operand:SDWIM 2 "<general_operand>")))]
6334   ""
6335   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6337 (define_insn_and_split "*sub<dwi>3_doubleword"
6338   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6339         (minus:<DWI>
6340           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6341           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6342    (clobber (reg:CC FLAGS_REG))]
6343   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6344   "#"
6345   "reload_completed"
6346   [(parallel [(set (reg:CC FLAGS_REG)
6347                    (compare:CC (match_dup 1) (match_dup 2)))
6348               (set (match_dup 0)
6349                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6350    (parallel [(set (match_dup 3)
6351                    (minus:DWIH
6352                      (match_dup 4)
6353                      (plus:DWIH
6354                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6355                        (match_dup 5))))
6356               (clobber (reg:CC FLAGS_REG))])]
6357   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6359 (define_insn "*sub<mode>_1"
6360   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6361         (minus:SWI
6362           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6363           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6364    (clobber (reg:CC FLAGS_REG))]
6365   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6366   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6367   [(set_attr "type" "alu")
6368    (set_attr "mode" "<MODE>")])
6370 (define_insn "*subsi_1_zext"
6371   [(set (match_operand:DI 0 "register_operand" "=r")
6372         (zero_extend:DI
6373           (minus:SI (match_operand:SI 1 "register_operand" "0")
6374                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6375    (clobber (reg:CC FLAGS_REG))]
6376   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6377   "sub{l}\t{%2, %k0|%k0, %2}"
6378   [(set_attr "type" "alu")
6379    (set_attr "mode" "SI")])
6381 (define_insn "*subqi_1_slp"
6382   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6383         (minus:QI (match_dup 0)
6384                   (match_operand:QI 1 "general_operand" "qn,qm")))
6385    (clobber (reg:CC FLAGS_REG))]
6386   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6387    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6388   "sub{b}\t{%1, %0|%0, %1}"
6389   [(set_attr "type" "alu1")
6390    (set_attr "mode" "QI")])
6392 (define_insn "*sub<mode>_2"
6393   [(set (reg FLAGS_REG)
6394         (compare
6395           (minus:SWI
6396             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6397             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6398           (const_int 0)))
6399    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6400         (minus:SWI (match_dup 1) (match_dup 2)))]
6401   "ix86_match_ccmode (insn, CCGOCmode)
6402    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6403   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6404   [(set_attr "type" "alu")
6405    (set_attr "mode" "<MODE>")])
6407 (define_insn "*subsi_2_zext"
6408   [(set (reg FLAGS_REG)
6409         (compare
6410           (minus:SI (match_operand:SI 1 "register_operand" "0")
6411                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6412           (const_int 0)))
6413    (set (match_operand:DI 0 "register_operand" "=r")
6414         (zero_extend:DI
6415           (minus:SI (match_dup 1)
6416                     (match_dup 2))))]
6417   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6418    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6419   "sub{l}\t{%2, %k0|%k0, %2}"
6420   [(set_attr "type" "alu")
6421    (set_attr "mode" "SI")])
6423 (define_insn "*sub<mode>_3"
6424   [(set (reg FLAGS_REG)
6425         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6426                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6427    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6428         (minus:SWI (match_dup 1) (match_dup 2)))]
6429   "ix86_match_ccmode (insn, CCmode)
6430    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6431   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6432   [(set_attr "type" "alu")
6433    (set_attr "mode" "<MODE>")])
6435 (define_insn "*subsi_3_zext"
6436   [(set (reg FLAGS_REG)
6437         (compare (match_operand:SI 1 "register_operand" "0")
6438                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6439    (set (match_operand:DI 0 "register_operand" "=r")
6440         (zero_extend:DI
6441           (minus:SI (match_dup 1)
6442                     (match_dup 2))))]
6443   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6444    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6445   "sub{l}\t{%2, %1|%1, %2}"
6446   [(set_attr "type" "alu")
6447    (set_attr "mode" "SI")])
6449 ;; Add with carry and subtract with borrow
6451 (define_expand "<plusminus_insn><mode>3_carry"
6452   [(parallel
6453     [(set (match_operand:SWI 0 "nonimmediate_operand")
6454           (plusminus:SWI
6455             (match_operand:SWI 1 "nonimmediate_operand")
6456             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6457                        [(match_operand 3 "flags_reg_operand")
6458                         (const_int 0)])
6459                       (match_operand:SWI 2 "<general_operand>"))))
6460      (clobber (reg:CC FLAGS_REG))])]
6461   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6463 (define_insn "*<plusminus_insn><mode>3_carry"
6464   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6465         (plusminus:SWI
6466           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6467           (plus:SWI
6468             (match_operator 3 "ix86_carry_flag_operator"
6469              [(reg FLAGS_REG) (const_int 0)])
6470             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6471    (clobber (reg:CC FLAGS_REG))]
6472   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6473   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6474   [(set_attr "type" "alu")
6475    (set_attr "use_carry" "1")
6476    (set_attr "pent_pair" "pu")
6477    (set_attr "mode" "<MODE>")])
6479 (define_insn "*addsi3_carry_zext"
6480   [(set (match_operand:DI 0 "register_operand" "=r")
6481         (zero_extend:DI
6482           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6483                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6484                              [(reg FLAGS_REG) (const_int 0)])
6485                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6486    (clobber (reg:CC FLAGS_REG))]
6487   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6488   "adc{l}\t{%2, %k0|%k0, %2}"
6489   [(set_attr "type" "alu")
6490    (set_attr "use_carry" "1")
6491    (set_attr "pent_pair" "pu")
6492    (set_attr "mode" "SI")])
6494 (define_insn "*subsi3_carry_zext"
6495   [(set (match_operand:DI 0 "register_operand" "=r")
6496         (zero_extend:DI
6497           (minus:SI (match_operand:SI 1 "register_operand" "0")
6498                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6499                               [(reg FLAGS_REG) (const_int 0)])
6500                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6501    (clobber (reg:CC FLAGS_REG))]
6502   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6503   "sbb{l}\t{%2, %k0|%k0, %2}"
6504   [(set_attr "type" "alu")
6505    (set_attr "pent_pair" "pu")
6506    (set_attr "mode" "SI")])
6508 ;; Overflow setting add and subtract instructions
6510 (define_insn "*add<mode>3_cconly_overflow"
6511   [(set (reg:CCC FLAGS_REG)
6512         (compare:CCC
6513           (plus:SWI
6514             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6515             (match_operand:SWI 2 "<general_operand>" "<g>"))
6516           (match_dup 1)))
6517    (clobber (match_scratch:SWI 0 "=<r>"))]
6518   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6519   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6520   [(set_attr "type" "alu")
6521    (set_attr "mode" "<MODE>")])
6523 (define_insn "*sub<mode>3_cconly_overflow"
6524   [(set (reg:CCC FLAGS_REG)
6525         (compare:CCC
6526           (minus:SWI
6527             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6528             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6529           (match_dup 0)))]
6530   ""
6531   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6532   [(set_attr "type" "icmp")
6533    (set_attr "mode" "<MODE>")])
6535 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6536   [(set (reg:CCC FLAGS_REG)
6537         (compare:CCC
6538             (plusminus:SWI
6539                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6540                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6541             (match_dup 1)))
6542    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6543         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6544   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6545   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6546   [(set_attr "type" "alu")
6547    (set_attr "mode" "<MODE>")])
6549 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6550   [(set (reg:CCC FLAGS_REG)
6551         (compare:CCC
6552           (plusminus:SI
6553             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6554             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6555           (match_dup 1)))
6556    (set (match_operand:DI 0 "register_operand" "=r")
6557         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6558   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6559   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6560   [(set_attr "type" "alu")
6561    (set_attr "mode" "SI")])
6563 ;; The patterns that match these are at the end of this file.
6565 (define_expand "<plusminus_insn>xf3"
6566   [(set (match_operand:XF 0 "register_operand")
6567         (plusminus:XF
6568           (match_operand:XF 1 "register_operand")
6569           (match_operand:XF 2 "register_operand")))]
6570   "TARGET_80387")
6572 (define_expand "<plusminus_insn><mode>3"
6573   [(set (match_operand:MODEF 0 "register_operand")
6574         (plusminus:MODEF
6575           (match_operand:MODEF 1 "register_operand")
6576           (match_operand:MODEF 2 "nonimmediate_operand")))]
6577   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6578     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6580 ;; Multiply instructions
6582 (define_expand "mul<mode>3"
6583   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6584                    (mult:SWIM248
6585                      (match_operand:SWIM248 1 "register_operand")
6586                      (match_operand:SWIM248 2 "<general_operand>")))
6587               (clobber (reg:CC FLAGS_REG))])])
6589 (define_expand "mulqi3"
6590   [(parallel [(set (match_operand:QI 0 "register_operand")
6591                    (mult:QI
6592                      (match_operand:QI 1 "register_operand")
6593                      (match_operand:QI 2 "nonimmediate_operand")))
6594               (clobber (reg:CC FLAGS_REG))])]
6595   "TARGET_QIMODE_MATH")
6597 ;; On AMDFAM10
6598 ;; IMUL reg32/64, reg32/64, imm8        Direct
6599 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6600 ;; IMUL reg32/64, reg32/64, imm32       Direct
6601 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6602 ;; IMUL reg32/64, reg32/64              Direct
6603 ;; IMUL reg32/64, mem32/64              Direct
6605 ;; On BDVER1, all above IMULs use DirectPath
6607 (define_insn "*mul<mode>3_1"
6608   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6609         (mult:SWI48
6610           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6611           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6612    (clobber (reg:CC FLAGS_REG))]
6613   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6614   "@
6615    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6616    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6617    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6618   [(set_attr "type" "imul")
6619    (set_attr "prefix_0f" "0,0,1")
6620    (set (attr "athlon_decode")
6621         (cond [(eq_attr "cpu" "athlon")
6622                   (const_string "vector")
6623                (eq_attr "alternative" "1")
6624                   (const_string "vector")
6625                (and (eq_attr "alternative" "2")
6626                     (match_operand 1 "memory_operand"))
6627                   (const_string "vector")]
6628               (const_string "direct")))
6629    (set (attr "amdfam10_decode")
6630         (cond [(and (eq_attr "alternative" "0,1")
6631                     (match_operand 1 "memory_operand"))
6632                   (const_string "vector")]
6633               (const_string "direct")))
6634    (set_attr "bdver1_decode" "direct")
6635    (set_attr "mode" "<MODE>")])
6637 (define_insn "*mulsi3_1_zext"
6638   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6639         (zero_extend:DI
6640           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6641                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6642    (clobber (reg:CC FLAGS_REG))]
6643   "TARGET_64BIT
6644    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6645   "@
6646    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6647    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6648    imul{l}\t{%2, %k0|%k0, %2}"
6649   [(set_attr "type" "imul")
6650    (set_attr "prefix_0f" "0,0,1")
6651    (set (attr "athlon_decode")
6652         (cond [(eq_attr "cpu" "athlon")
6653                   (const_string "vector")
6654                (eq_attr "alternative" "1")
6655                   (const_string "vector")
6656                (and (eq_attr "alternative" "2")
6657                     (match_operand 1 "memory_operand"))
6658                   (const_string "vector")]
6659               (const_string "direct")))
6660    (set (attr "amdfam10_decode")
6661         (cond [(and (eq_attr "alternative" "0,1")
6662                     (match_operand 1 "memory_operand"))
6663                   (const_string "vector")]
6664               (const_string "direct")))
6665    (set_attr "bdver1_decode" "direct")
6666    (set_attr "mode" "SI")])
6668 ;; On AMDFAM10
6669 ;; IMUL reg16, reg16, imm8      VectorPath
6670 ;; IMUL reg16, mem16, imm8      VectorPath
6671 ;; IMUL reg16, reg16, imm16     VectorPath
6672 ;; IMUL reg16, mem16, imm16     VectorPath
6673 ;; IMUL reg16, reg16            Direct
6674 ;; IMUL reg16, mem16            Direct
6676 ;; On BDVER1, all HI MULs use DoublePath
6678 (define_insn "*mulhi3_1"
6679   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6680         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6681                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6682    (clobber (reg:CC FLAGS_REG))]
6683   "TARGET_HIMODE_MATH
6684    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6685   "@
6686    imul{w}\t{%2, %1, %0|%0, %1, %2}
6687    imul{w}\t{%2, %1, %0|%0, %1, %2}
6688    imul{w}\t{%2, %0|%0, %2}"
6689   [(set_attr "type" "imul")
6690    (set_attr "prefix_0f" "0,0,1")
6691    (set (attr "athlon_decode")
6692         (cond [(eq_attr "cpu" "athlon")
6693                   (const_string "vector")
6694                (eq_attr "alternative" "1,2")
6695                   (const_string "vector")]
6696               (const_string "direct")))
6697    (set (attr "amdfam10_decode")
6698         (cond [(eq_attr "alternative" "0,1")
6699                   (const_string "vector")]
6700               (const_string "direct")))
6701    (set_attr "bdver1_decode" "double")
6702    (set_attr "mode" "HI")])
6704 ;;On AMDFAM10 and BDVER1
6705 ;; MUL reg8     Direct
6706 ;; MUL mem8     Direct
6708 (define_insn "*mulqi3_1"
6709   [(set (match_operand:QI 0 "register_operand" "=a")
6710         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6711                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6712    (clobber (reg:CC FLAGS_REG))]
6713   "TARGET_QIMODE_MATH
6714    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6715   "mul{b}\t%2"
6716   [(set_attr "type" "imul")
6717    (set_attr "length_immediate" "0")
6718    (set (attr "athlon_decode")
6719      (if_then_else (eq_attr "cpu" "athlon")
6720         (const_string "vector")
6721         (const_string "direct")))
6722    (set_attr "amdfam10_decode" "direct")
6723    (set_attr "bdver1_decode" "direct")
6724    (set_attr "mode" "QI")])
6726 (define_expand "<u>mul<mode><dwi>3"
6727   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6728                    (mult:<DWI>
6729                      (any_extend:<DWI>
6730                        (match_operand:DWIH 1 "nonimmediate_operand"))
6731                      (any_extend:<DWI>
6732                        (match_operand:DWIH 2 "register_operand"))))
6733               (clobber (reg:CC FLAGS_REG))])])
6735 (define_expand "<u>mulqihi3"
6736   [(parallel [(set (match_operand:HI 0 "register_operand")
6737                    (mult:HI
6738                      (any_extend:HI
6739                        (match_operand:QI 1 "nonimmediate_operand"))
6740                      (any_extend:HI
6741                        (match_operand:QI 2 "register_operand"))))
6742               (clobber (reg:CC FLAGS_REG))])]
6743   "TARGET_QIMODE_MATH")
6745 (define_insn "*bmi2_umulditi3_1"
6746   [(set (match_operand:DI 0 "register_operand" "=r")
6747         (mult:DI
6748           (match_operand:DI 2 "nonimmediate_operand" "%d")
6749           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6750    (set (match_operand:DI 1 "register_operand" "=r")
6751         (truncate:DI
6752           (lshiftrt:TI
6753             (mult:TI (zero_extend:TI (match_dup 2))
6754                      (zero_extend:TI (match_dup 3)))
6755             (const_int 64))))]
6756   "TARGET_64BIT && TARGET_BMI2
6757    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6758   "mulx\t{%3, %0, %1|%1, %0, %3}"
6759   [(set_attr "type" "imulx")
6760    (set_attr "prefix" "vex")
6761    (set_attr "mode" "DI")])
6763 (define_insn "*bmi2_umulsidi3_1"
6764   [(set (match_operand:SI 0 "register_operand" "=r")
6765         (mult:SI
6766           (match_operand:SI 2 "nonimmediate_operand" "%d")
6767           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6768    (set (match_operand:SI 1 "register_operand" "=r")
6769         (truncate:SI
6770           (lshiftrt:DI
6771             (mult:DI (zero_extend:DI (match_dup 2))
6772                      (zero_extend:DI (match_dup 3)))
6773             (const_int 32))))]
6774   "!TARGET_64BIT && TARGET_BMI2
6775    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6776   "mulx\t{%3, %0, %1|%1, %0, %3}"
6777   [(set_attr "type" "imulx")
6778    (set_attr "prefix" "vex")
6779    (set_attr "mode" "SI")])
6781 (define_insn "*umul<mode><dwi>3_1"
6782   [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6783         (mult:<DWI>
6784           (zero_extend:<DWI>
6785             (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6786           (zero_extend:<DWI>
6787             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6788    (clobber (reg:CC FLAGS_REG))]
6789   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6790   "@
6791    mul{<imodesuffix>}\t%2
6792    #"
6793   [(set_attr "isa" "*,bmi2")
6794    (set_attr "type" "imul,imulx")
6795    (set_attr "length_immediate" "0,*")
6796    (set (attr "athlon_decode")
6797         (cond [(eq_attr "alternative" "0")
6798                  (if_then_else (eq_attr "cpu" "athlon")
6799                    (const_string "vector")
6800                    (const_string "double"))]
6801               (const_string "*")))
6802    (set_attr "amdfam10_decode" "double,*")
6803    (set_attr "bdver1_decode" "direct,*")
6804    (set_attr "prefix" "orig,vex")
6805    (set_attr "mode" "<MODE>")])
6807 ;; Convert mul to the mulx pattern to avoid flags dependency.
6808 (define_split
6809  [(set (match_operand:<DWI> 0 "register_operand")
6810        (mult:<DWI>
6811          (zero_extend:<DWI>
6812            (match_operand:DWIH 1 "register_operand"))
6813          (zero_extend:<DWI>
6814            (match_operand:DWIH 2 "nonimmediate_operand"))))
6815   (clobber (reg:CC FLAGS_REG))]
6816  "TARGET_BMI2 && reload_completed
6817   && true_regnum (operands[1]) == DX_REG"
6818   [(parallel [(set (match_dup 3)
6819                    (mult:DWIH (match_dup 1) (match_dup 2)))
6820               (set (match_dup 4)
6821                    (truncate:DWIH
6822                      (lshiftrt:<DWI>
6823                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6824                                    (zero_extend:<DWI> (match_dup 2)))
6825                        (match_dup 5))))])]
6827   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6829   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6832 (define_insn "*mul<mode><dwi>3_1"
6833   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6834         (mult:<DWI>
6835           (sign_extend:<DWI>
6836             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6837           (sign_extend:<DWI>
6838             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6839    (clobber (reg:CC FLAGS_REG))]
6840   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6841   "imul{<imodesuffix>}\t%2"
6842   [(set_attr "type" "imul")
6843    (set_attr "length_immediate" "0")
6844    (set (attr "athlon_decode")
6845      (if_then_else (eq_attr "cpu" "athlon")
6846         (const_string "vector")
6847         (const_string "double")))
6848    (set_attr "amdfam10_decode" "double")
6849    (set_attr "bdver1_decode" "direct")
6850    (set_attr "mode" "<MODE>")])
6852 (define_insn "*<u>mulqihi3_1"
6853   [(set (match_operand:HI 0 "register_operand" "=a")
6854         (mult:HI
6855           (any_extend:HI
6856             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6857           (any_extend:HI
6858             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6859    (clobber (reg:CC FLAGS_REG))]
6860   "TARGET_QIMODE_MATH
6861    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6862   "<sgnprefix>mul{b}\t%2"
6863   [(set_attr "type" "imul")
6864    (set_attr "length_immediate" "0")
6865    (set (attr "athlon_decode")
6866      (if_then_else (eq_attr "cpu" "athlon")
6867         (const_string "vector")
6868         (const_string "direct")))
6869    (set_attr "amdfam10_decode" "direct")
6870    (set_attr "bdver1_decode" "direct")
6871    (set_attr "mode" "QI")])
6873 (define_expand "<s>mul<mode>3_highpart"
6874   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6875                    (truncate:SWI48
6876                      (lshiftrt:<DWI>
6877                        (mult:<DWI>
6878                          (any_extend:<DWI>
6879                            (match_operand:SWI48 1 "nonimmediate_operand"))
6880                          (any_extend:<DWI>
6881                            (match_operand:SWI48 2 "register_operand")))
6882                        (match_dup 4))))
6883               (clobber (match_scratch:SWI48 3))
6884               (clobber (reg:CC FLAGS_REG))])]
6885   ""
6886   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6888 (define_insn "*<s>muldi3_highpart_1"
6889   [(set (match_operand:DI 0 "register_operand" "=d")
6890         (truncate:DI
6891           (lshiftrt:TI
6892             (mult:TI
6893               (any_extend:TI
6894                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6895               (any_extend:TI
6896                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6897             (const_int 64))))
6898    (clobber (match_scratch:DI 3 "=1"))
6899    (clobber (reg:CC FLAGS_REG))]
6900   "TARGET_64BIT
6901    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6902   "<sgnprefix>mul{q}\t%2"
6903   [(set_attr "type" "imul")
6904    (set_attr "length_immediate" "0")
6905    (set (attr "athlon_decode")
6906      (if_then_else (eq_attr "cpu" "athlon")
6907         (const_string "vector")
6908         (const_string "double")))
6909    (set_attr "amdfam10_decode" "double")
6910    (set_attr "bdver1_decode" "direct")
6911    (set_attr "mode" "DI")])
6913 (define_insn "*<s>mulsi3_highpart_1"
6914   [(set (match_operand:SI 0 "register_operand" "=d")
6915         (truncate:SI
6916           (lshiftrt:DI
6917             (mult:DI
6918               (any_extend:DI
6919                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6920               (any_extend:DI
6921                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6922             (const_int 32))))
6923    (clobber (match_scratch:SI 3 "=1"))
6924    (clobber (reg:CC FLAGS_REG))]
6925   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6926   "<sgnprefix>mul{l}\t%2"
6927   [(set_attr "type" "imul")
6928    (set_attr "length_immediate" "0")
6929    (set (attr "athlon_decode")
6930      (if_then_else (eq_attr "cpu" "athlon")
6931         (const_string "vector")
6932         (const_string "double")))
6933    (set_attr "amdfam10_decode" "double")
6934    (set_attr "bdver1_decode" "direct")
6935    (set_attr "mode" "SI")])
6937 (define_insn "*<s>mulsi3_highpart_zext"
6938   [(set (match_operand:DI 0 "register_operand" "=d")
6939         (zero_extend:DI (truncate:SI
6940           (lshiftrt:DI
6941             (mult:DI (any_extend:DI
6942                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6943                      (any_extend:DI
6944                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6945             (const_int 32)))))
6946    (clobber (match_scratch:SI 3 "=1"))
6947    (clobber (reg:CC FLAGS_REG))]
6948   "TARGET_64BIT
6949    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950   "<sgnprefix>mul{l}\t%2"
6951   [(set_attr "type" "imul")
6952    (set_attr "length_immediate" "0")
6953    (set (attr "athlon_decode")
6954      (if_then_else (eq_attr "cpu" "athlon")
6955         (const_string "vector")
6956         (const_string "double")))
6957    (set_attr "amdfam10_decode" "double")
6958    (set_attr "bdver1_decode" "direct")
6959    (set_attr "mode" "SI")])
6961 ;; The patterns that match these are at the end of this file.
6963 (define_expand "mulxf3"
6964   [(set (match_operand:XF 0 "register_operand")
6965         (mult:XF (match_operand:XF 1 "register_operand")
6966                  (match_operand:XF 2 "register_operand")))]
6967   "TARGET_80387")
6969 (define_expand "mul<mode>3"
6970   [(set (match_operand:MODEF 0 "register_operand")
6971         (mult:MODEF (match_operand:MODEF 1 "register_operand")
6972                     (match_operand:MODEF 2 "nonimmediate_operand")))]
6973   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6974     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6976 ;; Divide instructions
6978 ;; The patterns that match these are at the end of this file.
6980 (define_expand "divxf3"
6981   [(set (match_operand:XF 0 "register_operand")
6982         (div:XF (match_operand:XF 1 "register_operand")
6983                 (match_operand:XF 2 "register_operand")))]
6984   "TARGET_80387")
6986 (define_expand "divdf3"
6987   [(set (match_operand:DF 0 "register_operand")
6988         (div:DF (match_operand:DF 1 "register_operand")
6989                 (match_operand:DF 2 "nonimmediate_operand")))]
6990    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6991     || (TARGET_SSE2 && TARGET_SSE_MATH)")
6993 (define_expand "divsf3"
6994   [(set (match_operand:SF 0 "register_operand")
6995         (div:SF (match_operand:SF 1 "register_operand")
6996                 (match_operand:SF 2 "nonimmediate_operand")))]
6997   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6998     || TARGET_SSE_MATH"
7000   if (TARGET_SSE_MATH
7001       && TARGET_RECIP_DIV
7002       && optimize_insn_for_speed_p ()
7003       && flag_finite_math_only && !flag_trapping_math
7004       && flag_unsafe_math_optimizations)
7005     {
7006       ix86_emit_swdivsf (operands[0], operands[1],
7007                          operands[2], SFmode);
7008       DONE;
7009     }
7012 ;; Divmod instructions.
7014 (define_expand "divmod<mode>4"
7015   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7016                    (div:SWIM248
7017                      (match_operand:SWIM248 1 "register_operand")
7018                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7019               (set (match_operand:SWIM248 3 "register_operand")
7020                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7021               (clobber (reg:CC FLAGS_REG))])])
7023 ;; Split with 8bit unsigned divide:
7024 ;;      if (dividend an divisor are in [0-255])
7025 ;;         use 8bit unsigned integer divide
7026 ;;       else
7027 ;;         use original integer divide
7028 (define_split
7029   [(set (match_operand:SWI48 0 "register_operand")
7030         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7031                     (match_operand:SWI48 3 "nonimmediate_operand")))
7032    (set (match_operand:SWI48 1 "register_operand")
7033         (mod:SWI48 (match_dup 2) (match_dup 3)))
7034    (clobber (reg:CC FLAGS_REG))]
7035   "TARGET_USE_8BIT_IDIV
7036    && TARGET_QIMODE_MATH
7037    && can_create_pseudo_p ()
7038    && !optimize_insn_for_size_p ()"
7039   [(const_int 0)]
7040   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7042 (define_insn_and_split "divmod<mode>4_1"
7043   [(set (match_operand:SWI48 0 "register_operand" "=a")
7044         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7045                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7046    (set (match_operand:SWI48 1 "register_operand" "=&d")
7047         (mod:SWI48 (match_dup 2) (match_dup 3)))
7048    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7049    (clobber (reg:CC FLAGS_REG))]
7050   ""
7051   "#"
7052   "reload_completed"
7053   [(parallel [(set (match_dup 1)
7054                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7055               (clobber (reg:CC FLAGS_REG))])
7056    (parallel [(set (match_dup 0)
7057                    (div:SWI48 (match_dup 2) (match_dup 3)))
7058               (set (match_dup 1)
7059                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7060               (use (match_dup 1))
7061               (clobber (reg:CC FLAGS_REG))])]
7063   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7065   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7066     operands[4] = operands[2];
7067   else
7068     {
7069       /* Avoid use of cltd in favor of a mov+shift.  */
7070       emit_move_insn (operands[1], operands[2]);
7071       operands[4] = operands[1];
7072     }
7074   [(set_attr "type" "multi")
7075    (set_attr "mode" "<MODE>")])
7077 (define_insn_and_split "*divmod<mode>4"
7078   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7079         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7080                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7081    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7082         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7083    (clobber (reg:CC FLAGS_REG))]
7084   ""
7085   "#"
7086   "reload_completed"
7087   [(parallel [(set (match_dup 1)
7088                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7089               (clobber (reg:CC FLAGS_REG))])
7090    (parallel [(set (match_dup 0)
7091                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7092               (set (match_dup 1)
7093                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7094               (use (match_dup 1))
7095               (clobber (reg:CC FLAGS_REG))])]
7097   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7099   if (<MODE>mode != HImode
7100       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7101     operands[4] = operands[2];
7102   else
7103     {
7104       /* Avoid use of cltd in favor of a mov+shift.  */
7105       emit_move_insn (operands[1], operands[2]);
7106       operands[4] = operands[1];
7107     }
7109   [(set_attr "type" "multi")
7110    (set_attr "mode" "<MODE>")])
7112 (define_insn "*divmod<mode>4_noext"
7113   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7114         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7115                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7116    (set (match_operand:SWIM248 1 "register_operand" "=d")
7117         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7118    (use (match_operand:SWIM248 4 "register_operand" "1"))
7119    (clobber (reg:CC FLAGS_REG))]
7120   ""
7121   "idiv{<imodesuffix>}\t%3"
7122   [(set_attr "type" "idiv")
7123    (set_attr "mode" "<MODE>")])
7125 (define_expand "divmodqi4"
7126   [(parallel [(set (match_operand:QI 0 "register_operand")
7127                    (div:QI
7128                      (match_operand:QI 1 "register_operand")
7129                      (match_operand:QI 2 "nonimmediate_operand")))
7130               (set (match_operand:QI 3 "register_operand")
7131                    (mod:QI (match_dup 1) (match_dup 2)))
7132               (clobber (reg:CC FLAGS_REG))])]
7133   "TARGET_QIMODE_MATH"
7135   rtx div, mod, insn;
7136   rtx tmp0, tmp1;
7137   
7138   tmp0 = gen_reg_rtx (HImode);
7139   tmp1 = gen_reg_rtx (HImode);
7141   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7142      in AX.  */
7143   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7144   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7146   /* Extract remainder from AH.  */
7147   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7148   insn = emit_move_insn (operands[3], tmp1);
7150   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7151   set_unique_reg_note (insn, REG_EQUAL, mod);
7153   /* Extract quotient from AL.  */
7154   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7156   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7157   set_unique_reg_note (insn, REG_EQUAL, div);
7159   DONE;
7162 ;; Divide AX by r/m8, with result stored in
7163 ;; AL <- Quotient
7164 ;; AH <- Remainder
7165 ;; Change div/mod to HImode and extend the second argument to HImode
7166 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7167 ;; combine may fail.
7168 (define_insn "divmodhiqi3"
7169   [(set (match_operand:HI 0 "register_operand" "=a")
7170         (ior:HI
7171           (ashift:HI
7172             (zero_extend:HI
7173               (truncate:QI
7174                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7175                         (sign_extend:HI
7176                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7177             (const_int 8))
7178           (zero_extend:HI
7179             (truncate:QI
7180               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7181    (clobber (reg:CC FLAGS_REG))]
7182   "TARGET_QIMODE_MATH"
7183   "idiv{b}\t%2"
7184   [(set_attr "type" "idiv")
7185    (set_attr "mode" "QI")])
7187 (define_expand "udivmod<mode>4"
7188   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7189                    (udiv:SWIM248
7190                      (match_operand:SWIM248 1 "register_operand")
7191                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7192               (set (match_operand:SWIM248 3 "register_operand")
7193                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7194               (clobber (reg:CC FLAGS_REG))])])
7196 ;; Split with 8bit unsigned divide:
7197 ;;      if (dividend an divisor are in [0-255])
7198 ;;         use 8bit unsigned integer divide
7199 ;;       else
7200 ;;         use original integer divide
7201 (define_split
7202   [(set (match_operand:SWI48 0 "register_operand")
7203         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7204                     (match_operand:SWI48 3 "nonimmediate_operand")))
7205    (set (match_operand:SWI48 1 "register_operand")
7206         (umod:SWI48 (match_dup 2) (match_dup 3)))
7207    (clobber (reg:CC FLAGS_REG))]
7208   "TARGET_USE_8BIT_IDIV
7209    && TARGET_QIMODE_MATH
7210    && can_create_pseudo_p ()
7211    && !optimize_insn_for_size_p ()"
7212   [(const_int 0)]
7213   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7215 (define_insn_and_split "udivmod<mode>4_1"
7216   [(set (match_operand:SWI48 0 "register_operand" "=a")
7217         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7218                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7219    (set (match_operand:SWI48 1 "register_operand" "=&d")
7220         (umod:SWI48 (match_dup 2) (match_dup 3)))
7221    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7222    (clobber (reg:CC FLAGS_REG))]
7223   ""
7224   "#"
7225   "reload_completed"
7226   [(set (match_dup 1) (const_int 0))
7227    (parallel [(set (match_dup 0)
7228                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7229               (set (match_dup 1)
7230                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7231               (use (match_dup 1))
7232               (clobber (reg:CC FLAGS_REG))])]
7233   ""
7234   [(set_attr "type" "multi")
7235    (set_attr "mode" "<MODE>")])
7237 (define_insn_and_split "*udivmod<mode>4"
7238   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7239         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7240                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7241    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7242         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7243    (clobber (reg:CC FLAGS_REG))]
7244   ""
7245   "#"
7246   "reload_completed"
7247   [(set (match_dup 1) (const_int 0))
7248    (parallel [(set (match_dup 0)
7249                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7250               (set (match_dup 1)
7251                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7252               (use (match_dup 1))
7253               (clobber (reg:CC FLAGS_REG))])]
7254   ""
7255   [(set_attr "type" "multi")
7256    (set_attr "mode" "<MODE>")])
7258 (define_insn "*udivmod<mode>4_noext"
7259   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7260         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7261                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7262    (set (match_operand:SWIM248 1 "register_operand" "=d")
7263         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7264    (use (match_operand:SWIM248 4 "register_operand" "1"))
7265    (clobber (reg:CC FLAGS_REG))]
7266   ""
7267   "div{<imodesuffix>}\t%3"
7268   [(set_attr "type" "idiv")
7269    (set_attr "mode" "<MODE>")])
7271 (define_expand "udivmodqi4"
7272   [(parallel [(set (match_operand:QI 0 "register_operand")
7273                    (udiv:QI
7274                      (match_operand:QI 1 "register_operand")
7275                      (match_operand:QI 2 "nonimmediate_operand")))
7276               (set (match_operand:QI 3 "register_operand")
7277                    (umod:QI (match_dup 1) (match_dup 2)))
7278               (clobber (reg:CC FLAGS_REG))])]
7279   "TARGET_QIMODE_MATH"
7281   rtx div, mod, insn;
7282   rtx tmp0, tmp1;
7283   
7284   tmp0 = gen_reg_rtx (HImode);
7285   tmp1 = gen_reg_rtx (HImode);
7287   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7288      in AX.  */
7289   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7290   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7292   /* Extract remainder from AH.  */
7293   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7294   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7295   insn = emit_move_insn (operands[3], tmp1);
7297   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7298   set_unique_reg_note (insn, REG_EQUAL, mod);
7300   /* Extract quotient from AL.  */
7301   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7303   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7304   set_unique_reg_note (insn, REG_EQUAL, div);
7306   DONE;
7309 (define_insn "udivmodhiqi3"
7310   [(set (match_operand:HI 0 "register_operand" "=a")
7311         (ior:HI
7312           (ashift:HI
7313             (zero_extend:HI
7314               (truncate:QI
7315                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7316                         (zero_extend:HI
7317                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7318             (const_int 8))
7319           (zero_extend:HI
7320             (truncate:QI
7321               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7322    (clobber (reg:CC FLAGS_REG))]
7323   "TARGET_QIMODE_MATH"
7324   "div{b}\t%2"
7325   [(set_attr "type" "idiv")
7326    (set_attr "mode" "QI")])
7328 ;; We cannot use div/idiv for double division, because it causes
7329 ;; "division by zero" on the overflow and that's not what we expect
7330 ;; from truncate.  Because true (non truncating) double division is
7331 ;; never generated, we can't create this insn anyway.
7333 ;(define_insn ""
7334 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7335 ;       (truncate:SI
7336 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7337 ;                  (zero_extend:DI
7338 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7339 ;   (set (match_operand:SI 3 "register_operand" "=d")
7340 ;       (truncate:SI
7341 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7342 ;   (clobber (reg:CC FLAGS_REG))]
7343 ;  ""
7344 ;  "div{l}\t{%2, %0|%0, %2}"
7345 ;  [(set_attr "type" "idiv")])
7347 ;;- Logical AND instructions
7349 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7350 ;; Note that this excludes ah.
7352 (define_expand "testsi_ccno_1"
7353   [(set (reg:CCNO FLAGS_REG)
7354         (compare:CCNO
7355           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7356                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7357           (const_int 0)))])
7359 (define_expand "testqi_ccz_1"
7360   [(set (reg:CCZ FLAGS_REG)
7361         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7362                              (match_operand:QI 1 "nonmemory_operand"))
7363                  (const_int 0)))])
7365 (define_expand "testdi_ccno_1"
7366   [(set (reg:CCNO FLAGS_REG)
7367         (compare:CCNO
7368           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7369                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7370           (const_int 0)))]
7371   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7373 (define_insn "*testdi_1"
7374   [(set (reg FLAGS_REG)
7375         (compare
7376          (and:DI
7377           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7378           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7379          (const_int 0)))]
7380   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7381    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7382   "@
7383    test{l}\t{%k1, %k0|%k0, %k1}
7384    test{l}\t{%k1, %k0|%k0, %k1}
7385    test{q}\t{%1, %0|%0, %1}
7386    test{q}\t{%1, %0|%0, %1}
7387    test{q}\t{%1, %0|%0, %1}"
7388   [(set_attr "type" "test")
7389    (set_attr "modrm" "0,1,0,1,1")
7390    (set_attr "mode" "SI,SI,DI,DI,DI")])
7392 (define_insn "*testqi_1_maybe_si"
7393   [(set (reg FLAGS_REG)
7394         (compare
7395           (and:QI
7396             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7397             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7398           (const_int 0)))]
7399    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7400     && ix86_match_ccmode (insn,
7401                          CONST_INT_P (operands[1])
7402                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7404   if (which_alternative == 3)
7405     {
7406       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7407         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7408       return "test{l}\t{%1, %k0|%k0, %1}";
7409     }
7410   return "test{b}\t{%1, %0|%0, %1}";
7412   [(set_attr "type" "test")
7413    (set_attr "modrm" "0,1,1,1")
7414    (set_attr "mode" "QI,QI,QI,SI")
7415    (set_attr "pent_pair" "uv,np,uv,np")])
7417 (define_insn "*test<mode>_1"
7418   [(set (reg FLAGS_REG)
7419         (compare
7420          (and:SWI124
7421           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7422           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7423          (const_int 0)))]
7424   "ix86_match_ccmode (insn, CCNOmode)
7425    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7426   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7427   [(set_attr "type" "test")
7428    (set_attr "modrm" "0,1,1")
7429    (set_attr "mode" "<MODE>")
7430    (set_attr "pent_pair" "uv,np,uv")])
7432 (define_expand "testqi_ext_ccno_0"
7433   [(set (reg:CCNO FLAGS_REG)
7434         (compare:CCNO
7435           (and:SI
7436             (zero_extract:SI
7437               (match_operand 0 "ext_register_operand")
7438               (const_int 8)
7439               (const_int 8))
7440             (match_operand 1 "const_int_operand"))
7441           (const_int 0)))])
7443 (define_insn "*testqi_ext_0"
7444   [(set (reg FLAGS_REG)
7445         (compare
7446           (and:SI
7447             (zero_extract:SI
7448               (match_operand 0 "ext_register_operand" "Q")
7449               (const_int 8)
7450               (const_int 8))
7451             (match_operand 1 "const_int_operand" "n"))
7452           (const_int 0)))]
7453   "ix86_match_ccmode (insn, CCNOmode)"
7454   "test{b}\t{%1, %h0|%h0, %1}"
7455   [(set_attr "type" "test")
7456    (set_attr "mode" "QI")
7457    (set_attr "length_immediate" "1")
7458    (set_attr "modrm" "1")
7459    (set_attr "pent_pair" "np")])
7461 (define_insn "*testqi_ext_1_rex64"
7462   [(set (reg FLAGS_REG)
7463         (compare
7464           (and:SI
7465             (zero_extract:SI
7466               (match_operand 0 "ext_register_operand" "Q")
7467               (const_int 8)
7468               (const_int 8))
7469             (zero_extend:SI
7470               (match_operand:QI 1 "register_operand" "Q")))
7471           (const_int 0)))]
7472   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7473   "test{b}\t{%1, %h0|%h0, %1}"
7474   [(set_attr "type" "test")
7475    (set_attr "mode" "QI")])
7477 (define_insn "*testqi_ext_1"
7478   [(set (reg FLAGS_REG)
7479         (compare
7480           (and:SI
7481             (zero_extract:SI
7482               (match_operand 0 "ext_register_operand" "Q")
7483               (const_int 8)
7484               (const_int 8))
7485             (zero_extend:SI
7486               (match_operand:QI 1 "general_operand" "Qm")))
7487           (const_int 0)))]
7488   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7489   "test{b}\t{%1, %h0|%h0, %1}"
7490   [(set_attr "type" "test")
7491    (set_attr "mode" "QI")])
7493 (define_insn "*testqi_ext_2"
7494   [(set (reg FLAGS_REG)
7495         (compare
7496           (and:SI
7497             (zero_extract:SI
7498               (match_operand 0 "ext_register_operand" "Q")
7499               (const_int 8)
7500               (const_int 8))
7501             (zero_extract:SI
7502               (match_operand 1 "ext_register_operand" "Q")
7503               (const_int 8)
7504               (const_int 8)))
7505           (const_int 0)))]
7506   "ix86_match_ccmode (insn, CCNOmode)"
7507   "test{b}\t{%h1, %h0|%h0, %h1}"
7508   [(set_attr "type" "test")
7509    (set_attr "mode" "QI")])
7511 (define_insn "*testqi_ext_3_rex64"
7512   [(set (reg FLAGS_REG)
7513         (compare (zero_extract:DI
7514                    (match_operand 0 "nonimmediate_operand" "rm")
7515                    (match_operand:DI 1 "const_int_operand")
7516                    (match_operand:DI 2 "const_int_operand"))
7517                  (const_int 0)))]
7518   "TARGET_64BIT
7519    && ix86_match_ccmode (insn, CCNOmode)
7520    && INTVAL (operands[1]) > 0
7521    && INTVAL (operands[2]) >= 0
7522    /* Ensure that resulting mask is zero or sign extended operand.  */
7523    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7524        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7525            && INTVAL (operands[1]) > 32))
7526    && (GET_MODE (operands[0]) == SImode
7527        || GET_MODE (operands[0]) == DImode
7528        || GET_MODE (operands[0]) == HImode
7529        || GET_MODE (operands[0]) == QImode)"
7530   "#")
7532 ;; Combine likes to form bit extractions for some tests.  Humor it.
7533 (define_insn "*testqi_ext_3"
7534   [(set (reg FLAGS_REG)
7535         (compare (zero_extract:SI
7536                    (match_operand 0 "nonimmediate_operand" "rm")
7537                    (match_operand:SI 1 "const_int_operand")
7538                    (match_operand:SI 2 "const_int_operand"))
7539                  (const_int 0)))]
7540   "ix86_match_ccmode (insn, CCNOmode)
7541    && INTVAL (operands[1]) > 0
7542    && INTVAL (operands[2]) >= 0
7543    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7544    && (GET_MODE (operands[0]) == SImode
7545        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7546        || GET_MODE (operands[0]) == HImode
7547        || GET_MODE (operands[0]) == QImode)"
7548   "#")
7550 (define_split
7551   [(set (match_operand 0 "flags_reg_operand")
7552         (match_operator 1 "compare_operator"
7553           [(zero_extract
7554              (match_operand 2 "nonimmediate_operand")
7555              (match_operand 3 "const_int_operand")
7556              (match_operand 4 "const_int_operand"))
7557            (const_int 0)]))]
7558   "ix86_match_ccmode (insn, CCNOmode)"
7559   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7561   rtx val = operands[2];
7562   HOST_WIDE_INT len = INTVAL (operands[3]);
7563   HOST_WIDE_INT pos = INTVAL (operands[4]);
7564   HOST_WIDE_INT mask;
7565   enum machine_mode mode, submode;
7567   mode = GET_MODE (val);
7568   if (MEM_P (val))
7569     {
7570       /* ??? Combine likes to put non-volatile mem extractions in QImode
7571          no matter the size of the test.  So find a mode that works.  */
7572       if (! MEM_VOLATILE_P (val))
7573         {
7574           mode = smallest_mode_for_size (pos + len, MODE_INT);
7575           val = adjust_address (val, mode, 0);
7576         }
7577     }
7578   else if (GET_CODE (val) == SUBREG
7579            && (submode = GET_MODE (SUBREG_REG (val)),
7580                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7581            && pos + len <= GET_MODE_BITSIZE (submode)
7582            && GET_MODE_CLASS (submode) == MODE_INT)
7583     {
7584       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7585       mode = submode;
7586       val = SUBREG_REG (val);
7587     }
7588   else if (mode == HImode && pos + len <= 8)
7589     {
7590       /* Small HImode tests can be converted to QImode.  */
7591       mode = QImode;
7592       val = gen_lowpart (QImode, val);
7593     }
7595   if (len == HOST_BITS_PER_WIDE_INT)
7596     mask = -1;
7597   else
7598     mask = ((HOST_WIDE_INT)1 << len) - 1;
7599   mask <<= pos;
7601   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7604 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7605 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7606 ;; this is relatively important trick.
7607 ;; Do the conversion only post-reload to avoid limiting of the register class
7608 ;; to QI regs.
7609 (define_split
7610   [(set (match_operand 0 "flags_reg_operand")
7611         (match_operator 1 "compare_operator"
7612           [(and (match_operand 2 "register_operand")
7613                 (match_operand 3 "const_int_operand"))
7614            (const_int 0)]))]
7615    "reload_completed
7616     && QI_REG_P (operands[2])
7617     && GET_MODE (operands[2]) != QImode
7618     && ((ix86_match_ccmode (insn, CCZmode)
7619          && !(INTVAL (operands[3]) & ~(255 << 8)))
7620         || (ix86_match_ccmode (insn, CCNOmode)
7621             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7622   [(set (match_dup 0)
7623         (match_op_dup 1
7624           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7625                    (match_dup 3))
7626            (const_int 0)]))]
7628   operands[2] = gen_lowpart (SImode, operands[2]);
7629   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7632 (define_split
7633   [(set (match_operand 0 "flags_reg_operand")
7634         (match_operator 1 "compare_operator"
7635           [(and (match_operand 2 "nonimmediate_operand")
7636                 (match_operand 3 "const_int_operand"))
7637            (const_int 0)]))]
7638    "reload_completed
7639     && GET_MODE (operands[2]) != QImode
7640     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7641     && ((ix86_match_ccmode (insn, CCZmode)
7642          && !(INTVAL (operands[3]) & ~255))
7643         || (ix86_match_ccmode (insn, CCNOmode)
7644             && !(INTVAL (operands[3]) & ~127)))"
7645   [(set (match_dup 0)
7646         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7647                          (const_int 0)]))]
7649   operands[2] = gen_lowpart (QImode, operands[2]);
7650   operands[3] = gen_lowpart (QImode, operands[3]);
7653 ;; %%% This used to optimize known byte-wide and operations to memory,
7654 ;; and sometimes to QImode registers.  If this is considered useful,
7655 ;; it should be done with splitters.
7657 (define_expand "and<mode>3"
7658   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7659         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7660                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7661   ""
7662   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7664 (define_insn "*anddi_1"
7665   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7666         (and:DI
7667          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7668          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7669    (clobber (reg:CC FLAGS_REG))]
7670   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7672   switch (get_attr_type (insn))
7673     {
7674     case TYPE_IMOVX:
7675       return "#";
7677     default:
7678       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7679       if (get_attr_mode (insn) == MODE_SI)
7680         return "and{l}\t{%k2, %k0|%k0, %k2}";
7681       else
7682         return "and{q}\t{%2, %0|%0, %2}";
7683     }
7685   [(set_attr "type" "alu,alu,alu,imovx")
7686    (set_attr "length_immediate" "*,*,*,0")
7687    (set (attr "prefix_rex")
7688      (if_then_else
7689        (and (eq_attr "type" "imovx")
7690             (and (match_test "INTVAL (operands[2]) == 0xff")
7691                  (match_operand 1 "ext_QIreg_operand")))
7692        (const_string "1")
7693        (const_string "*")))
7694    (set_attr "mode" "SI,DI,DI,SI")])
7696 (define_insn "*andsi_1"
7697   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7698         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7699                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7700    (clobber (reg:CC FLAGS_REG))]
7701   "ix86_binary_operator_ok (AND, SImode, operands)"
7703   switch (get_attr_type (insn))
7704     {
7705     case TYPE_IMOVX:
7706       return "#";
7708     default:
7709       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7710       return "and{l}\t{%2, %0|%0, %2}";
7711     }
7713   [(set_attr "type" "alu,alu,imovx")
7714    (set (attr "prefix_rex")
7715      (if_then_else
7716        (and (eq_attr "type" "imovx")
7717             (and (match_test "INTVAL (operands[2]) == 0xff")
7718                  (match_operand 1 "ext_QIreg_operand")))
7719        (const_string "1")
7720        (const_string "*")))
7721    (set_attr "length_immediate" "*,*,0")
7722    (set_attr "mode" "SI")])
7724 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7725 (define_insn "*andsi_1_zext"
7726   [(set (match_operand:DI 0 "register_operand" "=r")
7727         (zero_extend:DI
7728           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7729                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7730    (clobber (reg:CC FLAGS_REG))]
7731   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7732   "and{l}\t{%2, %k0|%k0, %2}"
7733   [(set_attr "type" "alu")
7734    (set_attr "mode" "SI")])
7736 (define_insn "*andhi_1"
7737   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7738         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7739                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7740    (clobber (reg:CC FLAGS_REG))]
7741   "ix86_binary_operator_ok (AND, HImode, operands)"
7743   switch (get_attr_type (insn))
7744     {
7745     case TYPE_IMOVX:
7746       return "#";
7748     default:
7749       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7750       return "and{w}\t{%2, %0|%0, %2}";
7751     }
7753   [(set_attr "type" "alu,alu,imovx")
7754    (set_attr "length_immediate" "*,*,0")
7755    (set (attr "prefix_rex")
7756      (if_then_else
7757        (and (eq_attr "type" "imovx")
7758             (match_operand 1 "ext_QIreg_operand"))
7759        (const_string "1")
7760        (const_string "*")))
7761    (set_attr "mode" "HI,HI,SI")])
7763 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7764 (define_insn "*andqi_1"
7765   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7766         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7767                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7768    (clobber (reg:CC FLAGS_REG))]
7769   "ix86_binary_operator_ok (AND, QImode, operands)"
7770   "@
7771    and{b}\t{%2, %0|%0, %2}
7772    and{b}\t{%2, %0|%0, %2}
7773    and{l}\t{%k2, %k0|%k0, %k2}"
7774   [(set_attr "type" "alu")
7775    (set_attr "mode" "QI,QI,SI")])
7777 (define_insn "*andqi_1_slp"
7778   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7779         (and:QI (match_dup 0)
7780                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7781    (clobber (reg:CC FLAGS_REG))]
7782   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7783    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7784   "and{b}\t{%1, %0|%0, %1}"
7785   [(set_attr "type" "alu1")
7786    (set_attr "mode" "QI")])
7788 (define_split
7789   [(set (match_operand:SWI248 0 "register_operand")
7790         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7791                     (match_operand:SWI248 2 "const_int_operand")))
7792    (clobber (reg:CC FLAGS_REG))]
7793   "reload_completed
7794    && true_regnum (operands[0]) != true_regnum (operands[1])"
7795   [(const_int 0)]
7797   enum machine_mode mode;
7799   if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7800     mode = SImode;
7801   else if (INTVAL (operands[2]) == 0xffff)
7802     mode = HImode;
7803   else
7804     {
7805       gcc_assert (INTVAL (operands[2]) == 0xff);
7806       mode = QImode;
7807     }
7809   operands[1] = gen_lowpart (mode, operands[1]);
7811   if (mode == SImode)
7812     emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
7813   else
7814     {
7815       rtx (*insn) (rtx, rtx);
7817       /* Zero extend to SImode to avoid partial register stalls.  */
7818       operands[0] = gen_lowpart (SImode, operands[0]);
7820       insn = (mode == HImode) ? gen_zero_extendhisi2 : gen_zero_extendqisi2;
7821       emit_insn (insn (operands[0], operands[1]));
7822     }
7823   DONE;
7826 (define_split
7827   [(set (match_operand 0 "register_operand")
7828         (and (match_dup 0)
7829              (const_int -65536)))
7830    (clobber (reg:CC FLAGS_REG))]
7831   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7832     || optimize_function_for_size_p (cfun)"
7833   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7834   "operands[1] = gen_lowpart (HImode, operands[0]);")
7836 (define_split
7837   [(set (match_operand 0 "ext_register_operand")
7838         (and (match_dup 0)
7839              (const_int -256)))
7840    (clobber (reg:CC FLAGS_REG))]
7841   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7842    && reload_completed"
7843   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7844   "operands[1] = gen_lowpart (QImode, operands[0]);")
7846 (define_split
7847   [(set (match_operand 0 "ext_register_operand")
7848         (and (match_dup 0)
7849              (const_int -65281)))
7850    (clobber (reg:CC FLAGS_REG))]
7851   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7852    && reload_completed"
7853   [(parallel [(set (zero_extract:SI (match_dup 0)
7854                                     (const_int 8)
7855                                     (const_int 8))
7856                    (xor:SI
7857                      (zero_extract:SI (match_dup 0)
7858                                       (const_int 8)
7859                                       (const_int 8))
7860                      (zero_extract:SI (match_dup 0)
7861                                       (const_int 8)
7862                                       (const_int 8))))
7863               (clobber (reg:CC FLAGS_REG))])]
7864   "operands[0] = gen_lowpart (SImode, operands[0]);")
7866 (define_insn "*anddi_2"
7867   [(set (reg FLAGS_REG)
7868         (compare
7869          (and:DI
7870           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7871           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7872          (const_int 0)))
7873    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7874         (and:DI (match_dup 1) (match_dup 2)))]
7875   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7876    && ix86_binary_operator_ok (AND, DImode, operands)"
7877   "@
7878    and{l}\t{%k2, %k0|%k0, %k2}
7879    and{q}\t{%2, %0|%0, %2}
7880    and{q}\t{%2, %0|%0, %2}"
7881   [(set_attr "type" "alu")
7882    (set_attr "mode" "SI,DI,DI")])
7884 (define_insn "*andqi_2_maybe_si"
7885   [(set (reg FLAGS_REG)
7886         (compare (and:QI
7887                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7888                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7889                  (const_int 0)))
7890    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7891         (and:QI (match_dup 1) (match_dup 2)))]
7892   "ix86_binary_operator_ok (AND, QImode, operands)
7893    && ix86_match_ccmode (insn,
7894                          CONST_INT_P (operands[2])
7895                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7897   if (which_alternative == 2)
7898     {
7899       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7900         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7901       return "and{l}\t{%2, %k0|%k0, %2}";
7902     }
7903   return "and{b}\t{%2, %0|%0, %2}";
7905   [(set_attr "type" "alu")
7906    (set_attr "mode" "QI,QI,SI")])
7908 (define_insn "*and<mode>_2"
7909   [(set (reg FLAGS_REG)
7910         (compare (and:SWI124
7911                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7912                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7913                  (const_int 0)))
7914    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7915         (and:SWI124 (match_dup 1) (match_dup 2)))]
7916   "ix86_match_ccmode (insn, CCNOmode)
7917    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7918   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7919   [(set_attr "type" "alu")
7920    (set_attr "mode" "<MODE>")])
7922 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7923 (define_insn "*andsi_2_zext"
7924   [(set (reg FLAGS_REG)
7925         (compare (and:SI
7926                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7927                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7928                  (const_int 0)))
7929    (set (match_operand:DI 0 "register_operand" "=r")
7930         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7931   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7932    && ix86_binary_operator_ok (AND, SImode, operands)"
7933   "and{l}\t{%2, %k0|%k0, %2}"
7934   [(set_attr "type" "alu")
7935    (set_attr "mode" "SI")])
7937 (define_insn "*andqi_2_slp"
7938   [(set (reg FLAGS_REG)
7939         (compare (and:QI
7940                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7941                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7942                  (const_int 0)))
7943    (set (strict_low_part (match_dup 0))
7944         (and:QI (match_dup 0) (match_dup 1)))]
7945   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7946    && ix86_match_ccmode (insn, CCNOmode)
7947    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7948   "and{b}\t{%1, %0|%0, %1}"
7949   [(set_attr "type" "alu1")
7950    (set_attr "mode" "QI")])
7952 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7953 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7954 ;; for a QImode operand, which of course failed.
7955 (define_insn "andqi_ext_0"
7956   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7957                          (const_int 8)
7958                          (const_int 8))
7959         (and:SI
7960           (zero_extract:SI
7961             (match_operand 1 "ext_register_operand" "0")
7962             (const_int 8)
7963             (const_int 8))
7964           (match_operand 2 "const_int_operand" "n")))
7965    (clobber (reg:CC FLAGS_REG))]
7966   ""
7967   "and{b}\t{%2, %h0|%h0, %2}"
7968   [(set_attr "type" "alu")
7969    (set_attr "length_immediate" "1")
7970    (set_attr "modrm" "1")
7971    (set_attr "mode" "QI")])
7973 ;; Generated by peephole translating test to and.  This shows up
7974 ;; often in fp comparisons.
7975 (define_insn "*andqi_ext_0_cc"
7976   [(set (reg FLAGS_REG)
7977         (compare
7978           (and:SI
7979             (zero_extract:SI
7980               (match_operand 1 "ext_register_operand" "0")
7981               (const_int 8)
7982               (const_int 8))
7983             (match_operand 2 "const_int_operand" "n"))
7984           (const_int 0)))
7985    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7986                          (const_int 8)
7987                          (const_int 8))
7988         (and:SI
7989           (zero_extract:SI
7990             (match_dup 1)
7991             (const_int 8)
7992             (const_int 8))
7993           (match_dup 2)))]
7994   "ix86_match_ccmode (insn, CCNOmode)"
7995   "and{b}\t{%2, %h0|%h0, %2}"
7996   [(set_attr "type" "alu")
7997    (set_attr "length_immediate" "1")
7998    (set_attr "modrm" "1")
7999    (set_attr "mode" "QI")])
8001 (define_insn "*andqi_ext_1_rex64"
8002   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8003                          (const_int 8)
8004                          (const_int 8))
8005         (and:SI
8006           (zero_extract:SI
8007             (match_operand 1 "ext_register_operand" "0")
8008             (const_int 8)
8009             (const_int 8))
8010           (zero_extend:SI
8011             (match_operand 2 "ext_register_operand" "Q"))))
8012    (clobber (reg:CC FLAGS_REG))]
8013   "TARGET_64BIT"
8014   "and{b}\t{%2, %h0|%h0, %2}"
8015   [(set_attr "type" "alu")
8016    (set_attr "length_immediate" "0")
8017    (set_attr "mode" "QI")])
8019 (define_insn "*andqi_ext_1"
8020   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8021                          (const_int 8)
8022                          (const_int 8))
8023         (and:SI
8024           (zero_extract:SI
8025             (match_operand 1 "ext_register_operand" "0")
8026             (const_int 8)
8027             (const_int 8))
8028           (zero_extend:SI
8029             (match_operand:QI 2 "general_operand" "Qm"))))
8030    (clobber (reg:CC FLAGS_REG))]
8031   "!TARGET_64BIT"
8032   "and{b}\t{%2, %h0|%h0, %2}"
8033   [(set_attr "type" "alu")
8034    (set_attr "length_immediate" "0")
8035    (set_attr "mode" "QI")])
8037 (define_insn "*andqi_ext_2"
8038   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8039                          (const_int 8)
8040                          (const_int 8))
8041         (and:SI
8042           (zero_extract:SI
8043             (match_operand 1 "ext_register_operand" "%0")
8044             (const_int 8)
8045             (const_int 8))
8046           (zero_extract:SI
8047             (match_operand 2 "ext_register_operand" "Q")
8048             (const_int 8)
8049             (const_int 8))))
8050    (clobber (reg:CC FLAGS_REG))]
8051   ""
8052   "and{b}\t{%h2, %h0|%h0, %h2}"
8053   [(set_attr "type" "alu")
8054    (set_attr "length_immediate" "0")
8055    (set_attr "mode" "QI")])
8057 ;; Convert wide AND instructions with immediate operand to shorter QImode
8058 ;; equivalents when possible.
8059 ;; Don't do the splitting with memory operands, since it introduces risk
8060 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8061 ;; for size, but that can (should?) be handled by generic code instead.
8062 (define_split
8063   [(set (match_operand 0 "register_operand")
8064         (and (match_operand 1 "register_operand")
8065              (match_operand 2 "const_int_operand")))
8066    (clobber (reg:CC FLAGS_REG))]
8067    "reload_completed
8068     && QI_REG_P (operands[0])
8069     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8070     && !(~INTVAL (operands[2]) & ~(255 << 8))
8071     && GET_MODE (operands[0]) != QImode"
8072   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8073                    (and:SI (zero_extract:SI (match_dup 1)
8074                                             (const_int 8) (const_int 8))
8075                            (match_dup 2)))
8076               (clobber (reg:CC FLAGS_REG))])]
8078   operands[0] = gen_lowpart (SImode, operands[0]);
8079   operands[1] = gen_lowpart (SImode, operands[1]);
8080   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8083 ;; Since AND can be encoded with sign extended immediate, this is only
8084 ;; profitable when 7th bit is not set.
8085 (define_split
8086   [(set (match_operand 0 "register_operand")
8087         (and (match_operand 1 "general_operand")
8088              (match_operand 2 "const_int_operand")))
8089    (clobber (reg:CC FLAGS_REG))]
8090    "reload_completed
8091     && ANY_QI_REG_P (operands[0])
8092     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8093     && !(~INTVAL (operands[2]) & ~255)
8094     && !(INTVAL (operands[2]) & 128)
8095     && GET_MODE (operands[0]) != QImode"
8096   [(parallel [(set (strict_low_part (match_dup 0))
8097                    (and:QI (match_dup 1)
8098                            (match_dup 2)))
8099               (clobber (reg:CC FLAGS_REG))])]
8101   operands[0] = gen_lowpart (QImode, operands[0]);
8102   operands[1] = gen_lowpart (QImode, operands[1]);
8103   operands[2] = gen_lowpart (QImode, operands[2]);
8106 ;; Logical inclusive and exclusive OR instructions
8108 ;; %%% This used to optimize known byte-wide and operations to memory.
8109 ;; If this is considered useful, it should be done with splitters.
8111 (define_expand "<code><mode>3"
8112   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8113         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8114                      (match_operand:SWIM 2 "<general_operand>")))]
8115   ""
8116   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8118 (define_insn "*<code><mode>_1"
8119   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8120         (any_or:SWI248
8121          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8122          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8123    (clobber (reg:CC FLAGS_REG))]
8124   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8125   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8126   [(set_attr "type" "alu")
8127    (set_attr "mode" "<MODE>")])
8129 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8130 (define_insn "*<code>qi_1"
8131   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8132         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8133                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8134    (clobber (reg:CC FLAGS_REG))]
8135   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8136   "@
8137    <logic>{b}\t{%2, %0|%0, %2}
8138    <logic>{b}\t{%2, %0|%0, %2}
8139    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8140   [(set_attr "type" "alu")
8141    (set_attr "mode" "QI,QI,SI")])
8143 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8144 (define_insn "*<code>si_1_zext"
8145   [(set (match_operand:DI 0 "register_operand" "=r")
8146         (zero_extend:DI
8147          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8148                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8149    (clobber (reg:CC FLAGS_REG))]
8150   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8151   "<logic>{l}\t{%2, %k0|%k0, %2}"
8152   [(set_attr "type" "alu")
8153    (set_attr "mode" "SI")])
8155 (define_insn "*<code>si_1_zext_imm"
8156   [(set (match_operand:DI 0 "register_operand" "=r")
8157         (any_or:DI
8158          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8159          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8160    (clobber (reg:CC FLAGS_REG))]
8161   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8162   "<logic>{l}\t{%2, %k0|%k0, %2}"
8163   [(set_attr "type" "alu")
8164    (set_attr "mode" "SI")])
8166 (define_insn "*<code>qi_1_slp"
8167   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8168         (any_or:QI (match_dup 0)
8169                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8170    (clobber (reg:CC FLAGS_REG))]
8171   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8172    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8173   "<logic>{b}\t{%1, %0|%0, %1}"
8174   [(set_attr "type" "alu1")
8175    (set_attr "mode" "QI")])
8177 (define_insn "*<code><mode>_2"
8178   [(set (reg FLAGS_REG)
8179         (compare (any_or:SWI
8180                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8181                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8182                  (const_int 0)))
8183    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8184         (any_or:SWI (match_dup 1) (match_dup 2)))]
8185   "ix86_match_ccmode (insn, CCNOmode)
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>")])
8191 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8192 ;; ??? Special case for immediate operand is missing - it is tricky.
8193 (define_insn "*<code>si_2_zext"
8194   [(set (reg FLAGS_REG)
8195         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8196                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8197                  (const_int 0)))
8198    (set (match_operand:DI 0 "register_operand" "=r")
8199         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8200   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8201    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8202   "<logic>{l}\t{%2, %k0|%k0, %2}"
8203   [(set_attr "type" "alu")
8204    (set_attr "mode" "SI")])
8206 (define_insn "*<code>si_2_zext_imm"
8207   [(set (reg FLAGS_REG)
8208         (compare (any_or:SI
8209                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8210                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8211                  (const_int 0)))
8212    (set (match_operand:DI 0 "register_operand" "=r")
8213         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8214   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8215    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8216   "<logic>{l}\t{%2, %k0|%k0, %2}"
8217   [(set_attr "type" "alu")
8218    (set_attr "mode" "SI")])
8220 (define_insn "*<code>qi_2_slp"
8221   [(set (reg FLAGS_REG)
8222         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8223                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8224                  (const_int 0)))
8225    (set (strict_low_part (match_dup 0))
8226         (any_or:QI (match_dup 0) (match_dup 1)))]
8227   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8228    && ix86_match_ccmode (insn, CCNOmode)
8229    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8230   "<logic>{b}\t{%1, %0|%0, %1}"
8231   [(set_attr "type" "alu1")
8232    (set_attr "mode" "QI")])
8234 (define_insn "*<code><mode>_3"
8235   [(set (reg FLAGS_REG)
8236         (compare (any_or:SWI
8237                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8238                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8239                  (const_int 0)))
8240    (clobber (match_scratch:SWI 0 "=<r>"))]
8241   "ix86_match_ccmode (insn, CCNOmode)
8242    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8243   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8244   [(set_attr "type" "alu")
8245    (set_attr "mode" "<MODE>")])
8247 (define_insn "*<code>qi_ext_0"
8248   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8249                          (const_int 8)
8250                          (const_int 8))
8251         (any_or:SI
8252           (zero_extract:SI
8253             (match_operand 1 "ext_register_operand" "0")
8254             (const_int 8)
8255             (const_int 8))
8256           (match_operand 2 "const_int_operand" "n")))
8257    (clobber (reg:CC FLAGS_REG))]
8258   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8259   "<logic>{b}\t{%2, %h0|%h0, %2}"
8260   [(set_attr "type" "alu")
8261    (set_attr "length_immediate" "1")
8262    (set_attr "modrm" "1")
8263    (set_attr "mode" "QI")])
8265 (define_insn "*<code>qi_ext_1_rex64"
8266   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8267                          (const_int 8)
8268                          (const_int 8))
8269         (any_or:SI
8270           (zero_extract:SI
8271             (match_operand 1 "ext_register_operand" "0")
8272             (const_int 8)
8273             (const_int 8))
8274           (zero_extend:SI
8275             (match_operand 2 "ext_register_operand" "Q"))))
8276    (clobber (reg:CC FLAGS_REG))]
8277   "TARGET_64BIT
8278    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8279   "<logic>{b}\t{%2, %h0|%h0, %2}"
8280   [(set_attr "type" "alu")
8281    (set_attr "length_immediate" "0")
8282    (set_attr "mode" "QI")])
8284 (define_insn "*<code>qi_ext_1"
8285   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8286                          (const_int 8)
8287                          (const_int 8))
8288         (any_or:SI
8289           (zero_extract:SI
8290             (match_operand 1 "ext_register_operand" "0")
8291             (const_int 8)
8292             (const_int 8))
8293           (zero_extend:SI
8294             (match_operand:QI 2 "general_operand" "Qm"))))
8295    (clobber (reg:CC FLAGS_REG))]
8296   "!TARGET_64BIT
8297    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8298   "<logic>{b}\t{%2, %h0|%h0, %2}"
8299   [(set_attr "type" "alu")
8300    (set_attr "length_immediate" "0")
8301    (set_attr "mode" "QI")])
8303 (define_insn "*<code>qi_ext_2"
8304   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8305                          (const_int 8)
8306                          (const_int 8))
8307         (any_or:SI
8308           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8309                            (const_int 8)
8310                            (const_int 8))
8311           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8312                            (const_int 8)
8313                            (const_int 8))))
8314    (clobber (reg:CC FLAGS_REG))]
8315   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8316   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8317   [(set_attr "type" "alu")
8318    (set_attr "length_immediate" "0")
8319    (set_attr "mode" "QI")])
8321 (define_split
8322   [(set (match_operand 0 "register_operand")
8323         (any_or (match_operand 1 "register_operand")
8324                 (match_operand 2 "const_int_operand")))
8325    (clobber (reg:CC FLAGS_REG))]
8326    "reload_completed
8327     && QI_REG_P (operands[0])
8328     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8329     && !(INTVAL (operands[2]) & ~(255 << 8))
8330     && GET_MODE (operands[0]) != QImode"
8331   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8332                    (any_or:SI (zero_extract:SI (match_dup 1)
8333                                                (const_int 8) (const_int 8))
8334                               (match_dup 2)))
8335               (clobber (reg:CC FLAGS_REG))])]
8337   operands[0] = gen_lowpart (SImode, operands[0]);
8338   operands[1] = gen_lowpart (SImode, operands[1]);
8339   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8342 ;; Since OR can be encoded with sign extended immediate, this is only
8343 ;; profitable when 7th bit is set.
8344 (define_split
8345   [(set (match_operand 0 "register_operand")
8346         (any_or (match_operand 1 "general_operand")
8347                 (match_operand 2 "const_int_operand")))
8348    (clobber (reg:CC FLAGS_REG))]
8349    "reload_completed
8350     && ANY_QI_REG_P (operands[0])
8351     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8352     && !(INTVAL (operands[2]) & ~255)
8353     && (INTVAL (operands[2]) & 128)
8354     && GET_MODE (operands[0]) != QImode"
8355   [(parallel [(set (strict_low_part (match_dup 0))
8356                    (any_or:QI (match_dup 1)
8357                               (match_dup 2)))
8358               (clobber (reg:CC FLAGS_REG))])]
8360   operands[0] = gen_lowpart (QImode, operands[0]);
8361   operands[1] = gen_lowpart (QImode, operands[1]);
8362   operands[2] = gen_lowpart (QImode, operands[2]);
8365 (define_expand "xorqi_cc_ext_1"
8366   [(parallel [
8367      (set (reg:CCNO FLAGS_REG)
8368           (compare:CCNO
8369             (xor:SI
8370               (zero_extract:SI
8371                 (match_operand 1 "ext_register_operand")
8372                 (const_int 8)
8373                 (const_int 8))
8374               (match_operand:QI 2 "general_operand"))
8375             (const_int 0)))
8376      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8377                            (const_int 8)
8378                            (const_int 8))
8379           (xor:SI
8380             (zero_extract:SI
8381              (match_dup 1)
8382              (const_int 8)
8383              (const_int 8))
8384             (match_dup 2)))])])
8386 (define_insn "*xorqi_cc_ext_1_rex64"
8387   [(set (reg FLAGS_REG)
8388         (compare
8389           (xor:SI
8390             (zero_extract:SI
8391               (match_operand 1 "ext_register_operand" "0")
8392               (const_int 8)
8393               (const_int 8))
8394             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8395           (const_int 0)))
8396    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8397                          (const_int 8)
8398                          (const_int 8))
8399         (xor:SI
8400           (zero_extract:SI
8401            (match_dup 1)
8402            (const_int 8)
8403            (const_int 8))
8404           (match_dup 2)))]
8405   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8406   "xor{b}\t{%2, %h0|%h0, %2}"
8407   [(set_attr "type" "alu")
8408    (set_attr "modrm" "1")
8409    (set_attr "mode" "QI")])
8411 (define_insn "*xorqi_cc_ext_1"
8412   [(set (reg FLAGS_REG)
8413         (compare
8414           (xor:SI
8415             (zero_extract:SI
8416               (match_operand 1 "ext_register_operand" "0")
8417               (const_int 8)
8418               (const_int 8))
8419             (match_operand:QI 2 "general_operand" "qmn"))
8420           (const_int 0)))
8421    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8422                          (const_int 8)
8423                          (const_int 8))
8424         (xor:SI
8425           (zero_extract:SI
8426            (match_dup 1)
8427            (const_int 8)
8428            (const_int 8))
8429           (match_dup 2)))]
8430   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8431   "xor{b}\t{%2, %h0|%h0, %2}"
8432   [(set_attr "type" "alu")
8433    (set_attr "modrm" "1")
8434    (set_attr "mode" "QI")])
8436 ;; Negation instructions
8438 (define_expand "neg<mode>2"
8439   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8440         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8441   ""
8442   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8444 (define_insn_and_split "*neg<dwi>2_doubleword"
8445   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8446         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8447    (clobber (reg:CC FLAGS_REG))]
8448   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8449   "#"
8450   "reload_completed"
8451   [(parallel
8452     [(set (reg:CCZ FLAGS_REG)
8453           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8454      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8455    (parallel
8456     [(set (match_dup 2)
8457           (plus:DWIH (match_dup 3)
8458                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8459                                 (const_int 0))))
8460      (clobber (reg:CC FLAGS_REG))])
8461    (parallel
8462     [(set (match_dup 2)
8463           (neg:DWIH (match_dup 2)))
8464      (clobber (reg:CC FLAGS_REG))])]
8465   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8467 (define_insn "*neg<mode>2_1"
8468   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8469         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8470    (clobber (reg:CC FLAGS_REG))]
8471   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8472   "neg{<imodesuffix>}\t%0"
8473   [(set_attr "type" "negnot")
8474    (set_attr "mode" "<MODE>")])
8476 ;; Combine is quite creative about this pattern.
8477 (define_insn "*negsi2_1_zext"
8478   [(set (match_operand:DI 0 "register_operand" "=r")
8479         (lshiftrt:DI
8480           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8481                              (const_int 32)))
8482         (const_int 32)))
8483    (clobber (reg:CC FLAGS_REG))]
8484   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8485   "neg{l}\t%k0"
8486   [(set_attr "type" "negnot")
8487    (set_attr "mode" "SI")])
8489 ;; The problem with neg is that it does not perform (compare x 0),
8490 ;; it really performs (compare 0 x), which leaves us with the zero
8491 ;; flag being the only useful item.
8493 (define_insn "*neg<mode>2_cmpz"
8494   [(set (reg:CCZ FLAGS_REG)
8495         (compare:CCZ
8496           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8497                    (const_int 0)))
8498    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8499         (neg:SWI (match_dup 1)))]
8500   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8501   "neg{<imodesuffix>}\t%0"
8502   [(set_attr "type" "negnot")
8503    (set_attr "mode" "<MODE>")])
8505 (define_insn "*negsi2_cmpz_zext"
8506   [(set (reg:CCZ FLAGS_REG)
8507         (compare:CCZ
8508           (lshiftrt:DI
8509             (neg:DI (ashift:DI
8510                       (match_operand:DI 1 "register_operand" "0")
8511                       (const_int 32)))
8512             (const_int 32))
8513           (const_int 0)))
8514    (set (match_operand:DI 0 "register_operand" "=r")
8515         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8516                                         (const_int 32)))
8517                      (const_int 32)))]
8518   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8519   "neg{l}\t%k0"
8520   [(set_attr "type" "negnot")
8521    (set_attr "mode" "SI")])
8523 ;; Changing of sign for FP values is doable using integer unit too.
8525 (define_expand "<code><mode>2"
8526   [(set (match_operand:X87MODEF 0 "register_operand")
8527         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8528   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8529   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8531 (define_insn "*absneg<mode>2_mixed"
8532   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8533         (match_operator:MODEF 3 "absneg_operator"
8534           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8535    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8536    (clobber (reg:CC FLAGS_REG))]
8537   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8538   "#")
8540 (define_insn "*absneg<mode>2_sse"
8541   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8542         (match_operator:MODEF 3 "absneg_operator"
8543           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8544    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8545    (clobber (reg:CC FLAGS_REG))]
8546   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8547   "#")
8549 (define_insn "*absneg<mode>2_i387"
8550   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8551         (match_operator:X87MODEF 3 "absneg_operator"
8552           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8553    (use (match_operand 2))
8554    (clobber (reg:CC FLAGS_REG))]
8555   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8556   "#")
8558 (define_expand "<code>tf2"
8559   [(set (match_operand:TF 0 "register_operand")
8560         (absneg:TF (match_operand:TF 1 "register_operand")))]
8561   "TARGET_SSE2"
8562   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8564 (define_insn "*absnegtf2_sse"
8565   [(set (match_operand:TF 0 "register_operand" "=x,x")
8566         (match_operator:TF 3 "absneg_operator"
8567           [(match_operand:TF 1 "register_operand" "0,x")]))
8568    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8569    (clobber (reg:CC FLAGS_REG))]
8570   "TARGET_SSE2"
8571   "#")
8573 ;; Splitters for fp abs and neg.
8575 (define_split
8576   [(set (match_operand 0 "fp_register_operand")
8577         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8578    (use (match_operand 2))
8579    (clobber (reg:CC FLAGS_REG))]
8580   "reload_completed"
8581   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8583 (define_split
8584   [(set (match_operand 0 "register_operand")
8585         (match_operator 3 "absneg_operator"
8586           [(match_operand 1 "register_operand")]))
8587    (use (match_operand 2 "nonimmediate_operand"))
8588    (clobber (reg:CC FLAGS_REG))]
8589   "reload_completed && SSE_REG_P (operands[0])"
8590   [(set (match_dup 0) (match_dup 3))]
8592   enum machine_mode mode = GET_MODE (operands[0]);
8593   enum machine_mode vmode = GET_MODE (operands[2]);
8594   rtx tmp;
8596   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8597   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8598   if (operands_match_p (operands[0], operands[2]))
8599     {
8600       tmp = operands[1];
8601       operands[1] = operands[2];
8602       operands[2] = tmp;
8603     }
8604   if (GET_CODE (operands[3]) == ABS)
8605     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8606   else
8607     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8608   operands[3] = tmp;
8611 (define_split
8612   [(set (match_operand:SF 0 "register_operand")
8613         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8614    (use (match_operand:V4SF 2))
8615    (clobber (reg:CC FLAGS_REG))]
8616   "reload_completed"
8617   [(parallel [(set (match_dup 0) (match_dup 1))
8618               (clobber (reg:CC FLAGS_REG))])]
8620   rtx tmp;
8621   operands[0] = gen_lowpart (SImode, operands[0]);
8622   if (GET_CODE (operands[1]) == ABS)
8623     {
8624       tmp = gen_int_mode (0x7fffffff, SImode);
8625       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8626     }
8627   else
8628     {
8629       tmp = gen_int_mode (0x80000000, SImode);
8630       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8631     }
8632   operands[1] = tmp;
8635 (define_split
8636   [(set (match_operand:DF 0 "register_operand")
8637         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8638    (use (match_operand 2))
8639    (clobber (reg:CC FLAGS_REG))]
8640   "reload_completed"
8641   [(parallel [(set (match_dup 0) (match_dup 1))
8642               (clobber (reg:CC FLAGS_REG))])]
8644   rtx tmp;
8645   if (TARGET_64BIT)
8646     {
8647       tmp = gen_lowpart (DImode, operands[0]);
8648       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8649       operands[0] = tmp;
8651       if (GET_CODE (operands[1]) == ABS)
8652         tmp = const0_rtx;
8653       else
8654         tmp = gen_rtx_NOT (DImode, tmp);
8655     }
8656   else
8657     {
8658       operands[0] = gen_highpart (SImode, operands[0]);
8659       if (GET_CODE (operands[1]) == ABS)
8660         {
8661           tmp = gen_int_mode (0x7fffffff, SImode);
8662           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8663         }
8664       else
8665         {
8666           tmp = gen_int_mode (0x80000000, SImode);
8667           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8668         }
8669     }
8670   operands[1] = tmp;
8673 (define_split
8674   [(set (match_operand:XF 0 "register_operand")
8675         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8676    (use (match_operand 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))])]
8682   rtx tmp;
8683   operands[0] = gen_rtx_REG (SImode,
8684                              true_regnum (operands[0])
8685                              + (TARGET_64BIT ? 1 : 2));
8686   if (GET_CODE (operands[1]) == ABS)
8687     {
8688       tmp = GEN_INT (0x7fff);
8689       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8690     }
8691   else
8692     {
8693       tmp = GEN_INT (0x8000);
8694       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8695     }
8696   operands[1] = tmp;
8699 ;; Conditionalize these after reload. If they match before reload, we
8700 ;; lose the clobber and ability to use integer instructions.
8702 (define_insn "*<code><mode>2_1"
8703   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8704         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8705   "TARGET_80387
8706    && (reload_completed
8707        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8708   "f<absneg_mnemonic>"
8709   [(set_attr "type" "fsgn")
8710    (set_attr "mode" "<MODE>")])
8712 (define_insn "*<code>extendsfdf2"
8713   [(set (match_operand:DF 0 "register_operand" "=f")
8714         (absneg:DF (float_extend:DF
8715                      (match_operand:SF 1 "register_operand" "0"))))]
8716   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8717   "f<absneg_mnemonic>"
8718   [(set_attr "type" "fsgn")
8719    (set_attr "mode" "DF")])
8721 (define_insn "*<code>extendsfxf2"
8722   [(set (match_operand:XF 0 "register_operand" "=f")
8723         (absneg:XF (float_extend:XF
8724                      (match_operand:SF 1 "register_operand" "0"))))]
8725   "TARGET_80387"
8726   "f<absneg_mnemonic>"
8727   [(set_attr "type" "fsgn")
8728    (set_attr "mode" "XF")])
8730 (define_insn "*<code>extenddfxf2"
8731   [(set (match_operand:XF 0 "register_operand" "=f")
8732         (absneg:XF (float_extend:XF
8733                      (match_operand:DF 1 "register_operand" "0"))))]
8734   "TARGET_80387"
8735   "f<absneg_mnemonic>"
8736   [(set_attr "type" "fsgn")
8737    (set_attr "mode" "XF")])
8739 ;; Copysign instructions
8741 (define_mode_iterator CSGNMODE [SF DF TF])
8742 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8744 (define_expand "copysign<mode>3"
8745   [(match_operand:CSGNMODE 0 "register_operand")
8746    (match_operand:CSGNMODE 1 "nonmemory_operand")
8747    (match_operand:CSGNMODE 2 "register_operand")]
8748   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8749    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8750   "ix86_expand_copysign (operands); DONE;")
8752 (define_insn_and_split "copysign<mode>3_const"
8753   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8754         (unspec:CSGNMODE
8755           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8756            (match_operand:CSGNMODE 2 "register_operand" "0")
8757            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8758           UNSPEC_COPYSIGN))]
8759   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8760    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8761   "#"
8762   "&& reload_completed"
8763   [(const_int 0)]
8764   "ix86_split_copysign_const (operands); DONE;")
8766 (define_insn "copysign<mode>3_var"
8767   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8768         (unspec:CSGNMODE
8769           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8770            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8771            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8772            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8773           UNSPEC_COPYSIGN))
8774    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8775   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8776    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8777   "#")
8779 (define_split
8780   [(set (match_operand:CSGNMODE 0 "register_operand")
8781         (unspec:CSGNMODE
8782           [(match_operand:CSGNMODE 2 "register_operand")
8783            (match_operand:CSGNMODE 3 "register_operand")
8784            (match_operand:<CSGNVMODE> 4)
8785            (match_operand:<CSGNVMODE> 5)]
8786           UNSPEC_COPYSIGN))
8787    (clobber (match_scratch:<CSGNVMODE> 1))]
8788   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8789     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8790    && reload_completed"
8791   [(const_int 0)]
8792   "ix86_split_copysign_var (operands); DONE;")
8794 ;; One complement instructions
8796 (define_expand "one_cmpl<mode>2"
8797   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8798         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8799   ""
8800   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8802 (define_insn "*one_cmpl<mode>2_1"
8803   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8804         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8805   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8806   "not{<imodesuffix>}\t%0"
8807   [(set_attr "type" "negnot")
8808    (set_attr "mode" "<MODE>")])
8810 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8811 (define_insn "*one_cmplqi2_1"
8812   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8813         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8814   "ix86_unary_operator_ok (NOT, QImode, operands)"
8815   "@
8816    not{b}\t%0
8817    not{l}\t%k0"
8818   [(set_attr "type" "negnot")
8819    (set_attr "mode" "QI,SI")])
8821 ;; ??? Currently never generated - xor is used instead.
8822 (define_insn "*one_cmplsi2_1_zext"
8823   [(set (match_operand:DI 0 "register_operand" "=r")
8824         (zero_extend:DI
8825           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8826   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8827   "not{l}\t%k0"
8828   [(set_attr "type" "negnot")
8829    (set_attr "mode" "SI")])
8831 (define_insn "*one_cmpl<mode>2_2"
8832   [(set (reg FLAGS_REG)
8833         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8834                  (const_int 0)))
8835    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8836         (not:SWI (match_dup 1)))]
8837   "ix86_match_ccmode (insn, CCNOmode)
8838    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8839   "#"
8840   [(set_attr "type" "alu1")
8841    (set_attr "mode" "<MODE>")])
8843 (define_split
8844   [(set (match_operand 0 "flags_reg_operand")
8845         (match_operator 2 "compare_operator"
8846           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8847            (const_int 0)]))
8848    (set (match_operand:SWI 1 "nonimmediate_operand")
8849         (not:SWI (match_dup 3)))]
8850   "ix86_match_ccmode (insn, CCNOmode)"
8851   [(parallel [(set (match_dup 0)
8852                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8853                                     (const_int 0)]))
8854               (set (match_dup 1)
8855                    (xor:SWI (match_dup 3) (const_int -1)))])])
8857 ;; ??? Currently never generated - xor is used instead.
8858 (define_insn "*one_cmplsi2_2_zext"
8859   [(set (reg FLAGS_REG)
8860         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8861                  (const_int 0)))
8862    (set (match_operand:DI 0 "register_operand" "=r")
8863         (zero_extend:DI (not:SI (match_dup 1))))]
8864   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8865    && ix86_unary_operator_ok (NOT, SImode, operands)"
8866   "#"
8867   [(set_attr "type" "alu1")
8868    (set_attr "mode" "SI")])
8870 (define_split
8871   [(set (match_operand 0 "flags_reg_operand")
8872         (match_operator 2 "compare_operator"
8873           [(not:SI (match_operand:SI 3 "register_operand"))
8874            (const_int 0)]))
8875    (set (match_operand:DI 1 "register_operand")
8876         (zero_extend:DI (not:SI (match_dup 3))))]
8877   "ix86_match_ccmode (insn, CCNOmode)"
8878   [(parallel [(set (match_dup 0)
8879                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8880                                     (const_int 0)]))
8881               (set (match_dup 1)
8882                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8884 ;; Shift instructions
8886 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8887 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8888 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8889 ;; from the assembler input.
8891 ;; This instruction shifts the target reg/mem as usual, but instead of
8892 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8893 ;; is a left shift double, bits are taken from the high order bits of
8894 ;; reg, else if the insn is a shift right double, bits are taken from the
8895 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8896 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8898 ;; Since sh[lr]d does not change the `reg' operand, that is done
8899 ;; separately, making all shifts emit pairs of shift double and normal
8900 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8901 ;; support a 63 bit shift, each shift where the count is in a reg expands
8902 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8904 ;; If the shift count is a constant, we need never emit more than one
8905 ;; shift pair, instead using moves and sign extension for counts greater
8906 ;; than 31.
8908 (define_expand "ashl<mode>3"
8909   [(set (match_operand:SDWIM 0 "<shift_operand>")
8910         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
8911                       (match_operand:QI 2 "nonmemory_operand")))]
8912   ""
8913   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8915 (define_insn "*ashl<mode>3_doubleword"
8916   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8917         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8918                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8919    (clobber (reg:CC FLAGS_REG))]
8920   ""
8921   "#"
8922   [(set_attr "type" "multi")])
8924 (define_split
8925   [(set (match_operand:DWI 0 "register_operand")
8926         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
8927                     (match_operand:QI 2 "nonmemory_operand")))
8928    (clobber (reg:CC FLAGS_REG))]
8929   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8930   [(const_int 0)]
8931   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8933 ;; By default we don't ask for a scratch register, because when DWImode
8934 ;; values are manipulated, registers are already at a premium.  But if
8935 ;; we have one handy, we won't turn it away.
8937 (define_peephole2
8938   [(match_scratch:DWIH 3 "r")
8939    (parallel [(set (match_operand:<DWI> 0 "register_operand")
8940                    (ashift:<DWI>
8941                      (match_operand:<DWI> 1 "nonmemory_operand")
8942                      (match_operand:QI 2 "nonmemory_operand")))
8943               (clobber (reg:CC FLAGS_REG))])
8944    (match_dup 3)]
8945   "TARGET_CMOVE"
8946   [(const_int 0)]
8947   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8949 (define_insn "x86_64_shld"
8950   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8951         (ior:DI (ashift:DI (match_dup 0)
8952                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
8953                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8954                   (minus:QI (const_int 64) (match_dup 2)))))
8955    (clobber (reg:CC FLAGS_REG))]
8956   "TARGET_64BIT"
8957   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8958   [(set_attr "type" "ishift")
8959    (set_attr "prefix_0f" "1")
8960    (set_attr "mode" "DI")
8961    (set_attr "athlon_decode" "vector")
8962    (set_attr "amdfam10_decode" "vector")
8963    (set_attr "bdver1_decode" "vector")])
8965 (define_insn "x86_shld"
8966   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8967         (ior:SI (ashift:SI (match_dup 0)
8968                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
8969                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8970                   (minus:QI (const_int 32) (match_dup 2)))))
8971    (clobber (reg:CC FLAGS_REG))]
8972   ""
8973   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8974   [(set_attr "type" "ishift")
8975    (set_attr "prefix_0f" "1")
8976    (set_attr "mode" "SI")
8977    (set_attr "pent_pair" "np")
8978    (set_attr "athlon_decode" "vector")
8979    (set_attr "amdfam10_decode" "vector")
8980    (set_attr "bdver1_decode" "vector")])
8982 (define_expand "x86_shift<mode>_adj_1"
8983   [(set (reg:CCZ FLAGS_REG)
8984         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
8985                              (match_dup 4))
8986                      (const_int 0)))
8987    (set (match_operand:SWI48 0 "register_operand")
8988         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8989                             (match_operand:SWI48 1 "register_operand")
8990                             (match_dup 0)))
8991    (set (match_dup 1)
8992         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8993                             (match_operand:SWI48 3 "register_operand")
8994                             (match_dup 1)))]
8995   "TARGET_CMOVE"
8996   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8998 (define_expand "x86_shift<mode>_adj_2"
8999   [(use (match_operand:SWI48 0 "register_operand"))
9000    (use (match_operand:SWI48 1 "register_operand"))
9001    (use (match_operand:QI 2 "register_operand"))]
9002   ""
9004   rtx label = gen_label_rtx ();
9005   rtx tmp;
9007   emit_insn (gen_testqi_ccz_1 (operands[2],
9008                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9010   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9011   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9012   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9013                               gen_rtx_LABEL_REF (VOIDmode, label),
9014                               pc_rtx);
9015   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9016   JUMP_LABEL (tmp) = label;
9018   emit_move_insn (operands[0], operands[1]);
9019   ix86_expand_clear (operands[1]);
9021   emit_label (label);
9022   LABEL_NUSES (label) = 1;
9024   DONE;
9027 ;; Avoid useless masking of count operand.
9028 (define_insn_and_split "*ashl<mode>3_mask"
9029   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9030         (ashift:SWI48
9031           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9032           (subreg:QI
9033             (and:SI
9034               (match_operand:SI 2 "nonimmediate_operand" "c")
9035               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9036    (clobber (reg:CC FLAGS_REG))]
9037   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9038    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9039       == GET_MODE_BITSIZE (<MODE>mode)-1"
9040   "#"
9041   "&& 1"
9042   [(parallel [(set (match_dup 0)
9043                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9044               (clobber (reg:CC FLAGS_REG))])]
9046   if (can_create_pseudo_p ())
9047     operands [2] = force_reg (SImode, operands[2]);
9049   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9051   [(set_attr "type" "ishift")
9052    (set_attr "mode" "<MODE>")])
9054 (define_insn "*bmi2_ashl<mode>3_1"
9055   [(set (match_operand:SWI48 0 "register_operand" "=r")
9056         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9057                       (match_operand:SWI48 2 "register_operand" "r")))]
9058   "TARGET_BMI2"
9059   "shlx\t{%2, %1, %0|%0, %1, %2}"
9060   [(set_attr "type" "ishiftx")
9061    (set_attr "mode" "<MODE>")])
9063 (define_insn "*ashl<mode>3_1"
9064   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9065         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9066                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9067    (clobber (reg:CC FLAGS_REG))]
9068   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9070   switch (get_attr_type (insn))
9071     {
9072     case TYPE_LEA:
9073     case TYPE_ISHIFTX:
9074       return "#";
9076     case TYPE_ALU:
9077       gcc_assert (operands[2] == const1_rtx);
9078       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9079       return "add{<imodesuffix>}\t%0, %0";
9081     default:
9082       if (operands[2] == const1_rtx
9083           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9084         return "sal{<imodesuffix>}\t%0";
9085       else
9086         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9087     }
9089   [(set_attr "isa" "*,*,bmi2")
9090    (set (attr "type")
9091      (cond [(eq_attr "alternative" "1")
9092               (const_string "lea")
9093             (eq_attr "alternative" "2")
9094               (const_string "ishiftx")
9095             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9096                       (match_operand 0 "register_operand"))
9097                  (match_operand 2 "const1_operand"))
9098               (const_string "alu")
9099            ]
9100            (const_string "ishift")))
9101    (set (attr "length_immediate")
9102      (if_then_else
9103        (ior (eq_attr "type" "alu")
9104             (and (eq_attr "type" "ishift")
9105                  (and (match_operand 2 "const1_operand")
9106                       (ior (match_test "TARGET_SHIFT1")
9107                            (match_test "optimize_function_for_size_p (cfun)")))))
9108        (const_string "0")
9109        (const_string "*")))
9110    (set_attr "mode" "<MODE>")])
9112 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9113 (define_split
9114   [(set (match_operand:SWI48 0 "register_operand")
9115         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9116                       (match_operand:QI 2 "register_operand")))
9117    (clobber (reg:CC FLAGS_REG))]
9118   "TARGET_BMI2 && reload_completed"
9119   [(set (match_dup 0)
9120         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9121   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9123 (define_insn "*bmi2_ashlsi3_1_zext"
9124   [(set (match_operand:DI 0 "register_operand" "=r")
9125         (zero_extend:DI
9126           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9127                      (match_operand:SI 2 "register_operand" "r"))))]
9128   "TARGET_64BIT && TARGET_BMI2"
9129   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9130   [(set_attr "type" "ishiftx")
9131    (set_attr "mode" "SI")])
9133 (define_insn "*ashlsi3_1_zext"
9134   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9135         (zero_extend:DI
9136           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9137                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9138    (clobber (reg:CC FLAGS_REG))]
9139   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9141   switch (get_attr_type (insn))
9142     {
9143     case TYPE_LEA:
9144     case TYPE_ISHIFTX:
9145       return "#";
9147     case TYPE_ALU:
9148       gcc_assert (operands[2] == const1_rtx);
9149       return "add{l}\t%k0, %k0";
9151     default:
9152       if (operands[2] == const1_rtx
9153           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9154         return "sal{l}\t%k0";
9155       else
9156         return "sal{l}\t{%2, %k0|%k0, %2}";
9157     }
9159   [(set_attr "isa" "*,*,bmi2")
9160    (set (attr "type")
9161      (cond [(eq_attr "alternative" "1")
9162               (const_string "lea")
9163             (eq_attr "alternative" "2")
9164               (const_string "ishiftx")
9165             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9166                  (match_operand 2 "const1_operand"))
9167               (const_string "alu")
9168            ]
9169            (const_string "ishift")))
9170    (set (attr "length_immediate")
9171      (if_then_else
9172        (ior (eq_attr "type" "alu")
9173             (and (eq_attr "type" "ishift")
9174                  (and (match_operand 2 "const1_operand")
9175                       (ior (match_test "TARGET_SHIFT1")
9176                            (match_test "optimize_function_for_size_p (cfun)")))))
9177        (const_string "0")
9178        (const_string "*")))
9179    (set_attr "mode" "SI")])
9181 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9182 (define_split
9183   [(set (match_operand:DI 0 "register_operand")
9184         (zero_extend:DI
9185           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9186                      (match_operand:QI 2 "register_operand"))))
9187    (clobber (reg:CC FLAGS_REG))]
9188   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9189   [(set (match_dup 0)
9190         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9191   "operands[2] = gen_lowpart (SImode, operands[2]);")
9193 (define_insn "*ashlhi3_1"
9194   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9195         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9196                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9197    (clobber (reg:CC FLAGS_REG))]
9198   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9200   switch (get_attr_type (insn))
9201     {
9202     case TYPE_LEA:
9203       return "#";
9205     case TYPE_ALU:
9206       gcc_assert (operands[2] == const1_rtx);
9207       return "add{w}\t%0, %0";
9209     default:
9210       if (operands[2] == const1_rtx
9211           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9212         return "sal{w}\t%0";
9213       else
9214         return "sal{w}\t{%2, %0|%0, %2}";
9215     }
9217   [(set (attr "type")
9218      (cond [(eq_attr "alternative" "1")
9219               (const_string "lea")
9220             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9221                       (match_operand 0 "register_operand"))
9222                  (match_operand 2 "const1_operand"))
9223               (const_string "alu")
9224            ]
9225            (const_string "ishift")))
9226    (set (attr "length_immediate")
9227      (if_then_else
9228        (ior (eq_attr "type" "alu")
9229             (and (eq_attr "type" "ishift")
9230                  (and (match_operand 2 "const1_operand")
9231                       (ior (match_test "TARGET_SHIFT1")
9232                            (match_test "optimize_function_for_size_p (cfun)")))))
9233        (const_string "0")
9234        (const_string "*")))
9235    (set_attr "mode" "HI,SI")])
9237 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9238 (define_insn "*ashlqi3_1"
9239   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9240         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9241                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9242    (clobber (reg:CC FLAGS_REG))]
9243   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9245   switch (get_attr_type (insn))
9246     {
9247     case TYPE_LEA:
9248       return "#";
9250     case TYPE_ALU:
9251       gcc_assert (operands[2] == const1_rtx);
9252       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9253         return "add{l}\t%k0, %k0";
9254       else
9255         return "add{b}\t%0, %0";
9257     default:
9258       if (operands[2] == const1_rtx
9259           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9260         {
9261           if (get_attr_mode (insn) == MODE_SI)
9262             return "sal{l}\t%k0";
9263           else
9264             return "sal{b}\t%0";
9265         }
9266       else
9267         {
9268           if (get_attr_mode (insn) == MODE_SI)
9269             return "sal{l}\t{%2, %k0|%k0, %2}";
9270           else
9271             return "sal{b}\t{%2, %0|%0, %2}";
9272         }
9273     }
9275   [(set (attr "type")
9276      (cond [(eq_attr "alternative" "2")
9277               (const_string "lea")
9278             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9279                       (match_operand 0 "register_operand"))
9280                  (match_operand 2 "const1_operand"))
9281               (const_string "alu")
9282            ]
9283            (const_string "ishift")))
9284    (set (attr "length_immediate")
9285      (if_then_else
9286        (ior (eq_attr "type" "alu")
9287             (and (eq_attr "type" "ishift")
9288                  (and (match_operand 2 "const1_operand")
9289                       (ior (match_test "TARGET_SHIFT1")
9290                            (match_test "optimize_function_for_size_p (cfun)")))))
9291        (const_string "0")
9292        (const_string "*")))
9293    (set_attr "mode" "QI,SI,SI")])
9295 (define_insn "*ashlqi3_1_slp"
9296   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9297         (ashift:QI (match_dup 0)
9298                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9299    (clobber (reg:CC FLAGS_REG))]
9300   "(optimize_function_for_size_p (cfun)
9301     || !TARGET_PARTIAL_FLAG_REG_STALL
9302     || (operands[1] == const1_rtx
9303         && (TARGET_SHIFT1
9304             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9306   switch (get_attr_type (insn))
9307     {
9308     case TYPE_ALU:
9309       gcc_assert (operands[1] == const1_rtx);
9310       return "add{b}\t%0, %0";
9312     default:
9313       if (operands[1] == const1_rtx
9314           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9315         return "sal{b}\t%0";
9316       else
9317         return "sal{b}\t{%1, %0|%0, %1}";
9318     }
9320   [(set (attr "type")
9321      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9322                       (match_operand 0 "register_operand"))
9323                  (match_operand 1 "const1_operand"))
9324               (const_string "alu")
9325            ]
9326            (const_string "ishift1")))
9327    (set (attr "length_immediate")
9328      (if_then_else
9329        (ior (eq_attr "type" "alu")
9330             (and (eq_attr "type" "ishift1")
9331                  (and (match_operand 1 "const1_operand")
9332                       (ior (match_test "TARGET_SHIFT1")
9333                            (match_test "optimize_function_for_size_p (cfun)")))))
9334        (const_string "0")
9335        (const_string "*")))
9336    (set_attr "mode" "QI")])
9338 ;; Convert ashift to the lea pattern to avoid flags dependency.
9339 (define_split
9340   [(set (match_operand 0 "register_operand")
9341         (ashift (match_operand 1 "index_register_operand")
9342                 (match_operand:QI 2 "const_int_operand")))
9343    (clobber (reg:CC FLAGS_REG))]
9344   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9345    && reload_completed
9346    && true_regnum (operands[0]) != true_regnum (operands[1])"
9347   [(const_int 0)]
9349   enum machine_mode mode = GET_MODE (operands[0]);
9350   rtx pat;
9352   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9353     { 
9354       mode = SImode; 
9355       operands[0] = gen_lowpart (mode, operands[0]);
9356       operands[1] = gen_lowpart (mode, operands[1]);
9357     }
9359   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9361   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9363   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9364   DONE;
9367 ;; Convert ashift to the lea pattern to avoid flags dependency.
9368 (define_split
9369   [(set (match_operand:DI 0 "register_operand")
9370         (zero_extend:DI
9371           (ashift:SI (match_operand:SI 1 "index_register_operand")
9372                      (match_operand:QI 2 "const_int_operand"))))
9373    (clobber (reg:CC FLAGS_REG))]
9374   "TARGET_64BIT && reload_completed
9375    && true_regnum (operands[0]) != true_regnum (operands[1])"
9376   [(set (match_dup 0)
9377         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9379   operands[1] = gen_lowpart (DImode, operands[1]);
9380   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9383 ;; This pattern can't accept a variable shift count, since shifts by
9384 ;; zero don't affect the flags.  We assume that shifts by constant
9385 ;; zero are optimized away.
9386 (define_insn "*ashl<mode>3_cmp"
9387   [(set (reg FLAGS_REG)
9388         (compare
9389           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9390                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9391           (const_int 0)))
9392    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9393         (ashift:SWI (match_dup 1) (match_dup 2)))]
9394   "(optimize_function_for_size_p (cfun)
9395     || !TARGET_PARTIAL_FLAG_REG_STALL
9396     || (operands[2] == const1_rtx
9397         && (TARGET_SHIFT1
9398             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9399    && ix86_match_ccmode (insn, CCGOCmode)
9400    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9402   switch (get_attr_type (insn))
9403     {
9404     case TYPE_ALU:
9405       gcc_assert (operands[2] == const1_rtx);
9406       return "add{<imodesuffix>}\t%0, %0";
9408     default:
9409       if (operands[2] == const1_rtx
9410           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9411         return "sal{<imodesuffix>}\t%0";
9412       else
9413         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9414     }
9416   [(set (attr "type")
9417      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9418                       (match_operand 0 "register_operand"))
9419                  (match_operand 2 "const1_operand"))
9420               (const_string "alu")
9421            ]
9422            (const_string "ishift")))
9423    (set (attr "length_immediate")
9424      (if_then_else
9425        (ior (eq_attr "type" "alu")
9426             (and (eq_attr "type" "ishift")
9427                  (and (match_operand 2 "const1_operand")
9428                       (ior (match_test "TARGET_SHIFT1")
9429                            (match_test "optimize_function_for_size_p (cfun)")))))
9430        (const_string "0")
9431        (const_string "*")))
9432    (set_attr "mode" "<MODE>")])
9434 (define_insn "*ashlsi3_cmp_zext"
9435   [(set (reg FLAGS_REG)
9436         (compare
9437           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9438                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9439           (const_int 0)))
9440    (set (match_operand:DI 0 "register_operand" "=r")
9441         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9442   "TARGET_64BIT
9443    && (optimize_function_for_size_p (cfun)
9444        || !TARGET_PARTIAL_FLAG_REG_STALL
9445        || (operands[2] == const1_rtx
9446            && (TARGET_SHIFT1
9447                || TARGET_DOUBLE_WITH_ADD)))
9448    && ix86_match_ccmode (insn, CCGOCmode)
9449    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9451   switch (get_attr_type (insn))
9452     {
9453     case TYPE_ALU:
9454       gcc_assert (operands[2] == const1_rtx);
9455       return "add{l}\t%k0, %k0";
9457     default:
9458       if (operands[2] == const1_rtx
9459           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9460         return "sal{l}\t%k0";
9461       else
9462         return "sal{l}\t{%2, %k0|%k0, %2}";
9463     }
9465   [(set (attr "type")
9466      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9467                  (match_operand 2 "const1_operand"))
9468               (const_string "alu")
9469            ]
9470            (const_string "ishift")))
9471    (set (attr "length_immediate")
9472      (if_then_else
9473        (ior (eq_attr "type" "alu")
9474             (and (eq_attr "type" "ishift")
9475                  (and (match_operand 2 "const1_operand")
9476                       (ior (match_test "TARGET_SHIFT1")
9477                            (match_test "optimize_function_for_size_p (cfun)")))))
9478        (const_string "0")
9479        (const_string "*")))
9480    (set_attr "mode" "SI")])
9482 (define_insn "*ashl<mode>3_cconly"
9483   [(set (reg FLAGS_REG)
9484         (compare
9485           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9486                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9487           (const_int 0)))
9488    (clobber (match_scratch:SWI 0 "=<r>"))]
9489   "(optimize_function_for_size_p (cfun)
9490     || !TARGET_PARTIAL_FLAG_REG_STALL
9491     || (operands[2] == const1_rtx
9492         && (TARGET_SHIFT1
9493             || TARGET_DOUBLE_WITH_ADD)))
9494    && ix86_match_ccmode (insn, CCGOCmode)"
9496   switch (get_attr_type (insn))
9497     {
9498     case TYPE_ALU:
9499       gcc_assert (operands[2] == const1_rtx);
9500       return "add{<imodesuffix>}\t%0, %0";
9502     default:
9503       if (operands[2] == const1_rtx
9504           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9505         return "sal{<imodesuffix>}\t%0";
9506       else
9507         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9508     }
9510   [(set (attr "type")
9511      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9512                       (match_operand 0 "register_operand"))
9513                  (match_operand 2 "const1_operand"))
9514               (const_string "alu")
9515            ]
9516            (const_string "ishift")))
9517    (set (attr "length_immediate")
9518      (if_then_else
9519        (ior (eq_attr "type" "alu")
9520             (and (eq_attr "type" "ishift")
9521                  (and (match_operand 2 "const1_operand")
9522                       (ior (match_test "TARGET_SHIFT1")
9523                            (match_test "optimize_function_for_size_p (cfun)")))))
9524        (const_string "0")
9525        (const_string "*")))
9526    (set_attr "mode" "<MODE>")])
9528 ;; See comment above `ashl<mode>3' about how this works.
9530 (define_expand "<shift_insn><mode>3"
9531   [(set (match_operand:SDWIM 0 "<shift_operand>")
9532         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9533                            (match_operand:QI 2 "nonmemory_operand")))]
9534   ""
9535   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9537 ;; Avoid useless masking of count operand.
9538 (define_insn_and_split "*<shift_insn><mode>3_mask"
9539   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9540         (any_shiftrt:SWI48
9541           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9542           (subreg:QI
9543             (and:SI
9544               (match_operand:SI 2 "nonimmediate_operand" "c")
9545               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9546    (clobber (reg:CC FLAGS_REG))]
9547   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9548    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9549       == GET_MODE_BITSIZE (<MODE>mode)-1"
9550   "#"
9551   "&& 1"
9552   [(parallel [(set (match_dup 0)
9553                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9554               (clobber (reg:CC FLAGS_REG))])]
9556   if (can_create_pseudo_p ())
9557     operands [2] = force_reg (SImode, operands[2]);
9559   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9561   [(set_attr "type" "ishift")
9562    (set_attr "mode" "<MODE>")])
9564 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9565   [(set (match_operand:DWI 0 "register_operand" "=r")
9566         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9567                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9568    (clobber (reg:CC FLAGS_REG))]
9569   ""
9570   "#"
9571   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9572   [(const_int 0)]
9573   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9574   [(set_attr "type" "multi")])
9576 ;; By default we don't ask for a scratch register, because when DWImode
9577 ;; values are manipulated, registers are already at a premium.  But if
9578 ;; we have one handy, we won't turn it away.
9580 (define_peephole2
9581   [(match_scratch:DWIH 3 "r")
9582    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9583                    (any_shiftrt:<DWI>
9584                      (match_operand:<DWI> 1 "register_operand")
9585                      (match_operand:QI 2 "nonmemory_operand")))
9586               (clobber (reg:CC FLAGS_REG))])
9587    (match_dup 3)]
9588   "TARGET_CMOVE"
9589   [(const_int 0)]
9590   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9592 (define_insn "x86_64_shrd"
9593   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9594         (ior:DI (ashiftrt:DI (match_dup 0)
9595                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9596                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9597                   (minus:QI (const_int 64) (match_dup 2)))))
9598    (clobber (reg:CC FLAGS_REG))]
9599   "TARGET_64BIT"
9600   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9601   [(set_attr "type" "ishift")
9602    (set_attr "prefix_0f" "1")
9603    (set_attr "mode" "DI")
9604    (set_attr "athlon_decode" "vector")
9605    (set_attr "amdfam10_decode" "vector")
9606    (set_attr "bdver1_decode" "vector")])
9608 (define_insn "x86_shrd"
9609   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9610         (ior:SI (ashiftrt:SI (match_dup 0)
9611                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9612                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9613                   (minus:QI (const_int 32) (match_dup 2)))))
9614    (clobber (reg:CC FLAGS_REG))]
9615   ""
9616   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9617   [(set_attr "type" "ishift")
9618    (set_attr "prefix_0f" "1")
9619    (set_attr "mode" "SI")
9620    (set_attr "pent_pair" "np")
9621    (set_attr "athlon_decode" "vector")
9622    (set_attr "amdfam10_decode" "vector")
9623    (set_attr "bdver1_decode" "vector")])
9625 (define_insn "ashrdi3_cvt"
9626   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9627         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9628                      (match_operand:QI 2 "const_int_operand")))
9629    (clobber (reg:CC FLAGS_REG))]
9630   "TARGET_64BIT && INTVAL (operands[2]) == 63
9631    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9632    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9633   "@
9634    {cqto|cqo}
9635    sar{q}\t{%2, %0|%0, %2}"
9636   [(set_attr "type" "imovx,ishift")
9637    (set_attr "prefix_0f" "0,*")
9638    (set_attr "length_immediate" "0,*")
9639    (set_attr "modrm" "0,1")
9640    (set_attr "mode" "DI")])
9642 (define_insn "ashrsi3_cvt"
9643   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9644         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9645                      (match_operand:QI 2 "const_int_operand")))
9646    (clobber (reg:CC FLAGS_REG))]
9647   "INTVAL (operands[2]) == 31
9648    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9649    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9650   "@
9651    {cltd|cdq}
9652    sar{l}\t{%2, %0|%0, %2}"
9653   [(set_attr "type" "imovx,ishift")
9654    (set_attr "prefix_0f" "0,*")
9655    (set_attr "length_immediate" "0,*")
9656    (set_attr "modrm" "0,1")
9657    (set_attr "mode" "SI")])
9659 (define_insn "*ashrsi3_cvt_zext"
9660   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9661         (zero_extend:DI
9662           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9663                        (match_operand:QI 2 "const_int_operand"))))
9664    (clobber (reg:CC FLAGS_REG))]
9665   "TARGET_64BIT && INTVAL (operands[2]) == 31
9666    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9667    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9668   "@
9669    {cltd|cdq}
9670    sar{l}\t{%2, %k0|%k0, %2}"
9671   [(set_attr "type" "imovx,ishift")
9672    (set_attr "prefix_0f" "0,*")
9673    (set_attr "length_immediate" "0,*")
9674    (set_attr "modrm" "0,1")
9675    (set_attr "mode" "SI")])
9677 (define_expand "x86_shift<mode>_adj_3"
9678   [(use (match_operand:SWI48 0 "register_operand"))
9679    (use (match_operand:SWI48 1 "register_operand"))
9680    (use (match_operand:QI 2 "register_operand"))]
9681   ""
9683   rtx label = gen_label_rtx ();
9684   rtx tmp;
9686   emit_insn (gen_testqi_ccz_1 (operands[2],
9687                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9689   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9690   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9691   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9692                               gen_rtx_LABEL_REF (VOIDmode, label),
9693                               pc_rtx);
9694   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9695   JUMP_LABEL (tmp) = label;
9697   emit_move_insn (operands[0], operands[1]);
9698   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9699                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9700   emit_label (label);
9701   LABEL_NUSES (label) = 1;
9703   DONE;
9706 (define_insn "*bmi2_<shift_insn><mode>3_1"
9707   [(set (match_operand:SWI48 0 "register_operand" "=r")
9708         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9709                            (match_operand:SWI48 2 "register_operand" "r")))]
9710   "TARGET_BMI2"
9711   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9712   [(set_attr "type" "ishiftx")
9713    (set_attr "mode" "<MODE>")])
9715 (define_insn "*<shift_insn><mode>3_1"
9716   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9717         (any_shiftrt:SWI48
9718           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9719           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9720    (clobber (reg:CC FLAGS_REG))]
9721   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9723   switch (get_attr_type (insn))
9724     {
9725     case TYPE_ISHIFTX:
9726       return "#";
9728     default:
9729       if (operands[2] == const1_rtx
9730           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9731         return "<shift>{<imodesuffix>}\t%0";
9732       else
9733         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9734     }
9736   [(set_attr "isa" "*,bmi2")
9737    (set_attr "type" "ishift,ishiftx")
9738    (set (attr "length_immediate")
9739      (if_then_else
9740        (and (match_operand 2 "const1_operand")
9741             (ior (match_test "TARGET_SHIFT1")
9742                  (match_test "optimize_function_for_size_p (cfun)")))
9743        (const_string "0")
9744        (const_string "*")))
9745    (set_attr "mode" "<MODE>")])
9747 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9748 (define_split
9749   [(set (match_operand:SWI48 0 "register_operand")
9750         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9751                            (match_operand:QI 2 "register_operand")))
9752    (clobber (reg:CC FLAGS_REG))]
9753   "TARGET_BMI2 && reload_completed"
9754   [(set (match_dup 0)
9755         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9756   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9758 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9759   [(set (match_operand:DI 0 "register_operand" "=r")
9760         (zero_extend:DI
9761           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9762                           (match_operand:SI 2 "register_operand" "r"))))]
9763   "TARGET_64BIT && TARGET_BMI2"
9764   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9765   [(set_attr "type" "ishiftx")
9766    (set_attr "mode" "SI")])
9768 (define_insn "*<shift_insn>si3_1_zext"
9769   [(set (match_operand:DI 0 "register_operand" "=r,r")
9770         (zero_extend:DI
9771           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9772                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9773    (clobber (reg:CC FLAGS_REG))]
9774   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9776   switch (get_attr_type (insn))
9777     {
9778     case TYPE_ISHIFTX:
9779       return "#";
9781     default:
9782       if (operands[2] == const1_rtx
9783           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9784         return "<shift>{l}\t%k0";
9785       else
9786         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9787     }
9789   [(set_attr "isa" "*,bmi2")
9790    (set_attr "type" "ishift,ishiftx")
9791    (set (attr "length_immediate")
9792      (if_then_else
9793        (and (match_operand 2 "const1_operand")
9794             (ior (match_test "TARGET_SHIFT1")
9795                  (match_test "optimize_function_for_size_p (cfun)")))
9796        (const_string "0")
9797        (const_string "*")))
9798    (set_attr "mode" "SI")])
9800 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9801 (define_split
9802   [(set (match_operand:DI 0 "register_operand")
9803         (zero_extend:DI
9804           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9805                           (match_operand:QI 2 "register_operand"))))
9806    (clobber (reg:CC FLAGS_REG))]
9807   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9808   [(set (match_dup 0)
9809         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9810   "operands[2] = gen_lowpart (SImode, operands[2]);")
9812 (define_insn "*<shift_insn><mode>3_1"
9813   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9814         (any_shiftrt:SWI12
9815           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9816           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9817    (clobber (reg:CC FLAGS_REG))]
9818   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9820   if (operands[2] == const1_rtx
9821       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9822     return "<shift>{<imodesuffix>}\t%0";
9823   else
9824     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9826   [(set_attr "type" "ishift")
9827    (set (attr "length_immediate")
9828      (if_then_else
9829        (and (match_operand 2 "const1_operand")
9830             (ior (match_test "TARGET_SHIFT1")
9831                  (match_test "optimize_function_for_size_p (cfun)")))
9832        (const_string "0")
9833        (const_string "*")))
9834    (set_attr "mode" "<MODE>")])
9836 (define_insn "*<shift_insn>qi3_1_slp"
9837   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9838         (any_shiftrt:QI (match_dup 0)
9839                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9840    (clobber (reg:CC FLAGS_REG))]
9841   "(optimize_function_for_size_p (cfun)
9842     || !TARGET_PARTIAL_REG_STALL
9843     || (operands[1] == const1_rtx
9844         && TARGET_SHIFT1))"
9846   if (operands[1] == const1_rtx
9847       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9848     return "<shift>{b}\t%0";
9849   else
9850     return "<shift>{b}\t{%1, %0|%0, %1}";
9852   [(set_attr "type" "ishift1")
9853    (set (attr "length_immediate")
9854      (if_then_else
9855        (and (match_operand 1 "const1_operand")
9856             (ior (match_test "TARGET_SHIFT1")
9857                  (match_test "optimize_function_for_size_p (cfun)")))
9858        (const_string "0")
9859        (const_string "*")))
9860    (set_attr "mode" "QI")])
9862 ;; This pattern can't accept a variable shift count, since shifts by
9863 ;; zero don't affect the flags.  We assume that shifts by constant
9864 ;; zero are optimized away.
9865 (define_insn "*<shift_insn><mode>3_cmp"
9866   [(set (reg FLAGS_REG)
9867         (compare
9868           (any_shiftrt:SWI
9869             (match_operand:SWI 1 "nonimmediate_operand" "0")
9870             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9871           (const_int 0)))
9872    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9873         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9874   "(optimize_function_for_size_p (cfun)
9875     || !TARGET_PARTIAL_FLAG_REG_STALL
9876     || (operands[2] == const1_rtx
9877         && TARGET_SHIFT1))
9878    && ix86_match_ccmode (insn, CCGOCmode)
9879    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9881   if (operands[2] == const1_rtx
9882       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9883     return "<shift>{<imodesuffix>}\t%0";
9884   else
9885     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9887   [(set_attr "type" "ishift")
9888    (set (attr "length_immediate")
9889      (if_then_else
9890        (and (match_operand 2 "const1_operand")
9891             (ior (match_test "TARGET_SHIFT1")
9892                  (match_test "optimize_function_for_size_p (cfun)")))
9893        (const_string "0")
9894        (const_string "*")))
9895    (set_attr "mode" "<MODE>")])
9897 (define_insn "*<shift_insn>si3_cmp_zext"
9898   [(set (reg FLAGS_REG)
9899         (compare
9900           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9901                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9902           (const_int 0)))
9903    (set (match_operand:DI 0 "register_operand" "=r")
9904         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9905   "TARGET_64BIT
9906    && (optimize_function_for_size_p (cfun)
9907        || !TARGET_PARTIAL_FLAG_REG_STALL
9908        || (operands[2] == const1_rtx
9909            && TARGET_SHIFT1))
9910    && ix86_match_ccmode (insn, CCGOCmode)
9911    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9913   if (operands[2] == const1_rtx
9914       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9915     return "<shift>{l}\t%k0";
9916   else
9917     return "<shift>{l}\t{%2, %k0|%k0, %2}";
9919   [(set_attr "type" "ishift")
9920    (set (attr "length_immediate")
9921      (if_then_else
9922        (and (match_operand 2 "const1_operand")
9923             (ior (match_test "TARGET_SHIFT1")
9924                  (match_test "optimize_function_for_size_p (cfun)")))
9925        (const_string "0")
9926        (const_string "*")))
9927    (set_attr "mode" "SI")])
9929 (define_insn "*<shift_insn><mode>3_cconly"
9930   [(set (reg FLAGS_REG)
9931         (compare
9932           (any_shiftrt:SWI
9933             (match_operand:SWI 1 "register_operand" "0")
9934             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9935           (const_int 0)))
9936    (clobber (match_scratch:SWI 0 "=<r>"))]
9937   "(optimize_function_for_size_p (cfun)
9938     || !TARGET_PARTIAL_FLAG_REG_STALL
9939     || (operands[2] == const1_rtx
9940         && TARGET_SHIFT1))
9941    && ix86_match_ccmode (insn, CCGOCmode)"
9943   if (operands[2] == const1_rtx
9944       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9945     return "<shift>{<imodesuffix>}\t%0";
9946   else
9947     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9949   [(set_attr "type" "ishift")
9950    (set (attr "length_immediate")
9951      (if_then_else
9952        (and (match_operand 2 "const1_operand")
9953             (ior (match_test "TARGET_SHIFT1")
9954                  (match_test "optimize_function_for_size_p (cfun)")))
9955        (const_string "0")
9956        (const_string "*")))
9957    (set_attr "mode" "<MODE>")])
9959 ;; Rotate instructions
9961 (define_expand "<rotate_insn>ti3"
9962   [(set (match_operand:TI 0 "register_operand")
9963         (any_rotate:TI (match_operand:TI 1 "register_operand")
9964                        (match_operand:QI 2 "nonmemory_operand")))]
9965   "TARGET_64BIT"
9967   if (const_1_to_63_operand (operands[2], VOIDmode))
9968     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9969                 (operands[0], operands[1], operands[2]));
9970   else
9971     FAIL;
9973   DONE;
9976 (define_expand "<rotate_insn>di3"
9977   [(set (match_operand:DI 0 "shiftdi_operand")
9978         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
9979                        (match_operand:QI 2 "nonmemory_operand")))]
9980  ""
9982   if (TARGET_64BIT)
9983     ix86_expand_binary_operator (<CODE>, DImode, operands);
9984   else if (const_1_to_31_operand (operands[2], VOIDmode))
9985     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9986                 (operands[0], operands[1], operands[2]));
9987   else
9988     FAIL;
9990   DONE;
9993 (define_expand "<rotate_insn><mode>3"
9994   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
9995         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
9996                             (match_operand:QI 2 "nonmemory_operand")))]
9997   ""
9998   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10000 ;; Avoid useless masking of count operand.
10001 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10002   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10003         (any_rotate:SWI48
10004           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10005           (subreg:QI
10006             (and:SI
10007               (match_operand:SI 2 "nonimmediate_operand" "c")
10008               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10009    (clobber (reg:CC FLAGS_REG))]
10010   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10011    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10012       == GET_MODE_BITSIZE (<MODE>mode)-1"
10013   "#"
10014   "&& 1"
10015   [(parallel [(set (match_dup 0)
10016                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10017               (clobber (reg:CC FLAGS_REG))])]
10019   if (can_create_pseudo_p ())
10020     operands [2] = force_reg (SImode, operands[2]);
10022   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10024   [(set_attr "type" "rotate")
10025    (set_attr "mode" "<MODE>")])
10027 ;; Implement rotation using two double-precision
10028 ;; shift instructions and a scratch register.
10030 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10031  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10032        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10033                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10034   (clobber (reg:CC FLAGS_REG))
10035   (clobber (match_scratch:DWIH 3 "=&r"))]
10036  ""
10037  "#"
10038  "reload_completed"
10039  [(set (match_dup 3) (match_dup 4))
10040   (parallel
10041    [(set (match_dup 4)
10042          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10043                    (lshiftrt:DWIH (match_dup 5)
10044                                   (minus:QI (match_dup 6) (match_dup 2)))))
10045     (clobber (reg:CC FLAGS_REG))])
10046   (parallel
10047    [(set (match_dup 5)
10048          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10049                    (lshiftrt:DWIH (match_dup 3)
10050                                   (minus:QI (match_dup 6) (match_dup 2)))))
10051     (clobber (reg:CC FLAGS_REG))])]
10053   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10055   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10058 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10059  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10060        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10061                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10062   (clobber (reg:CC FLAGS_REG))
10063   (clobber (match_scratch:DWIH 3 "=&r"))]
10064  ""
10065  "#"
10066  "reload_completed"
10067  [(set (match_dup 3) (match_dup 4))
10068   (parallel
10069    [(set (match_dup 4)
10070          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10071                    (ashift:DWIH (match_dup 5)
10072                                 (minus:QI (match_dup 6) (match_dup 2)))))
10073     (clobber (reg:CC FLAGS_REG))])
10074   (parallel
10075    [(set (match_dup 5)
10076          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10077                    (ashift:DWIH (match_dup 3)
10078                                 (minus:QI (match_dup 6) (match_dup 2)))))
10079     (clobber (reg:CC FLAGS_REG))])]
10081   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10083   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10086 (define_insn "*bmi2_rorx<mode>3_1"
10087   [(set (match_operand:SWI48 0 "register_operand" "=r")
10088         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10089                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10090   "TARGET_BMI2"
10091   "rorx\t{%2, %1, %0|%0, %1, %2}"
10092   [(set_attr "type" "rotatex")
10093    (set_attr "mode" "<MODE>")])
10095 (define_insn "*<rotate_insn><mode>3_1"
10096   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10097         (any_rotate:SWI48
10098           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10099           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10100    (clobber (reg:CC FLAGS_REG))]
10101   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10103   switch (get_attr_type (insn))
10104     {
10105     case TYPE_ROTATEX:
10106       return "#";
10108     default:
10109       if (operands[2] == const1_rtx
10110           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10111         return "<rotate>{<imodesuffix>}\t%0";
10112       else
10113         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10114     }
10116   [(set_attr "isa" "*,bmi2")
10117    (set_attr "type" "rotate,rotatex")
10118    (set (attr "length_immediate")
10119      (if_then_else
10120        (and (eq_attr "type" "rotate")
10121             (and (match_operand 2 "const1_operand")
10122                  (ior (match_test "TARGET_SHIFT1")
10123                       (match_test "optimize_function_for_size_p (cfun)"))))
10124        (const_string "0")
10125        (const_string "*")))
10126    (set_attr "mode" "<MODE>")])
10128 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10129 (define_split
10130   [(set (match_operand:SWI48 0 "register_operand")
10131         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10132                       (match_operand:QI 2 "immediate_operand")))
10133    (clobber (reg:CC FLAGS_REG))]
10134   "TARGET_BMI2 && reload_completed"
10135   [(set (match_dup 0)
10136         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10138   operands[2]
10139     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10142 (define_split
10143   [(set (match_operand:SWI48 0 "register_operand")
10144         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10145                         (match_operand:QI 2 "immediate_operand")))
10146    (clobber (reg:CC FLAGS_REG))]
10147   "TARGET_BMI2 && reload_completed"
10148   [(set (match_dup 0)
10149         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10151 (define_insn "*bmi2_rorxsi3_1_zext"
10152   [(set (match_operand:DI 0 "register_operand" "=r")
10153         (zero_extend:DI
10154           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10155                        (match_operand:QI 2 "immediate_operand" "I"))))]
10156   "TARGET_64BIT && TARGET_BMI2"
10157   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10158   [(set_attr "type" "rotatex")
10159    (set_attr "mode" "SI")])
10161 (define_insn "*<rotate_insn>si3_1_zext"
10162   [(set (match_operand:DI 0 "register_operand" "=r,r")
10163         (zero_extend:DI
10164           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10165                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10166    (clobber (reg:CC FLAGS_REG))]
10167   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10169   switch (get_attr_type (insn))
10170     {
10171     case TYPE_ROTATEX:
10172       return "#";
10174     default:
10175       if (operands[2] == const1_rtx
10176           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10177         return "<rotate>{l}\t%k0";
10178       else
10179         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10180     }
10182   [(set_attr "isa" "*,bmi2")
10183    (set_attr "type" "rotate,rotatex")
10184    (set (attr "length_immediate")
10185      (if_then_else
10186        (and (eq_attr "type" "rotate")
10187             (and (match_operand 2 "const1_operand")
10188                  (ior (match_test "TARGET_SHIFT1")
10189                       (match_test "optimize_function_for_size_p (cfun)"))))
10190        (const_string "0")
10191        (const_string "*")))
10192    (set_attr "mode" "SI")])
10194 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10195 (define_split
10196   [(set (match_operand:DI 0 "register_operand")
10197         (zero_extend:DI
10198           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10199                      (match_operand:QI 2 "immediate_operand"))))
10200    (clobber (reg:CC FLAGS_REG))]
10201   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10202   [(set (match_dup 0)
10203         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10205   operands[2]
10206     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10209 (define_split
10210   [(set (match_operand:DI 0 "register_operand")
10211         (zero_extend:DI
10212           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10213                        (match_operand:QI 2 "immediate_operand"))))
10214    (clobber (reg:CC FLAGS_REG))]
10215   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10216   [(set (match_dup 0)
10217         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10219 (define_insn "*<rotate_insn><mode>3_1"
10220   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10221         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10222                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10223    (clobber (reg:CC FLAGS_REG))]
10224   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10226   if (operands[2] == const1_rtx
10227       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10228     return "<rotate>{<imodesuffix>}\t%0";
10229   else
10230     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10232   [(set_attr "type" "rotate")
10233    (set (attr "length_immediate")
10234      (if_then_else
10235        (and (match_operand 2 "const1_operand")
10236             (ior (match_test "TARGET_SHIFT1")
10237                  (match_test "optimize_function_for_size_p (cfun)")))
10238        (const_string "0")
10239        (const_string "*")))
10240    (set_attr "mode" "<MODE>")])
10242 (define_insn "*<rotate_insn>qi3_1_slp"
10243   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10244         (any_rotate:QI (match_dup 0)
10245                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10246    (clobber (reg:CC FLAGS_REG))]
10247   "(optimize_function_for_size_p (cfun)
10248     || !TARGET_PARTIAL_REG_STALL
10249     || (operands[1] == const1_rtx
10250         && TARGET_SHIFT1))"
10252   if (operands[1] == const1_rtx
10253       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10254     return "<rotate>{b}\t%0";
10255   else
10256     return "<rotate>{b}\t{%1, %0|%0, %1}";
10258   [(set_attr "type" "rotate1")
10259    (set (attr "length_immediate")
10260      (if_then_else
10261        (and (match_operand 1 "const1_operand")
10262             (ior (match_test "TARGET_SHIFT1")
10263                  (match_test "optimize_function_for_size_p (cfun)")))
10264        (const_string "0")
10265        (const_string "*")))
10266    (set_attr "mode" "QI")])
10268 (define_split
10269  [(set (match_operand:HI 0 "register_operand")
10270        (any_rotate:HI (match_dup 0) (const_int 8)))
10271   (clobber (reg:CC FLAGS_REG))]
10272  "reload_completed
10273   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10274  [(parallel [(set (strict_low_part (match_dup 0))
10275                   (bswap:HI (match_dup 0)))
10276              (clobber (reg:CC FLAGS_REG))])])
10278 ;; Bit set / bit test instructions
10280 (define_expand "extv"
10281   [(set (match_operand:SI 0 "register_operand")
10282         (sign_extract:SI (match_operand:SI 1 "register_operand")
10283                          (match_operand:SI 2 "const8_operand")
10284                          (match_operand:SI 3 "const8_operand")))]
10285   ""
10287   /* Handle extractions from %ah et al.  */
10288   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10289     FAIL;
10291   /* From mips.md: extract_bit_field doesn't verify that our source
10292      matches the predicate, so check it again here.  */
10293   if (! ext_register_operand (operands[1], VOIDmode))
10294     FAIL;
10297 (define_expand "extzv"
10298   [(set (match_operand:SI 0 "register_operand")
10299         (zero_extract:SI (match_operand 1 "ext_register_operand")
10300                          (match_operand:SI 2 "const8_operand")
10301                          (match_operand:SI 3 "const8_operand")))]
10302   ""
10304   /* Handle extractions from %ah et al.  */
10305   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10306     FAIL;
10308   /* From mips.md: extract_bit_field doesn't verify that our source
10309      matches the predicate, so check it again here.  */
10310   if (! ext_register_operand (operands[1], VOIDmode))
10311     FAIL;
10314 (define_expand "insv"
10315   [(set (zero_extract (match_operand 0 "register_operand")
10316                       (match_operand 1 "const_int_operand")
10317                       (match_operand 2 "const_int_operand"))
10318         (match_operand 3 "register_operand"))]
10319   ""
10321   rtx (*gen_mov_insv_1) (rtx, rtx);
10323   if (ix86_expand_pinsr (operands))
10324     DONE;
10326   /* Handle insertions to %ah et al.  */
10327   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10328     FAIL;
10330   /* From mips.md: insert_bit_field doesn't verify that our source
10331      matches the predicate, so check it again here.  */
10332   if (! ext_register_operand (operands[0], VOIDmode))
10333     FAIL;
10335   gen_mov_insv_1 = (TARGET_64BIT
10336                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10338   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10339   DONE;
10342 ;; %%% bts, btr, btc, bt.
10343 ;; In general these instructions are *slow* when applied to memory,
10344 ;; since they enforce atomic operation.  When applied to registers,
10345 ;; it depends on the cpu implementation.  They're never faster than
10346 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10347 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10348 ;; within the instruction itself, so operating on bits in the high
10349 ;; 32-bits of a register becomes easier.
10351 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10352 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10353 ;; negdf respectively, so they can never be disabled entirely.
10355 (define_insn "*btsq"
10356   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10357                          (const_int 1)
10358                          (match_operand:DI 1 "const_0_to_63_operand"))
10359         (const_int 1))
10360    (clobber (reg:CC FLAGS_REG))]
10361   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10362   "bts{q}\t{%1, %0|%0, %1}"
10363   [(set_attr "type" "alu1")
10364    (set_attr "prefix_0f" "1")
10365    (set_attr "mode" "DI")])
10367 (define_insn "*btrq"
10368   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10369                          (const_int 1)
10370                          (match_operand:DI 1 "const_0_to_63_operand"))
10371         (const_int 0))
10372    (clobber (reg:CC FLAGS_REG))]
10373   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10374   "btr{q}\t{%1, %0|%0, %1}"
10375   [(set_attr "type" "alu1")
10376    (set_attr "prefix_0f" "1")
10377    (set_attr "mode" "DI")])
10379 (define_insn "*btcq"
10380   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10381                          (const_int 1)
10382                          (match_operand:DI 1 "const_0_to_63_operand"))
10383         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10384    (clobber (reg:CC FLAGS_REG))]
10385   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10386   "btc{q}\t{%1, %0|%0, %1}"
10387   [(set_attr "type" "alu1")
10388    (set_attr "prefix_0f" "1")
10389    (set_attr "mode" "DI")])
10391 ;; Allow Nocona to avoid these instructions if a register is available.
10393 (define_peephole2
10394   [(match_scratch:DI 2 "r")
10395    (parallel [(set (zero_extract:DI
10396                      (match_operand:DI 0 "register_operand")
10397                      (const_int 1)
10398                      (match_operand:DI 1 "const_0_to_63_operand"))
10399                    (const_int 1))
10400               (clobber (reg:CC FLAGS_REG))])]
10401   "TARGET_64BIT && !TARGET_USE_BT"
10402   [(const_int 0)]
10404   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10405   rtx op1;
10407   if (HOST_BITS_PER_WIDE_INT >= 64)
10408     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10409   else if (i < HOST_BITS_PER_WIDE_INT)
10410     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10411   else
10412     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10414   op1 = immed_double_const (lo, hi, DImode);
10415   if (i >= 31)
10416     {
10417       emit_move_insn (operands[2], op1);
10418       op1 = operands[2];
10419     }
10421   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10422   DONE;
10425 (define_peephole2
10426   [(match_scratch:DI 2 "r")
10427    (parallel [(set (zero_extract:DI
10428                      (match_operand:DI 0 "register_operand")
10429                      (const_int 1)
10430                      (match_operand:DI 1 "const_0_to_63_operand"))
10431                    (const_int 0))
10432               (clobber (reg:CC FLAGS_REG))])]
10433   "TARGET_64BIT && !TARGET_USE_BT"
10434   [(const_int 0)]
10436   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10437   rtx op1;
10439   if (HOST_BITS_PER_WIDE_INT >= 64)
10440     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10441   else if (i < HOST_BITS_PER_WIDE_INT)
10442     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10443   else
10444     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10446   op1 = immed_double_const (~lo, ~hi, DImode);
10447   if (i >= 32)
10448     {
10449       emit_move_insn (operands[2], op1);
10450       op1 = operands[2];
10451     }
10453   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10454   DONE;
10457 (define_peephole2
10458   [(match_scratch:DI 2 "r")
10459    (parallel [(set (zero_extract:DI
10460                      (match_operand:DI 0 "register_operand")
10461                      (const_int 1)
10462                      (match_operand:DI 1 "const_0_to_63_operand"))
10463               (not:DI (zero_extract:DI
10464                         (match_dup 0) (const_int 1) (match_dup 1))))
10465               (clobber (reg:CC FLAGS_REG))])]
10466   "TARGET_64BIT && !TARGET_USE_BT"
10467   [(const_int 0)]
10469   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10470   rtx op1;
10472   if (HOST_BITS_PER_WIDE_INT >= 64)
10473     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10474   else if (i < HOST_BITS_PER_WIDE_INT)
10475     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10476   else
10477     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10479   op1 = immed_double_const (lo, hi, DImode);
10480   if (i >= 31)
10481     {
10482       emit_move_insn (operands[2], op1);
10483       op1 = operands[2];
10484     }
10486   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10487   DONE;
10490 (define_insn "*bt<mode>"
10491   [(set (reg:CCC FLAGS_REG)
10492         (compare:CCC
10493           (zero_extract:SWI48
10494             (match_operand:SWI48 0 "register_operand" "r")
10495             (const_int 1)
10496             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10497           (const_int 0)))]
10498   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10499   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10500   [(set_attr "type" "alu1")
10501    (set_attr "prefix_0f" "1")
10502    (set_attr "mode" "<MODE>")])
10504 ;; Store-flag instructions.
10506 ;; For all sCOND expanders, also expand the compare or test insn that
10507 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10509 (define_insn_and_split "*setcc_di_1"
10510   [(set (match_operand:DI 0 "register_operand" "=q")
10511         (match_operator:DI 1 "ix86_comparison_operator"
10512           [(reg FLAGS_REG) (const_int 0)]))]
10513   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10514   "#"
10515   "&& reload_completed"
10516   [(set (match_dup 2) (match_dup 1))
10517    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10519   PUT_MODE (operands[1], QImode);
10520   operands[2] = gen_lowpart (QImode, operands[0]);
10523 (define_insn_and_split "*setcc_si_1_and"
10524   [(set (match_operand:SI 0 "register_operand" "=q")
10525         (match_operator:SI 1 "ix86_comparison_operator"
10526           [(reg FLAGS_REG) (const_int 0)]))
10527    (clobber (reg:CC FLAGS_REG))]
10528   "!TARGET_PARTIAL_REG_STALL
10529    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10530   "#"
10531   "&& reload_completed"
10532   [(set (match_dup 2) (match_dup 1))
10533    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10534               (clobber (reg:CC FLAGS_REG))])]
10536   PUT_MODE (operands[1], QImode);
10537   operands[2] = gen_lowpart (QImode, operands[0]);
10540 (define_insn_and_split "*setcc_si_1_movzbl"
10541   [(set (match_operand:SI 0 "register_operand" "=q")
10542         (match_operator:SI 1 "ix86_comparison_operator"
10543           [(reg FLAGS_REG) (const_int 0)]))]
10544   "!TARGET_PARTIAL_REG_STALL
10545    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10546   "#"
10547   "&& reload_completed"
10548   [(set (match_dup 2) (match_dup 1))
10549    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10551   PUT_MODE (operands[1], QImode);
10552   operands[2] = gen_lowpart (QImode, operands[0]);
10555 (define_insn "*setcc_qi"
10556   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10557         (match_operator:QI 1 "ix86_comparison_operator"
10558           [(reg FLAGS_REG) (const_int 0)]))]
10559   ""
10560   "set%C1\t%0"
10561   [(set_attr "type" "setcc")
10562    (set_attr "mode" "QI")])
10564 (define_insn "*setcc_qi_slp"
10565   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10566         (match_operator:QI 1 "ix86_comparison_operator"
10567           [(reg FLAGS_REG) (const_int 0)]))]
10568   ""
10569   "set%C1\t%0"
10570   [(set_attr "type" "setcc")
10571    (set_attr "mode" "QI")])
10573 ;; In general it is not safe to assume too much about CCmode registers,
10574 ;; so simplify-rtx stops when it sees a second one.  Under certain
10575 ;; conditions this is safe on x86, so help combine not create
10577 ;;      seta    %al
10578 ;;      testb   %al, %al
10579 ;;      sete    %al
10581 (define_split
10582   [(set (match_operand:QI 0 "nonimmediate_operand")
10583         (ne:QI (match_operator 1 "ix86_comparison_operator"
10584                  [(reg FLAGS_REG) (const_int 0)])
10585             (const_int 0)))]
10586   ""
10587   [(set (match_dup 0) (match_dup 1))]
10588   "PUT_MODE (operands[1], QImode);")
10590 (define_split
10591   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10592         (ne:QI (match_operator 1 "ix86_comparison_operator"
10593                  [(reg FLAGS_REG) (const_int 0)])
10594             (const_int 0)))]
10595   ""
10596   [(set (match_dup 0) (match_dup 1))]
10597   "PUT_MODE (operands[1], QImode);")
10599 (define_split
10600   [(set (match_operand:QI 0 "nonimmediate_operand")
10601         (eq:QI (match_operator 1 "ix86_comparison_operator"
10602                  [(reg FLAGS_REG) (const_int 0)])
10603             (const_int 0)))]
10604   ""
10605   [(set (match_dup 0) (match_dup 1))]
10607   rtx new_op1 = copy_rtx (operands[1]);
10608   operands[1] = new_op1;
10609   PUT_MODE (new_op1, QImode);
10610   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10611                                              GET_MODE (XEXP (new_op1, 0))));
10613   /* Make sure that (a) the CCmode we have for the flags is strong
10614      enough for the reversed compare or (b) we have a valid FP compare.  */
10615   if (! ix86_comparison_operator (new_op1, VOIDmode))
10616     FAIL;
10619 (define_split
10620   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10621         (eq: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))]
10627   rtx new_op1 = copy_rtx (operands[1]);
10628   operands[1] = new_op1;
10629   PUT_MODE (new_op1, QImode);
10630   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10631                                              GET_MODE (XEXP (new_op1, 0))));
10633   /* Make sure that (a) the CCmode we have for the flags is strong
10634      enough for the reversed compare or (b) we have a valid FP compare.  */
10635   if (! ix86_comparison_operator (new_op1, VOIDmode))
10636     FAIL;
10639 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10640 ;; subsequent logical operations are used to imitate conditional moves.
10641 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10642 ;; it directly.
10644 (define_insn "setcc_<mode>_sse"
10645   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10646         (match_operator:MODEF 3 "sse_comparison_operator"
10647           [(match_operand:MODEF 1 "register_operand" "0,x")
10648            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10649   "SSE_FLOAT_MODE_P (<MODE>mode)"
10650   "@
10651    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10652    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10653   [(set_attr "isa" "noavx,avx")
10654    (set_attr "type" "ssecmp")
10655    (set_attr "length_immediate" "1")
10656    (set_attr "prefix" "orig,vex")
10657    (set_attr "mode" "<MODE>")])
10659 ;; Basic conditional jump instructions.
10660 ;; We ignore the overflow flag for signed branch instructions.
10662 (define_insn "*jcc_1"
10663   [(set (pc)
10664         (if_then_else (match_operator 1 "ix86_comparison_operator"
10665                                       [(reg FLAGS_REG) (const_int 0)])
10666                       (label_ref (match_operand 0))
10667                       (pc)))]
10668   ""
10669   "%+j%C1\t%l0"
10670   [(set_attr "type" "ibr")
10671    (set_attr "modrm" "0")
10672    (set (attr "length")
10673            (if_then_else (and (ge (minus (match_dup 0) (pc))
10674                                   (const_int -126))
10675                               (lt (minus (match_dup 0) (pc))
10676                                   (const_int 128)))
10677              (const_int 2)
10678              (const_int 6)))])
10680 (define_insn "*jcc_2"
10681   [(set (pc)
10682         (if_then_else (match_operator 1 "ix86_comparison_operator"
10683                                       [(reg FLAGS_REG) (const_int 0)])
10684                       (pc)
10685                       (label_ref (match_operand 0))))]
10686   ""
10687   "%+j%c1\t%l0"
10688   [(set_attr "type" "ibr")
10689    (set_attr "modrm" "0")
10690    (set (attr "length")
10691            (if_then_else (and (ge (minus (match_dup 0) (pc))
10692                                   (const_int -126))
10693                               (lt (minus (match_dup 0) (pc))
10694                                   (const_int 128)))
10695              (const_int 2)
10696              (const_int 6)))])
10698 ;; In general it is not safe to assume too much about CCmode registers,
10699 ;; so simplify-rtx stops when it sees a second one.  Under certain
10700 ;; conditions this is safe on x86, so help combine not create
10702 ;;      seta    %al
10703 ;;      testb   %al, %al
10704 ;;      je      Lfoo
10706 (define_split
10707   [(set (pc)
10708         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10709                                       [(reg FLAGS_REG) (const_int 0)])
10710                           (const_int 0))
10711                       (label_ref (match_operand 1))
10712                       (pc)))]
10713   ""
10714   [(set (pc)
10715         (if_then_else (match_dup 0)
10716                       (label_ref (match_dup 1))
10717                       (pc)))]
10718   "PUT_MODE (operands[0], VOIDmode);")
10720 (define_split
10721   [(set (pc)
10722         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10723                                       [(reg FLAGS_REG) (const_int 0)])
10724                           (const_int 0))
10725                       (label_ref (match_operand 1))
10726                       (pc)))]
10727   ""
10728   [(set (pc)
10729         (if_then_else (match_dup 0)
10730                       (label_ref (match_dup 1))
10731                       (pc)))]
10733   rtx new_op0 = copy_rtx (operands[0]);
10734   operands[0] = new_op0;
10735   PUT_MODE (new_op0, VOIDmode);
10736   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10737                                              GET_MODE (XEXP (new_op0, 0))));
10739   /* Make sure that (a) the CCmode we have for the flags is strong
10740      enough for the reversed compare or (b) we have a valid FP compare.  */
10741   if (! ix86_comparison_operator (new_op0, VOIDmode))
10742     FAIL;
10745 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10746 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10747 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10748 ;; appropriate modulo of the bit offset value.
10750 (define_insn_and_split "*jcc_bt<mode>"
10751   [(set (pc)
10752         (if_then_else (match_operator 0 "bt_comparison_operator"
10753                         [(zero_extract:SWI48
10754                            (match_operand:SWI48 1 "register_operand" "r")
10755                            (const_int 1)
10756                            (zero_extend:SI
10757                              (match_operand:QI 2 "register_operand" "r")))
10758                          (const_int 0)])
10759                       (label_ref (match_operand 3))
10760                       (pc)))
10761    (clobber (reg:CC FLAGS_REG))]
10762   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10763   "#"
10764   "&& 1"
10765   [(set (reg:CCC FLAGS_REG)
10766         (compare:CCC
10767           (zero_extract:SWI48
10768             (match_dup 1)
10769             (const_int 1)
10770             (match_dup 2))
10771           (const_int 0)))
10772    (set (pc)
10773         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10774                       (label_ref (match_dup 3))
10775                       (pc)))]
10777   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10779   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10782 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10783 ;; also for DImode, this is what combine produces.
10784 (define_insn_and_split "*jcc_bt<mode>_mask"
10785   [(set (pc)
10786         (if_then_else (match_operator 0 "bt_comparison_operator"
10787                         [(zero_extract:SWI48
10788                            (match_operand:SWI48 1 "register_operand" "r")
10789                            (const_int 1)
10790                            (and:SI
10791                              (match_operand:SI 2 "register_operand" "r")
10792                              (match_operand:SI 3 "const_int_operand" "n")))])
10793                       (label_ref (match_operand 4))
10794                       (pc)))
10795    (clobber (reg:CC FLAGS_REG))]
10796   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10797    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10798       == GET_MODE_BITSIZE (<MODE>mode)-1"
10799   "#"
10800   "&& 1"
10801   [(set (reg:CCC FLAGS_REG)
10802         (compare:CCC
10803           (zero_extract:SWI48
10804             (match_dup 1)
10805             (const_int 1)
10806             (match_dup 2))
10807           (const_int 0)))
10808    (set (pc)
10809         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10810                       (label_ref (match_dup 4))
10811                       (pc)))]
10813   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10815   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10818 (define_insn_and_split "*jcc_btsi_1"
10819   [(set (pc)
10820         (if_then_else (match_operator 0 "bt_comparison_operator"
10821                         [(and:SI
10822                            (lshiftrt:SI
10823                              (match_operand:SI 1 "register_operand" "r")
10824                              (match_operand:QI 2 "register_operand" "r"))
10825                            (const_int 1))
10826                          (const_int 0)])
10827                       (label_ref (match_operand 3))
10828                       (pc)))
10829    (clobber (reg:CC FLAGS_REG))]
10830   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10831   "#"
10832   "&& 1"
10833   [(set (reg:CCC FLAGS_REG)
10834         (compare:CCC
10835           (zero_extract:SI
10836             (match_dup 1)
10837             (const_int 1)
10838             (match_dup 2))
10839           (const_int 0)))
10840    (set (pc)
10841         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10842                       (label_ref (match_dup 3))
10843                       (pc)))]
10845   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10847   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10850 ;; avoid useless masking of bit offset operand
10851 (define_insn_and_split "*jcc_btsi_mask_1"
10852   [(set (pc)
10853         (if_then_else
10854           (match_operator 0 "bt_comparison_operator"
10855             [(and:SI
10856                (lshiftrt:SI
10857                  (match_operand:SI 1 "register_operand" "r")
10858                  (subreg:QI
10859                    (and:SI
10860                      (match_operand:SI 2 "register_operand" "r")
10861                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10862                (const_int 1))
10863              (const_int 0)])
10864           (label_ref (match_operand 4))
10865           (pc)))
10866    (clobber (reg:CC FLAGS_REG))]
10867   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10868    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
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 4))
10881                       (pc)))]
10882   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10884 ;; Define combination compare-and-branch fp compare instructions to help
10885 ;; combine.
10887 (define_insn "*fp_jcc_1_387"
10888   [(set (pc)
10889         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10890                         [(match_operand 1 "register_operand" "f")
10891                          (match_operand 2 "nonimmediate_operand" "fm")])
10892           (label_ref (match_operand 3))
10893           (pc)))
10894    (clobber (reg:CCFP FPSR_REG))
10895    (clobber (reg:CCFP FLAGS_REG))
10896    (clobber (match_scratch:HI 4 "=a"))]
10897   "TARGET_80387
10898    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10899    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10900    && SELECT_CC_MODE (GET_CODE (operands[0]),
10901                       operands[1], operands[2]) == CCFPmode
10902    && !TARGET_CMOVE"
10903   "#")
10905 (define_insn "*fp_jcc_1r_387"
10906   [(set (pc)
10907         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10908                         [(match_operand 1 "register_operand" "f")
10909                          (match_operand 2 "nonimmediate_operand" "fm")])
10910           (pc)
10911           (label_ref (match_operand 3))))
10912    (clobber (reg:CCFP FPSR_REG))
10913    (clobber (reg:CCFP FLAGS_REG))
10914    (clobber (match_scratch:HI 4 "=a"))]
10915   "TARGET_80387
10916    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10917    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10918    && SELECT_CC_MODE (GET_CODE (operands[0]),
10919                       operands[1], operands[2]) == CCFPmode
10920    && !TARGET_CMOVE"
10921   "#")
10923 (define_insn "*fp_jcc_2_387"
10924   [(set (pc)
10925         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10926                         [(match_operand 1 "register_operand" "f")
10927                          (match_operand 2 "register_operand" "f")])
10928           (label_ref (match_operand 3))
10929           (pc)))
10930    (clobber (reg:CCFP FPSR_REG))
10931    (clobber (reg:CCFP FLAGS_REG))
10932    (clobber (match_scratch:HI 4 "=a"))]
10933   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10934    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10935    && !TARGET_CMOVE"
10936   "#")
10938 (define_insn "*fp_jcc_2r_387"
10939   [(set (pc)
10940         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10941                         [(match_operand 1 "register_operand" "f")
10942                          (match_operand 2 "register_operand" "f")])
10943           (pc)
10944           (label_ref (match_operand 3))))
10945    (clobber (reg:CCFP FPSR_REG))
10946    (clobber (reg:CCFP FLAGS_REG))
10947    (clobber (match_scratch:HI 4 "=a"))]
10948   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10949    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10950    && !TARGET_CMOVE"
10951   "#")
10953 (define_insn "*fp_jcc_3_387"
10954   [(set (pc)
10955         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10956                         [(match_operand 1 "register_operand" "f")
10957                          (match_operand 2 "const0_operand")])
10958           (label_ref (match_operand 3))
10959           (pc)))
10960    (clobber (reg:CCFP FPSR_REG))
10961    (clobber (reg:CCFP FLAGS_REG))
10962    (clobber (match_scratch:HI 4 "=a"))]
10963   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10964    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10965    && SELECT_CC_MODE (GET_CODE (operands[0]),
10966                       operands[1], operands[2]) == CCFPmode
10967    && !TARGET_CMOVE"
10968   "#")
10970 (define_split
10971   [(set (pc)
10972         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10973                         [(match_operand 1 "register_operand")
10974                          (match_operand 2 "nonimmediate_operand")])
10975           (match_operand 3)
10976           (match_operand 4)))
10977    (clobber (reg:CCFP FPSR_REG))
10978    (clobber (reg:CCFP FLAGS_REG))]
10979   "reload_completed"
10980   [(const_int 0)]
10982   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10983                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10984   DONE;
10987 (define_split
10988   [(set (pc)
10989         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10990                         [(match_operand 1 "register_operand")
10991                          (match_operand 2 "general_operand")])
10992           (match_operand 3)
10993           (match_operand 4)))
10994    (clobber (reg:CCFP FPSR_REG))
10995    (clobber (reg:CCFP FLAGS_REG))
10996    (clobber (match_scratch:HI 5 "=a"))]
10997   "reload_completed"
10998   [(const_int 0)]
11000   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11001                         operands[3], operands[4], operands[5], NULL_RTX);
11002   DONE;
11005 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11006 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11007 ;; with a precedence over other operators and is always put in the first
11008 ;; place. Swap condition and operands to match ficom instruction.
11010 (define_insn "*fp_jcc_4_<mode>_387"
11011   [(set (pc)
11012         (if_then_else
11013           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11014             [(match_operator 1 "float_operator"
11015               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11016              (match_operand 3 "register_operand" "f,f")])
11017           (label_ref (match_operand 4))
11018           (pc)))
11019    (clobber (reg:CCFP FPSR_REG))
11020    (clobber (reg:CCFP FLAGS_REG))
11021    (clobber (match_scratch:HI 5 "=a,a"))]
11022   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11023    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11024    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11025    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11026    && !TARGET_CMOVE"
11027   "#")
11029 (define_split
11030   [(set (pc)
11031         (if_then_else
11032           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11033             [(match_operator 1 "float_operator"
11034               [(match_operand:SWI24 2 "memory_operand")])
11035              (match_operand 3 "register_operand")])
11036           (match_operand 4)
11037           (match_operand 5)))
11038    (clobber (reg:CCFP FPSR_REG))
11039    (clobber (reg:CCFP FLAGS_REG))
11040    (clobber (match_scratch:HI 6 "=a"))]
11041   "reload_completed"
11042   [(const_int 0)]
11044   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11046   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11047                         operands[3], operands[7],
11048                         operands[4], operands[5], operands[6], NULL_RTX);
11049   DONE;
11052 ;; %%% Kill this when reload knows how to do it.
11053 (define_split
11054   [(set (pc)
11055         (if_then_else
11056           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11057             [(match_operator 1 "float_operator"
11058               [(match_operand:SWI24 2 "register_operand")])
11059              (match_operand 3 "register_operand")])
11060           (match_operand 4)
11061           (match_operand 5)))
11062    (clobber (reg:CCFP FPSR_REG))
11063    (clobber (reg:CCFP FLAGS_REG))
11064    (clobber (match_scratch:HI 6 "=a"))]
11065   "reload_completed"
11066   [(const_int 0)]
11068   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11069   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11071   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11072                         operands[3], operands[7],
11073                         operands[4], operands[5], operands[6], operands[2]);
11074   DONE;
11077 ;; Unconditional and other jump instructions
11079 (define_insn "jump"
11080   [(set (pc)
11081         (label_ref (match_operand 0)))]
11082   ""
11083   "jmp\t%l0"
11084   [(set_attr "type" "ibr")
11085    (set (attr "length")
11086            (if_then_else (and (ge (minus (match_dup 0) (pc))
11087                                   (const_int -126))
11088                               (lt (minus (match_dup 0) (pc))
11089                                   (const_int 128)))
11090              (const_int 2)
11091              (const_int 5)))
11092    (set_attr "modrm" "0")])
11094 (define_expand "indirect_jump"
11095   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11096   ""
11098   if (TARGET_X32)
11099     operands[0] = convert_memory_address (word_mode, operands[0]);
11102 (define_insn "*indirect_jump"
11103   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11104   ""
11105   "jmp\t%A0"
11106   [(set_attr "type" "ibr")
11107    (set_attr "length_immediate" "0")])
11109 (define_expand "tablejump"
11110   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11111               (use (label_ref (match_operand 1)))])]
11112   ""
11114   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11115      relative.  Convert the relative address to an absolute address.  */
11116   if (flag_pic)
11117     {
11118       rtx op0, op1;
11119       enum rtx_code code;
11121       /* We can't use @GOTOFF for text labels on VxWorks;
11122          see gotoff_operand.  */
11123       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11124         {
11125           code = PLUS;
11126           op0 = operands[0];
11127           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11128         }
11129       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11130         {
11131           code = PLUS;
11132           op0 = operands[0];
11133           op1 = pic_offset_table_rtx;
11134         }
11135       else
11136         {
11137           code = MINUS;
11138           op0 = pic_offset_table_rtx;
11139           op1 = operands[0];
11140         }
11142       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11143                                          OPTAB_DIRECT);
11144     }
11146   if (TARGET_X32)
11147     operands[0] = convert_memory_address (word_mode, operands[0]);
11150 (define_insn "*tablejump_1"
11151   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11152    (use (label_ref (match_operand 1)))]
11153   ""
11154   "jmp\t%A0"
11155   [(set_attr "type" "ibr")
11156    (set_attr "length_immediate" "0")])
11158 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11160 (define_peephole2
11161   [(set (reg FLAGS_REG) (match_operand 0))
11162    (set (match_operand:QI 1 "register_operand")
11163         (match_operator:QI 2 "ix86_comparison_operator"
11164           [(reg FLAGS_REG) (const_int 0)]))
11165    (set (match_operand 3 "q_regs_operand")
11166         (zero_extend (match_dup 1)))]
11167   "(peep2_reg_dead_p (3, operands[1])
11168     || operands_match_p (operands[1], operands[3]))
11169    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11170   [(set (match_dup 4) (match_dup 0))
11171    (set (strict_low_part (match_dup 5))
11172         (match_dup 2))]
11174   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11175   operands[5] = gen_lowpart (QImode, operands[3]);
11176   ix86_expand_clear (operands[3]);
11179 (define_peephole2
11180   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11181               (match_operand 4)])
11182    (set (match_operand:QI 1 "register_operand")
11183         (match_operator:QI 2 "ix86_comparison_operator"
11184           [(reg FLAGS_REG) (const_int 0)]))
11185    (set (match_operand 3 "q_regs_operand")
11186         (zero_extend (match_dup 1)))]
11187   "(peep2_reg_dead_p (3, operands[1])
11188     || operands_match_p (operands[1], operands[3]))
11189    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11190   [(parallel [(set (match_dup 5) (match_dup 0))
11191               (match_dup 4)])
11192    (set (strict_low_part (match_dup 6))
11193         (match_dup 2))]
11195   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11196   operands[6] = gen_lowpart (QImode, operands[3]);
11197   ix86_expand_clear (operands[3]);
11200 ;; Similar, but match zero extend with andsi3.
11202 (define_peephole2
11203   [(set (reg FLAGS_REG) (match_operand 0))
11204    (set (match_operand:QI 1 "register_operand")
11205         (match_operator:QI 2 "ix86_comparison_operator"
11206           [(reg FLAGS_REG) (const_int 0)]))
11207    (parallel [(set (match_operand:SI 3 "q_regs_operand")
11208                    (and:SI (match_dup 3) (const_int 255)))
11209               (clobber (reg:CC FLAGS_REG))])]
11210   "REGNO (operands[1]) == REGNO (operands[3])
11211    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11212   [(set (match_dup 4) (match_dup 0))
11213    (set (strict_low_part (match_dup 5))
11214         (match_dup 2))]
11216   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11217   operands[5] = gen_lowpart (QImode, operands[3]);
11218   ix86_expand_clear (operands[3]);
11221 (define_peephole2
11222   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11223               (match_operand 4)])
11224    (set (match_operand:QI 1 "register_operand")
11225         (match_operator:QI 2 "ix86_comparison_operator"
11226           [(reg FLAGS_REG) (const_int 0)]))
11227    (parallel [(set (match_operand 3 "q_regs_operand")
11228                    (zero_extend (match_dup 1)))
11229               (clobber (reg:CC FLAGS_REG))])]
11230   "(peep2_reg_dead_p (3, operands[1])
11231     || operands_match_p (operands[1], operands[3]))
11232    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11233   [(parallel [(set (match_dup 5) (match_dup 0))
11234               (match_dup 4)])
11235    (set (strict_low_part (match_dup 6))
11236         (match_dup 2))]
11238   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11239   operands[6] = gen_lowpart (QImode, operands[3]);
11240   ix86_expand_clear (operands[3]);
11243 ;; Call instructions.
11245 ;; The predicates normally associated with named expanders are not properly
11246 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11247 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11249 ;; P6 processors will jump to the address after the decrement when %esp
11250 ;; is used as a call operand, so they will execute return address as a code.
11251 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11253 ;; Register constraint for call instruction.
11254 (define_mode_attr c [(SI "l") (DI "r")])
11256 ;; Call subroutine returning no value.
11258 (define_expand "call"
11259   [(call (match_operand:QI 0)
11260          (match_operand 1))
11261    (use (match_operand 2))]
11262   ""
11264   ix86_expand_call (NULL, operands[0], operands[1],
11265                     operands[2], NULL, false);
11266   DONE;
11269 (define_expand "sibcall"
11270   [(call (match_operand:QI 0)
11271          (match_operand 1))
11272    (use (match_operand 2))]
11273   ""
11275   ix86_expand_call (NULL, operands[0], operands[1],
11276                     operands[2], NULL, true);
11277   DONE;
11280 (define_insn_and_split "*call_vzeroupper"
11281   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11282          (match_operand 1))
11283    (unspec [(match_operand 2 "const_int_operand")]
11284            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11285   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11286   "#"
11287   "&& reload_completed"
11288   [(const_int 0)]
11289   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11290   [(set_attr "type" "call")])
11292 (define_insn "*call"
11293   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11294          (match_operand 1))]
11295   "!SIBLING_CALL_P (insn)"
11296   "* return ix86_output_call_insn (insn, operands[0]);"
11297   [(set_attr "type" "call")])
11299 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11300   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11301          (match_operand 1))
11302    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11303    (clobber (reg:TI XMM6_REG))
11304    (clobber (reg:TI XMM7_REG))
11305    (clobber (reg:TI XMM8_REG))
11306    (clobber (reg:TI XMM9_REG))
11307    (clobber (reg:TI XMM10_REG))
11308    (clobber (reg:TI XMM11_REG))
11309    (clobber (reg:TI XMM12_REG))
11310    (clobber (reg:TI XMM13_REG))
11311    (clobber (reg:TI XMM14_REG))
11312    (clobber (reg:TI XMM15_REG))
11313    (clobber (reg:DI SI_REG))
11314    (clobber (reg:DI DI_REG))
11315    (unspec [(match_operand 2 "const_int_operand")]
11316            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11317   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11318   "#"
11319   "&& reload_completed"
11320   [(const_int 0)]
11321   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11322   [(set_attr "type" "call")])
11324 (define_insn "*call_rex64_ms_sysv"
11325   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11326          (match_operand 1))
11327    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11328    (clobber (reg:TI XMM6_REG))
11329    (clobber (reg:TI XMM7_REG))
11330    (clobber (reg:TI XMM8_REG))
11331    (clobber (reg:TI XMM9_REG))
11332    (clobber (reg:TI XMM10_REG))
11333    (clobber (reg:TI XMM11_REG))
11334    (clobber (reg:TI XMM12_REG))
11335    (clobber (reg:TI XMM13_REG))
11336    (clobber (reg:TI XMM14_REG))
11337    (clobber (reg:TI XMM15_REG))
11338    (clobber (reg:DI SI_REG))
11339    (clobber (reg:DI DI_REG))]
11340   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11341   "* return ix86_output_call_insn (insn, operands[0]);"
11342   [(set_attr "type" "call")])
11344 (define_insn_and_split "*sibcall_vzeroupper"
11345   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11346          (match_operand 1))
11347    (unspec [(match_operand 2 "const_int_operand")]
11348            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11349   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11350   "#"
11351   "&& reload_completed"
11352   [(const_int 0)]
11353   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11354   [(set_attr "type" "call")])
11356 (define_insn "*sibcall"
11357   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11358          (match_operand 1))]
11359   "SIBLING_CALL_P (insn)"
11360   "* return ix86_output_call_insn (insn, operands[0]);"
11361   [(set_attr "type" "call")])
11363 (define_expand "call_pop"
11364   [(parallel [(call (match_operand:QI 0)
11365                     (match_operand:SI 1))
11366               (set (reg:SI SP_REG)
11367                    (plus:SI (reg:SI SP_REG)
11368                             (match_operand:SI 3)))])]
11369   "!TARGET_64BIT"
11371   ix86_expand_call (NULL, operands[0], operands[1],
11372                     operands[2], operands[3], false);
11373   DONE;
11376 (define_insn_and_split "*call_pop_vzeroupper"
11377   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11378          (match_operand 1))
11379    (set (reg:SI SP_REG)
11380         (plus:SI (reg:SI SP_REG)
11381                  (match_operand:SI 2 "immediate_operand" "i")))
11382    (unspec [(match_operand 3 "const_int_operand")]
11383            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11384   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11385   "#"
11386   "&& reload_completed"
11387   [(const_int 0)]
11388   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11389   [(set_attr "type" "call")])
11391 (define_insn "*call_pop"
11392   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
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   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11398   "* return ix86_output_call_insn (insn, operands[0]);"
11399   [(set_attr "type" "call")])
11401 (define_insn_and_split "*sibcall_pop_vzeroupper"
11402   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11403          (match_operand 1))
11404    (set (reg:SI SP_REG)
11405         (plus:SI (reg:SI SP_REG)
11406                  (match_operand:SI 2 "immediate_operand" "i")))
11407    (unspec [(match_operand 3 "const_int_operand")]
11408            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11409   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11410   "#"
11411   "&& reload_completed"
11412   [(const_int 0)]
11413   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11414   [(set_attr "type" "call")])
11416 (define_insn "*sibcall_pop"
11417   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11418          (match_operand 1))
11419    (set (reg:SI SP_REG)
11420         (plus:SI (reg:SI SP_REG)
11421                  (match_operand:SI 2 "immediate_operand" "i")))]
11422   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11423   "* return ix86_output_call_insn (insn, operands[0]);"
11424   [(set_attr "type" "call")])
11426 ;; Call subroutine, returning value in operand 0
11428 (define_expand "call_value"
11429   [(set (match_operand 0)
11430         (call (match_operand:QI 1)
11431               (match_operand 2)))
11432    (use (match_operand 3))]
11433   ""
11435   ix86_expand_call (operands[0], operands[1], operands[2],
11436                     operands[3], NULL, false);
11437   DONE;
11440 (define_expand "sibcall_value"
11441   [(set (match_operand 0)
11442         (call (match_operand:QI 1)
11443               (match_operand 2)))
11444    (use (match_operand 3))]
11445   ""
11447   ix86_expand_call (operands[0], operands[1], operands[2],
11448                     operands[3], NULL, true);
11449   DONE;
11452 (define_insn_and_split "*call_value_vzeroupper"
11453   [(set (match_operand 0)
11454         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11455               (match_operand 2)))
11456    (unspec [(match_operand 3 "const_int_operand")]
11457            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11458   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11459   "#"
11460   "&& reload_completed"
11461   [(const_int 0)]
11462   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11463   [(set_attr "type" "callv")])
11465 (define_insn "*call_value"
11466   [(set (match_operand 0)
11467         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11468               (match_operand 2)))]
11469   "!SIBLING_CALL_P (insn)"
11470   "* return ix86_output_call_insn (insn, operands[1]);"
11471   [(set_attr "type" "callv")])
11473 (define_insn_and_split "*sibcall_value_vzeroupper"
11474   [(set (match_operand 0)
11475         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11476               (match_operand 2)))
11477    (unspec [(match_operand 3 "const_int_operand")]
11478            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11479   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11480   "#"
11481   "&& reload_completed"
11482   [(const_int 0)]
11483   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11484   [(set_attr "type" "callv")])
11486 (define_insn "*sibcall_value"
11487   [(set (match_operand 0)
11488         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11489               (match_operand 2)))]
11490   "SIBLING_CALL_P (insn)"
11491   "* return ix86_output_call_insn (insn, operands[1]);"
11492   [(set_attr "type" "callv")])
11494 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11495   [(set (match_operand 0)
11496         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11497               (match_operand 2)))
11498    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11499    (clobber (reg:TI XMM6_REG))
11500    (clobber (reg:TI XMM7_REG))
11501    (clobber (reg:TI XMM8_REG))
11502    (clobber (reg:TI XMM9_REG))
11503    (clobber (reg:TI XMM10_REG))
11504    (clobber (reg:TI XMM11_REG))
11505    (clobber (reg:TI XMM12_REG))
11506    (clobber (reg:TI XMM13_REG))
11507    (clobber (reg:TI XMM14_REG))
11508    (clobber (reg:TI XMM15_REG))
11509    (clobber (reg:DI SI_REG))
11510    (clobber (reg:DI DI_REG))
11511    (unspec [(match_operand 3 "const_int_operand")]
11512            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11513   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11514   "#"
11515   "&& reload_completed"
11516   [(const_int 0)]
11517   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11518   [(set_attr "type" "callv")])
11520 (define_insn "*call_value_rex64_ms_sysv"
11521   [(set (match_operand 0)
11522         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11523               (match_operand 2)))
11524    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11525    (clobber (reg:TI XMM6_REG))
11526    (clobber (reg:TI XMM7_REG))
11527    (clobber (reg:TI XMM8_REG))
11528    (clobber (reg:TI XMM9_REG))
11529    (clobber (reg:TI XMM10_REG))
11530    (clobber (reg:TI XMM11_REG))
11531    (clobber (reg:TI XMM12_REG))
11532    (clobber (reg:TI XMM13_REG))
11533    (clobber (reg:TI XMM14_REG))
11534    (clobber (reg:TI XMM15_REG))
11535    (clobber (reg:DI SI_REG))
11536    (clobber (reg:DI DI_REG))]
11537   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11538   "* return ix86_output_call_insn (insn, operands[1]);"
11539   [(set_attr "type" "callv")])
11541 (define_expand "call_value_pop"
11542   [(parallel [(set (match_operand 0)
11543                    (call (match_operand:QI 1)
11544                          (match_operand:SI 2)))
11545               (set (reg:SI SP_REG)
11546                    (plus:SI (reg:SI SP_REG)
11547                             (match_operand:SI 4)))])]
11548   "!TARGET_64BIT"
11550   ix86_expand_call (operands[0], operands[1], operands[2],
11551                     operands[3], operands[4], false);
11552   DONE;
11555 (define_insn_and_split "*call_value_pop_vzeroupper"
11556   [(set (match_operand 0)
11557         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11558               (match_operand 2)))
11559    (set (reg:SI SP_REG)
11560         (plus:SI (reg:SI SP_REG)
11561                  (match_operand:SI 3 "immediate_operand" "i")))
11562    (unspec [(match_operand 4 "const_int_operand")]
11563            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11564   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11565   "#"
11566   "&& reload_completed"
11567   [(const_int 0)]
11568   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11569   [(set_attr "type" "callv")])
11571 (define_insn "*call_value_pop"
11572   [(set (match_operand 0)
11573         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11574               (match_operand 2)))
11575    (set (reg:SI SP_REG)
11576         (plus:SI (reg:SI SP_REG)
11577                  (match_operand:SI 3 "immediate_operand" "i")))]
11578   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11579   "* return ix86_output_call_insn (insn, operands[1]);"
11580   [(set_attr "type" "callv")])
11582 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11583   [(set (match_operand 0)
11584         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11585               (match_operand 2)))
11586    (set (reg:SI SP_REG)
11587         (plus:SI (reg:SI SP_REG)
11588                  (match_operand:SI 3 "immediate_operand" "i")))
11589    (unspec [(match_operand 4 "const_int_operand")]
11590            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11591   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11592   "#"
11593   "&& reload_completed"
11594   [(const_int 0)]
11595   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11596   [(set_attr "type" "callv")])
11598 (define_insn "*sibcall_value_pop"
11599   [(set (match_operand 0)
11600         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11601               (match_operand 2)))
11602    (set (reg:SI SP_REG)
11603         (plus:SI (reg:SI SP_REG)
11604                  (match_operand:SI 3 "immediate_operand" "i")))]
11605   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11606   "* return ix86_output_call_insn (insn, operands[1]);"
11607   [(set_attr "type" "callv")])
11609 ;; Call subroutine returning any type.
11611 (define_expand "untyped_call"
11612   [(parallel [(call (match_operand 0)
11613                     (const_int 0))
11614               (match_operand 1)
11615               (match_operand 2)])]
11616   ""
11618   int i;
11620   /* In order to give reg-stack an easier job in validating two
11621      coprocessor registers as containing a possible return value,
11622      simply pretend the untyped call returns a complex long double
11623      value. 
11625      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11626      and should have the default ABI.  */
11628   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11629                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11630                     operands[0], const0_rtx,
11631                     GEN_INT ((TARGET_64BIT
11632                               ? (ix86_abi == SYSV_ABI
11633                                  ? X86_64_SSE_REGPARM_MAX
11634                                  : X86_64_MS_SSE_REGPARM_MAX)
11635                               : X86_32_SSE_REGPARM_MAX)
11636                              - 1),
11637                     NULL, false);
11639   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11640     {
11641       rtx set = XVECEXP (operands[2], 0, i);
11642       emit_move_insn (SET_DEST (set), SET_SRC (set));
11643     }
11645   /* The optimizer does not know that the call sets the function value
11646      registers we stored in the result block.  We avoid problems by
11647      claiming that all hard registers are used and clobbered at this
11648      point.  */
11649   emit_insn (gen_blockage ());
11651   DONE;
11654 ;; Prologue and epilogue instructions
11656 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11657 ;; all of memory.  This blocks insns from being moved across this point.
11659 (define_insn "blockage"
11660   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11661   ""
11662   ""
11663   [(set_attr "length" "0")])
11665 ;; Do not schedule instructions accessing memory across this point.
11667 (define_expand "memory_blockage"
11668   [(set (match_dup 0)
11669         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11670   ""
11672   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11673   MEM_VOLATILE_P (operands[0]) = 1;
11676 (define_insn "*memory_blockage"
11677   [(set (match_operand:BLK 0)
11678         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11679   ""
11680   ""
11681   [(set_attr "length" "0")])
11683 ;; As USE insns aren't meaningful after reload, this is used instead
11684 ;; to prevent deleting instructions setting registers for PIC code
11685 (define_insn "prologue_use"
11686   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11687   ""
11688   ""
11689   [(set_attr "length" "0")])
11691 ;; Insn emitted into the body of a function to return from a function.
11692 ;; This is only done if the function's epilogue is known to be simple.
11693 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11695 (define_expand "return"
11696   [(simple_return)]
11697   "ix86_can_use_return_insn_p ()"
11699   ix86_maybe_emit_epilogue_vzeroupper ();
11700   if (crtl->args.pops_args)
11701     {
11702       rtx popc = GEN_INT (crtl->args.pops_args);
11703       emit_jump_insn (gen_simple_return_pop_internal (popc));
11704       DONE;
11705     }
11708 ;; We need to disable this for TARGET_SEH, as otherwise
11709 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11710 ;; the maximum size of prologue in unwind information.
11712 (define_expand "simple_return"
11713   [(simple_return)]
11714   "!TARGET_SEH"
11716   ix86_maybe_emit_epilogue_vzeroupper ();
11717   if (crtl->args.pops_args)
11718     {
11719       rtx popc = GEN_INT (crtl->args.pops_args);
11720       emit_jump_insn (gen_simple_return_pop_internal (popc));
11721       DONE;
11722     }
11725 (define_insn "simple_return_internal"
11726   [(simple_return)]
11727   "reload_completed"
11728   "ret"
11729   [(set_attr "length" "1")
11730    (set_attr "atom_unit" "jeu")
11731    (set_attr "length_immediate" "0")
11732    (set_attr "modrm" "0")])
11734 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11735 ;; instruction Athlon and K8 have.
11737 (define_insn "simple_return_internal_long"
11738   [(simple_return)
11739    (unspec [(const_int 0)] UNSPEC_REP)]
11740   "reload_completed"
11741   "rep\;ret"
11742   [(set_attr "length" "2")
11743    (set_attr "atom_unit" "jeu")
11744    (set_attr "length_immediate" "0")
11745    (set_attr "prefix_rep" "1")
11746    (set_attr "modrm" "0")])
11748 (define_insn "simple_return_pop_internal"
11749   [(simple_return)
11750    (use (match_operand:SI 0 "const_int_operand"))]
11751   "reload_completed"
11752   "ret\t%0"
11753   [(set_attr "length" "3")
11754    (set_attr "atom_unit" "jeu")
11755    (set_attr "length_immediate" "2")
11756    (set_attr "modrm" "0")])
11758 (define_insn "simple_return_indirect_internal"
11759   [(simple_return)
11760    (use (match_operand:SI 0 "register_operand" "r"))]
11761   "reload_completed"
11762   "jmp\t%A0"
11763   [(set_attr "type" "ibr")
11764    (set_attr "length_immediate" "0")])
11766 (define_insn "nop"
11767   [(const_int 0)]
11768   ""
11769   "nop"
11770   [(set_attr "length" "1")
11771    (set_attr "length_immediate" "0")
11772    (set_attr "modrm" "0")])
11774 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11775 (define_insn "nops"
11776   [(unspec_volatile [(match_operand 0 "const_int_operand")]
11777                     UNSPECV_NOPS)]
11778   "reload_completed"
11780   int num = INTVAL (operands[0]);
11782   gcc_assert (num >= 1 && num <= 8);
11784   while (num--)
11785     fputs ("\tnop\n", asm_out_file);
11787   return "";
11789   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11790    (set_attr "length_immediate" "0")
11791    (set_attr "modrm" "0")])
11793 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11794 ;; branch prediction penalty for the third jump in a 16-byte
11795 ;; block on K8.
11797 (define_insn "pad"
11798   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11799   ""
11801 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11802   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11803 #else
11804   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11805      The align insn is used to avoid 3 jump instructions in the row to improve
11806      branch prediction and the benefits hardly outweigh the cost of extra 8
11807      nops on the average inserted by full alignment pseudo operation.  */
11808 #endif
11809   return "";
11811   [(set_attr "length" "16")])
11813 (define_expand "prologue"
11814   [(const_int 0)]
11815   ""
11816   "ix86_expand_prologue (); DONE;")
11818 (define_insn "set_got"
11819   [(set (match_operand:SI 0 "register_operand" "=r")
11820         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11821    (clobber (reg:CC FLAGS_REG))]
11822   "!TARGET_64BIT"
11823   "* return output_set_got (operands[0], NULL_RTX);"
11824   [(set_attr "type" "multi")
11825    (set_attr "length" "12")])
11827 (define_insn "set_got_labelled"
11828   [(set (match_operand:SI 0 "register_operand" "=r")
11829         (unspec:SI [(label_ref (match_operand 1))]
11830          UNSPEC_SET_GOT))
11831    (clobber (reg:CC FLAGS_REG))]
11832   "!TARGET_64BIT"
11833   "* return output_set_got (operands[0], operands[1]);"
11834   [(set_attr "type" "multi")
11835    (set_attr "length" "12")])
11837 (define_insn "set_got_rex64"
11838   [(set (match_operand:DI 0 "register_operand" "=r")
11839         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11840   "TARGET_64BIT"
11841   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11842   [(set_attr "type" "lea")
11843    (set_attr "length_address" "4")
11844    (set_attr "mode" "DI")])
11846 (define_insn "set_rip_rex64"
11847   [(set (match_operand:DI 0 "register_operand" "=r")
11848         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11849   "TARGET_64BIT"
11850   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11851   [(set_attr "type" "lea")
11852    (set_attr "length_address" "4")
11853    (set_attr "mode" "DI")])
11855 (define_insn "set_got_offset_rex64"
11856   [(set (match_operand:DI 0 "register_operand" "=r")
11857         (unspec:DI
11858           [(label_ref (match_operand 1))]
11859           UNSPEC_SET_GOT_OFFSET))]
11860   "TARGET_LP64"
11861   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11862   [(set_attr "type" "imov")
11863    (set_attr "length_immediate" "0")
11864    (set_attr "length_address" "8")
11865    (set_attr "mode" "DI")])
11867 (define_expand "epilogue"
11868   [(const_int 0)]
11869   ""
11870   "ix86_expand_epilogue (1); DONE;")
11872 (define_expand "sibcall_epilogue"
11873   [(const_int 0)]
11874   ""
11875   "ix86_expand_epilogue (0); DONE;")
11877 (define_expand "eh_return"
11878   [(use (match_operand 0 "register_operand"))]
11879   ""
11881   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11883   /* Tricky bit: we write the address of the handler to which we will
11884      be returning into someone else's stack frame, one word below the
11885      stack address we wish to restore.  */
11886   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11887   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11888   tmp = gen_rtx_MEM (Pmode, tmp);
11889   emit_move_insn (tmp, ra);
11891   emit_jump_insn (gen_eh_return_internal ());
11892   emit_barrier ();
11893   DONE;
11896 (define_insn_and_split "eh_return_internal"
11897   [(eh_return)]
11898   ""
11899   "#"
11900   "epilogue_completed"
11901   [(const_int 0)]
11902   "ix86_expand_epilogue (2); DONE;")
11904 (define_insn "leave"
11905   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11906    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11907    (clobber (mem:BLK (scratch)))]
11908   "!TARGET_64BIT"
11909   "leave"
11910   [(set_attr "type" "leave")])
11912 (define_insn "leave_rex64"
11913   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11914    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11915    (clobber (mem:BLK (scratch)))]
11916   "TARGET_64BIT"
11917   "leave"
11918   [(set_attr "type" "leave")])
11920 ;; Handle -fsplit-stack.
11922 (define_expand "split_stack_prologue"
11923   [(const_int 0)]
11924   ""
11926   ix86_expand_split_stack_prologue ();
11927   DONE;
11930 ;; In order to support the call/return predictor, we use a return
11931 ;; instruction which the middle-end doesn't see.
11932 (define_insn "split_stack_return"
11933   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11934                      UNSPECV_SPLIT_STACK_RETURN)]
11935   ""
11937   if (operands[0] == const0_rtx)
11938     return "ret";
11939   else
11940     return "ret\t%0";
11942   [(set_attr "atom_unit" "jeu")
11943    (set_attr "modrm" "0")
11944    (set (attr "length")
11945         (if_then_else (match_operand:SI 0 "const0_operand")
11946                       (const_int 1)
11947                       (const_int 3)))
11948    (set (attr "length_immediate")
11949         (if_then_else (match_operand:SI 0 "const0_operand")
11950                       (const_int 0)
11951                       (const_int 2)))])
11953 ;; If there are operand 0 bytes available on the stack, jump to
11954 ;; operand 1.
11956 (define_expand "split_stack_space_check"
11957   [(set (pc) (if_then_else
11958               (ltu (minus (reg SP_REG)
11959                           (match_operand 0 "register_operand"))
11960                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11961               (label_ref (match_operand 1))
11962               (pc)))]
11963   ""
11965   rtx reg, size, limit;
11967   reg = gen_reg_rtx (Pmode);
11968   size = force_reg (Pmode, operands[0]);
11969   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11970   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11971                           UNSPEC_STACK_CHECK);
11972   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11973   ix86_expand_branch (GEU, reg, limit, operands[1]);
11975   DONE;
11978 ;; Bit manipulation instructions.
11980 (define_expand "ffs<mode>2"
11981   [(set (match_dup 2) (const_int -1))
11982    (parallel [(set (reg:CCZ FLAGS_REG)
11983                    (compare:CCZ
11984                      (match_operand:SWI48 1 "nonimmediate_operand")
11985                      (const_int 0)))
11986               (set (match_operand:SWI48 0 "register_operand")
11987                    (ctz:SWI48 (match_dup 1)))])
11988    (set (match_dup 0) (if_then_else:SWI48
11989                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11990                         (match_dup 2)
11991                         (match_dup 0)))
11992    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11993               (clobber (reg:CC FLAGS_REG))])]
11994   ""
11996   if (<MODE>mode == SImode && !TARGET_CMOVE)
11997     {
11998       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11999       DONE;
12000     }
12001   operands[2] = gen_reg_rtx (<MODE>mode);
12004 (define_insn_and_split "ffssi2_no_cmove"
12005   [(set (match_operand:SI 0 "register_operand" "=r")
12006         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12007    (clobber (match_scratch:SI 2 "=&q"))
12008    (clobber (reg:CC FLAGS_REG))]
12009   "!TARGET_CMOVE"
12010   "#"
12011   "&& reload_completed"
12012   [(parallel [(set (reg:CCZ FLAGS_REG)
12013                    (compare:CCZ (match_dup 1) (const_int 0)))
12014               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12015    (set (strict_low_part (match_dup 3))
12016         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12017    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12018               (clobber (reg:CC FLAGS_REG))])
12019    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12020               (clobber (reg:CC FLAGS_REG))])
12021    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12022               (clobber (reg:CC FLAGS_REG))])]
12024   operands[3] = gen_lowpart (QImode, operands[2]);
12025   ix86_expand_clear (operands[2]);
12028 (define_insn "*ffs<mode>_1"
12029   [(set (reg:CCZ FLAGS_REG)
12030         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12031                      (const_int 0)))
12032    (set (match_operand:SWI48 0 "register_operand" "=r")
12033         (ctz:SWI48 (match_dup 1)))]
12034   ""
12035   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12036   [(set_attr "type" "alu1")
12037    (set_attr "prefix_0f" "1")
12038    (set_attr "mode" "<MODE>")])
12040 (define_insn "ctz<mode>2"
12041   [(set (match_operand:SWI248 0 "register_operand" "=r")
12042         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12043    (clobber (reg:CC FLAGS_REG))]
12044   ""
12046   if (TARGET_BMI)
12047     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12048   else
12049     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12051   [(set_attr "type" "alu1")
12052    (set_attr "prefix_0f" "1")
12053    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12054    (set_attr "mode" "<MODE>")])
12056 (define_expand "clz<mode>2"
12057   [(parallel
12058      [(set (match_operand:SWI248 0 "register_operand")
12059            (minus:SWI248
12060              (match_dup 2)
12061              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12062       (clobber (reg:CC FLAGS_REG))])
12063    (parallel
12064      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12065       (clobber (reg:CC FLAGS_REG))])]
12066   ""
12068   if (TARGET_LZCNT)
12069     {
12070       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12071       DONE;
12072     }
12073   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12076 (define_insn "clz<mode>2_lzcnt"
12077   [(set (match_operand:SWI248 0 "register_operand" "=r")
12078         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12079    (clobber (reg:CC FLAGS_REG))]
12080   "TARGET_LZCNT"
12081   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12082   [(set_attr "prefix_rep" "1")
12083    (set_attr "type" "bitmanip")
12084    (set_attr "mode" "<MODE>")])
12086 ;; BMI instructions.
12087 (define_insn "*bmi_andn_<mode>"
12088   [(set (match_operand:SWI48 0 "register_operand" "=r")
12089         (and:SWI48
12090           (not:SWI48
12091             (match_operand:SWI48 1 "register_operand" "r"))
12092             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12093    (clobber (reg:CC FLAGS_REG))]
12094   "TARGET_BMI"
12095   "andn\t{%2, %1, %0|%0, %1, %2}"
12096   [(set_attr "type" "bitmanip")
12097    (set_attr "mode" "<MODE>")])
12099 (define_insn "bmi_bextr_<mode>"
12100   [(set (match_operand:SWI48 0 "register_operand" "=r")
12101         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12102                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12103                        UNSPEC_BEXTR))
12104    (clobber (reg:CC FLAGS_REG))]
12105   "TARGET_BMI"
12106   "bextr\t{%2, %1, %0|%0, %1, %2}"
12107   [(set_attr "type" "bitmanip")
12108    (set_attr "mode" "<MODE>")])
12110 (define_insn "*bmi_blsi_<mode>"
12111   [(set (match_operand:SWI48 0 "register_operand" "=r")
12112         (and:SWI48
12113           (neg:SWI48
12114             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12115           (match_dup 1)))
12116    (clobber (reg:CC FLAGS_REG))]
12117   "TARGET_BMI"
12118   "blsi\t{%1, %0|%0, %1}"
12119   [(set_attr "type" "bitmanip")
12120    (set_attr "mode" "<MODE>")])
12122 (define_insn "*bmi_blsmsk_<mode>"
12123   [(set (match_operand:SWI48 0 "register_operand" "=r")
12124         (xor:SWI48
12125           (plus:SWI48
12126             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12127             (const_int -1))
12128           (match_dup 1)))
12129    (clobber (reg:CC FLAGS_REG))]
12130   "TARGET_BMI"
12131   "blsmsk\t{%1, %0|%0, %1}"
12132   [(set_attr "type" "bitmanip")
12133    (set_attr "mode" "<MODE>")])
12135 (define_insn "*bmi_blsr_<mode>"
12136   [(set (match_operand:SWI48 0 "register_operand" "=r")
12137         (and:SWI48
12138           (plus:SWI48
12139             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12140             (const_int -1))
12141           (match_dup 1)))
12142    (clobber (reg:CC FLAGS_REG))]
12143    "TARGET_BMI"
12144    "blsr\t{%1, %0|%0, %1}"
12145   [(set_attr "type" "bitmanip")
12146    (set_attr "mode" "<MODE>")])
12148 ;; BMI2 instructions.
12149 (define_insn "bmi2_bzhi_<mode>3"
12150   [(set (match_operand:SWI48 0 "register_operand" "=r")
12151         (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12152                    (lshiftrt:SWI48 (const_int -1)
12153                                    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "TARGET_BMI2"
12156   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12157   [(set_attr "type" "bitmanip")
12158    (set_attr "prefix" "vex")
12159    (set_attr "mode" "<MODE>")])
12161 (define_insn "bmi2_pdep_<mode>3"
12162   [(set (match_operand:SWI48 0 "register_operand" "=r")
12163         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12164                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12165                        UNSPEC_PDEP))]
12166   "TARGET_BMI2"
12167   "pdep\t{%2, %1, %0|%0, %1, %2}"
12168   [(set_attr "type" "bitmanip")
12169    (set_attr "prefix" "vex")
12170    (set_attr "mode" "<MODE>")])
12172 (define_insn "bmi2_pext_<mode>3"
12173   [(set (match_operand:SWI48 0 "register_operand" "=r")
12174         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12175                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12176                        UNSPEC_PEXT))]
12177   "TARGET_BMI2"
12178   "pext\t{%2, %1, %0|%0, %1, %2}"
12179   [(set_attr "type" "bitmanip")
12180    (set_attr "prefix" "vex")
12181    (set_attr "mode" "<MODE>")])
12183 ;; TBM instructions.
12184 (define_insn "tbm_bextri_<mode>"
12185   [(set (match_operand:SWI48 0 "register_operand" "=r")
12186         (zero_extract:SWI48
12187           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12188           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12189           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12190    (clobber (reg:CC FLAGS_REG))]
12191    "TARGET_TBM"
12193   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12194   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12196   [(set_attr "type" "bitmanip")
12197    (set_attr "mode" "<MODE>")])
12199 (define_insn "*tbm_blcfill_<mode>"
12200   [(set (match_operand:SWI48 0 "register_operand" "=r")
12201         (and:SWI48
12202           (plus:SWI48
12203             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12204             (const_int 1))
12205           (match_dup 1)))
12206    (clobber (reg:CC FLAGS_REG))]
12207    "TARGET_TBM"
12208    "blcfill\t{%1, %0|%0, %1}"
12209   [(set_attr "type" "bitmanip")
12210    (set_attr "mode" "<MODE>")])
12212 (define_insn "*tbm_blci_<mode>"
12213   [(set (match_operand:SWI48 0 "register_operand" "=r")
12214         (ior:SWI48
12215           (not:SWI48
12216             (plus:SWI48
12217               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12218               (const_int 1)))
12219           (match_dup 1)))
12220    (clobber (reg:CC FLAGS_REG))]
12221    "TARGET_TBM"
12222    "blci\t{%1, %0|%0, %1}"
12223   [(set_attr "type" "bitmanip")
12224    (set_attr "mode" "<MODE>")])
12226 (define_insn "*tbm_blcic_<mode>"
12227   [(set (match_operand:SWI48 0 "register_operand" "=r")
12228         (and:SWI48
12229           (plus:SWI48
12230             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12231             (const_int 1))
12232           (not:SWI48
12233             (match_dup 1))))
12234    (clobber (reg:CC FLAGS_REG))]
12235    "TARGET_TBM"
12236    "blcic\t{%1, %0|%0, %1}"
12237   [(set_attr "type" "bitmanip")
12238    (set_attr "mode" "<MODE>")])
12240 (define_insn "*tbm_blcmsk_<mode>"
12241   [(set (match_operand:SWI48 0 "register_operand" "=r")
12242         (xor:SWI48
12243           (plus:SWI48
12244             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12245             (const_int 1))
12246           (match_dup 1)))
12247    (clobber (reg:CC FLAGS_REG))]
12248    "TARGET_TBM"
12249    "blcmsk\t{%1, %0|%0, %1}"
12250   [(set_attr "type" "bitmanip")
12251    (set_attr "mode" "<MODE>")])
12253 (define_insn "*tbm_blcs_<mode>"
12254   [(set (match_operand:SWI48 0 "register_operand" "=r")
12255         (ior:SWI48
12256           (plus:SWI48
12257             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12258             (const_int 1))
12259           (match_dup 1)))
12260    (clobber (reg:CC FLAGS_REG))]
12261    "TARGET_TBM"
12262    "blcs\t{%1, %0|%0, %1}"
12263   [(set_attr "type" "bitmanip")
12264    (set_attr "mode" "<MODE>")])
12266 (define_insn "*tbm_blsfill_<mode>"
12267   [(set (match_operand:SWI48 0 "register_operand" "=r")
12268         (ior:SWI48
12269           (plus:SWI48
12270             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12271             (const_int -1))
12272           (match_dup 1)))
12273    (clobber (reg:CC FLAGS_REG))]
12274    "TARGET_TBM"
12275    "blsfill\t{%1, %0|%0, %1}"
12276   [(set_attr "type" "bitmanip")
12277    (set_attr "mode" "<MODE>")])
12279 (define_insn "*tbm_blsic_<mode>"
12280   [(set (match_operand:SWI48 0 "register_operand" "=r")
12281         (ior:SWI48
12282           (plus:SWI48
12283             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12284             (const_int -1))
12285           (not:SWI48
12286             (match_dup 1))))
12287    (clobber (reg:CC FLAGS_REG))]
12288    "TARGET_TBM"
12289    "blsic\t{%1, %0|%0, %1}"
12290   [(set_attr "type" "bitmanip")
12291    (set_attr "mode" "<MODE>")])
12293 (define_insn "*tbm_t1mskc_<mode>"
12294   [(set (match_operand:SWI48 0 "register_operand" "=r")
12295         (ior:SWI48
12296           (plus:SWI48
12297             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12298             (const_int 1))
12299           (not:SWI48
12300             (match_dup 1))))
12301    (clobber (reg:CC FLAGS_REG))]
12302    "TARGET_TBM"
12303    "t1mskc\t{%1, %0|%0, %1}"
12304   [(set_attr "type" "bitmanip")
12305    (set_attr "mode" "<MODE>")])
12307 (define_insn "*tbm_tzmsk_<mode>"
12308   [(set (match_operand:SWI48 0 "register_operand" "=r")
12309         (and:SWI48
12310           (plus:SWI48
12311             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12312             (const_int -1))
12313           (not:SWI48
12314             (match_dup 1))))
12315    (clobber (reg:CC FLAGS_REG))]
12316    "TARGET_TBM"
12317    "tzmsk\t{%1, %0|%0, %1}"
12318   [(set_attr "type" "bitmanip")
12319    (set_attr "mode" "<MODE>")])
12321 (define_insn "bsr_rex64"
12322   [(set (match_operand:DI 0 "register_operand" "=r")
12323         (minus:DI (const_int 63)
12324                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12325    (clobber (reg:CC FLAGS_REG))]
12326   "TARGET_64BIT"
12327   "bsr{q}\t{%1, %0|%0, %1}"
12328   [(set_attr "type" "alu1")
12329    (set_attr "prefix_0f" "1")
12330    (set_attr "mode" "DI")])
12332 (define_insn "bsr"
12333   [(set (match_operand:SI 0 "register_operand" "=r")
12334         (minus:SI (const_int 31)
12335                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12336    (clobber (reg:CC FLAGS_REG))]
12337   ""
12338   "bsr{l}\t{%1, %0|%0, %1}"
12339   [(set_attr "type" "alu1")
12340    (set_attr "prefix_0f" "1")
12341    (set_attr "mode" "SI")])
12343 (define_insn "*bsrhi"
12344   [(set (match_operand:HI 0 "register_operand" "=r")
12345         (minus:HI (const_int 15)
12346                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12347    (clobber (reg:CC FLAGS_REG))]
12348   ""
12349   "bsr{w}\t{%1, %0|%0, %1}"
12350   [(set_attr "type" "alu1")
12351    (set_attr "prefix_0f" "1")
12352    (set_attr "mode" "HI")])
12354 (define_insn "popcount<mode>2"
12355   [(set (match_operand:SWI248 0 "register_operand" "=r")
12356         (popcount:SWI248
12357           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12358    (clobber (reg:CC FLAGS_REG))]
12359   "TARGET_POPCNT"
12361 #if TARGET_MACHO
12362   return "popcnt\t{%1, %0|%0, %1}";
12363 #else
12364   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12365 #endif
12367   [(set_attr "prefix_rep" "1")
12368    (set_attr "type" "bitmanip")
12369    (set_attr "mode" "<MODE>")])
12371 (define_insn "*popcount<mode>2_cmp"
12372   [(set (reg FLAGS_REG)
12373         (compare
12374           (popcount:SWI248
12375             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12376           (const_int 0)))
12377    (set (match_operand:SWI248 0 "register_operand" "=r")
12378         (popcount:SWI248 (match_dup 1)))]
12379   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12381 #if TARGET_MACHO
12382   return "popcnt\t{%1, %0|%0, %1}";
12383 #else
12384   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12385 #endif
12387   [(set_attr "prefix_rep" "1")
12388    (set_attr "type" "bitmanip")
12389    (set_attr "mode" "<MODE>")])
12391 (define_insn "*popcountsi2_cmp_zext"
12392   [(set (reg FLAGS_REG)
12393         (compare
12394           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12395           (const_int 0)))
12396    (set (match_operand:DI 0 "register_operand" "=r")
12397         (zero_extend:DI(popcount:SI (match_dup 1))))]
12398   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12400 #if TARGET_MACHO
12401   return "popcnt\t{%1, %0|%0, %1}";
12402 #else
12403   return "popcnt{l}\t{%1, %0|%0, %1}";
12404 #endif
12406   [(set_attr "prefix_rep" "1")
12407    (set_attr "type" "bitmanip")
12408    (set_attr "mode" "SI")])
12410 (define_expand "bswap<mode>2"
12411   [(set (match_operand:SWI48 0 "register_operand")
12412         (bswap:SWI48 (match_operand:SWI48 1 "register_operand")))]
12413   ""
12415   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12416     {
12417       rtx x = operands[0];
12419       emit_move_insn (x, operands[1]);
12420       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12421       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12422       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12423       DONE;
12424     }
12427 (define_insn "*bswap<mode>2_movbe"
12428   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12429         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12430   "TARGET_MOVBE
12431    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12432   "@
12433     bswap\t%0
12434     movbe\t{%1, %0|%0, %1}
12435     movbe\t{%1, %0|%0, %1}"
12436   [(set_attr "type" "bitmanip,imov,imov")
12437    (set_attr "modrm" "0,1,1")
12438    (set_attr "prefix_0f" "*,1,1")
12439    (set_attr "prefix_extra" "*,1,1")
12440    (set_attr "mode" "<MODE>")])
12442 (define_insn "*bswap<mode>2_1"
12443   [(set (match_operand:SWI48 0 "register_operand" "=r")
12444         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12445   "TARGET_BSWAP"
12446   "bswap\t%0"
12447   [(set_attr "type" "bitmanip")
12448    (set_attr "modrm" "0")
12449    (set_attr "mode" "<MODE>")])
12451 (define_insn "*bswaphi_lowpart_1"
12452   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12453         (bswap:HI (match_dup 0)))
12454    (clobber (reg:CC FLAGS_REG))]
12455   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12456   "@
12457     xchg{b}\t{%h0, %b0|%b0, %h0}
12458     rol{w}\t{$8, %0|%0, 8}"
12459   [(set_attr "length" "2,4")
12460    (set_attr "mode" "QI,HI")])
12462 (define_insn "bswaphi_lowpart"
12463   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12464         (bswap:HI (match_dup 0)))
12465    (clobber (reg:CC FLAGS_REG))]
12466   ""
12467   "rol{w}\t{$8, %0|%0, 8}"
12468   [(set_attr "length" "4")
12469    (set_attr "mode" "HI")])
12471 (define_expand "paritydi2"
12472   [(set (match_operand:DI 0 "register_operand")
12473         (parity:DI (match_operand:DI 1 "register_operand")))]
12474   "! TARGET_POPCNT"
12476   rtx scratch = gen_reg_rtx (QImode);
12477   rtx cond;
12479   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12480                                 NULL_RTX, operands[1]));
12482   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12483                          gen_rtx_REG (CCmode, FLAGS_REG),
12484                          const0_rtx);
12485   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12487   if (TARGET_64BIT)
12488     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12489   else
12490     {
12491       rtx tmp = gen_reg_rtx (SImode);
12493       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12494       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12495     }
12496   DONE;
12499 (define_expand "paritysi2"
12500   [(set (match_operand:SI 0 "register_operand")
12501         (parity:SI (match_operand:SI 1 "register_operand")))]
12502   "! TARGET_POPCNT"
12504   rtx scratch = gen_reg_rtx (QImode);
12505   rtx cond;
12507   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12509   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12510                          gen_rtx_REG (CCmode, FLAGS_REG),
12511                          const0_rtx);
12512   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12514   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12515   DONE;
12518 (define_insn_and_split "paritydi2_cmp"
12519   [(set (reg:CC FLAGS_REG)
12520         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12521                    UNSPEC_PARITY))
12522    (clobber (match_scratch:DI 0 "=r"))
12523    (clobber (match_scratch:SI 1 "=&r"))
12524    (clobber (match_scratch:HI 2 "=Q"))]
12525   "! TARGET_POPCNT"
12526   "#"
12527   "&& reload_completed"
12528   [(parallel
12529      [(set (match_dup 1)
12530            (xor:SI (match_dup 1) (match_dup 4)))
12531       (clobber (reg:CC FLAGS_REG))])
12532    (parallel
12533      [(set (reg:CC FLAGS_REG)
12534            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12535       (clobber (match_dup 1))
12536       (clobber (match_dup 2))])]
12538   operands[4] = gen_lowpart (SImode, operands[3]);
12540   if (TARGET_64BIT)
12541     {
12542       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12543       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12544     }
12545   else
12546     operands[1] = gen_highpart (SImode, operands[3]);
12549 (define_insn_and_split "paritysi2_cmp"
12550   [(set (reg:CC FLAGS_REG)
12551         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12552                    UNSPEC_PARITY))
12553    (clobber (match_scratch:SI 0 "=r"))
12554    (clobber (match_scratch:HI 1 "=&Q"))]
12555   "! TARGET_POPCNT"
12556   "#"
12557   "&& reload_completed"
12558   [(parallel
12559      [(set (match_dup 1)
12560            (xor:HI (match_dup 1) (match_dup 3)))
12561       (clobber (reg:CC FLAGS_REG))])
12562    (parallel
12563      [(set (reg:CC FLAGS_REG)
12564            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12565       (clobber (match_dup 1))])]
12567   operands[3] = gen_lowpart (HImode, operands[2]);
12569   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12570   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12573 (define_insn "*parityhi2_cmp"
12574   [(set (reg:CC FLAGS_REG)
12575         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12576                    UNSPEC_PARITY))
12577    (clobber (match_scratch:HI 0 "=Q"))]
12578   "! TARGET_POPCNT"
12579   "xor{b}\t{%h0, %b0|%b0, %h0}"
12580   [(set_attr "length" "2")
12581    (set_attr "mode" "HI")])
12584 ;; Thread-local storage patterns for ELF.
12586 ;; Note that these code sequences must appear exactly as shown
12587 ;; in order to allow linker relaxation.
12589 (define_insn "*tls_global_dynamic_32_gnu"
12590   [(set (match_operand:SI 0 "register_operand" "=a")
12591         (unspec:SI
12592          [(match_operand:SI 1 "register_operand" "b")
12593           (match_operand 2 "tls_symbolic_operand")
12594           (match_operand 3 "constant_call_address_operand" "z")]
12595          UNSPEC_TLS_GD))
12596    (clobber (match_scratch:SI 4 "=d"))
12597    (clobber (match_scratch:SI 5 "=c"))
12598    (clobber (reg:CC FLAGS_REG))]
12599   "!TARGET_64BIT && TARGET_GNU_TLS"
12601   output_asm_insn
12602     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12603   if (TARGET_SUN_TLS)
12604 #ifdef HAVE_AS_IX86_TLSGDPLT
12605     return "call\t%a2@tlsgdplt";
12606 #else
12607     return "call\t%p3@plt";
12608 #endif
12609   return "call\t%P3";
12611   [(set_attr "type" "multi")
12612    (set_attr "length" "12")])
12614 (define_expand "tls_global_dynamic_32"
12615   [(parallel
12616     [(set (match_operand:SI 0 "register_operand")
12617           (unspec:SI [(match_operand:SI 2 "register_operand")
12618                       (match_operand 1 "tls_symbolic_operand")
12619                       (match_operand 3 "constant_call_address_operand")]
12620                      UNSPEC_TLS_GD))
12621      (clobber (match_scratch:SI 4))
12622      (clobber (match_scratch:SI 5))
12623      (clobber (reg:CC FLAGS_REG))])])
12625 (define_insn "*tls_global_dynamic_64_<mode>"
12626   [(set (match_operand:P 0 "register_operand" "=a")
12627         (call:P
12628          (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12629          (match_operand 3)))
12630    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12631              UNSPEC_TLS_GD)]
12632   "TARGET_64BIT"
12634   if (!TARGET_X32)
12635     fputs (ASM_BYTE "0x66\n", asm_out_file);
12636   output_asm_insn
12637     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12638   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12639   fputs ("\trex64\n", asm_out_file);
12640   if (TARGET_SUN_TLS)
12641     return "call\t%p2@plt";
12642   return "call\t%P2";
12644   [(set_attr "type" "multi")
12645    (set (attr "length")
12646         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12648 (define_expand "tls_global_dynamic_64_<mode>"
12649   [(parallel
12650     [(set (match_operand:P 0 "register_operand")
12651           (call:P
12652            (mem:QI (match_operand 2 "constant_call_address_operand"))
12653            (const_int 0)))
12654      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12655                UNSPEC_TLS_GD)])]
12656   "TARGET_64BIT")
12658 (define_insn "*tls_local_dynamic_base_32_gnu"
12659   [(set (match_operand:SI 0 "register_operand" "=a")
12660         (unspec:SI
12661          [(match_operand:SI 1 "register_operand" "b")
12662           (match_operand 2 "constant_call_address_operand" "z")]
12663          UNSPEC_TLS_LD_BASE))
12664    (clobber (match_scratch:SI 3 "=d"))
12665    (clobber (match_scratch:SI 4 "=c"))
12666    (clobber (reg:CC FLAGS_REG))]
12667   "!TARGET_64BIT && TARGET_GNU_TLS"
12669   output_asm_insn
12670     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12671   if (TARGET_SUN_TLS)
12672 #ifdef HAVE_AS_IX86_TLSLDMPLT
12673     return "call\t%&@tlsldmplt";
12674 #else
12675     return "call\t%p2@plt";
12676 #endif
12677   return "call\t%P2";
12679   [(set_attr "type" "multi")
12680    (set_attr "length" "11")])
12682 (define_expand "tls_local_dynamic_base_32"
12683   [(parallel
12684      [(set (match_operand:SI 0 "register_operand")
12685            (unspec:SI
12686             [(match_operand:SI 1 "register_operand")
12687              (match_operand 2 "constant_call_address_operand")]
12688             UNSPEC_TLS_LD_BASE))
12689       (clobber (match_scratch:SI 3))
12690       (clobber (match_scratch:SI 4))
12691       (clobber (reg:CC FLAGS_REG))])])
12693 (define_insn "*tls_local_dynamic_base_64_<mode>"
12694   [(set (match_operand:P 0 "register_operand" "=a")
12695         (call:P
12696          (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12697          (match_operand 2)))
12698    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12699   "TARGET_64BIT"
12701   output_asm_insn
12702     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12703   if (TARGET_SUN_TLS)
12704     return "call\t%p1@plt";
12705   return "call\t%P1";
12707   [(set_attr "type" "multi")
12708    (set_attr "length" "12")])
12710 (define_expand "tls_local_dynamic_base_64_<mode>"
12711   [(parallel
12712      [(set (match_operand:P 0 "register_operand")
12713            (call:P
12714             (mem:QI (match_operand 1 "constant_call_address_operand"))
12715             (const_int 0)))
12716       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12717   "TARGET_64BIT")
12719 ;; Local dynamic of a single variable is a lose.  Show combine how
12720 ;; to convert that back to global dynamic.
12722 (define_insn_and_split "*tls_local_dynamic_32_once"
12723   [(set (match_operand:SI 0 "register_operand" "=a")
12724         (plus:SI
12725          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12726                      (match_operand 2 "constant_call_address_operand" "z")]
12727                     UNSPEC_TLS_LD_BASE)
12728          (const:SI (unspec:SI
12729                     [(match_operand 3 "tls_symbolic_operand")]
12730                     UNSPEC_DTPOFF))))
12731    (clobber (match_scratch:SI 4 "=d"))
12732    (clobber (match_scratch:SI 5 "=c"))
12733    (clobber (reg:CC FLAGS_REG))]
12734   ""
12735   "#"
12736   ""
12737   [(parallel
12738      [(set (match_dup 0)
12739            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12740                       UNSPEC_TLS_GD))
12741       (clobber (match_dup 4))
12742       (clobber (match_dup 5))
12743       (clobber (reg:CC FLAGS_REG))])])
12745 ;; Segment register for the thread base ptr load
12746 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12748 ;; Load and add the thread base pointer from %<tp_seg>:0.
12749 (define_insn "*load_tp_x32"
12750   [(set (match_operand:SI 0 "register_operand" "=r")
12751         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12752   "TARGET_X32"
12753   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12754   [(set_attr "type" "imov")
12755    (set_attr "modrm" "0")
12756    (set_attr "length" "7")
12757    (set_attr "memory" "load")
12758    (set_attr "imm_disp" "false")])
12760 (define_insn "*load_tp_x32_zext"
12761   [(set (match_operand:DI 0 "register_operand" "=r")
12762         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12763   "TARGET_X32"
12764   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12765   [(set_attr "type" "imov")
12766    (set_attr "modrm" "0")
12767    (set_attr "length" "7")
12768    (set_attr "memory" "load")
12769    (set_attr "imm_disp" "false")])
12771 (define_insn "*load_tp_<mode>"
12772   [(set (match_operand:P 0 "register_operand" "=r")
12773         (unspec:P [(const_int 0)] UNSPEC_TP))]
12774   "!TARGET_X32"
12775   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12776   [(set_attr "type" "imov")
12777    (set_attr "modrm" "0")
12778    (set_attr "length" "7")
12779    (set_attr "memory" "load")
12780    (set_attr "imm_disp" "false")])
12782 (define_insn "*add_tp_x32"
12783   [(set (match_operand:SI 0 "register_operand" "=r")
12784         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12785                  (match_operand:SI 1 "register_operand" "0")))
12786    (clobber (reg:CC FLAGS_REG))]
12787   "TARGET_X32"
12788   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12789   [(set_attr "type" "alu")
12790    (set_attr "modrm" "0")
12791    (set_attr "length" "7")
12792    (set_attr "memory" "load")
12793    (set_attr "imm_disp" "false")])
12795 (define_insn "*add_tp_x32_zext"
12796   [(set (match_operand:DI 0 "register_operand" "=r")
12797         (zero_extend:DI
12798           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12799                    (match_operand:SI 1 "register_operand" "0"))))
12800    (clobber (reg:CC FLAGS_REG))]
12801   "TARGET_X32"
12802   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12803   [(set_attr "type" "alu")
12804    (set_attr "modrm" "0")
12805    (set_attr "length" "7")
12806    (set_attr "memory" "load")
12807    (set_attr "imm_disp" "false")])
12809 (define_insn "*add_tp_<mode>"
12810   [(set (match_operand:P 0 "register_operand" "=r")
12811         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12812                 (match_operand:P 1 "register_operand" "0")))
12813    (clobber (reg:CC FLAGS_REG))]
12814   "!TARGET_X32"
12815   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12816   [(set_attr "type" "alu")
12817    (set_attr "modrm" "0")
12818    (set_attr "length" "7")
12819    (set_attr "memory" "load")
12820    (set_attr "imm_disp" "false")])
12822 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12823 ;; %rax as destination of the initial executable code sequence.
12824 (define_insn "tls_initial_exec_64_sun"
12825   [(set (match_operand:DI 0 "register_operand" "=a")
12826         (unspec:DI
12827          [(match_operand 1 "tls_symbolic_operand")]
12828          UNSPEC_TLS_IE_SUN))
12829    (clobber (reg:CC FLAGS_REG))]
12830   "TARGET_64BIT && TARGET_SUN_TLS"
12832   output_asm_insn
12833     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12834   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12836   [(set_attr "type" "multi")])
12838 ;; GNU2 TLS patterns can be split.
12840 (define_expand "tls_dynamic_gnu2_32"
12841   [(set (match_dup 3)
12842         (plus:SI (match_operand:SI 2 "register_operand")
12843                  (const:SI
12844                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12845                              UNSPEC_TLSDESC))))
12846    (parallel
12847     [(set (match_operand:SI 0 "register_operand")
12848           (unspec:SI [(match_dup 1) (match_dup 3)
12849                       (match_dup 2) (reg:SI SP_REG)]
12850                       UNSPEC_TLSDESC))
12851      (clobber (reg:CC FLAGS_REG))])]
12852   "!TARGET_64BIT && TARGET_GNU2_TLS"
12854   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12855   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12858 (define_insn "*tls_dynamic_gnu2_lea_32"
12859   [(set (match_operand:SI 0 "register_operand" "=r")
12860         (plus:SI (match_operand:SI 1 "register_operand" "b")
12861                  (const:SI
12862                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12863                               UNSPEC_TLSDESC))))]
12864   "!TARGET_64BIT && TARGET_GNU2_TLS"
12865   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12866   [(set_attr "type" "lea")
12867    (set_attr "mode" "SI")
12868    (set_attr "length" "6")
12869    (set_attr "length_address" "4")])
12871 (define_insn "*tls_dynamic_gnu2_call_32"
12872   [(set (match_operand:SI 0 "register_operand" "=a")
12873         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12874                     (match_operand:SI 2 "register_operand" "0")
12875                     ;; we have to make sure %ebx still points to the GOT
12876                     (match_operand:SI 3 "register_operand" "b")
12877                     (reg:SI SP_REG)]
12878                    UNSPEC_TLSDESC))
12879    (clobber (reg:CC FLAGS_REG))]
12880   "!TARGET_64BIT && TARGET_GNU2_TLS"
12881   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12882   [(set_attr "type" "call")
12883    (set_attr "length" "2")
12884    (set_attr "length_address" "0")])
12886 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12887   [(set (match_operand:SI 0 "register_operand" "=&a")
12888         (plus:SI
12889          (unspec:SI [(match_operand 3 "tls_modbase_operand")
12890                      (match_operand:SI 4)
12891                      (match_operand:SI 2 "register_operand" "b")
12892                      (reg:SI SP_REG)]
12893                     UNSPEC_TLSDESC)
12894          (const:SI (unspec:SI
12895                     [(match_operand 1 "tls_symbolic_operand")]
12896                     UNSPEC_DTPOFF))))
12897    (clobber (reg:CC FLAGS_REG))]
12898   "!TARGET_64BIT && TARGET_GNU2_TLS"
12899   "#"
12900   ""
12901   [(set (match_dup 0) (match_dup 5))]
12903   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12904   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12907 (define_expand "tls_dynamic_gnu2_64"
12908   [(set (match_dup 2)
12909         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12910                    UNSPEC_TLSDESC))
12911    (parallel
12912     [(set (match_operand:DI 0 "register_operand")
12913           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12914                      UNSPEC_TLSDESC))
12915      (clobber (reg:CC FLAGS_REG))])]
12916   "TARGET_64BIT && TARGET_GNU2_TLS"
12918   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12919   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12922 (define_insn "*tls_dynamic_gnu2_lea_64"
12923   [(set (match_operand:DI 0 "register_operand" "=r")
12924         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12925                    UNSPEC_TLSDESC))]
12926   "TARGET_64BIT && TARGET_GNU2_TLS"
12927   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12928   [(set_attr "type" "lea")
12929    (set_attr "mode" "DI")
12930    (set_attr "length" "7")
12931    (set_attr "length_address" "4")])
12933 (define_insn "*tls_dynamic_gnu2_call_64"
12934   [(set (match_operand:DI 0 "register_operand" "=a")
12935         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
12936                     (match_operand:DI 2 "register_operand" "0")
12937                     (reg:DI SP_REG)]
12938                    UNSPEC_TLSDESC))
12939    (clobber (reg:CC FLAGS_REG))]
12940   "TARGET_64BIT && TARGET_GNU2_TLS"
12941   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12942   [(set_attr "type" "call")
12943    (set_attr "length" "2")
12944    (set_attr "length_address" "0")])
12946 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12947   [(set (match_operand:DI 0 "register_operand" "=&a")
12948         (plus:DI
12949          (unspec:DI [(match_operand 2 "tls_modbase_operand")
12950                      (match_operand:DI 3)
12951                      (reg:DI SP_REG)]
12952                     UNSPEC_TLSDESC)
12953          (const:DI (unspec:DI
12954                     [(match_operand 1 "tls_symbolic_operand")]
12955                     UNSPEC_DTPOFF))))
12956    (clobber (reg:CC FLAGS_REG))]
12957   "TARGET_64BIT && TARGET_GNU2_TLS"
12958   "#"
12959   ""
12960   [(set (match_dup 0) (match_dup 4))]
12962   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12963   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12966 ;; These patterns match the binary 387 instructions for addM3, subM3,
12967 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12968 ;; SFmode.  The first is the normal insn, the second the same insn but
12969 ;; with one operand a conversion, and the third the same insn but with
12970 ;; the other operand a conversion.  The conversion may be SFmode or
12971 ;; SImode if the target mode DFmode, but only SImode if the target mode
12972 ;; is SFmode.
12974 ;; Gcc is slightly more smart about handling normal two address instructions
12975 ;; so use special patterns for add and mull.
12977 (define_insn "*fop_<mode>_comm_mixed"
12978   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12979         (match_operator:MODEF 3 "binary_fp_operator"
12980           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12981            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12982   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12983    && COMMUTATIVE_ARITH_P (operands[3])
12984    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12985   "* return output_387_binary_op (insn, operands);"
12986   [(set (attr "type")
12987         (if_then_else (eq_attr "alternative" "1,2")
12988            (if_then_else (match_operand:MODEF 3 "mult_operator")
12989               (const_string "ssemul")
12990               (const_string "sseadd"))
12991            (if_then_else (match_operand:MODEF 3 "mult_operator")
12992               (const_string "fmul")
12993               (const_string "fop"))))
12994    (set_attr "isa" "*,noavx,avx")
12995    (set_attr "prefix" "orig,orig,vex")
12996    (set_attr "mode" "<MODE>")])
12998 (define_insn "*fop_<mode>_comm_sse"
12999   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13000         (match_operator:MODEF 3 "binary_fp_operator"
13001           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13002            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13003   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13004    && COMMUTATIVE_ARITH_P (operands[3])
13005    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13006   "* return output_387_binary_op (insn, operands);"
13007   [(set (attr "type")
13008         (if_then_else (match_operand:MODEF 3 "mult_operator")
13009            (const_string "ssemul")
13010            (const_string "sseadd")))
13011    (set_attr "isa" "noavx,avx")
13012    (set_attr "prefix" "orig,vex")
13013    (set_attr "mode" "<MODE>")])
13015 (define_insn "*fop_<mode>_comm_i387"
13016   [(set (match_operand:MODEF 0 "register_operand" "=f")
13017         (match_operator:MODEF 3 "binary_fp_operator"
13018           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13019            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13020   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13021    && COMMUTATIVE_ARITH_P (operands[3])
13022    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13023   "* return output_387_binary_op (insn, operands);"
13024   [(set (attr "type")
13025         (if_then_else (match_operand:MODEF 3 "mult_operator")
13026            (const_string "fmul")
13027            (const_string "fop")))
13028    (set_attr "mode" "<MODE>")])
13030 (define_insn "*fop_<mode>_1_mixed"
13031   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13032         (match_operator:MODEF 3 "binary_fp_operator"
13033           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13034            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13035   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13036    && !COMMUTATIVE_ARITH_P (operands[3])
13037    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13038   "* return output_387_binary_op (insn, operands);"
13039   [(set (attr "type")
13040         (cond [(and (eq_attr "alternative" "2,3")
13041                     (match_operand:MODEF 3 "mult_operator"))
13042                  (const_string "ssemul")
13043                (and (eq_attr "alternative" "2,3")
13044                     (match_operand:MODEF 3 "div_operator"))
13045                  (const_string "ssediv")
13046                (eq_attr "alternative" "2,3")
13047                  (const_string "sseadd")
13048                (match_operand:MODEF 3 "mult_operator")
13049                  (const_string "fmul")
13050                (match_operand:MODEF 3 "div_operator")
13051                  (const_string "fdiv")
13052               ]
13053               (const_string "fop")))
13054    (set_attr "isa" "*,*,noavx,avx")
13055    (set_attr "prefix" "orig,orig,orig,vex")
13056    (set_attr "mode" "<MODE>")])
13058 (define_insn "*rcpsf2_sse"
13059   [(set (match_operand:SF 0 "register_operand" "=x")
13060         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13061                    UNSPEC_RCP))]
13062   "TARGET_SSE_MATH"
13063   "%vrcpss\t{%1, %d0|%d0, %1}"
13064   [(set_attr "type" "sse")
13065    (set_attr "atom_sse_attr" "rcp")
13066    (set_attr "prefix" "maybe_vex")
13067    (set_attr "mode" "SF")])
13069 (define_insn "*fop_<mode>_1_sse"
13070   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13071         (match_operator:MODEF 3 "binary_fp_operator"
13072           [(match_operand:MODEF 1 "register_operand" "0,x")
13073            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13074   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13075    && !COMMUTATIVE_ARITH_P (operands[3])"
13076   "* return output_387_binary_op (insn, operands);"
13077   [(set (attr "type")
13078         (cond [(match_operand:MODEF 3 "mult_operator")
13079                  (const_string "ssemul")
13080                (match_operand:MODEF 3 "div_operator")
13081                  (const_string "ssediv")
13082               ]
13083               (const_string "sseadd")))
13084    (set_attr "isa" "noavx,avx")
13085    (set_attr "prefix" "orig,vex")
13086    (set_attr "mode" "<MODE>")])
13088 ;; This pattern is not fully shadowed by the pattern above.
13089 (define_insn "*fop_<mode>_1_i387"
13090   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13091         (match_operator:MODEF 3 "binary_fp_operator"
13092           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13093            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13094   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13095    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13096    && !COMMUTATIVE_ARITH_P (operands[3])
13097    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13098   "* return output_387_binary_op (insn, operands);"
13099   [(set (attr "type")
13100         (cond [(match_operand:MODEF 3 "mult_operator")
13101                  (const_string "fmul")
13102                (match_operand:MODEF 3 "div_operator")
13103                  (const_string "fdiv")
13104               ]
13105               (const_string "fop")))
13106    (set_attr "mode" "<MODE>")])
13108 ;; ??? Add SSE splitters for these!
13109 (define_insn "*fop_<MODEF:mode>_2_i387"
13110   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13111         (match_operator:MODEF 3 "binary_fp_operator"
13112           [(float:MODEF
13113              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13114            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13115   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13116    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13117    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13118   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13119   [(set (attr "type")
13120         (cond [(match_operand:MODEF 3 "mult_operator")
13121                  (const_string "fmul")
13122                (match_operand:MODEF 3 "div_operator")
13123                  (const_string "fdiv")
13124               ]
13125               (const_string "fop")))
13126    (set_attr "fp_int_src" "true")
13127    (set_attr "mode" "<SWI24:MODE>")])
13129 (define_insn "*fop_<MODEF:mode>_3_i387"
13130   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13131         (match_operator:MODEF 3 "binary_fp_operator"
13132           [(match_operand:MODEF 1 "register_operand" "0,0")
13133            (float:MODEF
13134              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13135   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13136    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13137    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13138   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13139   [(set (attr "type")
13140         (cond [(match_operand:MODEF 3 "mult_operator")
13141                  (const_string "fmul")
13142                (match_operand:MODEF 3 "div_operator")
13143                  (const_string "fdiv")
13144               ]
13145               (const_string "fop")))
13146    (set_attr "fp_int_src" "true")
13147    (set_attr "mode" "<MODE>")])
13149 (define_insn "*fop_df_4_i387"
13150   [(set (match_operand:DF 0 "register_operand" "=f,f")
13151         (match_operator:DF 3 "binary_fp_operator"
13152            [(float_extend:DF
13153              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13154             (match_operand:DF 2 "register_operand" "0,f")]))]
13155   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13156    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13157    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13158   "* return output_387_binary_op (insn, operands);"
13159   [(set (attr "type")
13160         (cond [(match_operand:DF 3 "mult_operator")
13161                  (const_string "fmul")
13162                (match_operand:DF 3 "div_operator")
13163                  (const_string "fdiv")
13164               ]
13165               (const_string "fop")))
13166    (set_attr "mode" "SF")])
13168 (define_insn "*fop_df_5_i387"
13169   [(set (match_operand:DF 0 "register_operand" "=f,f")
13170         (match_operator:DF 3 "binary_fp_operator"
13171           [(match_operand:DF 1 "register_operand" "0,f")
13172            (float_extend:DF
13173             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13174   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13175    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13176   "* return output_387_binary_op (insn, operands);"
13177   [(set (attr "type")
13178         (cond [(match_operand:DF 3 "mult_operator")
13179                  (const_string "fmul")
13180                (match_operand:DF 3 "div_operator")
13181                  (const_string "fdiv")
13182               ]
13183               (const_string "fop")))
13184    (set_attr "mode" "SF")])
13186 (define_insn "*fop_df_6_i387"
13187   [(set (match_operand:DF 0 "register_operand" "=f,f")
13188         (match_operator:DF 3 "binary_fp_operator"
13189           [(float_extend:DF
13190             (match_operand:SF 1 "register_operand" "0,f"))
13191            (float_extend:DF
13192             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13193   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13194    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13195   "* return output_387_binary_op (insn, operands);"
13196   [(set (attr "type")
13197         (cond [(match_operand:DF 3 "mult_operator")
13198                  (const_string "fmul")
13199                (match_operand:DF 3 "div_operator")
13200                  (const_string "fdiv")
13201               ]
13202               (const_string "fop")))
13203    (set_attr "mode" "SF")])
13205 (define_insn "*fop_xf_comm_i387"
13206   [(set (match_operand:XF 0 "register_operand" "=f")
13207         (match_operator:XF 3 "binary_fp_operator"
13208                         [(match_operand:XF 1 "register_operand" "%0")
13209                          (match_operand:XF 2 "register_operand" "f")]))]
13210   "TARGET_80387
13211    && COMMUTATIVE_ARITH_P (operands[3])"
13212   "* return output_387_binary_op (insn, operands);"
13213   [(set (attr "type")
13214         (if_then_else (match_operand:XF 3 "mult_operator")
13215            (const_string "fmul")
13216            (const_string "fop")))
13217    (set_attr "mode" "XF")])
13219 (define_insn "*fop_xf_1_i387"
13220   [(set (match_operand:XF 0 "register_operand" "=f,f")
13221         (match_operator:XF 3 "binary_fp_operator"
13222                         [(match_operand:XF 1 "register_operand" "0,f")
13223                          (match_operand:XF 2 "register_operand" "f,0")]))]
13224   "TARGET_80387
13225    && !COMMUTATIVE_ARITH_P (operands[3])"
13226   "* return output_387_binary_op (insn, operands);"
13227   [(set (attr "type")
13228         (cond [(match_operand:XF 3 "mult_operator")
13229                  (const_string "fmul")
13230                (match_operand:XF 3 "div_operator")
13231                  (const_string "fdiv")
13232               ]
13233               (const_string "fop")))
13234    (set_attr "mode" "XF")])
13236 (define_insn "*fop_xf_2_i387"
13237   [(set (match_operand:XF 0 "register_operand" "=f,f")
13238         (match_operator:XF 3 "binary_fp_operator"
13239           [(float:XF
13240              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13241            (match_operand:XF 2 "register_operand" "0,0")]))]
13242   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13243   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13244   [(set (attr "type")
13245         (cond [(match_operand:XF 3 "mult_operator")
13246                  (const_string "fmul")
13247                (match_operand:XF 3 "div_operator")
13248                  (const_string "fdiv")
13249               ]
13250               (const_string "fop")))
13251    (set_attr "fp_int_src" "true")
13252    (set_attr "mode" "<MODE>")])
13254 (define_insn "*fop_xf_3_i387"
13255   [(set (match_operand:XF 0 "register_operand" "=f,f")
13256         (match_operator:XF 3 "binary_fp_operator"
13257           [(match_operand:XF 1 "register_operand" "0,0")
13258            (float:XF
13259              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13260   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13261   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13262   [(set (attr "type")
13263         (cond [(match_operand:XF 3 "mult_operator")
13264                  (const_string "fmul")
13265                (match_operand:XF 3 "div_operator")
13266                  (const_string "fdiv")
13267               ]
13268               (const_string "fop")))
13269    (set_attr "fp_int_src" "true")
13270    (set_attr "mode" "<MODE>")])
13272 (define_insn "*fop_xf_4_i387"
13273   [(set (match_operand:XF 0 "register_operand" "=f,f")
13274         (match_operator:XF 3 "binary_fp_operator"
13275            [(float_extend:XF
13276               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13277             (match_operand:XF 2 "register_operand" "0,f")]))]
13278   "TARGET_80387"
13279   "* return output_387_binary_op (insn, operands);"
13280   [(set (attr "type")
13281         (cond [(match_operand:XF 3 "mult_operator")
13282                  (const_string "fmul")
13283                (match_operand:XF 3 "div_operator")
13284                  (const_string "fdiv")
13285               ]
13286               (const_string "fop")))
13287    (set_attr "mode" "<MODE>")])
13289 (define_insn "*fop_xf_5_i387"
13290   [(set (match_operand:XF 0 "register_operand" "=f,f")
13291         (match_operator:XF 3 "binary_fp_operator"
13292           [(match_operand:XF 1 "register_operand" "0,f")
13293            (float_extend:XF
13294              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13295   "TARGET_80387"
13296   "* return output_387_binary_op (insn, operands);"
13297   [(set (attr "type")
13298         (cond [(match_operand:XF 3 "mult_operator")
13299                  (const_string "fmul")
13300                (match_operand:XF 3 "div_operator")
13301                  (const_string "fdiv")
13302               ]
13303               (const_string "fop")))
13304    (set_attr "mode" "<MODE>")])
13306 (define_insn "*fop_xf_6_i387"
13307   [(set (match_operand:XF 0 "register_operand" "=f,f")
13308         (match_operator:XF 3 "binary_fp_operator"
13309           [(float_extend:XF
13310              (match_operand:MODEF 1 "register_operand" "0,f"))
13311            (float_extend:XF
13312              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13313   "TARGET_80387"
13314   "* return output_387_binary_op (insn, operands);"
13315   [(set (attr "type")
13316         (cond [(match_operand:XF 3 "mult_operator")
13317                  (const_string "fmul")
13318                (match_operand:XF 3 "div_operator")
13319                  (const_string "fdiv")
13320               ]
13321               (const_string "fop")))
13322    (set_attr "mode" "<MODE>")])
13324 (define_split
13325   [(set (match_operand 0 "register_operand")
13326         (match_operator 3 "binary_fp_operator"
13327            [(float (match_operand:SWI24 1 "register_operand"))
13328             (match_operand 2 "register_operand")]))]
13329   "reload_completed
13330    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13331    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13332   [(const_int 0)]
13334   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13335   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13336   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13337                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13338                                           GET_MODE (operands[3]),
13339                                           operands[4],
13340                                           operands[2])));
13341   ix86_free_from_memory (GET_MODE (operands[1]));
13342   DONE;
13345 (define_split
13346   [(set (match_operand 0 "register_operand")
13347         (match_operator 3 "binary_fp_operator"
13348            [(match_operand 1 "register_operand")
13349             (float (match_operand:SWI24 2 "register_operand"))]))]
13350   "reload_completed
13351    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13352    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13353   [(const_int 0)]
13355   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13356   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13357   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13358                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13359                                           GET_MODE (operands[3]),
13360                                           operands[1],
13361                                           operands[4])));
13362   ix86_free_from_memory (GET_MODE (operands[2]));
13363   DONE;
13366 ;; FPU special functions.
13368 ;; This pattern implements a no-op XFmode truncation for
13369 ;; all fancy i386 XFmode math functions.
13371 (define_insn "truncxf<mode>2_i387_noop_unspec"
13372   [(set (match_operand:MODEF 0 "register_operand" "=f")
13373         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13374         UNSPEC_TRUNC_NOOP))]
13375   "TARGET_USE_FANCY_MATH_387"
13376   "* return output_387_reg_move (insn, operands);"
13377   [(set_attr "type" "fmov")
13378    (set_attr "mode" "<MODE>")])
13380 (define_insn "sqrtxf2"
13381   [(set (match_operand:XF 0 "register_operand" "=f")
13382         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13383   "TARGET_USE_FANCY_MATH_387"
13384   "fsqrt"
13385   [(set_attr "type" "fpspc")
13386    (set_attr "mode" "XF")
13387    (set_attr "athlon_decode" "direct")
13388    (set_attr "amdfam10_decode" "direct")
13389    (set_attr "bdver1_decode" "direct")])
13391 (define_insn "sqrt_extend<mode>xf2_i387"
13392   [(set (match_operand:XF 0 "register_operand" "=f")
13393         (sqrt:XF
13394           (float_extend:XF
13395             (match_operand:MODEF 1 "register_operand" "0"))))]
13396   "TARGET_USE_FANCY_MATH_387"
13397   "fsqrt"
13398   [(set_attr "type" "fpspc")
13399    (set_attr "mode" "XF")
13400    (set_attr "athlon_decode" "direct")
13401    (set_attr "amdfam10_decode" "direct")
13402    (set_attr "bdver1_decode" "direct")])
13404 (define_insn "*rsqrtsf2_sse"
13405   [(set (match_operand:SF 0 "register_operand" "=x")
13406         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13407                    UNSPEC_RSQRT))]
13408   "TARGET_SSE_MATH"
13409   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13410   [(set_attr "type" "sse")
13411    (set_attr "atom_sse_attr" "rcp")
13412    (set_attr "prefix" "maybe_vex")
13413    (set_attr "mode" "SF")])
13415 (define_expand "rsqrtsf2"
13416   [(set (match_operand:SF 0 "register_operand")
13417         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13418                    UNSPEC_RSQRT))]
13419   "TARGET_SSE_MATH"
13421   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13422   DONE;
13425 (define_insn "*sqrt<mode>2_sse"
13426   [(set (match_operand:MODEF 0 "register_operand" "=x")
13427         (sqrt:MODEF
13428           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13429   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13430   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13431   [(set_attr "type" "sse")
13432    (set_attr "atom_sse_attr" "sqrt")
13433    (set_attr "prefix" "maybe_vex")
13434    (set_attr "mode" "<MODE>")
13435    (set_attr "athlon_decode" "*")
13436    (set_attr "amdfam10_decode" "*")
13437    (set_attr "bdver1_decode" "*")])
13439 (define_expand "sqrt<mode>2"
13440   [(set (match_operand:MODEF 0 "register_operand")
13441         (sqrt:MODEF
13442           (match_operand:MODEF 1 "nonimmediate_operand")))]
13443   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13444    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13446   if (<MODE>mode == SFmode
13447       && TARGET_SSE_MATH
13448       && TARGET_RECIP_SQRT
13449       && !optimize_function_for_size_p (cfun)
13450       && flag_finite_math_only && !flag_trapping_math
13451       && flag_unsafe_math_optimizations)
13452     {
13453       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13454       DONE;
13455     }
13457   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13458     {
13459       rtx op0 = gen_reg_rtx (XFmode);
13460       rtx op1 = force_reg (<MODE>mode, operands[1]);
13462       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13463       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13464       DONE;
13465    }
13468 (define_insn "fpremxf4_i387"
13469   [(set (match_operand:XF 0 "register_operand" "=f")
13470         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13471                     (match_operand:XF 3 "register_operand" "1")]
13472                    UNSPEC_FPREM_F))
13473    (set (match_operand:XF 1 "register_operand" "=u")
13474         (unspec:XF [(match_dup 2) (match_dup 3)]
13475                    UNSPEC_FPREM_U))
13476    (set (reg:CCFP FPSR_REG)
13477         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13478                      UNSPEC_C2_FLAG))]
13479   "TARGET_USE_FANCY_MATH_387"
13480   "fprem"
13481   [(set_attr "type" "fpspc")
13482    (set_attr "mode" "XF")])
13484 (define_expand "fmodxf3"
13485   [(use (match_operand:XF 0 "register_operand"))
13486    (use (match_operand:XF 1 "general_operand"))
13487    (use (match_operand:XF 2 "general_operand"))]
13488   "TARGET_USE_FANCY_MATH_387"
13490   rtx label = gen_label_rtx ();
13492   rtx op1 = gen_reg_rtx (XFmode);
13493   rtx op2 = gen_reg_rtx (XFmode);
13495   emit_move_insn (op2, operands[2]);
13496   emit_move_insn (op1, operands[1]);
13498   emit_label (label);
13499   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13500   ix86_emit_fp_unordered_jump (label);
13501   LABEL_NUSES (label) = 1;
13503   emit_move_insn (operands[0], op1);
13504   DONE;
13507 (define_expand "fmod<mode>3"
13508   [(use (match_operand:MODEF 0 "register_operand"))
13509    (use (match_operand:MODEF 1 "general_operand"))
13510    (use (match_operand:MODEF 2 "general_operand"))]
13511   "TARGET_USE_FANCY_MATH_387"
13513   rtx (*gen_truncxf) (rtx, rtx);
13515   rtx label = gen_label_rtx ();
13517   rtx op1 = gen_reg_rtx (XFmode);
13518   rtx op2 = gen_reg_rtx (XFmode);
13520   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13521   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13523   emit_label (label);
13524   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13525   ix86_emit_fp_unordered_jump (label);
13526   LABEL_NUSES (label) = 1;
13528   /* Truncate the result properly for strict SSE math.  */
13529   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13530       && !TARGET_MIX_SSE_I387)
13531     gen_truncxf = gen_truncxf<mode>2;
13532   else
13533     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13535   emit_insn (gen_truncxf (operands[0], op1));
13536   DONE;
13539 (define_insn "fprem1xf4_i387"
13540   [(set (match_operand:XF 0 "register_operand" "=f")
13541         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13542                     (match_operand:XF 3 "register_operand" "1")]
13543                    UNSPEC_FPREM1_F))
13544    (set (match_operand:XF 1 "register_operand" "=u")
13545         (unspec:XF [(match_dup 2) (match_dup 3)]
13546                    UNSPEC_FPREM1_U))
13547    (set (reg:CCFP FPSR_REG)
13548         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13549                      UNSPEC_C2_FLAG))]
13550   "TARGET_USE_FANCY_MATH_387"
13551   "fprem1"
13552   [(set_attr "type" "fpspc")
13553    (set_attr "mode" "XF")])
13555 (define_expand "remainderxf3"
13556   [(use (match_operand:XF 0 "register_operand"))
13557    (use (match_operand:XF 1 "general_operand"))
13558    (use (match_operand:XF 2 "general_operand"))]
13559   "TARGET_USE_FANCY_MATH_387"
13561   rtx label = gen_label_rtx ();
13563   rtx op1 = gen_reg_rtx (XFmode);
13564   rtx op2 = gen_reg_rtx (XFmode);
13566   emit_move_insn (op2, operands[2]);
13567   emit_move_insn (op1, operands[1]);
13569   emit_label (label);
13570   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13571   ix86_emit_fp_unordered_jump (label);
13572   LABEL_NUSES (label) = 1;
13574   emit_move_insn (operands[0], op1);
13575   DONE;
13578 (define_expand "remainder<mode>3"
13579   [(use (match_operand:MODEF 0 "register_operand"))
13580    (use (match_operand:MODEF 1 "general_operand"))
13581    (use (match_operand:MODEF 2 "general_operand"))]
13582   "TARGET_USE_FANCY_MATH_387"
13584   rtx (*gen_truncxf) (rtx, rtx);
13586   rtx label = gen_label_rtx ();
13588   rtx op1 = gen_reg_rtx (XFmode);
13589   rtx op2 = gen_reg_rtx (XFmode);
13591   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13592   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13594   emit_label (label);
13596   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13597   ix86_emit_fp_unordered_jump (label);
13598   LABEL_NUSES (label) = 1;
13600   /* Truncate the result properly for strict SSE math.  */
13601   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13602       && !TARGET_MIX_SSE_I387)
13603     gen_truncxf = gen_truncxf<mode>2;
13604   else
13605     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13607   emit_insn (gen_truncxf (operands[0], op1));
13608   DONE;
13611 (define_insn "*sinxf2_i387"
13612   [(set (match_operand:XF 0 "register_operand" "=f")
13613         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13614   "TARGET_USE_FANCY_MATH_387
13615    && flag_unsafe_math_optimizations"
13616   "fsin"
13617   [(set_attr "type" "fpspc")
13618    (set_attr "mode" "XF")])
13620 (define_insn "*sin_extend<mode>xf2_i387"
13621   [(set (match_operand:XF 0 "register_operand" "=f")
13622         (unspec:XF [(float_extend:XF
13623                       (match_operand:MODEF 1 "register_operand" "0"))]
13624                    UNSPEC_SIN))]
13625   "TARGET_USE_FANCY_MATH_387
13626    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13627        || TARGET_MIX_SSE_I387)
13628    && flag_unsafe_math_optimizations"
13629   "fsin"
13630   [(set_attr "type" "fpspc")
13631    (set_attr "mode" "XF")])
13633 (define_insn "*cosxf2_i387"
13634   [(set (match_operand:XF 0 "register_operand" "=f")
13635         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13636   "TARGET_USE_FANCY_MATH_387
13637    && flag_unsafe_math_optimizations"
13638   "fcos"
13639   [(set_attr "type" "fpspc")
13640    (set_attr "mode" "XF")])
13642 (define_insn "*cos_extend<mode>xf2_i387"
13643   [(set (match_operand:XF 0 "register_operand" "=f")
13644         (unspec:XF [(float_extend:XF
13645                       (match_operand:MODEF 1 "register_operand" "0"))]
13646                    UNSPEC_COS))]
13647   "TARGET_USE_FANCY_MATH_387
13648    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13649        || TARGET_MIX_SSE_I387)
13650    && flag_unsafe_math_optimizations"
13651   "fcos"
13652   [(set_attr "type" "fpspc")
13653    (set_attr "mode" "XF")])
13655 ;; When sincos pattern is defined, sin and cos builtin functions will be
13656 ;; expanded to sincos pattern with one of its outputs left unused.
13657 ;; CSE pass will figure out if two sincos patterns can be combined,
13658 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13659 ;; depending on the unused output.
13661 (define_insn "sincosxf3"
13662   [(set (match_operand:XF 0 "register_operand" "=f")
13663         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13664                    UNSPEC_SINCOS_COS))
13665    (set (match_operand:XF 1 "register_operand" "=u")
13666         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13667   "TARGET_USE_FANCY_MATH_387
13668    && flag_unsafe_math_optimizations"
13669   "fsincos"
13670   [(set_attr "type" "fpspc")
13671    (set_attr "mode" "XF")])
13673 (define_split
13674   [(set (match_operand:XF 0 "register_operand")
13675         (unspec:XF [(match_operand:XF 2 "register_operand")]
13676                    UNSPEC_SINCOS_COS))
13677    (set (match_operand:XF 1 "register_operand")
13678         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13679   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13680    && can_create_pseudo_p ()"
13681   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13683 (define_split
13684   [(set (match_operand:XF 0 "register_operand")
13685         (unspec:XF [(match_operand:XF 2 "register_operand")]
13686                    UNSPEC_SINCOS_COS))
13687    (set (match_operand:XF 1 "register_operand")
13688         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13689   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13690    && can_create_pseudo_p ()"
13691   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13693 (define_insn "sincos_extend<mode>xf3_i387"
13694   [(set (match_operand:XF 0 "register_operand" "=f")
13695         (unspec:XF [(float_extend:XF
13696                       (match_operand:MODEF 2 "register_operand" "0"))]
13697                    UNSPEC_SINCOS_COS))
13698    (set (match_operand:XF 1 "register_operand" "=u")
13699         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13700   "TARGET_USE_FANCY_MATH_387
13701    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13702        || TARGET_MIX_SSE_I387)
13703    && flag_unsafe_math_optimizations"
13704   "fsincos"
13705   [(set_attr "type" "fpspc")
13706    (set_attr "mode" "XF")])
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[0]))
13716    && can_create_pseudo_p ()"
13717   [(set (match_dup 1)
13718         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13720 (define_split
13721   [(set (match_operand:XF 0 "register_operand")
13722         (unspec:XF [(float_extend:XF
13723                       (match_operand:MODEF 2 "register_operand"))]
13724                    UNSPEC_SINCOS_COS))
13725    (set (match_operand:XF 1 "register_operand")
13726         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13727   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13728    && can_create_pseudo_p ()"
13729   [(set (match_dup 0)
13730         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13732 (define_expand "sincos<mode>3"
13733   [(use (match_operand:MODEF 0 "register_operand"))
13734    (use (match_operand:MODEF 1 "register_operand"))
13735    (use (match_operand:MODEF 2 "register_operand"))]
13736   "TARGET_USE_FANCY_MATH_387
13737    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13738        || TARGET_MIX_SSE_I387)
13739    && flag_unsafe_math_optimizations"
13741   rtx op0 = gen_reg_rtx (XFmode);
13742   rtx op1 = gen_reg_rtx (XFmode);
13744   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13745   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13746   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13747   DONE;
13750 (define_insn "fptanxf4_i387"
13751   [(set (match_operand:XF 0 "register_operand" "=f")
13752         (match_operand:XF 3 "const_double_operand" "F"))
13753    (set (match_operand:XF 1 "register_operand" "=u")
13754         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13755                    UNSPEC_TAN))]
13756   "TARGET_USE_FANCY_MATH_387
13757    && flag_unsafe_math_optimizations
13758    && standard_80387_constant_p (operands[3]) == 2"
13759   "fptan"
13760   [(set_attr "type" "fpspc")
13761    (set_attr "mode" "XF")])
13763 (define_insn "fptan_extend<mode>xf4_i387"
13764   [(set (match_operand:MODEF 0 "register_operand" "=f")
13765         (match_operand:MODEF 3 "const_double_operand" "F"))
13766    (set (match_operand:XF 1 "register_operand" "=u")
13767         (unspec:XF [(float_extend:XF
13768                       (match_operand:MODEF 2 "register_operand" "0"))]
13769                    UNSPEC_TAN))]
13770   "TARGET_USE_FANCY_MATH_387
13771    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13772        || TARGET_MIX_SSE_I387)
13773    && flag_unsafe_math_optimizations
13774    && standard_80387_constant_p (operands[3]) == 2"
13775   "fptan"
13776   [(set_attr "type" "fpspc")
13777    (set_attr "mode" "XF")])
13779 (define_expand "tanxf2"
13780   [(use (match_operand:XF 0 "register_operand"))
13781    (use (match_operand:XF 1 "register_operand"))]
13782   "TARGET_USE_FANCY_MATH_387
13783    && flag_unsafe_math_optimizations"
13785   rtx one = gen_reg_rtx (XFmode);
13786   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13788   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13789   DONE;
13792 (define_expand "tan<mode>2"
13793   [(use (match_operand:MODEF 0 "register_operand"))
13794    (use (match_operand:MODEF 1 "register_operand"))]
13795   "TARGET_USE_FANCY_MATH_387
13796    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13797        || TARGET_MIX_SSE_I387)
13798    && flag_unsafe_math_optimizations"
13800   rtx op0 = gen_reg_rtx (XFmode);
13802   rtx one = gen_reg_rtx (<MODE>mode);
13803   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13805   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13806                                              operands[1], op2));
13807   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13808   DONE;
13811 (define_insn "*fpatanxf3_i387"
13812   [(set (match_operand:XF 0 "register_operand" "=f")
13813         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13814                     (match_operand:XF 2 "register_operand" "u")]
13815                    UNSPEC_FPATAN))
13816    (clobber (match_scratch:XF 3 "=2"))]
13817   "TARGET_USE_FANCY_MATH_387
13818    && flag_unsafe_math_optimizations"
13819   "fpatan"
13820   [(set_attr "type" "fpspc")
13821    (set_attr "mode" "XF")])
13823 (define_insn "fpatan_extend<mode>xf3_i387"
13824   [(set (match_operand:XF 0 "register_operand" "=f")
13825         (unspec:XF [(float_extend:XF
13826                       (match_operand:MODEF 1 "register_operand" "0"))
13827                     (float_extend:XF
13828                       (match_operand:MODEF 2 "register_operand" "u"))]
13829                    UNSPEC_FPATAN))
13830    (clobber (match_scratch:XF 3 "=2"))]
13831   "TARGET_USE_FANCY_MATH_387
13832    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13833        || TARGET_MIX_SSE_I387)
13834    && flag_unsafe_math_optimizations"
13835   "fpatan"
13836   [(set_attr "type" "fpspc")
13837    (set_attr "mode" "XF")])
13839 (define_expand "atan2xf3"
13840   [(parallel [(set (match_operand:XF 0 "register_operand")
13841                    (unspec:XF [(match_operand:XF 2 "register_operand")
13842                                (match_operand:XF 1 "register_operand")]
13843                               UNSPEC_FPATAN))
13844               (clobber (match_scratch:XF 3))])]
13845   "TARGET_USE_FANCY_MATH_387
13846    && flag_unsafe_math_optimizations")
13848 (define_expand "atan2<mode>3"
13849   [(use (match_operand:MODEF 0 "register_operand"))
13850    (use (match_operand:MODEF 1 "register_operand"))
13851    (use (match_operand:MODEF 2 "register_operand"))]
13852   "TARGET_USE_FANCY_MATH_387
13853    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13854        || TARGET_MIX_SSE_I387)
13855    && flag_unsafe_math_optimizations"
13857   rtx op0 = gen_reg_rtx (XFmode);
13859   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13860   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13861   DONE;
13864 (define_expand "atanxf2"
13865   [(parallel [(set (match_operand:XF 0 "register_operand")
13866                    (unspec:XF [(match_dup 2)
13867                                (match_operand:XF 1 "register_operand")]
13868                               UNSPEC_FPATAN))
13869               (clobber (match_scratch:XF 3))])]
13870   "TARGET_USE_FANCY_MATH_387
13871    && flag_unsafe_math_optimizations"
13873   operands[2] = gen_reg_rtx (XFmode);
13874   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13877 (define_expand "atan<mode>2"
13878   [(use (match_operand:MODEF 0 "register_operand"))
13879    (use (match_operand:MODEF 1 "register_operand"))]
13880   "TARGET_USE_FANCY_MATH_387
13881    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13882        || TARGET_MIX_SSE_I387)
13883    && flag_unsafe_math_optimizations"
13885   rtx op0 = gen_reg_rtx (XFmode);
13887   rtx op2 = gen_reg_rtx (<MODE>mode);
13888   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13890   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13891   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13892   DONE;
13895 (define_expand "asinxf2"
13896   [(set (match_dup 2)
13897         (mult:XF (match_operand:XF 1 "register_operand")
13898                  (match_dup 1)))
13899    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13900    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13901    (parallel [(set (match_operand:XF 0 "register_operand")
13902                    (unspec:XF [(match_dup 5) (match_dup 1)]
13903                               UNSPEC_FPATAN))
13904               (clobber (match_scratch:XF 6))])]
13905   "TARGET_USE_FANCY_MATH_387
13906    && flag_unsafe_math_optimizations"
13908   int i;
13910   if (optimize_insn_for_size_p ())
13911     FAIL;
13913   for (i = 2; i < 6; i++)
13914     operands[i] = gen_reg_rtx (XFmode);
13916   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13919 (define_expand "asin<mode>2"
13920   [(use (match_operand:MODEF 0 "register_operand"))
13921    (use (match_operand:MODEF 1 "general_operand"))]
13922  "TARGET_USE_FANCY_MATH_387
13923    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13924        || TARGET_MIX_SSE_I387)
13925    && flag_unsafe_math_optimizations"
13927   rtx op0 = gen_reg_rtx (XFmode);
13928   rtx op1 = gen_reg_rtx (XFmode);
13930   if (optimize_insn_for_size_p ())
13931     FAIL;
13933   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13934   emit_insn (gen_asinxf2 (op0, op1));
13935   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13936   DONE;
13939 (define_expand "acosxf2"
13940   [(set (match_dup 2)
13941         (mult:XF (match_operand:XF 1 "register_operand")
13942                  (match_dup 1)))
13943    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13944    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13945    (parallel [(set (match_operand:XF 0 "register_operand")
13946                    (unspec:XF [(match_dup 1) (match_dup 5)]
13947                               UNSPEC_FPATAN))
13948               (clobber (match_scratch:XF 6))])]
13949   "TARGET_USE_FANCY_MATH_387
13950    && flag_unsafe_math_optimizations"
13952   int i;
13954   if (optimize_insn_for_size_p ())
13955     FAIL;
13957   for (i = 2; i < 6; i++)
13958     operands[i] = gen_reg_rtx (XFmode);
13960   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13963 (define_expand "acos<mode>2"
13964   [(use (match_operand:MODEF 0 "register_operand"))
13965    (use (match_operand:MODEF 1 "general_operand"))]
13966  "TARGET_USE_FANCY_MATH_387
13967    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13968        || TARGET_MIX_SSE_I387)
13969    && flag_unsafe_math_optimizations"
13971   rtx op0 = gen_reg_rtx (XFmode);
13972   rtx op1 = gen_reg_rtx (XFmode);
13974   if (optimize_insn_for_size_p ())
13975     FAIL;
13977   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13978   emit_insn (gen_acosxf2 (op0, op1));
13979   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13980   DONE;
13983 (define_insn "fyl2xxf3_i387"
13984   [(set (match_operand:XF 0 "register_operand" "=f")
13985         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13986                     (match_operand:XF 2 "register_operand" "u")]
13987                    UNSPEC_FYL2X))
13988    (clobber (match_scratch:XF 3 "=2"))]
13989   "TARGET_USE_FANCY_MATH_387
13990    && flag_unsafe_math_optimizations"
13991   "fyl2x"
13992   [(set_attr "type" "fpspc")
13993    (set_attr "mode" "XF")])
13995 (define_insn "fyl2x_extend<mode>xf3_i387"
13996   [(set (match_operand:XF 0 "register_operand" "=f")
13997         (unspec:XF [(float_extend:XF
13998                       (match_operand:MODEF 1 "register_operand" "0"))
13999                     (match_operand:XF 2 "register_operand" "u")]
14000                    UNSPEC_FYL2X))
14001    (clobber (match_scratch:XF 3 "=2"))]
14002   "TARGET_USE_FANCY_MATH_387
14003    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14004        || TARGET_MIX_SSE_I387)
14005    && flag_unsafe_math_optimizations"
14006   "fyl2x"
14007   [(set_attr "type" "fpspc")
14008    (set_attr "mode" "XF")])
14010 (define_expand "logxf2"
14011   [(parallel [(set (match_operand:XF 0 "register_operand")
14012                    (unspec:XF [(match_operand:XF 1 "register_operand")
14013                                (match_dup 2)] UNSPEC_FYL2X))
14014               (clobber (match_scratch:XF 3))])]
14015   "TARGET_USE_FANCY_MATH_387
14016    && flag_unsafe_math_optimizations"
14018   operands[2] = gen_reg_rtx (XFmode);
14019   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14022 (define_expand "log<mode>2"
14023   [(use (match_operand:MODEF 0 "register_operand"))
14024    (use (match_operand:MODEF 1 "register_operand"))]
14025   "TARGET_USE_FANCY_MATH_387
14026    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14027        || TARGET_MIX_SSE_I387)
14028    && flag_unsafe_math_optimizations"
14030   rtx op0 = gen_reg_rtx (XFmode);
14032   rtx op2 = gen_reg_rtx (XFmode);
14033   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14035   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14036   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14037   DONE;
14040 (define_expand "log10xf2"
14041   [(parallel [(set (match_operand:XF 0 "register_operand")
14042                    (unspec:XF [(match_operand:XF 1 "register_operand")
14043                                (match_dup 2)] UNSPEC_FYL2X))
14044               (clobber (match_scratch:XF 3))])]
14045   "TARGET_USE_FANCY_MATH_387
14046    && flag_unsafe_math_optimizations"
14048   operands[2] = gen_reg_rtx (XFmode);
14049   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14052 (define_expand "log10<mode>2"
14053   [(use (match_operand:MODEF 0 "register_operand"))
14054    (use (match_operand:MODEF 1 "register_operand"))]
14055   "TARGET_USE_FANCY_MATH_387
14056    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14057        || TARGET_MIX_SSE_I387)
14058    && flag_unsafe_math_optimizations"
14060   rtx op0 = gen_reg_rtx (XFmode);
14062   rtx op2 = gen_reg_rtx (XFmode);
14063   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14065   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14066   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14067   DONE;
14070 (define_expand "log2xf2"
14071   [(parallel [(set (match_operand:XF 0 "register_operand")
14072                    (unspec:XF [(match_operand:XF 1 "register_operand")
14073                                (match_dup 2)] UNSPEC_FYL2X))
14074               (clobber (match_scratch:XF 3))])]
14075   "TARGET_USE_FANCY_MATH_387
14076    && flag_unsafe_math_optimizations"
14078   operands[2] = gen_reg_rtx (XFmode);
14079   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14082 (define_expand "log2<mode>2"
14083   [(use (match_operand:MODEF 0 "register_operand"))
14084    (use (match_operand:MODEF 1 "register_operand"))]
14085   "TARGET_USE_FANCY_MATH_387
14086    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14087        || TARGET_MIX_SSE_I387)
14088    && flag_unsafe_math_optimizations"
14090   rtx op0 = gen_reg_rtx (XFmode);
14092   rtx op2 = gen_reg_rtx (XFmode);
14093   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14095   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14096   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14097   DONE;
14100 (define_insn "fyl2xp1xf3_i387"
14101   [(set (match_operand:XF 0 "register_operand" "=f")
14102         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14103                     (match_operand:XF 2 "register_operand" "u")]
14104                    UNSPEC_FYL2XP1))
14105    (clobber (match_scratch:XF 3 "=2"))]
14106   "TARGET_USE_FANCY_MATH_387
14107    && flag_unsafe_math_optimizations"
14108   "fyl2xp1"
14109   [(set_attr "type" "fpspc")
14110    (set_attr "mode" "XF")])
14112 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14113   [(set (match_operand:XF 0 "register_operand" "=f")
14114         (unspec:XF [(float_extend:XF
14115                       (match_operand:MODEF 1 "register_operand" "0"))
14116                     (match_operand:XF 2 "register_operand" "u")]
14117                    UNSPEC_FYL2XP1))
14118    (clobber (match_scratch:XF 3 "=2"))]
14119   "TARGET_USE_FANCY_MATH_387
14120    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14121        || TARGET_MIX_SSE_I387)
14122    && flag_unsafe_math_optimizations"
14123   "fyl2xp1"
14124   [(set_attr "type" "fpspc")
14125    (set_attr "mode" "XF")])
14127 (define_expand "log1pxf2"
14128   [(use (match_operand:XF 0 "register_operand"))
14129    (use (match_operand:XF 1 "register_operand"))]
14130   "TARGET_USE_FANCY_MATH_387
14131    && flag_unsafe_math_optimizations"
14133   if (optimize_insn_for_size_p ())
14134     FAIL;
14136   ix86_emit_i387_log1p (operands[0], operands[1]);
14137   DONE;
14140 (define_expand "log1p<mode>2"
14141   [(use (match_operand:MODEF 0 "register_operand"))
14142    (use (match_operand:MODEF 1 "register_operand"))]
14143   "TARGET_USE_FANCY_MATH_387
14144    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14145        || TARGET_MIX_SSE_I387)
14146    && flag_unsafe_math_optimizations"
14148   rtx op0;
14150   if (optimize_insn_for_size_p ())
14151     FAIL;
14153   op0 = gen_reg_rtx (XFmode);
14155   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14157   ix86_emit_i387_log1p (op0, operands[1]);
14158   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14159   DONE;
14162 (define_insn "fxtractxf3_i387"
14163   [(set (match_operand:XF 0 "register_operand" "=f")
14164         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14165                    UNSPEC_XTRACT_FRACT))
14166    (set (match_operand:XF 1 "register_operand" "=u")
14167         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14168   "TARGET_USE_FANCY_MATH_387
14169    && flag_unsafe_math_optimizations"
14170   "fxtract"
14171   [(set_attr "type" "fpspc")
14172    (set_attr "mode" "XF")])
14174 (define_insn "fxtract_extend<mode>xf3_i387"
14175   [(set (match_operand:XF 0 "register_operand" "=f")
14176         (unspec:XF [(float_extend:XF
14177                       (match_operand:MODEF 2 "register_operand" "0"))]
14178                    UNSPEC_XTRACT_FRACT))
14179    (set (match_operand:XF 1 "register_operand" "=u")
14180         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14181   "TARGET_USE_FANCY_MATH_387
14182    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14183        || TARGET_MIX_SSE_I387)
14184    && flag_unsafe_math_optimizations"
14185   "fxtract"
14186   [(set_attr "type" "fpspc")
14187    (set_attr "mode" "XF")])
14189 (define_expand "logbxf2"
14190   [(parallel [(set (match_dup 2)
14191                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14192                               UNSPEC_XTRACT_FRACT))
14193               (set (match_operand:XF 0 "register_operand")
14194                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14195   "TARGET_USE_FANCY_MATH_387
14196    && flag_unsafe_math_optimizations"
14197   "operands[2] = gen_reg_rtx (XFmode);")
14199 (define_expand "logb<mode>2"
14200   [(use (match_operand:MODEF 0 "register_operand"))
14201    (use (match_operand:MODEF 1 "register_operand"))]
14202   "TARGET_USE_FANCY_MATH_387
14203    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14204        || TARGET_MIX_SSE_I387)
14205    && flag_unsafe_math_optimizations"
14207   rtx op0 = gen_reg_rtx (XFmode);
14208   rtx op1 = gen_reg_rtx (XFmode);
14210   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14211   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14212   DONE;
14215 (define_expand "ilogbxf2"
14216   [(use (match_operand:SI 0 "register_operand"))
14217    (use (match_operand:XF 1 "register_operand"))]
14218   "TARGET_USE_FANCY_MATH_387
14219    && flag_unsafe_math_optimizations"
14221   rtx op0, op1;
14223   if (optimize_insn_for_size_p ())
14224     FAIL;
14226   op0 = gen_reg_rtx (XFmode);
14227   op1 = gen_reg_rtx (XFmode);
14229   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14230   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14231   DONE;
14234 (define_expand "ilogb<mode>2"
14235   [(use (match_operand:SI 0 "register_operand"))
14236    (use (match_operand:MODEF 1 "register_operand"))]
14237   "TARGET_USE_FANCY_MATH_387
14238    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14239        || TARGET_MIX_SSE_I387)
14240    && flag_unsafe_math_optimizations"
14242   rtx op0, op1;
14244   if (optimize_insn_for_size_p ())
14245     FAIL;
14247   op0 = gen_reg_rtx (XFmode);
14248   op1 = gen_reg_rtx (XFmode);
14250   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14251   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14252   DONE;
14255 (define_insn "*f2xm1xf2_i387"
14256   [(set (match_operand:XF 0 "register_operand" "=f")
14257         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14258                    UNSPEC_F2XM1))]
14259   "TARGET_USE_FANCY_MATH_387
14260    && flag_unsafe_math_optimizations"
14261   "f2xm1"
14262   [(set_attr "type" "fpspc")
14263    (set_attr "mode" "XF")])
14265 (define_insn "*fscalexf4_i387"
14266   [(set (match_operand:XF 0 "register_operand" "=f")
14267         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14268                     (match_operand:XF 3 "register_operand" "1")]
14269                    UNSPEC_FSCALE_FRACT))
14270    (set (match_operand:XF 1 "register_operand" "=u")
14271         (unspec:XF [(match_dup 2) (match_dup 3)]
14272                    UNSPEC_FSCALE_EXP))]
14273   "TARGET_USE_FANCY_MATH_387
14274    && flag_unsafe_math_optimizations"
14275   "fscale"
14276   [(set_attr "type" "fpspc")
14277    (set_attr "mode" "XF")])
14279 (define_expand "expNcorexf3"
14280   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14281                                (match_operand:XF 2 "register_operand")))
14282    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14283    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14284    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14285    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14286    (parallel [(set (match_operand:XF 0 "register_operand")
14287                    (unspec:XF [(match_dup 8) (match_dup 4)]
14288                               UNSPEC_FSCALE_FRACT))
14289               (set (match_dup 9)
14290                    (unspec:XF [(match_dup 8) (match_dup 4)]
14291                               UNSPEC_FSCALE_EXP))])]
14292   "TARGET_USE_FANCY_MATH_387
14293    && flag_unsafe_math_optimizations"
14295   int i;
14297   if (optimize_insn_for_size_p ())
14298     FAIL;
14300   for (i = 3; i < 10; i++)
14301     operands[i] = gen_reg_rtx (XFmode);
14303   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14306 (define_expand "expxf2"
14307   [(use (match_operand:XF 0 "register_operand"))
14308    (use (match_operand:XF 1 "register_operand"))]
14309   "TARGET_USE_FANCY_MATH_387
14310    && flag_unsafe_math_optimizations"
14312   rtx op2;
14314   if (optimize_insn_for_size_p ())
14315     FAIL;
14317   op2 = gen_reg_rtx (XFmode);
14318   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14320   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14321   DONE;
14324 (define_expand "exp<mode>2"
14325   [(use (match_operand:MODEF 0 "register_operand"))
14326    (use (match_operand:MODEF 1 "general_operand"))]
14327  "TARGET_USE_FANCY_MATH_387
14328    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14329        || TARGET_MIX_SSE_I387)
14330    && flag_unsafe_math_optimizations"
14332   rtx op0, op1;
14334   if (optimize_insn_for_size_p ())
14335     FAIL;
14337   op0 = gen_reg_rtx (XFmode);
14338   op1 = gen_reg_rtx (XFmode);
14340   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14341   emit_insn (gen_expxf2 (op0, op1));
14342   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14343   DONE;
14346 (define_expand "exp10xf2"
14347   [(use (match_operand:XF 0 "register_operand"))
14348    (use (match_operand:XF 1 "register_operand"))]
14349   "TARGET_USE_FANCY_MATH_387
14350    && flag_unsafe_math_optimizations"
14352   rtx op2;
14354   if (optimize_insn_for_size_p ())
14355     FAIL;
14357   op2 = gen_reg_rtx (XFmode);
14358   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14360   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14361   DONE;
14364 (define_expand "exp10<mode>2"
14365   [(use (match_operand:MODEF 0 "register_operand"))
14366    (use (match_operand:MODEF 1 "general_operand"))]
14367  "TARGET_USE_FANCY_MATH_387
14368    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14369        || TARGET_MIX_SSE_I387)
14370    && flag_unsafe_math_optimizations"
14372   rtx op0, op1;
14374   if (optimize_insn_for_size_p ())
14375     FAIL;
14377   op0 = gen_reg_rtx (XFmode);
14378   op1 = gen_reg_rtx (XFmode);
14380   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14381   emit_insn (gen_exp10xf2 (op0, op1));
14382   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14383   DONE;
14386 (define_expand "exp2xf2"
14387   [(use (match_operand:XF 0 "register_operand"))
14388    (use (match_operand:XF 1 "register_operand"))]
14389   "TARGET_USE_FANCY_MATH_387
14390    && flag_unsafe_math_optimizations"
14392   rtx op2;
14394   if (optimize_insn_for_size_p ())
14395     FAIL;
14397   op2 = gen_reg_rtx (XFmode);
14398   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14400   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14401   DONE;
14404 (define_expand "exp2<mode>2"
14405   [(use (match_operand:MODEF 0 "register_operand"))
14406    (use (match_operand:MODEF 1 "general_operand"))]
14407  "TARGET_USE_FANCY_MATH_387
14408    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14409        || TARGET_MIX_SSE_I387)
14410    && flag_unsafe_math_optimizations"
14412   rtx op0, op1;
14414   if (optimize_insn_for_size_p ())
14415     FAIL;
14417   op0 = gen_reg_rtx (XFmode);
14418   op1 = gen_reg_rtx (XFmode);
14420   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14421   emit_insn (gen_exp2xf2 (op0, op1));
14422   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14423   DONE;
14426 (define_expand "expm1xf2"
14427   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14428                                (match_dup 2)))
14429    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14430    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14431    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14432    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14433    (parallel [(set (match_dup 7)
14434                    (unspec:XF [(match_dup 6) (match_dup 4)]
14435                               UNSPEC_FSCALE_FRACT))
14436               (set (match_dup 8)
14437                    (unspec:XF [(match_dup 6) (match_dup 4)]
14438                               UNSPEC_FSCALE_EXP))])
14439    (parallel [(set (match_dup 10)
14440                    (unspec:XF [(match_dup 9) (match_dup 8)]
14441                               UNSPEC_FSCALE_FRACT))
14442               (set (match_dup 11)
14443                    (unspec:XF [(match_dup 9) (match_dup 8)]
14444                               UNSPEC_FSCALE_EXP))])
14445    (set (match_dup 12) (minus:XF (match_dup 10)
14446                                  (float_extend:XF (match_dup 13))))
14447    (set (match_operand:XF 0 "register_operand")
14448         (plus:XF (match_dup 12) (match_dup 7)))]
14449   "TARGET_USE_FANCY_MATH_387
14450    && flag_unsafe_math_optimizations"
14452   int i;
14454   if (optimize_insn_for_size_p ())
14455     FAIL;
14457   for (i = 2; i < 13; i++)
14458     operands[i] = gen_reg_rtx (XFmode);
14460   operands[13]
14461     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14463   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14466 (define_expand "expm1<mode>2"
14467   [(use (match_operand:MODEF 0 "register_operand"))
14468    (use (match_operand:MODEF 1 "general_operand"))]
14469  "TARGET_USE_FANCY_MATH_387
14470    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14471        || TARGET_MIX_SSE_I387)
14472    && flag_unsafe_math_optimizations"
14474   rtx op0, op1;
14476   if (optimize_insn_for_size_p ())
14477     FAIL;
14479   op0 = gen_reg_rtx (XFmode);
14480   op1 = gen_reg_rtx (XFmode);
14482   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14483   emit_insn (gen_expm1xf2 (op0, op1));
14484   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14485   DONE;
14488 (define_expand "ldexpxf3"
14489   [(set (match_dup 3)
14490         (float:XF (match_operand:SI 2 "register_operand")))
14491    (parallel [(set (match_operand:XF 0 " register_operand")
14492                    (unspec:XF [(match_operand:XF 1 "register_operand")
14493                                (match_dup 3)]
14494                               UNSPEC_FSCALE_FRACT))
14495               (set (match_dup 4)
14496                    (unspec:XF [(match_dup 1) (match_dup 3)]
14497                               UNSPEC_FSCALE_EXP))])]
14498   "TARGET_USE_FANCY_MATH_387
14499    && flag_unsafe_math_optimizations"
14501   if (optimize_insn_for_size_p ())
14502     FAIL;
14504   operands[3] = gen_reg_rtx (XFmode);
14505   operands[4] = gen_reg_rtx (XFmode);
14508 (define_expand "ldexp<mode>3"
14509   [(use (match_operand:MODEF 0 "register_operand"))
14510    (use (match_operand:MODEF 1 "general_operand"))
14511    (use (match_operand:SI 2 "register_operand"))]
14512  "TARGET_USE_FANCY_MATH_387
14513    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14514        || TARGET_MIX_SSE_I387)
14515    && flag_unsafe_math_optimizations"
14517   rtx op0, op1;
14519   if (optimize_insn_for_size_p ())
14520     FAIL;
14522   op0 = gen_reg_rtx (XFmode);
14523   op1 = gen_reg_rtx (XFmode);
14525   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14526   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14527   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14528   DONE;
14531 (define_expand "scalbxf3"
14532   [(parallel [(set (match_operand:XF 0 " register_operand")
14533                    (unspec:XF [(match_operand:XF 1 "register_operand")
14534                                (match_operand:XF 2 "register_operand")]
14535                               UNSPEC_FSCALE_FRACT))
14536               (set (match_dup 3)
14537                    (unspec:XF [(match_dup 1) (match_dup 2)]
14538                               UNSPEC_FSCALE_EXP))])]
14539   "TARGET_USE_FANCY_MATH_387
14540    && flag_unsafe_math_optimizations"
14542   if (optimize_insn_for_size_p ())
14543     FAIL;
14545   operands[3] = gen_reg_rtx (XFmode);
14548 (define_expand "scalb<mode>3"
14549   [(use (match_operand:MODEF 0 "register_operand"))
14550    (use (match_operand:MODEF 1 "general_operand"))
14551    (use (match_operand:MODEF 2 "general_operand"))]
14552  "TARGET_USE_FANCY_MATH_387
14553    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14554        || TARGET_MIX_SSE_I387)
14555    && flag_unsafe_math_optimizations"
14557   rtx op0, op1, op2;
14559   if (optimize_insn_for_size_p ())
14560     FAIL;
14562   op0 = gen_reg_rtx (XFmode);
14563   op1 = gen_reg_rtx (XFmode);
14564   op2 = gen_reg_rtx (XFmode);
14566   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14567   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14568   emit_insn (gen_scalbxf3 (op0, op1, op2));
14569   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14570   DONE;
14573 (define_expand "significandxf2"
14574   [(parallel [(set (match_operand:XF 0 "register_operand")
14575                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14576                               UNSPEC_XTRACT_FRACT))
14577               (set (match_dup 2)
14578                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14579   "TARGET_USE_FANCY_MATH_387
14580    && flag_unsafe_math_optimizations"
14581   "operands[2] = gen_reg_rtx (XFmode);")
14583 (define_expand "significand<mode>2"
14584   [(use (match_operand:MODEF 0 "register_operand"))
14585    (use (match_operand:MODEF 1 "register_operand"))]
14586   "TARGET_USE_FANCY_MATH_387
14587    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14588        || TARGET_MIX_SSE_I387)
14589    && flag_unsafe_math_optimizations"
14591   rtx op0 = gen_reg_rtx (XFmode);
14592   rtx op1 = gen_reg_rtx (XFmode);
14594   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14595   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14596   DONE;
14600 (define_insn "sse4_1_round<mode>2"
14601   [(set (match_operand:MODEF 0 "register_operand" "=x")
14602         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14603                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14604                       UNSPEC_ROUND))]
14605   "TARGET_ROUND"
14606   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14607   [(set_attr "type" "ssecvt")
14608    (set_attr "prefix_extra" "1")
14609    (set_attr "prefix" "maybe_vex")
14610    (set_attr "mode" "<MODE>")])
14612 (define_insn "rintxf2"
14613   [(set (match_operand:XF 0 "register_operand" "=f")
14614         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14615                    UNSPEC_FRNDINT))]
14616   "TARGET_USE_FANCY_MATH_387
14617    && flag_unsafe_math_optimizations"
14618   "frndint"
14619   [(set_attr "type" "fpspc")
14620    (set_attr "mode" "XF")])
14622 (define_expand "rint<mode>2"
14623   [(use (match_operand:MODEF 0 "register_operand"))
14624    (use (match_operand:MODEF 1 "register_operand"))]
14625   "(TARGET_USE_FANCY_MATH_387
14626     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14627         || TARGET_MIX_SSE_I387)
14628     && flag_unsafe_math_optimizations)
14629    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14630        && !flag_trapping_math)"
14632   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14633       && !flag_trapping_math)
14634     {
14635       if (TARGET_ROUND)
14636         emit_insn (gen_sse4_1_round<mode>2
14637                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14638       else if (optimize_insn_for_size_p ())
14639         FAIL;
14640       else
14641         ix86_expand_rint (operands[0], operands[1]);
14642     }
14643   else
14644     {
14645       rtx op0 = gen_reg_rtx (XFmode);
14646       rtx op1 = gen_reg_rtx (XFmode);
14648       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14649       emit_insn (gen_rintxf2 (op0, op1));
14651       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14652     }
14653   DONE;
14656 (define_expand "round<mode>2"
14657   [(match_operand:X87MODEF 0 "register_operand")
14658    (match_operand:X87MODEF 1 "nonimmediate_operand")]
14659   "(TARGET_USE_FANCY_MATH_387
14660     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14661         || TARGET_MIX_SSE_I387)
14662     && flag_unsafe_math_optimizations)
14663    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14664        && !flag_trapping_math && !flag_rounding_math)"
14666   if (optimize_insn_for_size_p ())
14667     FAIL;
14669   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14670       && !flag_trapping_math && !flag_rounding_math)
14671     {
14672       if (TARGET_ROUND)
14673         {
14674           operands[1] = force_reg (<MODE>mode, operands[1]);
14675           ix86_expand_round_sse4 (operands[0], operands[1]);
14676         }
14677       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14678         ix86_expand_round (operands[0], operands[1]);
14679       else
14680         ix86_expand_rounddf_32 (operands[0], operands[1]);
14681     }
14682   else
14683     {
14684       operands[1] = force_reg (<MODE>mode, operands[1]);
14685       ix86_emit_i387_round (operands[0], operands[1]);
14686     }
14687   DONE;
14690 (define_insn_and_split "*fistdi2_1"
14691   [(set (match_operand:DI 0 "nonimmediate_operand")
14692         (unspec:DI [(match_operand:XF 1 "register_operand")]
14693                    UNSPEC_FIST))]
14694   "TARGET_USE_FANCY_MATH_387
14695    && can_create_pseudo_p ()"
14696   "#"
14697   "&& 1"
14698   [(const_int 0)]
14700   if (memory_operand (operands[0], VOIDmode))
14701     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14702   else
14703     {
14704       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14705       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14706                                          operands[2]));
14707     }
14708   DONE;
14710   [(set_attr "type" "fpspc")
14711    (set_attr "mode" "DI")])
14713 (define_insn "fistdi2"
14714   [(set (match_operand:DI 0 "memory_operand" "=m")
14715         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14716                    UNSPEC_FIST))
14717    (clobber (match_scratch:XF 2 "=&1f"))]
14718   "TARGET_USE_FANCY_MATH_387"
14719   "* return output_fix_trunc (insn, operands, false);"
14720   [(set_attr "type" "fpspc")
14721    (set_attr "mode" "DI")])
14723 (define_insn "fistdi2_with_temp"
14724   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14725         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14726                    UNSPEC_FIST))
14727    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14728    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14729   "TARGET_USE_FANCY_MATH_387"
14730   "#"
14731   [(set_attr "type" "fpspc")
14732    (set_attr "mode" "DI")])
14734 (define_split
14735   [(set (match_operand:DI 0 "register_operand")
14736         (unspec:DI [(match_operand:XF 1 "register_operand")]
14737                    UNSPEC_FIST))
14738    (clobber (match_operand:DI 2 "memory_operand"))
14739    (clobber (match_scratch 3))]
14740   "reload_completed"
14741   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14742               (clobber (match_dup 3))])
14743    (set (match_dup 0) (match_dup 2))])
14745 (define_split
14746   [(set (match_operand:DI 0 "memory_operand")
14747         (unspec:DI [(match_operand:XF 1 "register_operand")]
14748                    UNSPEC_FIST))
14749    (clobber (match_operand:DI 2 "memory_operand"))
14750    (clobber (match_scratch 3))]
14751   "reload_completed"
14752   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14753               (clobber (match_dup 3))])])
14755 (define_insn_and_split "*fist<mode>2_1"
14756   [(set (match_operand:SWI24 0 "register_operand")
14757         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14758                       UNSPEC_FIST))]
14759   "TARGET_USE_FANCY_MATH_387
14760    && can_create_pseudo_p ()"
14761   "#"
14762   "&& 1"
14763   [(const_int 0)]
14765   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14766   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14767                                         operands[2]));
14768   DONE;
14770   [(set_attr "type" "fpspc")
14771    (set_attr "mode" "<MODE>")])
14773 (define_insn "fist<mode>2"
14774   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14775         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14776                       UNSPEC_FIST))]
14777   "TARGET_USE_FANCY_MATH_387"
14778   "* return output_fix_trunc (insn, operands, false);"
14779   [(set_attr "type" "fpspc")
14780    (set_attr "mode" "<MODE>")])
14782 (define_insn "fist<mode>2_with_temp"
14783   [(set (match_operand:SWI24 0 "register_operand" "=r")
14784         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14785                       UNSPEC_FIST))
14786    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14787   "TARGET_USE_FANCY_MATH_387"
14788   "#"
14789   [(set_attr "type" "fpspc")
14790    (set_attr "mode" "<MODE>")])
14792 (define_split
14793   [(set (match_operand:SWI24 0 "register_operand")
14794         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14795                       UNSPEC_FIST))
14796    (clobber (match_operand:SWI24 2 "memory_operand"))]
14797   "reload_completed"
14798   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14799    (set (match_dup 0) (match_dup 2))])
14801 (define_split
14802   [(set (match_operand:SWI24 0 "memory_operand")
14803         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14804                       UNSPEC_FIST))
14805    (clobber (match_operand:SWI24 2 "memory_operand"))]
14806   "reload_completed"
14807   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14809 (define_expand "lrintxf<mode>2"
14810   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14811      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14812                      UNSPEC_FIST))]
14813   "TARGET_USE_FANCY_MATH_387")
14815 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14816   [(set (match_operand:SWI48x 0 "nonimmediate_operand")
14817      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
14818                         UNSPEC_FIX_NOTRUNC))]
14819   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14820    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14822 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14823   [(match_operand:SWI248x 0 "nonimmediate_operand")
14824    (match_operand:X87MODEF 1 "register_operand")]
14825   "(TARGET_USE_FANCY_MATH_387
14826     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14827         || TARGET_MIX_SSE_I387)
14828     && flag_unsafe_math_optimizations)
14829    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14830        && <SWI248x:MODE>mode != HImode 
14831        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14832        && !flag_trapping_math && !flag_rounding_math)"
14834   if (optimize_insn_for_size_p ())
14835     FAIL;
14837   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14838       && <SWI248x:MODE>mode != HImode
14839       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14840       && !flag_trapping_math && !flag_rounding_math)
14841     ix86_expand_lround (operands[0], operands[1]);
14842   else
14843     ix86_emit_i387_round (operands[0], operands[1]);
14844   DONE;
14847 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14848 (define_insn_and_split "frndintxf2_floor"
14849   [(set (match_operand:XF 0 "register_operand")
14850         (unspec:XF [(match_operand:XF 1 "register_operand")]
14851          UNSPEC_FRNDINT_FLOOR))
14852    (clobber (reg:CC FLAGS_REG))]
14853   "TARGET_USE_FANCY_MATH_387
14854    && flag_unsafe_math_optimizations
14855    && can_create_pseudo_p ()"
14856   "#"
14857   "&& 1"
14858   [(const_int 0)]
14860   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14862   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14863   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14865   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14866                                         operands[2], operands[3]));
14867   DONE;
14869   [(set_attr "type" "frndint")
14870    (set_attr "i387_cw" "floor")
14871    (set_attr "mode" "XF")])
14873 (define_insn "frndintxf2_floor_i387"
14874   [(set (match_operand:XF 0 "register_operand" "=f")
14875         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14876          UNSPEC_FRNDINT_FLOOR))
14877    (use (match_operand:HI 2 "memory_operand" "m"))
14878    (use (match_operand:HI 3 "memory_operand" "m"))]
14879   "TARGET_USE_FANCY_MATH_387
14880    && flag_unsafe_math_optimizations"
14881   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14882   [(set_attr "type" "frndint")
14883    (set_attr "i387_cw" "floor")
14884    (set_attr "mode" "XF")])
14886 (define_expand "floorxf2"
14887   [(use (match_operand:XF 0 "register_operand"))
14888    (use (match_operand:XF 1 "register_operand"))]
14889   "TARGET_USE_FANCY_MATH_387
14890    && flag_unsafe_math_optimizations"
14892   if (optimize_insn_for_size_p ())
14893     FAIL;
14894   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14895   DONE;
14898 (define_expand "floor<mode>2"
14899   [(use (match_operand:MODEF 0 "register_operand"))
14900    (use (match_operand:MODEF 1 "register_operand"))]
14901   "(TARGET_USE_FANCY_MATH_387
14902     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14903         || TARGET_MIX_SSE_I387)
14904     && flag_unsafe_math_optimizations)
14905    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14906        && !flag_trapping_math)"
14908   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14909       && !flag_trapping_math)
14910     {
14911       if (TARGET_ROUND)
14912         emit_insn (gen_sse4_1_round<mode>2
14913                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14914       else if (optimize_insn_for_size_p ())
14915         FAIL;
14916       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14917         ix86_expand_floorceil (operands[0], operands[1], true);
14918       else
14919         ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14920     }
14921   else
14922     {
14923       rtx op0, op1;
14925       if (optimize_insn_for_size_p ())
14926         FAIL;
14928       op0 = gen_reg_rtx (XFmode);
14929       op1 = gen_reg_rtx (XFmode);
14930       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14931       emit_insn (gen_frndintxf2_floor (op0, op1));
14933       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14934     }
14935   DONE;
14938 (define_insn_and_split "*fist<mode>2_floor_1"
14939   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14940         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14941                         UNSPEC_FIST_FLOOR))
14942    (clobber (reg:CC FLAGS_REG))]
14943   "TARGET_USE_FANCY_MATH_387
14944    && flag_unsafe_math_optimizations
14945    && can_create_pseudo_p ()"
14946   "#"
14947   "&& 1"
14948   [(const_int 0)]
14950   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14952   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14953   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14954   if (memory_operand (operands[0], VOIDmode))
14955     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14956                                       operands[2], operands[3]));
14957   else
14958     {
14959       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14960       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14961                                                   operands[2], operands[3],
14962                                                   operands[4]));
14963     }
14964   DONE;
14966   [(set_attr "type" "fistp")
14967    (set_attr "i387_cw" "floor")
14968    (set_attr "mode" "<MODE>")])
14970 (define_insn "fistdi2_floor"
14971   [(set (match_operand:DI 0 "memory_operand" "=m")
14972         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14973                    UNSPEC_FIST_FLOOR))
14974    (use (match_operand:HI 2 "memory_operand" "m"))
14975    (use (match_operand:HI 3 "memory_operand" "m"))
14976    (clobber (match_scratch:XF 4 "=&1f"))]
14977   "TARGET_USE_FANCY_MATH_387
14978    && flag_unsafe_math_optimizations"
14979   "* return output_fix_trunc (insn, operands, false);"
14980   [(set_attr "type" "fistp")
14981    (set_attr "i387_cw" "floor")
14982    (set_attr "mode" "DI")])
14984 (define_insn "fistdi2_floor_with_temp"
14985   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14986         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14987                    UNSPEC_FIST_FLOOR))
14988    (use (match_operand:HI 2 "memory_operand" "m,m"))
14989    (use (match_operand:HI 3 "memory_operand" "m,m"))
14990    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14991    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14992   "TARGET_USE_FANCY_MATH_387
14993    && flag_unsafe_math_optimizations"
14994   "#"
14995   [(set_attr "type" "fistp")
14996    (set_attr "i387_cw" "floor")
14997    (set_attr "mode" "DI")])
14999 (define_split
15000   [(set (match_operand:DI 0 "register_operand")
15001         (unspec:DI [(match_operand:XF 1 "register_operand")]
15002                    UNSPEC_FIST_FLOOR))
15003    (use (match_operand:HI 2 "memory_operand"))
15004    (use (match_operand:HI 3 "memory_operand"))
15005    (clobber (match_operand:DI 4 "memory_operand"))
15006    (clobber (match_scratch 5))]
15007   "reload_completed"
15008   [(parallel [(set (match_dup 4)
15009                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15010               (use (match_dup 2))
15011               (use (match_dup 3))
15012               (clobber (match_dup 5))])
15013    (set (match_dup 0) (match_dup 4))])
15015 (define_split
15016   [(set (match_operand:DI 0 "memory_operand")
15017         (unspec:DI [(match_operand:XF 1 "register_operand")]
15018                    UNSPEC_FIST_FLOOR))
15019    (use (match_operand:HI 2 "memory_operand"))
15020    (use (match_operand:HI 3 "memory_operand"))
15021    (clobber (match_operand:DI 4 "memory_operand"))
15022    (clobber (match_scratch 5))]
15023   "reload_completed"
15024   [(parallel [(set (match_dup 0)
15025                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15026               (use (match_dup 2))
15027               (use (match_dup 3))
15028               (clobber (match_dup 5))])])
15030 (define_insn "fist<mode>2_floor"
15031   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15032         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15033                       UNSPEC_FIST_FLOOR))
15034    (use (match_operand:HI 2 "memory_operand" "m"))
15035    (use (match_operand:HI 3 "memory_operand" "m"))]
15036   "TARGET_USE_FANCY_MATH_387
15037    && flag_unsafe_math_optimizations"
15038   "* return output_fix_trunc (insn, operands, false);"
15039   [(set_attr "type" "fistp")
15040    (set_attr "i387_cw" "floor")
15041    (set_attr "mode" "<MODE>")])
15043 (define_insn "fist<mode>2_floor_with_temp"
15044   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15045         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15046                       UNSPEC_FIST_FLOOR))
15047    (use (match_operand:HI 2 "memory_operand" "m,m"))
15048    (use (match_operand:HI 3 "memory_operand" "m,m"))
15049    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15050   "TARGET_USE_FANCY_MATH_387
15051    && flag_unsafe_math_optimizations"
15052   "#"
15053   [(set_attr "type" "fistp")
15054    (set_attr "i387_cw" "floor")
15055    (set_attr "mode" "<MODE>")])
15057 (define_split
15058   [(set (match_operand:SWI24 0 "register_operand")
15059         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15060                       UNSPEC_FIST_FLOOR))
15061    (use (match_operand:HI 2 "memory_operand"))
15062    (use (match_operand:HI 3 "memory_operand"))
15063    (clobber (match_operand:SWI24 4 "memory_operand"))]
15064   "reload_completed"
15065   [(parallel [(set (match_dup 4)
15066                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15067               (use (match_dup 2))
15068               (use (match_dup 3))])
15069    (set (match_dup 0) (match_dup 4))])
15071 (define_split
15072   [(set (match_operand:SWI24 0 "memory_operand")
15073         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15074                       UNSPEC_FIST_FLOOR))
15075    (use (match_operand:HI 2 "memory_operand"))
15076    (use (match_operand:HI 3 "memory_operand"))
15077    (clobber (match_operand:SWI24 4 "memory_operand"))]
15078   "reload_completed"
15079   [(parallel [(set (match_dup 0)
15080                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15081               (use (match_dup 2))
15082               (use (match_dup 3))])])
15084 (define_expand "lfloorxf<mode>2"
15085   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15086                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15087                                    UNSPEC_FIST_FLOOR))
15088               (clobber (reg:CC FLAGS_REG))])]
15089   "TARGET_USE_FANCY_MATH_387
15090    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15091    && flag_unsafe_math_optimizations")
15093 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15094   [(match_operand:SWI48 0 "nonimmediate_operand")
15095    (match_operand:MODEF 1 "register_operand")]
15096   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15097    && !flag_trapping_math"
15099   if (TARGET_64BIT && optimize_insn_for_size_p ())
15100     FAIL;
15101   ix86_expand_lfloorceil (operands[0], operands[1], true);
15102   DONE;
15105 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15106 (define_insn_and_split "frndintxf2_ceil"
15107   [(set (match_operand:XF 0 "register_operand")
15108         (unspec:XF [(match_operand:XF 1 "register_operand")]
15109          UNSPEC_FRNDINT_CEIL))
15110    (clobber (reg:CC FLAGS_REG))]
15111   "TARGET_USE_FANCY_MATH_387
15112    && flag_unsafe_math_optimizations
15113    && can_create_pseudo_p ()"
15114   "#"
15115   "&& 1"
15116   [(const_int 0)]
15118   ix86_optimize_mode_switching[I387_CEIL] = 1;
15120   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15121   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15123   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15124                                        operands[2], operands[3]));
15125   DONE;
15127   [(set_attr "type" "frndint")
15128    (set_attr "i387_cw" "ceil")
15129    (set_attr "mode" "XF")])
15131 (define_insn "frndintxf2_ceil_i387"
15132   [(set (match_operand:XF 0 "register_operand" "=f")
15133         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15134          UNSPEC_FRNDINT_CEIL))
15135    (use (match_operand:HI 2 "memory_operand" "m"))
15136    (use (match_operand:HI 3 "memory_operand" "m"))]
15137   "TARGET_USE_FANCY_MATH_387
15138    && flag_unsafe_math_optimizations"
15139   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15140   [(set_attr "type" "frndint")
15141    (set_attr "i387_cw" "ceil")
15142    (set_attr "mode" "XF")])
15144 (define_expand "ceilxf2"
15145   [(use (match_operand:XF 0 "register_operand"))
15146    (use (match_operand:XF 1 "register_operand"))]
15147   "TARGET_USE_FANCY_MATH_387
15148    && flag_unsafe_math_optimizations"
15150   if (optimize_insn_for_size_p ())
15151     FAIL;
15152   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15153   DONE;
15156 (define_expand "ceil<mode>2"
15157   [(use (match_operand:MODEF 0 "register_operand"))
15158    (use (match_operand:MODEF 1 "register_operand"))]
15159   "(TARGET_USE_FANCY_MATH_387
15160     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15161         || TARGET_MIX_SSE_I387)
15162     && flag_unsafe_math_optimizations)
15163    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15164        && !flag_trapping_math)"
15166   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15167       && !flag_trapping_math)
15168     {
15169       if (TARGET_ROUND)
15170         emit_insn (gen_sse4_1_round<mode>2
15171                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15172       else if (optimize_insn_for_size_p ())
15173         FAIL;
15174       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15175         ix86_expand_floorceil (operands[0], operands[1], false);
15176       else
15177         ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15178     }
15179   else
15180     {
15181       rtx op0, op1;
15183       if (optimize_insn_for_size_p ())
15184         FAIL;
15186       op0 = gen_reg_rtx (XFmode);
15187       op1 = gen_reg_rtx (XFmode);
15188       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15189       emit_insn (gen_frndintxf2_ceil (op0, op1));
15191       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15192     }
15193   DONE;
15196 (define_insn_and_split "*fist<mode>2_ceil_1"
15197   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15198         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15199                         UNSPEC_FIST_CEIL))
15200    (clobber (reg:CC FLAGS_REG))]
15201   "TARGET_USE_FANCY_MATH_387
15202    && flag_unsafe_math_optimizations
15203    && can_create_pseudo_p ()"
15204   "#"
15205   "&& 1"
15206   [(const_int 0)]
15208   ix86_optimize_mode_switching[I387_CEIL] = 1;
15210   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15211   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15212   if (memory_operand (operands[0], VOIDmode))
15213     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15214                                      operands[2], operands[3]));
15215   else
15216     {
15217       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15218       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15219                                                  operands[2], operands[3],
15220                                                  operands[4]));
15221     }
15222   DONE;
15224   [(set_attr "type" "fistp")
15225    (set_attr "i387_cw" "ceil")
15226    (set_attr "mode" "<MODE>")])
15228 (define_insn "fistdi2_ceil"
15229   [(set (match_operand:DI 0 "memory_operand" "=m")
15230         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15231                    UNSPEC_FIST_CEIL))
15232    (use (match_operand:HI 2 "memory_operand" "m"))
15233    (use (match_operand:HI 3 "memory_operand" "m"))
15234    (clobber (match_scratch:XF 4 "=&1f"))]
15235   "TARGET_USE_FANCY_MATH_387
15236    && flag_unsafe_math_optimizations"
15237   "* return output_fix_trunc (insn, operands, false);"
15238   [(set_attr "type" "fistp")
15239    (set_attr "i387_cw" "ceil")
15240    (set_attr "mode" "DI")])
15242 (define_insn "fistdi2_ceil_with_temp"
15243   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15244         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15245                    UNSPEC_FIST_CEIL))
15246    (use (match_operand:HI 2 "memory_operand" "m,m"))
15247    (use (match_operand:HI 3 "memory_operand" "m,m"))
15248    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15249    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15250   "TARGET_USE_FANCY_MATH_387
15251    && flag_unsafe_math_optimizations"
15252   "#"
15253   [(set_attr "type" "fistp")
15254    (set_attr "i387_cw" "ceil")
15255    (set_attr "mode" "DI")])
15257 (define_split
15258   [(set (match_operand:DI 0 "register_operand")
15259         (unspec:DI [(match_operand:XF 1 "register_operand")]
15260                    UNSPEC_FIST_CEIL))
15261    (use (match_operand:HI 2 "memory_operand"))
15262    (use (match_operand:HI 3 "memory_operand"))
15263    (clobber (match_operand:DI 4 "memory_operand"))
15264    (clobber (match_scratch 5))]
15265   "reload_completed"
15266   [(parallel [(set (match_dup 4)
15267                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15268               (use (match_dup 2))
15269               (use (match_dup 3))
15270               (clobber (match_dup 5))])
15271    (set (match_dup 0) (match_dup 4))])
15273 (define_split
15274   [(set (match_operand:DI 0 "memory_operand")
15275         (unspec:DI [(match_operand:XF 1 "register_operand")]
15276                    UNSPEC_FIST_CEIL))
15277    (use (match_operand:HI 2 "memory_operand"))
15278    (use (match_operand:HI 3 "memory_operand"))
15279    (clobber (match_operand:DI 4 "memory_operand"))
15280    (clobber (match_scratch 5))]
15281   "reload_completed"
15282   [(parallel [(set (match_dup 0)
15283                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15284               (use (match_dup 2))
15285               (use (match_dup 3))
15286               (clobber (match_dup 5))])])
15288 (define_insn "fist<mode>2_ceil"
15289   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15290         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15291                       UNSPEC_FIST_CEIL))
15292    (use (match_operand:HI 2 "memory_operand" "m"))
15293    (use (match_operand:HI 3 "memory_operand" "m"))]
15294   "TARGET_USE_FANCY_MATH_387
15295    && flag_unsafe_math_optimizations"
15296   "* return output_fix_trunc (insn, operands, false);"
15297   [(set_attr "type" "fistp")
15298    (set_attr "i387_cw" "ceil")
15299    (set_attr "mode" "<MODE>")])
15301 (define_insn "fist<mode>2_ceil_with_temp"
15302   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15303         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15304                       UNSPEC_FIST_CEIL))
15305    (use (match_operand:HI 2 "memory_operand" "m,m"))
15306    (use (match_operand:HI 3 "memory_operand" "m,m"))
15307    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15308   "TARGET_USE_FANCY_MATH_387
15309    && flag_unsafe_math_optimizations"
15310   "#"
15311   [(set_attr "type" "fistp")
15312    (set_attr "i387_cw" "ceil")
15313    (set_attr "mode" "<MODE>")])
15315 (define_split
15316   [(set (match_operand:SWI24 0 "register_operand")
15317         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15318                       UNSPEC_FIST_CEIL))
15319    (use (match_operand:HI 2 "memory_operand"))
15320    (use (match_operand:HI 3 "memory_operand"))
15321    (clobber (match_operand:SWI24 4 "memory_operand"))]
15322   "reload_completed"
15323   [(parallel [(set (match_dup 4)
15324                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15325               (use (match_dup 2))
15326               (use (match_dup 3))])
15327    (set (match_dup 0) (match_dup 4))])
15329 (define_split
15330   [(set (match_operand:SWI24 0 "memory_operand")
15331         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15332                       UNSPEC_FIST_CEIL))
15333    (use (match_operand:HI 2 "memory_operand"))
15334    (use (match_operand:HI 3 "memory_operand"))
15335    (clobber (match_operand:SWI24 4 "memory_operand"))]
15336   "reload_completed"
15337   [(parallel [(set (match_dup 0)
15338                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15339               (use (match_dup 2))
15340               (use (match_dup 3))])])
15342 (define_expand "lceilxf<mode>2"
15343   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15344                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15345                                    UNSPEC_FIST_CEIL))
15346               (clobber (reg:CC FLAGS_REG))])]
15347   "TARGET_USE_FANCY_MATH_387
15348    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15349    && flag_unsafe_math_optimizations")
15351 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15352   [(match_operand:SWI48 0 "nonimmediate_operand")
15353    (match_operand:MODEF 1 "register_operand")]
15354   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15355    && !flag_trapping_math"
15357   ix86_expand_lfloorceil (operands[0], operands[1], false);
15358   DONE;
15361 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15362 (define_insn_and_split "frndintxf2_trunc"
15363   [(set (match_operand:XF 0 "register_operand")
15364         (unspec:XF [(match_operand:XF 1 "register_operand")]
15365          UNSPEC_FRNDINT_TRUNC))
15366    (clobber (reg:CC FLAGS_REG))]
15367   "TARGET_USE_FANCY_MATH_387
15368    && flag_unsafe_math_optimizations
15369    && can_create_pseudo_p ()"
15370   "#"
15371   "&& 1"
15372   [(const_int 0)]
15374   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15376   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15377   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15379   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15380                                         operands[2], operands[3]));
15381   DONE;
15383   [(set_attr "type" "frndint")
15384    (set_attr "i387_cw" "trunc")
15385    (set_attr "mode" "XF")])
15387 (define_insn "frndintxf2_trunc_i387"
15388   [(set (match_operand:XF 0 "register_operand" "=f")
15389         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15390          UNSPEC_FRNDINT_TRUNC))
15391    (use (match_operand:HI 2 "memory_operand" "m"))
15392    (use (match_operand:HI 3 "memory_operand" "m"))]
15393   "TARGET_USE_FANCY_MATH_387
15394    && flag_unsafe_math_optimizations"
15395   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15396   [(set_attr "type" "frndint")
15397    (set_attr "i387_cw" "trunc")
15398    (set_attr "mode" "XF")])
15400 (define_expand "btruncxf2"
15401   [(use (match_operand:XF 0 "register_operand"))
15402    (use (match_operand:XF 1 "register_operand"))]
15403   "TARGET_USE_FANCY_MATH_387
15404    && flag_unsafe_math_optimizations"
15406   if (optimize_insn_for_size_p ())
15407     FAIL;
15408   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15409   DONE;
15412 (define_expand "btrunc<mode>2"
15413   [(use (match_operand:MODEF 0 "register_operand"))
15414    (use (match_operand:MODEF 1 "register_operand"))]
15415   "(TARGET_USE_FANCY_MATH_387
15416     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15417         || TARGET_MIX_SSE_I387)
15418     && flag_unsafe_math_optimizations)
15419    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15420        && !flag_trapping_math)"
15422   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15423       && !flag_trapping_math)
15424     {
15425       if (TARGET_ROUND)
15426         emit_insn (gen_sse4_1_round<mode>2
15427                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15428       else if (optimize_insn_for_size_p ())
15429         FAIL;
15430       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15431         ix86_expand_trunc (operands[0], operands[1]);
15432       else
15433         ix86_expand_truncdf_32 (operands[0], operands[1]);
15434     }
15435   else
15436     {
15437       rtx op0, op1;
15439       if (optimize_insn_for_size_p ())
15440         FAIL;
15442       op0 = gen_reg_rtx (XFmode);
15443       op1 = gen_reg_rtx (XFmode);
15444       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15445       emit_insn (gen_frndintxf2_trunc (op0, op1));
15447       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15448     }
15449   DONE;
15452 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15453 (define_insn_and_split "frndintxf2_mask_pm"
15454   [(set (match_operand:XF 0 "register_operand")
15455         (unspec:XF [(match_operand:XF 1 "register_operand")]
15456          UNSPEC_FRNDINT_MASK_PM))
15457    (clobber (reg:CC FLAGS_REG))]
15458   "TARGET_USE_FANCY_MATH_387
15459    && flag_unsafe_math_optimizations
15460    && can_create_pseudo_p ()"
15461   "#"
15462   "&& 1"
15463   [(const_int 0)]
15465   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15467   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15468   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15470   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15471                                           operands[2], operands[3]));
15472   DONE;
15474   [(set_attr "type" "frndint")
15475    (set_attr "i387_cw" "mask_pm")
15476    (set_attr "mode" "XF")])
15478 (define_insn "frndintxf2_mask_pm_i387"
15479   [(set (match_operand:XF 0 "register_operand" "=f")
15480         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15481          UNSPEC_FRNDINT_MASK_PM))
15482    (use (match_operand:HI 2 "memory_operand" "m"))
15483    (use (match_operand:HI 3 "memory_operand" "m"))]
15484   "TARGET_USE_FANCY_MATH_387
15485    && flag_unsafe_math_optimizations"
15486   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15487   [(set_attr "type" "frndint")
15488    (set_attr "i387_cw" "mask_pm")
15489    (set_attr "mode" "XF")])
15491 (define_expand "nearbyintxf2"
15492   [(use (match_operand:XF 0 "register_operand"))
15493    (use (match_operand:XF 1 "register_operand"))]
15494   "TARGET_USE_FANCY_MATH_387
15495    && flag_unsafe_math_optimizations"
15497   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15498   DONE;
15501 (define_expand "nearbyint<mode>2"
15502   [(use (match_operand:MODEF 0 "register_operand"))
15503    (use (match_operand:MODEF 1 "register_operand"))]
15504   "TARGET_USE_FANCY_MATH_387
15505    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15506        || TARGET_MIX_SSE_I387)
15507    && flag_unsafe_math_optimizations"
15509   rtx op0 = gen_reg_rtx (XFmode);
15510   rtx op1 = gen_reg_rtx (XFmode);
15512   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15513   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15515   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15516   DONE;
15519 (define_insn "fxam<mode>2_i387"
15520   [(set (match_operand:HI 0 "register_operand" "=a")
15521         (unspec:HI
15522           [(match_operand:X87MODEF 1 "register_operand" "f")]
15523           UNSPEC_FXAM))]
15524   "TARGET_USE_FANCY_MATH_387"
15525   "fxam\n\tfnstsw\t%0"
15526   [(set_attr "type" "multi")
15527    (set_attr "length" "4")
15528    (set_attr "unit" "i387")
15529    (set_attr "mode" "<MODE>")])
15531 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15532   [(set (match_operand:HI 0 "register_operand")
15533         (unspec:HI
15534           [(match_operand:MODEF 1 "memory_operand")]
15535           UNSPEC_FXAM_MEM))]
15536   "TARGET_USE_FANCY_MATH_387
15537    && can_create_pseudo_p ()"
15538   "#"
15539   "&& 1"
15540   [(set (match_dup 2)(match_dup 1))
15541    (set (match_dup 0)
15542         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15544   operands[2] = gen_reg_rtx (<MODE>mode);
15546   MEM_VOLATILE_P (operands[1]) = 1;
15548   [(set_attr "type" "multi")
15549    (set_attr "unit" "i387")
15550    (set_attr "mode" "<MODE>")])
15552 (define_expand "isinfxf2"
15553   [(use (match_operand:SI 0 "register_operand"))
15554    (use (match_operand:XF 1 "register_operand"))]
15555   "TARGET_USE_FANCY_MATH_387
15556    && TARGET_C99_FUNCTIONS"
15558   rtx mask = GEN_INT (0x45);
15559   rtx val = GEN_INT (0x05);
15561   rtx cond;
15563   rtx scratch = gen_reg_rtx (HImode);
15564   rtx res = gen_reg_rtx (QImode);
15566   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15568   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15569   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15570   cond = gen_rtx_fmt_ee (EQ, QImode,
15571                          gen_rtx_REG (CCmode, FLAGS_REG),
15572                          const0_rtx);
15573   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15574   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15575   DONE;
15578 (define_expand "isinf<mode>2"
15579   [(use (match_operand:SI 0 "register_operand"))
15580    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15581   "TARGET_USE_FANCY_MATH_387
15582    && TARGET_C99_FUNCTIONS
15583    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15585   rtx mask = GEN_INT (0x45);
15586   rtx val = GEN_INT (0x05);
15588   rtx cond;
15590   rtx scratch = gen_reg_rtx (HImode);
15591   rtx res = gen_reg_rtx (QImode);
15593   /* Remove excess precision by forcing value through memory. */
15594   if (memory_operand (operands[1], VOIDmode))
15595     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15596   else
15597     {
15598       enum ix86_stack_slot slot = (virtuals_instantiated
15599                                    ? SLOT_TEMP
15600                                    : SLOT_VIRTUAL);
15601       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15603       emit_move_insn (temp, operands[1]);
15604       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15605     }
15607   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15608   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15609   cond = gen_rtx_fmt_ee (EQ, QImode,
15610                          gen_rtx_REG (CCmode, FLAGS_REG),
15611                          const0_rtx);
15612   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15613   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15614   DONE;
15617 (define_expand "signbitxf2"
15618   [(use (match_operand:SI 0 "register_operand"))
15619    (use (match_operand:XF 1 "register_operand"))]
15620   "TARGET_USE_FANCY_MATH_387"
15622   rtx scratch = gen_reg_rtx (HImode);
15624   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15625   emit_insn (gen_andsi3 (operands[0],
15626              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15627   DONE;
15630 (define_insn "movmsk_df"
15631   [(set (match_operand:SI 0 "register_operand" "=r")
15632         (unspec:SI
15633           [(match_operand:DF 1 "register_operand" "x")]
15634           UNSPEC_MOVMSK))]
15635   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15636   "%vmovmskpd\t{%1, %0|%0, %1}"
15637   [(set_attr "type" "ssemov")
15638    (set_attr "prefix" "maybe_vex")
15639    (set_attr "mode" "DF")])
15641 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15642 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15643 (define_expand "signbitdf2"
15644   [(use (match_operand:SI 0 "register_operand"))
15645    (use (match_operand:DF 1 "register_operand"))]
15646   "TARGET_USE_FANCY_MATH_387
15647    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15649   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15650     {
15651       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15652       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15653     }
15654   else
15655     {
15656       rtx scratch = gen_reg_rtx (HImode);
15658       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15659       emit_insn (gen_andsi3 (operands[0],
15660                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15661     }
15662   DONE;
15665 (define_expand "signbitsf2"
15666   [(use (match_operand:SI 0 "register_operand"))
15667    (use (match_operand:SF 1 "register_operand"))]
15668   "TARGET_USE_FANCY_MATH_387
15669    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15671   rtx scratch = gen_reg_rtx (HImode);
15673   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15674   emit_insn (gen_andsi3 (operands[0],
15675              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15676   DONE;
15679 ;; Block operation instructions
15681 (define_insn "cld"
15682   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15683   ""
15684   "cld"
15685   [(set_attr "length" "1")
15686    (set_attr "length_immediate" "0")
15687    (set_attr "modrm" "0")])
15689 (define_expand "movmem<mode>"
15690   [(use (match_operand:BLK 0 "memory_operand"))
15691    (use (match_operand:BLK 1 "memory_operand"))
15692    (use (match_operand:SWI48 2 "nonmemory_operand"))
15693    (use (match_operand:SWI48 3 "const_int_operand"))
15694    (use (match_operand:SI 4 "const_int_operand"))
15695    (use (match_operand:SI 5 "const_int_operand"))]
15696   ""
15698  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15699                          operands[4], operands[5]))
15700    DONE;
15701  else
15702    FAIL;
15705 ;; Most CPUs don't like single string operations
15706 ;; Handle this case here to simplify previous expander.
15708 (define_expand "strmov"
15709   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15710    (set (match_operand 1 "memory_operand") (match_dup 4))
15711    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15712               (clobber (reg:CC FLAGS_REG))])
15713    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15714               (clobber (reg:CC FLAGS_REG))])]
15715   ""
15717   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15719   /* If .md ever supports :P for Pmode, these can be directly
15720      in the pattern above.  */
15721   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15722   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15724   /* Can't use this if the user has appropriated esi or edi.  */
15725   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15726       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15727     {
15728       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15729                                       operands[2], operands[3],
15730                                       operands[5], operands[6]));
15731       DONE;
15732     }
15734   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15737 (define_expand "strmov_singleop"
15738   [(parallel [(set (match_operand 1 "memory_operand")
15739                    (match_operand 3 "memory_operand"))
15740               (set (match_operand 0 "register_operand")
15741                    (match_operand 4))
15742               (set (match_operand 2 "register_operand")
15743                    (match_operand 5))])]
15744   ""
15745   "ix86_current_function_needs_cld = 1;")
15747 (define_insn "*strmovdi_rex_1"
15748   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15749         (mem:DI (match_operand:P 3 "register_operand" "1")))
15750    (set (match_operand:P 0 "register_operand" "=D")
15751         (plus:P (match_dup 2)
15752                 (const_int 8)))
15753    (set (match_operand:P 1 "register_operand" "=S")
15754         (plus:P (match_dup 3)
15755                 (const_int 8)))]
15756   "TARGET_64BIT
15757    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15758   "%^movsq"
15759   [(set_attr "type" "str")
15760    (set_attr "memory" "both")
15761    (set_attr "mode" "DI")])
15763 (define_insn "*strmovsi_1"
15764   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15765         (mem:SI (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 4)))
15769    (set (match_operand:P 1 "register_operand" "=S")
15770         (plus:P (match_dup 3)
15771                 (const_int 4)))]
15772   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15773   "%^movs{l|d}"
15774   [(set_attr "type" "str")
15775    (set_attr "memory" "both")
15776    (set_attr "mode" "SI")])
15778 (define_insn "*strmovhi_1"
15779   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15780         (mem:HI (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 2)))
15784    (set (match_operand:P 1 "register_operand" "=S")
15785         (plus:P (match_dup 3)
15786                 (const_int 2)))]
15787   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15788   "%^movsw"
15789   [(set_attr "type" "str")
15790    (set_attr "memory" "both")
15791    (set_attr "mode" "HI")])
15793 (define_insn "*strmovqi_1"
15794   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15795         (mem:QI (match_operand:P 3 "register_operand" "1")))
15796    (set (match_operand:P 0 "register_operand" "=D")
15797         (plus:P (match_dup 2)
15798                 (const_int 1)))
15799    (set (match_operand:P 1 "register_operand" "=S")
15800         (plus:P (match_dup 3)
15801                 (const_int 1)))]
15802   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15803   "%^movsb"
15804   [(set_attr "type" "str")
15805    (set_attr "memory" "both")
15806    (set (attr "prefix_rex")
15807         (if_then_else
15808           (match_test "<P:MODE>mode == DImode")
15809           (const_string "0")
15810           (const_string "*")))
15811    (set_attr "mode" "QI")])
15813 (define_expand "rep_mov"
15814   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15815               (set (match_operand 0 "register_operand")
15816                    (match_operand 5))
15817               (set (match_operand 2 "register_operand")
15818                    (match_operand 6))
15819               (set (match_operand 1 "memory_operand")
15820                    (match_operand 3 "memory_operand"))
15821               (use (match_dup 4))])]
15822   ""
15823   "ix86_current_function_needs_cld = 1;")
15825 (define_insn "*rep_movdi_rex64"
15826   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15827    (set (match_operand:P 0 "register_operand" "=D")
15828         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15829                           (const_int 3))
15830                 (match_operand:P 3 "register_operand" "0")))
15831    (set (match_operand:P 1 "register_operand" "=S")
15832         (plus:P (ashift:P (match_dup 5) (const_int 3))
15833                 (match_operand:P 4 "register_operand" "1")))
15834    (set (mem:BLK (match_dup 3))
15835         (mem:BLK (match_dup 4)))
15836    (use (match_dup 5))]
15837   "TARGET_64BIT
15838    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15839   "%^rep{%;} movsq"
15840   [(set_attr "type" "str")
15841    (set_attr "prefix_rep" "1")
15842    (set_attr "memory" "both")
15843    (set_attr "mode" "DI")])
15845 (define_insn "*rep_movsi"
15846   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15847    (set (match_operand:P 0 "register_operand" "=D")
15848         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15849                           (const_int 2))
15850                  (match_operand:P 3 "register_operand" "0")))
15851    (set (match_operand:P 1 "register_operand" "=S")
15852         (plus:P (ashift:P (match_dup 5) (const_int 2))
15853                 (match_operand:P 4 "register_operand" "1")))
15854    (set (mem:BLK (match_dup 3))
15855         (mem:BLK (match_dup 4)))
15856    (use (match_dup 5))]
15857   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15858   "%^rep{%;} movs{l|d}"
15859   [(set_attr "type" "str")
15860    (set_attr "prefix_rep" "1")
15861    (set_attr "memory" "both")
15862    (set_attr "mode" "SI")])
15864 (define_insn "*rep_movqi"
15865   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15866    (set (match_operand:P 0 "register_operand" "=D")
15867         (plus:P (match_operand:P 3 "register_operand" "0")
15868                 (match_operand:P 5 "register_operand" "2")))
15869    (set (match_operand:P 1 "register_operand" "=S")
15870         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15871    (set (mem:BLK (match_dup 3))
15872         (mem:BLK (match_dup 4)))
15873    (use (match_dup 5))]
15874   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15875   "%^rep{%;} movsb"
15876   [(set_attr "type" "str")
15877    (set_attr "prefix_rep" "1")
15878    (set_attr "memory" "both")
15879    (set_attr "mode" "QI")])
15881 (define_expand "setmem<mode>"
15882    [(use (match_operand:BLK 0 "memory_operand"))
15883     (use (match_operand:SWI48 1 "nonmemory_operand"))
15884     (use (match_operand:QI 2 "nonmemory_operand"))
15885     (use (match_operand 3 "const_int_operand"))
15886     (use (match_operand:SI 4 "const_int_operand"))
15887     (use (match_operand:SI 5 "const_int_operand"))]
15888   ""
15890  if (ix86_expand_setmem (operands[0], operands[1],
15891                          operands[2], operands[3],
15892                          operands[4], operands[5]))
15893    DONE;
15894  else
15895    FAIL;
15898 ;; Most CPUs don't like single string operations
15899 ;; Handle this case here to simplify previous expander.
15901 (define_expand "strset"
15902   [(set (match_operand 1 "memory_operand")
15903         (match_operand 2 "register_operand"))
15904    (parallel [(set (match_operand 0 "register_operand")
15905                    (match_dup 3))
15906               (clobber (reg:CC FLAGS_REG))])]
15907   ""
15909   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15910     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15912   /* If .md ever supports :P for Pmode, this can be directly
15913      in the pattern above.  */
15914   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15915                               GEN_INT (GET_MODE_SIZE (GET_MODE
15916                                                       (operands[2]))));
15917   /* Can't use this if the user has appropriated eax or edi.  */
15918   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15919       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15920     {
15921       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15922                                       operands[3]));
15923       DONE;
15924     }
15927 (define_expand "strset_singleop"
15928   [(parallel [(set (match_operand 1 "memory_operand")
15929                    (match_operand 2 "register_operand"))
15930               (set (match_operand 0 "register_operand")
15931                    (match_operand 3))])]
15932   ""
15933   "ix86_current_function_needs_cld = 1;")
15935 (define_insn "*strsetdi_rex_1"
15936   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15937         (match_operand:DI 2 "register_operand" "a"))
15938    (set (match_operand:P 0 "register_operand" "=D")
15939         (plus:P (match_dup 1)
15940                 (const_int 8)))]
15941   "TARGET_64BIT
15942    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15943   "%^stosq"
15944   [(set_attr "type" "str")
15945    (set_attr "memory" "store")
15946    (set_attr "mode" "DI")])
15948 (define_insn "*strsetsi_1"
15949   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15950         (match_operand:SI 2 "register_operand" "a"))
15951    (set (match_operand:P 0 "register_operand" "=D")
15952         (plus:P (match_dup 1)
15953                 (const_int 4)))]
15954   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15955   "%^stos{l|d}"
15956   [(set_attr "type" "str")
15957    (set_attr "memory" "store")
15958    (set_attr "mode" "SI")])
15960 (define_insn "*strsethi_1"
15961   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15962         (match_operand:HI 2 "register_operand" "a"))
15963    (set (match_operand:P 0 "register_operand" "=D")
15964         (plus:P (match_dup 1)
15965                 (const_int 2)))]
15966   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15967   "%^stosw"
15968   [(set_attr "type" "str")
15969    (set_attr "memory" "store")
15970    (set_attr "mode" "HI")])
15972 (define_insn "*strsetqi_1"
15973   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15974         (match_operand:QI 2 "register_operand" "a"))
15975    (set (match_operand:P 0 "register_operand" "=D")
15976         (plus:P (match_dup 1)
15977                 (const_int 1)))]
15978   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15979   "%^stosb"
15980   [(set_attr "type" "str")
15981    (set_attr "memory" "store")
15982    (set (attr "prefix_rex")
15983         (if_then_else
15984           (match_test "<P:MODE>mode == DImode")
15985           (const_string "0")
15986           (const_string "*")))
15987    (set_attr "mode" "QI")])
15989 (define_expand "rep_stos"
15990   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15991               (set (match_operand 0 "register_operand")
15992                    (match_operand 4))
15993               (set (match_operand 2 "memory_operand") (const_int 0))
15994               (use (match_operand 3 "register_operand"))
15995               (use (match_dup 1))])]
15996   ""
15997   "ix86_current_function_needs_cld = 1;")
15999 (define_insn "*rep_stosdi_rex64"
16000   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16001    (set (match_operand:P 0 "register_operand" "=D")
16002         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16003                           (const_int 3))
16004                  (match_operand:P 3 "register_operand" "0")))
16005    (set (mem:BLK (match_dup 3))
16006         (const_int 0))
16007    (use (match_operand:DI 2 "register_operand" "a"))
16008    (use (match_dup 4))]
16009   "TARGET_64BIT
16010    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16011   "%^rep{%;} stosq"
16012   [(set_attr "type" "str")
16013    (set_attr "prefix_rep" "1")
16014    (set_attr "memory" "store")
16015    (set_attr "mode" "DI")])
16017 (define_insn "*rep_stossi"
16018   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16019    (set (match_operand:P 0 "register_operand" "=D")
16020         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16021                           (const_int 2))
16022                  (match_operand:P 3 "register_operand" "0")))
16023    (set (mem:BLK (match_dup 3))
16024         (const_int 0))
16025    (use (match_operand:SI 2 "register_operand" "a"))
16026    (use (match_dup 4))]
16027   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16028   "%^rep{%;} stos{l|d}"
16029   [(set_attr "type" "str")
16030    (set_attr "prefix_rep" "1")
16031    (set_attr "memory" "store")
16032    (set_attr "mode" "SI")])
16034 (define_insn "*rep_stosqi"
16035   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16036    (set (match_operand:P 0 "register_operand" "=D")
16037         (plus:P (match_operand:P 3 "register_operand" "0")
16038                 (match_operand:P 4 "register_operand" "1")))
16039    (set (mem:BLK (match_dup 3))
16040         (const_int 0))
16041    (use (match_operand:QI 2 "register_operand" "a"))
16042    (use (match_dup 4))]
16043   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16044   "%^rep{%;} stosb"
16045   [(set_attr "type" "str")
16046    (set_attr "prefix_rep" "1")
16047    (set_attr "memory" "store")
16048    (set (attr "prefix_rex")
16049         (if_then_else
16050           (match_test "<P:MODE>mode == DImode")
16051           (const_string "0")
16052           (const_string "*")))
16053    (set_attr "mode" "QI")])
16055 (define_expand "cmpstrnsi"
16056   [(set (match_operand:SI 0 "register_operand")
16057         (compare:SI (match_operand:BLK 1 "general_operand")
16058                     (match_operand:BLK 2 "general_operand")))
16059    (use (match_operand 3 "general_operand"))
16060    (use (match_operand 4 "immediate_operand"))]
16061   ""
16063   rtx addr1, addr2, out, outlow, count, countreg, align;
16065   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16066     FAIL;
16068   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16069   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16070     FAIL;
16072   out = operands[0];
16073   if (!REG_P (out))
16074     out = gen_reg_rtx (SImode);
16076   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16077   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16078   if (addr1 != XEXP (operands[1], 0))
16079     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16080   if (addr2 != XEXP (operands[2], 0))
16081     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16083   count = operands[3];
16084   countreg = ix86_zero_extend_to_Pmode (count);
16086   /* %%% Iff we are testing strict equality, we can use known alignment
16087      to good advantage.  This may be possible with combine, particularly
16088      once cc0 is dead.  */
16089   align = operands[4];
16091   if (CONST_INT_P (count))
16092     {
16093       if (INTVAL (count) == 0)
16094         {
16095           emit_move_insn (operands[0], const0_rtx);
16096           DONE;
16097         }
16098       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16099                                      operands[1], operands[2]));
16100     }
16101   else
16102     {
16103       rtx (*gen_cmp) (rtx, rtx);
16105       gen_cmp = (TARGET_64BIT
16106                  ? gen_cmpdi_1 : gen_cmpsi_1);
16108       emit_insn (gen_cmp (countreg, countreg));
16109       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16110                                   operands[1], operands[2]));
16111     }
16113   outlow = gen_lowpart (QImode, out);
16114   emit_insn (gen_cmpintqi (outlow));
16115   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16117   if (operands[0] != out)
16118     emit_move_insn (operands[0], out);
16120   DONE;
16123 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16125 (define_expand "cmpintqi"
16126   [(set (match_dup 1)
16127         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16128    (set (match_dup 2)
16129         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16130    (parallel [(set (match_operand:QI 0 "register_operand")
16131                    (minus:QI (match_dup 1)
16132                              (match_dup 2)))
16133               (clobber (reg:CC FLAGS_REG))])]
16134   ""
16136   operands[1] = gen_reg_rtx (QImode);
16137   operands[2] = gen_reg_rtx (QImode);
16140 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16141 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16143 (define_expand "cmpstrnqi_nz_1"
16144   [(parallel [(set (reg:CC FLAGS_REG)
16145                    (compare:CC (match_operand 4 "memory_operand")
16146                                (match_operand 5 "memory_operand")))
16147               (use (match_operand 2 "register_operand"))
16148               (use (match_operand:SI 3 "immediate_operand"))
16149               (clobber (match_operand 0 "register_operand"))
16150               (clobber (match_operand 1 "register_operand"))
16151               (clobber (match_dup 2))])]
16152   ""
16153   "ix86_current_function_needs_cld = 1;")
16155 (define_insn "*cmpstrnqi_nz_1"
16156   [(set (reg:CC FLAGS_REG)
16157         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16158                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16159    (use (match_operand:P 6 "register_operand" "2"))
16160    (use (match_operand:SI 3 "immediate_operand" "i"))
16161    (clobber (match_operand:P 0 "register_operand" "=S"))
16162    (clobber (match_operand:P 1 "register_operand" "=D"))
16163    (clobber (match_operand:P 2 "register_operand" "=c"))]
16164   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16165   "%^repz{%;} cmpsb"
16166   [(set_attr "type" "str")
16167    (set_attr "mode" "QI")
16168    (set (attr "prefix_rex")
16169         (if_then_else
16170           (match_test "<P:MODE>mode == DImode")
16171           (const_string "0")
16172           (const_string "*")))
16173    (set_attr "prefix_rep" "1")])
16175 ;; The same, but the count is not known to not be zero.
16177 (define_expand "cmpstrnqi_1"
16178   [(parallel [(set (reg:CC FLAGS_REG)
16179                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16180                                      (const_int 0))
16181                   (compare:CC (match_operand 4 "memory_operand")
16182                               (match_operand 5 "memory_operand"))
16183                   (const_int 0)))
16184               (use (match_operand:SI 3 "immediate_operand"))
16185               (use (reg:CC FLAGS_REG))
16186               (clobber (match_operand 0 "register_operand"))
16187               (clobber (match_operand 1 "register_operand"))
16188               (clobber (match_dup 2))])]
16189   ""
16190   "ix86_current_function_needs_cld = 1;")
16192 (define_insn "*cmpstrnqi_1"
16193   [(set (reg:CC FLAGS_REG)
16194         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16195                              (const_int 0))
16196           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16197                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16198           (const_int 0)))
16199    (use (match_operand:SI 3 "immediate_operand" "i"))
16200    (use (reg:CC FLAGS_REG))
16201    (clobber (match_operand:P 0 "register_operand" "=S"))
16202    (clobber (match_operand:P 1 "register_operand" "=D"))
16203    (clobber (match_operand:P 2 "register_operand" "=c"))]
16204   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16205   "%^repz{%;} cmpsb"
16206   [(set_attr "type" "str")
16207    (set_attr "mode" "QI")
16208    (set (attr "prefix_rex")
16209         (if_then_else
16210           (match_test "<P:MODE>mode == DImode")
16211           (const_string "0")
16212           (const_string "*")))
16213    (set_attr "prefix_rep" "1")])
16215 (define_expand "strlen<mode>"
16216   [(set (match_operand:P 0 "register_operand")
16217         (unspec:P [(match_operand:BLK 1 "general_operand")
16218                    (match_operand:QI 2 "immediate_operand")
16219                    (match_operand 3 "immediate_operand")]
16220                   UNSPEC_SCAS))]
16221   ""
16223  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16224    DONE;
16225  else
16226    FAIL;
16229 (define_expand "strlenqi_1"
16230   [(parallel [(set (match_operand 0 "register_operand")
16231                    (match_operand 2))
16232               (clobber (match_operand 1 "register_operand"))
16233               (clobber (reg:CC FLAGS_REG))])]
16234   ""
16235   "ix86_current_function_needs_cld = 1;")
16237 (define_insn "*strlenqi_1"
16238   [(set (match_operand:P 0 "register_operand" "=&c")
16239         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16240                    (match_operand:QI 2 "register_operand" "a")
16241                    (match_operand:P 3 "immediate_operand" "i")
16242                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16243    (clobber (match_operand:P 1 "register_operand" "=D"))
16244    (clobber (reg:CC FLAGS_REG))]
16245   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16246   "%^repnz{%;} scasb"
16247   [(set_attr "type" "str")
16248    (set_attr "mode" "QI")
16249    (set (attr "prefix_rex")
16250         (if_then_else
16251           (match_test "<P:MODE>mode == DImode")
16252           (const_string "0")
16253           (const_string "*")))
16254    (set_attr "prefix_rep" "1")])
16256 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16257 ;; handled in combine, but it is not currently up to the task.
16258 ;; When used for their truth value, the cmpstrn* expanders generate
16259 ;; code like this:
16261 ;;   repz cmpsb
16262 ;;   seta       %al
16263 ;;   setb       %dl
16264 ;;   cmpb       %al, %dl
16265 ;;   jcc        label
16267 ;; The intermediate three instructions are unnecessary.
16269 ;; This one handles cmpstrn*_nz_1...
16270 (define_peephole2
16271   [(parallel[
16272      (set (reg:CC FLAGS_REG)
16273           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16274                       (mem:BLK (match_operand 5 "register_operand"))))
16275      (use (match_operand 6 "register_operand"))
16276      (use (match_operand:SI 3 "immediate_operand"))
16277      (clobber (match_operand 0 "register_operand"))
16278      (clobber (match_operand 1 "register_operand"))
16279      (clobber (match_operand 2 "register_operand"))])
16280    (set (match_operand:QI 7 "register_operand")
16281         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16282    (set (match_operand:QI 8 "register_operand")
16283         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16284    (set (reg FLAGS_REG)
16285         (compare (match_dup 7) (match_dup 8)))
16286   ]
16287   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16288   [(parallel[
16289      (set (reg:CC FLAGS_REG)
16290           (compare:CC (mem:BLK (match_dup 4))
16291                       (mem:BLK (match_dup 5))))
16292      (use (match_dup 6))
16293      (use (match_dup 3))
16294      (clobber (match_dup 0))
16295      (clobber (match_dup 1))
16296      (clobber (match_dup 2))])])
16298 ;; ...and this one handles cmpstrn*_1.
16299 (define_peephole2
16300   [(parallel[
16301      (set (reg:CC FLAGS_REG)
16302           (if_then_else:CC (ne (match_operand 6 "register_operand")
16303                                (const_int 0))
16304             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16305                         (mem:BLK (match_operand 5 "register_operand")))
16306             (const_int 0)))
16307      (use (match_operand:SI 3 "immediate_operand"))
16308      (use (reg:CC FLAGS_REG))
16309      (clobber (match_operand 0 "register_operand"))
16310      (clobber (match_operand 1 "register_operand"))
16311      (clobber (match_operand 2 "register_operand"))])
16312    (set (match_operand:QI 7 "register_operand")
16313         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16314    (set (match_operand:QI 8 "register_operand")
16315         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16316    (set (reg FLAGS_REG)
16317         (compare (match_dup 7) (match_dup 8)))
16318   ]
16319   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16320   [(parallel[
16321      (set (reg:CC FLAGS_REG)
16322           (if_then_else:CC (ne (match_dup 6)
16323                                (const_int 0))
16324             (compare:CC (mem:BLK (match_dup 4))
16325                         (mem:BLK (match_dup 5)))
16326             (const_int 0)))
16327      (use (match_dup 3))
16328      (use (reg:CC FLAGS_REG))
16329      (clobber (match_dup 0))
16330      (clobber (match_dup 1))
16331      (clobber (match_dup 2))])])
16333 ;; Conditional move instructions.
16335 (define_expand "mov<mode>cc"
16336   [(set (match_operand:SWIM 0 "register_operand")
16337         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16338                            (match_operand:SWIM 2 "<general_operand>")
16339                            (match_operand:SWIM 3 "<general_operand>")))]
16340   ""
16341   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16343 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16344 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16345 ;; So just document what we're doing explicitly.
16347 (define_expand "x86_mov<mode>cc_0_m1"
16348   [(parallel
16349     [(set (match_operand:SWI48 0 "register_operand")
16350           (if_then_else:SWI48
16351             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16352              [(match_operand 1 "flags_reg_operand")
16353               (const_int 0)])
16354             (const_int -1)
16355             (const_int 0)))
16356      (clobber (reg:CC FLAGS_REG))])])
16358 (define_insn "*x86_mov<mode>cc_0_m1"
16359   [(set (match_operand:SWI48 0 "register_operand" "=r")
16360         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16361                              [(reg FLAGS_REG) (const_int 0)])
16362           (const_int -1)
16363           (const_int 0)))
16364    (clobber (reg:CC FLAGS_REG))]
16365   ""
16366   "sbb{<imodesuffix>}\t%0, %0"
16367   ; Since we don't have the proper number of operands for an alu insn,
16368   ; fill in all the blanks.
16369   [(set_attr "type" "alu")
16370    (set_attr "use_carry" "1")
16371    (set_attr "pent_pair" "pu")
16372    (set_attr "memory" "none")
16373    (set_attr "imm_disp" "false")
16374    (set_attr "mode" "<MODE>")
16375    (set_attr "length_immediate" "0")])
16377 (define_insn "*x86_mov<mode>cc_0_m1_se"
16378   [(set (match_operand:SWI48 0 "register_operand" "=r")
16379         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16380                              [(reg FLAGS_REG) (const_int 0)])
16381                             (const_int 1)
16382                             (const_int 0)))
16383    (clobber (reg:CC FLAGS_REG))]
16384   ""
16385   "sbb{<imodesuffix>}\t%0, %0"
16386   [(set_attr "type" "alu")
16387    (set_attr "use_carry" "1")
16388    (set_attr "pent_pair" "pu")
16389    (set_attr "memory" "none")
16390    (set_attr "imm_disp" "false")
16391    (set_attr "mode" "<MODE>")
16392    (set_attr "length_immediate" "0")])
16394 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16395   [(set (match_operand:SWI48 0 "register_operand" "=r")
16396         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16397                     [(reg FLAGS_REG) (const_int 0)])))]
16398   ""
16399   "sbb{<imodesuffix>}\t%0, %0"
16400   [(set_attr "type" "alu")
16401    (set_attr "use_carry" "1")
16402    (set_attr "pent_pair" "pu")
16403    (set_attr "memory" "none")
16404    (set_attr "imm_disp" "false")
16405    (set_attr "mode" "<MODE>")
16406    (set_attr "length_immediate" "0")])
16408 (define_insn "*mov<mode>cc_noc"
16409   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16410         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16411                                [(reg FLAGS_REG) (const_int 0)])
16412           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16413           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16414   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16415   "@
16416    cmov%O2%C1\t{%2, %0|%0, %2}
16417    cmov%O2%c1\t{%3, %0|%0, %3}"
16418   [(set_attr "type" "icmov")
16419    (set_attr "mode" "<MODE>")])
16421 (define_insn_and_split "*movqicc_noc"
16422   [(set (match_operand:QI 0 "register_operand" "=r,r")
16423         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16424                            [(match_operand 4 "flags_reg_operand")
16425                             (const_int 0)])
16426                       (match_operand:QI 2 "register_operand" "r,0")
16427                       (match_operand:QI 3 "register_operand" "0,r")))]
16428   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16429   "#"
16430   "&& reload_completed"
16431   [(set (match_dup 0)
16432         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16433                       (match_dup 2)
16434                       (match_dup 3)))]
16435   "operands[0] = gen_lowpart (SImode, operands[0]);
16436    operands[2] = gen_lowpart (SImode, operands[2]);
16437    operands[3] = gen_lowpart (SImode, operands[3]);"
16438   [(set_attr "type" "icmov")
16439    (set_attr "mode" "SI")])
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;")
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")])
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")])
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")])
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                                 [(match_operand 4 "flags_reg_operand")
16500                                  (const_int 0)])
16501                       (match_operand:DF 2 "nonimmediate_operand")
16502                       (match_operand:DF 3 "nonimmediate_operand")))]
16503   "!TARGET_64BIT && reload_completed"
16504   [(set (match_dup 2)
16505         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16506                       (match_dup 5)
16507                       (match_dup 6)))
16508    (set (match_dup 3)
16509         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16510                       (match_dup 7)
16511                       (match_dup 8)))]
16513   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16514   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16517 (define_insn "*movsfcc_1_387"
16518   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16519         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16520                                 [(reg FLAGS_REG) (const_int 0)])
16521                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16522                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16523   "TARGET_80387 && TARGET_CMOVE
16524    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16525   "@
16526    fcmov%F1\t{%2, %0|%0, %2}
16527    fcmov%f1\t{%3, %0|%0, %3}
16528    cmov%O2%C1\t{%2, %0|%0, %2}
16529    cmov%O2%c1\t{%3, %0|%0, %3}"
16530   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16531    (set_attr "mode" "SF,SF,SI,SI")])
16533 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16534 ;; the scalar versions to have only XMM registers as operands.
16536 ;; XOP conditional move
16537 (define_insn "*xop_pcmov_<mode>"
16538   [(set (match_operand:MODEF 0 "register_operand" "=x")
16539         (if_then_else:MODEF
16540           (match_operand:MODEF 1 "register_operand" "x")
16541           (match_operand:MODEF 2 "register_operand" "x")
16542           (match_operand:MODEF 3 "register_operand" "x")))]
16543   "TARGET_XOP"
16544   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16545   [(set_attr "type" "sse4arg")])
16547 ;; These versions of the min/max patterns are intentionally ignorant of
16548 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16549 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16550 ;; are undefined in this condition, we're certain this is correct.
16552 (define_insn "<code><mode>3"
16553   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16554         (smaxmin:MODEF
16555           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16556           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16557   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16558   "@
16559    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16560    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16561   [(set_attr "isa" "noavx,avx")
16562    (set_attr "prefix" "orig,vex")
16563    (set_attr "type" "sseadd")
16564    (set_attr "mode" "<MODE>")])
16566 ;; These versions of the min/max patterns implement exactly the operations
16567 ;;   min = (op1 < op2 ? op1 : op2)
16568 ;;   max = (!(op1 < op2) ? op1 : op2)
16569 ;; Their operands are not commutative, and thus they may be used in the
16570 ;; presence of -0.0 and NaN.
16572 (define_insn "*ieee_smin<mode>3"
16573   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16574         (unspec:MODEF
16575           [(match_operand:MODEF 1 "register_operand" "0,x")
16576            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16577          UNSPEC_IEEE_MIN))]
16578   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16579   "@
16580    min<ssemodesuffix>\t{%2, %0|%0, %2}
16581    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16582   [(set_attr "isa" "noavx,avx")
16583    (set_attr "prefix" "orig,vex")
16584    (set_attr "type" "sseadd")
16585    (set_attr "mode" "<MODE>")])
16587 (define_insn "*ieee_smax<mode>3"
16588   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16589         (unspec:MODEF
16590           [(match_operand:MODEF 1 "register_operand" "0,x")
16591            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16592          UNSPEC_IEEE_MAX))]
16593   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16594   "@
16595    max<ssemodesuffix>\t{%2, %0|%0, %2}
16596    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16597   [(set_attr "isa" "noavx,avx")
16598    (set_attr "prefix" "orig,vex")
16599    (set_attr "type" "sseadd")
16600    (set_attr "mode" "<MODE>")])
16602 ;; Make two stack loads independent:
16603 ;;   fld aa              fld aa
16604 ;;   fld %st(0)     ->   fld bb
16605 ;;   fmul bb             fmul %st(1), %st
16607 ;; Actually we only match the last two instructions for simplicity.
16608 (define_peephole2
16609   [(set (match_operand 0 "fp_register_operand")
16610         (match_operand 1 "fp_register_operand"))
16611    (set (match_dup 0)
16612         (match_operator 2 "binary_fp_operator"
16613            [(match_dup 0)
16614             (match_operand 3 "memory_operand")]))]
16615   "REGNO (operands[0]) != REGNO (operands[1])"
16616   [(set (match_dup 0) (match_dup 3))
16617    (set (match_dup 0) (match_dup 4))]
16619   ;; The % modifier is not operational anymore in peephole2's, so we have to
16620   ;; swap the operands manually in the case of addition and multiplication.
16622   rtx op0, op1;
16624   if (COMMUTATIVE_ARITH_P (operands[2]))
16625     op0 = operands[0], op1 = operands[1];
16626   else
16627     op0 = operands[1], op1 = operands[0];
16629   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16630                                 GET_MODE (operands[2]),
16631                                 op0, op1);
16634 ;; Conditional addition patterns
16635 (define_expand "add<mode>cc"
16636   [(match_operand:SWI 0 "register_operand")
16637    (match_operand 1 "ordered_comparison_operator")
16638    (match_operand:SWI 2 "register_operand")
16639    (match_operand:SWI 3 "const_int_operand")]
16640   ""
16641   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16643 ;; Misc patterns (?)
16645 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16646 ;; Otherwise there will be nothing to keep
16648 ;; [(set (reg ebp) (reg esp))]
16649 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16650 ;;  (clobber (eflags)]
16651 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16653 ;; in proper program order.
16655 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16656   [(set (match_operand:P 0 "register_operand" "=r,r")
16657         (plus:P (match_operand:P 1 "register_operand" "0,r")
16658                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16659    (clobber (reg:CC FLAGS_REG))
16660    (clobber (mem:BLK (scratch)))]
16661   ""
16663   switch (get_attr_type (insn))
16664     {
16665     case TYPE_IMOV:
16666       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16668     case TYPE_ALU:
16669       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16670       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16671         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16673       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16675     default:
16676       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16677       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16678     }
16680   [(set (attr "type")
16681         (cond [(and (eq_attr "alternative" "0")
16682                     (not (match_test "TARGET_OPT_AGU")))
16683                  (const_string "alu")
16684                (match_operand:<MODE> 2 "const0_operand")
16685                  (const_string "imov")
16686               ]
16687               (const_string "lea")))
16688    (set (attr "length_immediate")
16689         (cond [(eq_attr "type" "imov")
16690                  (const_string "0")
16691                (and (eq_attr "type" "alu")
16692                     (match_operand 2 "const128_operand"))
16693                  (const_string "1")
16694               ]
16695               (const_string "*")))
16696    (set_attr "mode" "<MODE>")])
16698 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16699   [(set (match_operand:P 0 "register_operand" "=r")
16700         (minus:P (match_operand:P 1 "register_operand" "0")
16701                  (match_operand:P 2 "register_operand" "r")))
16702    (clobber (reg:CC FLAGS_REG))
16703    (clobber (mem:BLK (scratch)))]
16704   ""
16705   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16706   [(set_attr "type" "alu")
16707    (set_attr "mode" "<MODE>")])
16709 (define_insn "allocate_stack_worker_probe_<mode>"
16710   [(set (match_operand:P 0 "register_operand" "=a")
16711         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16712                             UNSPECV_STACK_PROBE))
16713    (clobber (reg:CC FLAGS_REG))]
16714   "ix86_target_stack_probe ()"
16715   "call\t___chkstk_ms"
16716   [(set_attr "type" "multi")
16717    (set_attr "length" "5")])
16719 (define_expand "allocate_stack"
16720   [(match_operand 0 "register_operand")
16721    (match_operand 1 "general_operand")]
16722   "ix86_target_stack_probe ()"
16724   rtx x;
16726 #ifndef CHECK_STACK_LIMIT
16727 #define CHECK_STACK_LIMIT 0
16728 #endif
16730   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16731       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16732     {
16733       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16734                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16735       if (x != stack_pointer_rtx)
16736         emit_move_insn (stack_pointer_rtx, x);
16737     }
16738   else
16739     {
16740       x = copy_to_mode_reg (Pmode, operands[1]);
16741       if (TARGET_64BIT)
16742         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16743       else
16744         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16745       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16746                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16747       if (x != stack_pointer_rtx)
16748         emit_move_insn (stack_pointer_rtx, x);
16749     }
16751   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16752   DONE;
16755 ;; Use IOR for stack probes, this is shorter.
16756 (define_expand "probe_stack"
16757   [(match_operand 0 "memory_operand")]
16758   ""
16760   rtx (*gen_ior3) (rtx, rtx, rtx);
16762   gen_ior3 = (GET_MODE (operands[0]) == DImode
16763               ? gen_iordi3 : gen_iorsi3);
16765   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16766   DONE;
16769 (define_insn "adjust_stack_and_probe<mode>"
16770   [(set (match_operand:P 0 "register_operand" "=r")
16771         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16772                             UNSPECV_PROBE_STACK_RANGE))
16773    (set (reg:P SP_REG)
16774         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16775    (clobber (reg:CC FLAGS_REG))
16776    (clobber (mem:BLK (scratch)))]
16777   ""
16778   "* return output_adjust_stack_and_probe (operands[0]);"
16779   [(set_attr "type" "multi")])
16781 (define_insn "probe_stack_range<mode>"
16782   [(set (match_operand:P 0 "register_operand" "=r")
16783         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16784                             (match_operand:P 2 "const_int_operand" "n")]
16785                             UNSPECV_PROBE_STACK_RANGE))
16786    (clobber (reg:CC FLAGS_REG))]
16787   ""
16788   "* return output_probe_stack_range (operands[0], operands[2]);"
16789   [(set_attr "type" "multi")])
16791 (define_expand "builtin_setjmp_receiver"
16792   [(label_ref (match_operand 0))]
16793   "!TARGET_64BIT && flag_pic"
16795 #if TARGET_MACHO
16796   if (TARGET_MACHO)
16797     {
16798       rtx xops[3];
16799       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16800       rtx label_rtx = gen_label_rtx ();
16801       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16802       xops[0] = xops[1] = picreg;
16803       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16804       ix86_expand_binary_operator (MINUS, SImode, xops);
16805     }
16806   else
16807 #endif
16808     emit_insn (gen_set_got (pic_offset_table_rtx));
16809   DONE;
16812 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16814 (define_split
16815   [(set (match_operand 0 "register_operand")
16816         (match_operator 3 "promotable_binary_operator"
16817            [(match_operand 1 "register_operand")
16818             (match_operand 2 "aligned_operand")]))
16819    (clobber (reg:CC FLAGS_REG))]
16820   "! TARGET_PARTIAL_REG_STALL && reload_completed
16821    && ((GET_MODE (operands[0]) == HImode
16822         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16823             /* ??? next two lines just !satisfies_constraint_K (...) */
16824             || !CONST_INT_P (operands[2])
16825             || satisfies_constraint_K (operands[2])))
16826        || (GET_MODE (operands[0]) == QImode
16827            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16828   [(parallel [(set (match_dup 0)
16829                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16830               (clobber (reg:CC FLAGS_REG))])]
16832   operands[0] = gen_lowpart (SImode, operands[0]);
16833   operands[1] = gen_lowpart (SImode, operands[1]);
16834   if (GET_CODE (operands[3]) != ASHIFT)
16835     operands[2] = gen_lowpart (SImode, operands[2]);
16836   PUT_MODE (operands[3], SImode);
16839 ; Promote the QImode tests, as i386 has encoding of the AND
16840 ; instruction with 32-bit sign-extended immediate and thus the
16841 ; instruction size is unchanged, except in the %eax case for
16842 ; which it is increased by one byte, hence the ! optimize_size.
16843 (define_split
16844   [(set (match_operand 0 "flags_reg_operand")
16845         (match_operator 2 "compare_operator"
16846           [(and (match_operand 3 "aligned_operand")
16847                 (match_operand 4 "const_int_operand"))
16848            (const_int 0)]))
16849    (set (match_operand 1 "register_operand")
16850         (and (match_dup 3) (match_dup 4)))]
16851   "! TARGET_PARTIAL_REG_STALL && reload_completed
16852    && optimize_insn_for_speed_p ()
16853    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16854        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16855    /* Ensure that the operand will remain sign-extended immediate.  */
16856    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16857   [(parallel [(set (match_dup 0)
16858                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16859                                     (const_int 0)]))
16860               (set (match_dup 1)
16861                    (and:SI (match_dup 3) (match_dup 4)))])]
16863   operands[4]
16864     = gen_int_mode (INTVAL (operands[4])
16865                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16866   operands[1] = gen_lowpart (SImode, operands[1]);
16867   operands[3] = gen_lowpart (SImode, operands[3]);
16870 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16871 ; the TEST instruction with 32-bit sign-extended immediate and thus
16872 ; the instruction size would at least double, which is not what we
16873 ; want even with ! optimize_size.
16874 (define_split
16875   [(set (match_operand 0 "flags_reg_operand")
16876         (match_operator 1 "compare_operator"
16877           [(and (match_operand:HI 2 "aligned_operand")
16878                 (match_operand:HI 3 "const_int_operand"))
16879            (const_int 0)]))]
16880   "! TARGET_PARTIAL_REG_STALL && reload_completed
16881    && ! TARGET_FAST_PREFIX
16882    && optimize_insn_for_speed_p ()
16883    /* Ensure that the operand will remain sign-extended immediate.  */
16884    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16885   [(set (match_dup 0)
16886         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16887                          (const_int 0)]))]
16889   operands[3]
16890     = gen_int_mode (INTVAL (operands[3])
16891                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16892   operands[2] = gen_lowpart (SImode, operands[2]);
16895 (define_split
16896   [(set (match_operand 0 "register_operand")
16897         (neg (match_operand 1 "register_operand")))
16898    (clobber (reg:CC FLAGS_REG))]
16899   "! TARGET_PARTIAL_REG_STALL && reload_completed
16900    && (GET_MODE (operands[0]) == HImode
16901        || (GET_MODE (operands[0]) == QImode
16902            && (TARGET_PROMOTE_QImode
16903                || optimize_insn_for_size_p ())))"
16904   [(parallel [(set (match_dup 0)
16905                    (neg:SI (match_dup 1)))
16906               (clobber (reg:CC FLAGS_REG))])]
16908   operands[0] = gen_lowpart (SImode, operands[0]);
16909   operands[1] = gen_lowpart (SImode, operands[1]);
16912 (define_split
16913   [(set (match_operand 0 "register_operand")
16914         (not (match_operand 1 "register_operand")))]
16915   "! TARGET_PARTIAL_REG_STALL && reload_completed
16916    && (GET_MODE (operands[0]) == HImode
16917        || (GET_MODE (operands[0]) == QImode
16918            && (TARGET_PROMOTE_QImode
16919                || optimize_insn_for_size_p ())))"
16920   [(set (match_dup 0)
16921         (not:SI (match_dup 1)))]
16923   operands[0] = gen_lowpart (SImode, operands[0]);
16924   operands[1] = gen_lowpart (SImode, operands[1]);
16927 (define_split
16928   [(set (match_operand 0 "register_operand")
16929         (if_then_else (match_operator 1 "ordered_comparison_operator"
16930                                 [(reg FLAGS_REG) (const_int 0)])
16931                       (match_operand 2 "register_operand")
16932                       (match_operand 3 "register_operand")))]
16933   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16934    && (GET_MODE (operands[0]) == HImode
16935        || (GET_MODE (operands[0]) == QImode
16936            && (TARGET_PROMOTE_QImode
16937                || optimize_insn_for_size_p ())))"
16938   [(set (match_dup 0)
16939         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16941   operands[0] = gen_lowpart (SImode, operands[0]);
16942   operands[2] = gen_lowpart (SImode, operands[2]);
16943   operands[3] = gen_lowpart (SImode, operands[3]);
16946 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16947 ;; transform a complex memory operation into two memory to register operations.
16949 ;; Don't push memory operands
16950 (define_peephole2
16951   [(set (match_operand:SWI 0 "push_operand")
16952         (match_operand:SWI 1 "memory_operand"))
16953    (match_scratch:SWI 2 "<r>")]
16954   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16955    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16956   [(set (match_dup 2) (match_dup 1))
16957    (set (match_dup 0) (match_dup 2))])
16959 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16960 ;; SImode pushes.
16961 (define_peephole2
16962   [(set (match_operand:SF 0 "push_operand")
16963         (match_operand:SF 1 "memory_operand"))
16964    (match_scratch:SF 2 "r")]
16965   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16966    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16967   [(set (match_dup 2) (match_dup 1))
16968    (set (match_dup 0) (match_dup 2))])
16970 ;; Don't move an immediate directly to memory when the instruction
16971 ;; gets too big.
16972 (define_peephole2
16973   [(match_scratch:SWI124 1 "<r>")
16974    (set (match_operand:SWI124 0 "memory_operand")
16975         (const_int 0))]
16976   "optimize_insn_for_speed_p ()
16977    && !TARGET_USE_MOV0
16978    && TARGET_SPLIT_LONG_MOVES
16979    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16980    && peep2_regno_dead_p (0, FLAGS_REG)"
16981   [(parallel [(set (match_dup 2) (const_int 0))
16982               (clobber (reg:CC FLAGS_REG))])
16983    (set (match_dup 0) (match_dup 1))]
16984   "operands[2] = gen_lowpart (SImode, operands[1]);")
16986 (define_peephole2
16987   [(match_scratch:SWI124 2 "<r>")
16988    (set (match_operand:SWI124 0 "memory_operand")
16989         (match_operand:SWI124 1 "immediate_operand"))]
16990   "optimize_insn_for_speed_p ()
16991    && TARGET_SPLIT_LONG_MOVES
16992    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16993   [(set (match_dup 2) (match_dup 1))
16994    (set (match_dup 0) (match_dup 2))])
16996 ;; Don't compare memory with zero, load and use a test instead.
16997 (define_peephole2
16998   [(set (match_operand 0 "flags_reg_operand")
16999         (match_operator 1 "compare_operator"
17000           [(match_operand:SI 2 "memory_operand")
17001            (const_int 0)]))
17002    (match_scratch:SI 3 "r")]
17003   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17004   [(set (match_dup 3) (match_dup 2))
17005    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17007 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17008 ;; Don't split NOTs with a displacement operand, because resulting XOR
17009 ;; will not be pairable anyway.
17011 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17012 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17013 ;; so this split helps here as well.
17015 ;; Note: Can't do this as a regular split because we can't get proper
17016 ;; lifetime information then.
17018 (define_peephole2
17019   [(set (match_operand:SWI124 0 "nonimmediate_operand")
17020         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17021   "optimize_insn_for_speed_p ()
17022    && ((TARGET_NOT_UNPAIRABLE
17023         && (!MEM_P (operands[0])
17024             || !memory_displacement_operand (operands[0], <MODE>mode)))
17025        || (TARGET_NOT_VECTORMODE
17026            && long_memory_operand (operands[0], <MODE>mode)))
17027    && peep2_regno_dead_p (0, FLAGS_REG)"
17028   [(parallel [(set (match_dup 0)
17029                    (xor:SWI124 (match_dup 1) (const_int -1)))
17030               (clobber (reg:CC FLAGS_REG))])])
17032 ;; Non pairable "test imm, reg" instructions can be translated to
17033 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17034 ;; byte opcode instead of two, have a short form for byte operands),
17035 ;; so do it for other CPUs as well.  Given that the value was dead,
17036 ;; this should not create any new dependencies.  Pass on the sub-word
17037 ;; versions if we're concerned about partial register stalls.
17039 (define_peephole2
17040   [(set (match_operand 0 "flags_reg_operand")
17041         (match_operator 1 "compare_operator"
17042           [(and:SI (match_operand:SI 2 "register_operand")
17043                    (match_operand:SI 3 "immediate_operand"))
17044            (const_int 0)]))]
17045   "ix86_match_ccmode (insn, CCNOmode)
17046    && (true_regnum (operands[2]) != AX_REG
17047        || satisfies_constraint_K (operands[3]))
17048    && peep2_reg_dead_p (1, operands[2])"
17049   [(parallel
17050      [(set (match_dup 0)
17051            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17052                             (const_int 0)]))
17053       (set (match_dup 2)
17054            (and:SI (match_dup 2) (match_dup 3)))])])
17056 ;; We don't need to handle HImode case, because it will be promoted to SImode
17057 ;; on ! TARGET_PARTIAL_REG_STALL
17059 (define_peephole2
17060   [(set (match_operand 0 "flags_reg_operand")
17061         (match_operator 1 "compare_operator"
17062           [(and:QI (match_operand:QI 2 "register_operand")
17063                    (match_operand:QI 3 "immediate_operand"))
17064            (const_int 0)]))]
17065   "! TARGET_PARTIAL_REG_STALL
17066    && ix86_match_ccmode (insn, CCNOmode)
17067    && true_regnum (operands[2]) != AX_REG
17068    && peep2_reg_dead_p (1, operands[2])"
17069   [(parallel
17070      [(set (match_dup 0)
17071            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17072                             (const_int 0)]))
17073       (set (match_dup 2)
17074            (and:QI (match_dup 2) (match_dup 3)))])])
17076 (define_peephole2
17077   [(set (match_operand 0 "flags_reg_operand")
17078         (match_operator 1 "compare_operator"
17079           [(and:SI
17080              (zero_extract:SI
17081                (match_operand 2 "ext_register_operand")
17082                (const_int 8)
17083                (const_int 8))
17084              (match_operand 3 "const_int_operand"))
17085            (const_int 0)]))]
17086   "! TARGET_PARTIAL_REG_STALL
17087    && ix86_match_ccmode (insn, CCNOmode)
17088    && true_regnum (operands[2]) != AX_REG
17089    && peep2_reg_dead_p (1, operands[2])"
17090   [(parallel [(set (match_dup 0)
17091                    (match_op_dup 1
17092                      [(and:SI
17093                         (zero_extract:SI
17094                           (match_dup 2)
17095                           (const_int 8)
17096                           (const_int 8))
17097                         (match_dup 3))
17098                       (const_int 0)]))
17099               (set (zero_extract:SI (match_dup 2)
17100                                     (const_int 8)
17101                                     (const_int 8))
17102                    (and:SI
17103                      (zero_extract:SI
17104                        (match_dup 2)
17105                        (const_int 8)
17106                        (const_int 8))
17107                      (match_dup 3)))])])
17109 ;; Don't do logical operations with memory inputs.
17110 (define_peephole2
17111   [(match_scratch:SI 2 "r")
17112    (parallel [(set (match_operand:SI 0 "register_operand")
17113                    (match_operator:SI 3 "arith_or_logical_operator"
17114                      [(match_dup 0)
17115                       (match_operand:SI 1 "memory_operand")]))
17116               (clobber (reg:CC FLAGS_REG))])]
17117   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17118   [(set (match_dup 2) (match_dup 1))
17119    (parallel [(set (match_dup 0)
17120                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17121               (clobber (reg:CC FLAGS_REG))])])
17123 (define_peephole2
17124   [(match_scratch:SI 2 "r")
17125    (parallel [(set (match_operand:SI 0 "register_operand")
17126                    (match_operator:SI 3 "arith_or_logical_operator"
17127                      [(match_operand:SI 1 "memory_operand")
17128                       (match_dup 0)]))
17129               (clobber (reg:CC FLAGS_REG))])]
17130   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17131   [(set (match_dup 2) (match_dup 1))
17132    (parallel [(set (match_dup 0)
17133                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17134               (clobber (reg:CC FLAGS_REG))])])
17136 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17137 ;; refers to the destination of the load!
17139 (define_peephole2
17140   [(set (match_operand:SI 0 "register_operand")
17141         (match_operand:SI 1 "register_operand"))
17142    (parallel [(set (match_dup 0)
17143                    (match_operator:SI 3 "commutative_operator"
17144                      [(match_dup 0)
17145                       (match_operand:SI 2 "memory_operand")]))
17146               (clobber (reg:CC FLAGS_REG))])]
17147   "REGNO (operands[0]) != REGNO (operands[1])
17148    && GENERAL_REGNO_P (REGNO (operands[0]))
17149    && GENERAL_REGNO_P (REGNO (operands[1]))"
17150   [(set (match_dup 0) (match_dup 4))
17151    (parallel [(set (match_dup 0)
17152                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17153               (clobber (reg:CC FLAGS_REG))])]
17154   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17156 (define_peephole2
17157   [(set (match_operand 0 "register_operand")
17158         (match_operand 1 "register_operand"))
17159    (set (match_dup 0)
17160                    (match_operator 3 "commutative_operator"
17161                      [(match_dup 0)
17162                       (match_operand 2 "memory_operand")]))]
17163   "REGNO (operands[0]) != REGNO (operands[1])
17164    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17165        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17166   [(set (match_dup 0) (match_dup 2))
17167    (set (match_dup 0)
17168         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17170 ; Don't do logical operations with memory outputs
17172 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17173 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17174 ; the same decoder scheduling characteristics as the original.
17176 (define_peephole2
17177   [(match_scratch:SI 2 "r")
17178    (parallel [(set (match_operand:SI 0 "memory_operand")
17179                    (match_operator:SI 3 "arith_or_logical_operator"
17180                      [(match_dup 0)
17181                       (match_operand:SI 1 "nonmemory_operand")]))
17182               (clobber (reg:CC FLAGS_REG))])]
17183   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17184    /* Do not split stack checking probes.  */
17185    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17186   [(set (match_dup 2) (match_dup 0))
17187    (parallel [(set (match_dup 2)
17188                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17189               (clobber (reg:CC FLAGS_REG))])
17190    (set (match_dup 0) (match_dup 2))])
17192 (define_peephole2
17193   [(match_scratch:SI 2 "r")
17194    (parallel [(set (match_operand:SI 0 "memory_operand")
17195                    (match_operator:SI 3 "arith_or_logical_operator"
17196                      [(match_operand:SI 1 "nonmemory_operand")
17197                       (match_dup 0)]))
17198               (clobber (reg:CC FLAGS_REG))])]
17199   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17200    /* Do not split stack checking probes.  */
17201    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17202   [(set (match_dup 2) (match_dup 0))
17203    (parallel [(set (match_dup 2)
17204                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17205               (clobber (reg:CC FLAGS_REG))])
17206    (set (match_dup 0) (match_dup 2))])
17208 ;; Attempt to use arith or logical operations with memory outputs with
17209 ;; setting of flags.
17210 (define_peephole2
17211   [(set (match_operand:SWI 0 "register_operand")
17212         (match_operand:SWI 1 "memory_operand"))
17213    (parallel [(set (match_dup 0)
17214                    (match_operator:SWI 3 "plusminuslogic_operator"
17215                      [(match_dup 0)
17216                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17217               (clobber (reg:CC FLAGS_REG))])
17218    (set (match_dup 1) (match_dup 0))
17219    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17220   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17221    && peep2_reg_dead_p (4, operands[0])
17222    && !reg_overlap_mentioned_p (operands[0], operands[1])
17223    && ix86_match_ccmode (peep2_next_insn (3),
17224                          (GET_CODE (operands[3]) == PLUS
17225                           || GET_CODE (operands[3]) == MINUS)
17226                          ? CCGOCmode : CCNOmode)"
17227   [(parallel [(set (match_dup 4) (match_dup 5))
17228               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17229                                                   (match_dup 2)]))])]
17231   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17232   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17233                                 copy_rtx (operands[1]),
17234                                 copy_rtx (operands[2]));
17235   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17236                                  operands[5], const0_rtx);
17239 (define_peephole2
17240   [(parallel [(set (match_operand:SWI 0 "register_operand")
17241                    (match_operator:SWI 2 "plusminuslogic_operator"
17242                      [(match_dup 0)
17243                       (match_operand:SWI 1 "memory_operand")]))
17244               (clobber (reg:CC FLAGS_REG))])
17245    (set (match_dup 1) (match_dup 0))
17246    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17247   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17248    && GET_CODE (operands[2]) != MINUS
17249    && peep2_reg_dead_p (3, operands[0])
17250    && !reg_overlap_mentioned_p (operands[0], operands[1])
17251    && ix86_match_ccmode (peep2_next_insn (2),
17252                          GET_CODE (operands[2]) == PLUS
17253                          ? CCGOCmode : CCNOmode)"
17254   [(parallel [(set (match_dup 3) (match_dup 4))
17255               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17256                                                   (match_dup 0)]))])]
17258   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17259   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17260                                 copy_rtx (operands[1]),
17261                                 copy_rtx (operands[0]));
17262   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17263                                  operands[4], const0_rtx);
17266 (define_peephole2
17267   [(set (match_operand:SWI12 0 "register_operand")
17268         (match_operand:SWI12 1 "memory_operand"))
17269    (parallel [(set (match_operand:SI 4 "register_operand")
17270                    (match_operator:SI 3 "plusminuslogic_operator"
17271                      [(match_dup 4)
17272                       (match_operand:SI 2 "nonmemory_operand")]))
17273               (clobber (reg:CC FLAGS_REG))])
17274    (set (match_dup 1) (match_dup 0))
17275    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17276   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17277    && REG_P (operands[0]) && REG_P (operands[4])
17278    && REGNO (operands[0]) == REGNO (operands[4])
17279    && peep2_reg_dead_p (4, operands[0])
17280    && (<MODE>mode != QImode
17281        || immediate_operand (operands[2], SImode)
17282        || q_regs_operand (operands[2], SImode))
17283    && !reg_overlap_mentioned_p (operands[0], operands[1])
17284    && ix86_match_ccmode (peep2_next_insn (3),
17285                          (GET_CODE (operands[3]) == PLUS
17286                           || GET_CODE (operands[3]) == MINUS)
17287                          ? CCGOCmode : CCNOmode)"
17288   [(parallel [(set (match_dup 4) (match_dup 5))
17289               (set (match_dup 1) (match_dup 6))])]
17291   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17292   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17293   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17294                                 copy_rtx (operands[1]), operands[2]);
17295   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17296                                  operands[5], const0_rtx);
17297   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17298                                 copy_rtx (operands[1]),
17299                                 copy_rtx (operands[2]));
17302 ;; Attempt to always use XOR for zeroing registers.
17303 (define_peephole2
17304   [(set (match_operand 0 "register_operand")
17305         (match_operand 1 "const0_operand"))]
17306   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17307    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17308    && GENERAL_REG_P (operands[0])
17309    && peep2_regno_dead_p (0, FLAGS_REG)"
17310   [(parallel [(set (match_dup 0) (const_int 0))
17311               (clobber (reg:CC FLAGS_REG))])]
17312   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17314 (define_peephole2
17315   [(set (strict_low_part (match_operand 0 "register_operand"))
17316         (const_int 0))]
17317   "(GET_MODE (operands[0]) == QImode
17318     || GET_MODE (operands[0]) == HImode)
17319    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17320    && peep2_regno_dead_p (0, FLAGS_REG)"
17321   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17322               (clobber (reg:CC FLAGS_REG))])])
17324 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17325 (define_peephole2
17326   [(set (match_operand:SWI248 0 "register_operand")
17327         (const_int -1))]
17328   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17329    && peep2_regno_dead_p (0, FLAGS_REG)"
17330   [(parallel [(set (match_dup 0) (const_int -1))
17331               (clobber (reg:CC FLAGS_REG))])]
17333   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17334     operands[0] = gen_lowpart (SImode, operands[0]);
17337 ;; Attempt to convert simple lea to add/shift.
17338 ;; These can be created by move expanders.
17340 (define_peephole2
17341   [(set (match_operand:SWI48 0 "register_operand")
17342         (plus:SWI48 (match_dup 0)
17343                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17344   "peep2_regno_dead_p (0, FLAGS_REG)"
17345   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17346               (clobber (reg:CC FLAGS_REG))])])
17348 (define_peephole2
17349   [(set (match_operand:SI 0 "register_operand")
17350         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17351                             (match_operand:DI 2 "nonmemory_operand")) 0))]
17352   "TARGET_64BIT
17353    && peep2_regno_dead_p (0, FLAGS_REG)
17354    && REGNO (operands[0]) == REGNO (operands[1])"
17355   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17356               (clobber (reg:CC FLAGS_REG))])]
17357   "operands[2] = gen_lowpart (SImode, operands[2]);")
17359 (define_peephole2
17360   [(set (match_operand:SWI48 0 "register_operand")
17361         (mult:SWI48 (match_dup 0)
17362                     (match_operand:SWI48 1 "const_int_operand")))]
17363   "exact_log2 (INTVAL (operands[1])) >= 0
17364    && peep2_regno_dead_p (0, FLAGS_REG)"
17365   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17366               (clobber (reg:CC FLAGS_REG))])]
17367   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17369 (define_peephole2
17370   [(set (match_operand:SI 0 "register_operand")
17371         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17372                    (match_operand:DI 2 "const_int_operand")) 0))]
17373   "TARGET_64BIT
17374    && exact_log2 (INTVAL (operands[2])) >= 0
17375    && REGNO (operands[0]) == REGNO (operands[1])
17376    && peep2_regno_dead_p (0, FLAGS_REG)"
17377   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17378               (clobber (reg:CC FLAGS_REG))])]
17379   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17381 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17382 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17383 ;; On many CPUs it is also faster, since special hardware to avoid esp
17384 ;; dependencies is present.
17386 ;; While some of these conversions may be done using splitters, we use
17387 ;; peepholes in order to allow combine_stack_adjustments pass to see
17388 ;; nonobfuscated RTL.
17390 ;; Convert prologue esp subtractions to push.
17391 ;; We need register to push.  In order to keep verify_flow_info happy we have
17392 ;; two choices
17393 ;; - use scratch and clobber it in order to avoid dependencies
17394 ;; - use already live register
17395 ;; We can't use the second way right now, since there is no reliable way how to
17396 ;; verify that given register is live.  First choice will also most likely in
17397 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17398 ;; call clobbered registers are dead.  We may want to use base pointer as an
17399 ;; alternative when no register is available later.
17401 (define_peephole2
17402   [(match_scratch:W 1 "r")
17403    (parallel [(set (reg:P SP_REG)
17404                    (plus:P (reg:P SP_REG)
17405                            (match_operand:P 0 "const_int_operand")))
17406               (clobber (reg:CC FLAGS_REG))
17407               (clobber (mem:BLK (scratch)))])]
17408   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17409    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17410   [(clobber (match_dup 1))
17411    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17412               (clobber (mem:BLK (scratch)))])])
17414 (define_peephole2
17415   [(match_scratch:W 1 "r")
17416    (parallel [(set (reg:P SP_REG)
17417                    (plus:P (reg:P SP_REG)
17418                            (match_operand:P 0 "const_int_operand")))
17419               (clobber (reg:CC FLAGS_REG))
17420               (clobber (mem:BLK (scratch)))])]
17421   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17422    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17423   [(clobber (match_dup 1))
17424    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17425    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17426               (clobber (mem:BLK (scratch)))])])
17428 ;; Convert esp subtractions to push.
17429 (define_peephole2
17430   [(match_scratch:W 1 "r")
17431    (parallel [(set (reg:P SP_REG)
17432                    (plus:P (reg:P SP_REG)
17433                            (match_operand:P 0 "const_int_operand")))
17434               (clobber (reg:CC FLAGS_REG))])]
17435   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17436    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17437   [(clobber (match_dup 1))
17438    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17440 (define_peephole2
17441   [(match_scratch:W 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_DOUBLE_PUSH || optimize_insn_for_size_p ())
17447    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17448   [(clobber (match_dup 1))
17449    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17450    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17452 ;; Convert epilogue deallocator to pop.
17453 (define_peephole2
17454   [(match_scratch:W 1 "r")
17455    (parallel [(set (reg:P SP_REG)
17456                    (plus:P (reg:P SP_REG)
17457                            (match_operand:P 0 "const_int_operand")))
17458               (clobber (reg:CC FLAGS_REG))
17459               (clobber (mem:BLK (scratch)))])]
17460   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17461    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17462   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17463               (clobber (mem:BLK (scratch)))])])
17465 ;; Two pops case is tricky, since pop causes dependency
17466 ;; on destination register.  We use two registers if available.
17467 (define_peephole2
17468   [(match_scratch:W 1 "r")
17469    (match_scratch:W 2 "r")
17470    (parallel [(set (reg:P SP_REG)
17471                    (plus:P (reg:P SP_REG)
17472                            (match_operand:P 0 "const_int_operand")))
17473               (clobber (reg:CC FLAGS_REG))
17474               (clobber (mem:BLK (scratch)))])]
17475   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17476    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17477   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17478               (clobber (mem:BLK (scratch)))])
17479    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17481 (define_peephole2
17482   [(match_scratch:W 1 "r")
17483    (parallel [(set (reg:P SP_REG)
17484                    (plus:P (reg:P SP_REG)
17485                            (match_operand:P 0 "const_int_operand")))
17486               (clobber (reg:CC FLAGS_REG))
17487               (clobber (mem:BLK (scratch)))])]
17488   "optimize_insn_for_size_p ()
17489    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17490   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17491               (clobber (mem:BLK (scratch)))])
17492    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17494 ;; Convert esp additions to pop.
17495 (define_peephole2
17496   [(match_scratch:W 1 "r")
17497    (parallel [(set (reg:P SP_REG)
17498                    (plus:P (reg:P SP_REG)
17499                            (match_operand:P 0 "const_int_operand")))
17500               (clobber (reg:CC FLAGS_REG))])]
17501   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17502   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17504 ;; Two pops case is tricky, since pop causes dependency
17505 ;; on destination register.  We use two registers if available.
17506 (define_peephole2
17507   [(match_scratch:W 1 "r")
17508    (match_scratch:W 2 "r")
17509    (parallel [(set (reg:P SP_REG)
17510                    (plus:P (reg:P SP_REG)
17511                            (match_operand:P 0 "const_int_operand")))
17512               (clobber (reg:CC FLAGS_REG))])]
17513   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17514   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17515    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17517 (define_peephole2
17518   [(match_scratch:W 1 "r")
17519    (parallel [(set (reg:P SP_REG)
17520                    (plus:P (reg:P SP_REG)
17521                            (match_operand:P 0 "const_int_operand")))
17522               (clobber (reg:CC FLAGS_REG))])]
17523   "optimize_insn_for_size_p ()
17524    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17525   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17526    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17528 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17529 ;; required and register dies.  Similarly for 128 to -128.
17530 (define_peephole2
17531   [(set (match_operand 0 "flags_reg_operand")
17532         (match_operator 1 "compare_operator"
17533           [(match_operand 2 "register_operand")
17534            (match_operand 3 "const_int_operand")]))]
17535   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17536      && incdec_operand (operands[3], GET_MODE (operands[3])))
17537     || (!TARGET_FUSE_CMP_AND_BRANCH
17538         && INTVAL (operands[3]) == 128))
17539    && ix86_match_ccmode (insn, CCGCmode)
17540    && peep2_reg_dead_p (1, operands[2])"
17541   [(parallel [(set (match_dup 0)
17542                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17543               (clobber (match_dup 2))])])
17545 ;; Convert imul by three, five and nine into lea
17546 (define_peephole2
17547   [(parallel
17548     [(set (match_operand:SWI48 0 "register_operand")
17549           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17550                       (match_operand:SWI48 2 "const359_operand")))
17551      (clobber (reg:CC FLAGS_REG))])]
17552   "!TARGET_PARTIAL_REG_STALL
17553    || <MODE>mode == SImode
17554    || optimize_function_for_size_p (cfun)"
17555   [(set (match_dup 0)
17556         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17557                     (match_dup 1)))]
17558   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17560 (define_peephole2
17561   [(parallel
17562     [(set (match_operand:SWI48 0 "register_operand")
17563           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17564                       (match_operand:SWI48 2 "const359_operand")))
17565      (clobber (reg:CC FLAGS_REG))])]
17566   "optimize_insn_for_speed_p ()
17567    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17568   [(set (match_dup 0) (match_dup 1))
17569    (set (match_dup 0)
17570         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17571                     (match_dup 0)))]
17572   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17574 ;; imul $32bit_imm, mem, reg is vector decoded, while
17575 ;; imul $32bit_imm, reg, reg is direct decoded.
17576 (define_peephole2
17577   [(match_scratch:SWI48 3 "r")
17578    (parallel [(set (match_operand:SWI48 0 "register_operand")
17579                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17580                                (match_operand:SWI48 2 "immediate_operand")))
17581               (clobber (reg:CC FLAGS_REG))])]
17582   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17583    && !satisfies_constraint_K (operands[2])"
17584   [(set (match_dup 3) (match_dup 1))
17585    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17586               (clobber (reg:CC FLAGS_REG))])])
17588 (define_peephole2
17589   [(match_scratch:SI 3 "r")
17590    (parallel [(set (match_operand:DI 0 "register_operand")
17591                    (zero_extend:DI
17592                      (mult:SI (match_operand:SI 1 "memory_operand")
17593                               (match_operand:SI 2 "immediate_operand"))))
17594               (clobber (reg:CC FLAGS_REG))])]
17595   "TARGET_64BIT
17596    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17597    && !satisfies_constraint_K (operands[2])"
17598   [(set (match_dup 3) (match_dup 1))
17599    (parallel [(set (match_dup 0)
17600                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17601               (clobber (reg:CC FLAGS_REG))])])
17603 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17604 ;; Convert it into imul reg, reg
17605 ;; It would be better to force assembler to encode instruction using long
17606 ;; immediate, but there is apparently no way to do so.
17607 (define_peephole2
17608   [(parallel [(set (match_operand:SWI248 0 "register_operand")
17609                    (mult:SWI248
17610                     (match_operand:SWI248 1 "nonimmediate_operand")
17611                     (match_operand:SWI248 2 "const_int_operand")))
17612               (clobber (reg:CC FLAGS_REG))])
17613    (match_scratch:SWI248 3 "r")]
17614   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17615    && satisfies_constraint_K (operands[2])"
17616   [(set (match_dup 3) (match_dup 2))
17617    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17618               (clobber (reg:CC FLAGS_REG))])]
17620   if (!rtx_equal_p (operands[0], operands[1]))
17621     emit_move_insn (operands[0], operands[1]);
17624 ;; After splitting up read-modify operations, array accesses with memory
17625 ;; operands might end up in form:
17626 ;;  sall    $2, %eax
17627 ;;  movl    4(%esp), %edx
17628 ;;  addl    %edx, %eax
17629 ;; instead of pre-splitting:
17630 ;;  sall    $2, %eax
17631 ;;  addl    4(%esp), %eax
17632 ;; Turn it into:
17633 ;;  movl    4(%esp), %edx
17634 ;;  leal    (%edx,%eax,4), %eax
17636 (define_peephole2
17637   [(match_scratch:W 5 "r")
17638    (parallel [(set (match_operand 0 "register_operand")
17639                    (ashift (match_operand 1 "register_operand")
17640                            (match_operand 2 "const_int_operand")))
17641                (clobber (reg:CC FLAGS_REG))])
17642    (parallel [(set (match_operand 3 "register_operand")
17643                    (plus (match_dup 0)
17644                          (match_operand 4 "x86_64_general_operand")))
17645                    (clobber (reg:CC FLAGS_REG))])]
17646   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17647    /* Validate MODE for lea.  */
17648    && ((!TARGET_PARTIAL_REG_STALL
17649         && (GET_MODE (operands[0]) == QImode
17650             || GET_MODE (operands[0]) == HImode))
17651        || GET_MODE (operands[0]) == SImode
17652        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17653    && (rtx_equal_p (operands[0], operands[3])
17654        || peep2_reg_dead_p (2, operands[0]))
17655    /* We reorder load and the shift.  */
17656    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17657   [(set (match_dup 5) (match_dup 4))
17658    (set (match_dup 0) (match_dup 1))]
17660   enum machine_mode op1mode = GET_MODE (operands[1]);
17661   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17662   int scale = 1 << INTVAL (operands[2]);
17663   rtx index = gen_lowpart (word_mode, operands[1]);
17664   rtx base = gen_lowpart (word_mode, operands[5]);
17665   rtx dest = gen_lowpart (mode, operands[3]);
17667   operands[1] = gen_rtx_PLUS (word_mode, base,
17668                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17669   operands[5] = base;
17670   if (mode != word_mode)
17671     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17672   if (op1mode != word_mode)
17673     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17674   operands[0] = dest;
17677 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17678 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17679 ;; caught for use by garbage collectors and the like.  Using an insn that
17680 ;; maps to SIGILL makes it more likely the program will rightfully die.
17681 ;; Keeping with tradition, "6" is in honor of #UD.
17682 (define_insn "trap"
17683   [(trap_if (const_int 1) (const_int 6))]
17684   ""
17685   { return ASM_SHORT "0x0b0f"; }
17686   [(set_attr "length" "2")])
17688 (define_expand "prefetch"
17689   [(prefetch (match_operand 0 "address_operand")
17690              (match_operand:SI 1 "const_int_operand")
17691              (match_operand:SI 2 "const_int_operand"))]
17692   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17694   int rw = INTVAL (operands[1]);
17695   int locality = INTVAL (operands[2]);
17697   gcc_assert (rw == 0 || rw == 1);
17698   gcc_assert (locality >= 0 && locality <= 3);
17699   gcc_assert (GET_MODE (operands[0]) == Pmode
17700               || GET_MODE (operands[0]) == VOIDmode);
17702   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17703      supported by SSE counterpart or the SSE prefetch is not available
17704      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17705      of locality.  */
17706   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17707     operands[2] = GEN_INT (3);
17708   else
17709     operands[1] = const0_rtx;
17712 (define_insn "*prefetch_sse_<mode>"
17713   [(prefetch (match_operand:P 0 "address_operand" "p")
17714              (const_int 0)
17715              (match_operand:SI 1 "const_int_operand"))]
17716   "TARGET_PREFETCH_SSE"
17718   static const char * const patterns[4] = {
17719    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17720   };
17722   int locality = INTVAL (operands[1]);
17723   gcc_assert (locality >= 0 && locality <= 3);
17725   return patterns[locality];
17727   [(set_attr "type" "sse")
17728    (set_attr "atom_sse_attr" "prefetch")
17729    (set (attr "length_address")
17730         (symbol_ref "memory_address_length (operands[0])"))
17731    (set_attr "memory" "none")])
17733 (define_insn "*prefetch_3dnow_<mode>"
17734   [(prefetch (match_operand:P 0 "address_operand" "p")
17735              (match_operand:SI 1 "const_int_operand" "n")
17736              (const_int 3))]
17737   "TARGET_3DNOW"
17739   if (INTVAL (operands[1]) == 0)
17740     return "prefetch\t%a0";
17741   else
17742     return "prefetchw\t%a0";
17744   [(set_attr "type" "mmx")
17745    (set (attr "length_address")
17746         (symbol_ref "memory_address_length (operands[0])"))
17747    (set_attr "memory" "none")])
17749 (define_expand "stack_protect_set"
17750   [(match_operand 0 "memory_operand")
17751    (match_operand 1 "memory_operand")]
17752   ""
17754   rtx (*insn)(rtx, rtx);
17756 #ifdef TARGET_THREAD_SSP_OFFSET
17757   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17758   insn = (TARGET_LP64
17759           ? gen_stack_tls_protect_set_di
17760           : gen_stack_tls_protect_set_si);
17761 #else
17762   insn = (TARGET_LP64
17763           ? gen_stack_protect_set_di
17764           : gen_stack_protect_set_si);
17765 #endif
17767   emit_insn (insn (operands[0], operands[1]));
17768   DONE;
17771 (define_insn "stack_protect_set_<mode>"
17772   [(set (match_operand:PTR 0 "memory_operand" "=m")
17773         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17774                     UNSPEC_SP_SET))
17775    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17776    (clobber (reg:CC FLAGS_REG))]
17777   ""
17778   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17779   [(set_attr "type" "multi")])
17781 (define_insn "stack_tls_protect_set_<mode>"
17782   [(set (match_operand:PTR 0 "memory_operand" "=m")
17783         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17784                     UNSPEC_SP_TLS_SET))
17785    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17786    (clobber (reg:CC FLAGS_REG))]
17787   ""
17788   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17789   [(set_attr "type" "multi")])
17791 (define_expand "stack_protect_test"
17792   [(match_operand 0 "memory_operand")
17793    (match_operand 1 "memory_operand")
17794    (match_operand 2)]
17795   ""
17797   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17799   rtx (*insn)(rtx, rtx, rtx);
17801 #ifdef TARGET_THREAD_SSP_OFFSET
17802   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17803   insn = (TARGET_LP64
17804           ? gen_stack_tls_protect_test_di
17805           : gen_stack_tls_protect_test_si);
17806 #else
17807   insn = (TARGET_LP64
17808           ? gen_stack_protect_test_di
17809           : gen_stack_protect_test_si);
17810 #endif
17812   emit_insn (insn (flags, operands[0], operands[1]));
17814   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17815                                   flags, const0_rtx, operands[2]));
17816   DONE;
17819 (define_insn "stack_protect_test_<mode>"
17820   [(set (match_operand:CCZ 0 "flags_reg_operand")
17821         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17822                      (match_operand:PTR 2 "memory_operand" "m")]
17823                     UNSPEC_SP_TEST))
17824    (clobber (match_scratch:PTR 3 "=&r"))]
17825   ""
17826   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17827   [(set_attr "type" "multi")])
17829 (define_insn "stack_tls_protect_test_<mode>"
17830   [(set (match_operand:CCZ 0 "flags_reg_operand")
17831         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17832                      (match_operand:PTR 2 "const_int_operand" "i")]
17833                     UNSPEC_SP_TLS_TEST))
17834    (clobber (match_scratch:PTR 3 "=r"))]
17835   ""
17836   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17837   [(set_attr "type" "multi")])
17839 (define_insn "sse4_2_crc32<mode>"
17840   [(set (match_operand:SI 0 "register_operand" "=r")
17841         (unspec:SI
17842           [(match_operand:SI 1 "register_operand" "0")
17843            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17844           UNSPEC_CRC32))]
17845   "TARGET_SSE4_2 || TARGET_CRC32"
17846   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17847   [(set_attr "type" "sselog1")
17848    (set_attr "prefix_rep" "1")
17849    (set_attr "prefix_extra" "1")
17850    (set (attr "prefix_data16")
17851      (if_then_else (match_operand:HI 2)
17852        (const_string "1")
17853        (const_string "*")))
17854    (set (attr "prefix_rex")
17855      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17856        (const_string "1")
17857        (const_string "*")))
17858    (set_attr "mode" "SI")])
17860 (define_insn "sse4_2_crc32di"
17861   [(set (match_operand:DI 0 "register_operand" "=r")
17862         (unspec:DI
17863           [(match_operand:DI 1 "register_operand" "0")
17864            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17865           UNSPEC_CRC32))]
17866   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17867   "crc32{q}\t{%2, %0|%0, %2}"
17868   [(set_attr "type" "sselog1")
17869    (set_attr "prefix_rep" "1")
17870    (set_attr "prefix_extra" "1")
17871    (set_attr "mode" "DI")])
17873 (define_expand "rdpmc"
17874   [(match_operand:DI 0 "register_operand")
17875    (match_operand:SI 1 "register_operand")]
17876   ""
17878   rtx reg = gen_reg_rtx (DImode);
17879   rtx si;
17881   /* Force operand 1 into ECX.  */
17882   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17883   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17884   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17885                                 UNSPECV_RDPMC);
17887   if (TARGET_64BIT)
17888     {
17889       rtvec vec = rtvec_alloc (2);
17890       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17891       rtx upper = gen_reg_rtx (DImode);
17892       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17893                                         gen_rtvec (1, const0_rtx),
17894                                         UNSPECV_RDPMC);
17895       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17896       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17897       emit_insn (load);
17898       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17899                                    NULL, 1, OPTAB_DIRECT);
17900       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17901                                  OPTAB_DIRECT);
17902     }
17903   else
17904     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17905   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17906   DONE;
17909 (define_insn "*rdpmc"
17910   [(set (match_operand:DI 0 "register_operand" "=A")
17911         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17912                             UNSPECV_RDPMC))]
17913   "!TARGET_64BIT"
17914   "rdpmc"
17915   [(set_attr "type" "other")
17916    (set_attr "length" "2")])
17918 (define_insn "*rdpmc_rex64"
17919   [(set (match_operand:DI 0 "register_operand" "=a")
17920         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17921                             UNSPECV_RDPMC))
17922   (set (match_operand:DI 1 "register_operand" "=d")
17923        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17924   "TARGET_64BIT"
17925   "rdpmc"
17926   [(set_attr "type" "other")
17927    (set_attr "length" "2")])
17929 (define_expand "rdtsc"
17930   [(set (match_operand:DI 0 "register_operand")
17931         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17932   ""
17934   if (TARGET_64BIT)
17935     {
17936       rtvec vec = rtvec_alloc (2);
17937       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17938       rtx upper = gen_reg_rtx (DImode);
17939       rtx lower = gen_reg_rtx (DImode);
17940       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17941                                          gen_rtvec (1, const0_rtx),
17942                                          UNSPECV_RDTSC);
17943       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17944       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17945       emit_insn (load);
17946       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17947                                    NULL, 1, OPTAB_DIRECT);
17948       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17949                                    OPTAB_DIRECT);
17950       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17951       DONE;
17952     }
17955 (define_insn "*rdtsc"
17956   [(set (match_operand:DI 0 "register_operand" "=A")
17957         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17958   "!TARGET_64BIT"
17959   "rdtsc"
17960   [(set_attr "type" "other")
17961    (set_attr "length" "2")])
17963 (define_insn "*rdtsc_rex64"
17964   [(set (match_operand:DI 0 "register_operand" "=a")
17965         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17966    (set (match_operand:DI 1 "register_operand" "=d")
17967         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17968   "TARGET_64BIT"
17969   "rdtsc"
17970   [(set_attr "type" "other")
17971    (set_attr "length" "2")])
17973 (define_expand "rdtscp"
17974   [(match_operand:DI 0 "register_operand")
17975    (match_operand:SI 1 "memory_operand")]
17976   ""
17978   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17979                                     gen_rtvec (1, const0_rtx),
17980                                     UNSPECV_RDTSCP);
17981   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17982                                     gen_rtvec (1, const0_rtx),
17983                                     UNSPECV_RDTSCP);
17984   rtx reg = gen_reg_rtx (DImode);
17985   rtx tmp = gen_reg_rtx (SImode);
17987   if (TARGET_64BIT)
17988     {
17989       rtvec vec = rtvec_alloc (3);
17990       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17991       rtx upper = gen_reg_rtx (DImode);
17992       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17993       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17994       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17995       emit_insn (load);
17996       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17997                                    NULL, 1, OPTAB_DIRECT);
17998       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17999                                  OPTAB_DIRECT);
18000     }
18001   else
18002     {
18003       rtvec vec = rtvec_alloc (2);
18004       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18005       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18006       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18007       emit_insn (load);
18008     }
18009   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18010   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18011   DONE;
18014 (define_insn "*rdtscp"
18015   [(set (match_operand:DI 0 "register_operand" "=A")
18016         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18017    (set (match_operand:SI 1 "register_operand" "=c")
18018         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18019   "!TARGET_64BIT"
18020   "rdtscp"
18021   [(set_attr "type" "other")
18022    (set_attr "length" "3")])
18024 (define_insn "*rdtscp_rex64"
18025   [(set (match_operand:DI 0 "register_operand" "=a")
18026         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18027    (set (match_operand:DI 1 "register_operand" "=d")
18028         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18029    (set (match_operand:SI 2 "register_operand" "=c")
18030         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18031   "TARGET_64BIT"
18032   "rdtscp"
18033   [(set_attr "type" "other")
18034    (set_attr "length" "3")])
18036 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18038 ;; LWP instructions
18040 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18042 (define_expand "lwp_llwpcb"
18043   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18044                     UNSPECV_LLWP_INTRINSIC)]
18045   "TARGET_LWP")
18047 (define_insn "*lwp_llwpcb<mode>1"
18048   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18049                     UNSPECV_LLWP_INTRINSIC)]
18050   "TARGET_LWP"
18051   "llwpcb\t%0"
18052   [(set_attr "type" "lwp")
18053    (set_attr "mode" "<MODE>")
18054    (set_attr "length" "5")])
18056 (define_expand "lwp_slwpcb"
18057   [(set (match_operand 0 "register_operand" "=r")
18058         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18059   "TARGET_LWP"
18061   rtx (*insn)(rtx);
18063   insn = (Pmode == DImode
18064           ? gen_lwp_slwpcbdi
18065           : gen_lwp_slwpcbsi);
18067   emit_insn (insn (operands[0]));
18068   DONE;
18071 (define_insn "lwp_slwpcb<mode>"
18072   [(set (match_operand:P 0 "register_operand" "=r")
18073         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18074   "TARGET_LWP"
18075   "slwpcb\t%0"
18076   [(set_attr "type" "lwp")
18077    (set_attr "mode" "<MODE>")
18078    (set_attr "length" "5")])
18080 (define_expand "lwp_lwpval<mode>3"
18081   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18082                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18083                      (match_operand:SI 3 "const_int_operand" "i")]
18084                     UNSPECV_LWPVAL_INTRINSIC)]
18085   "TARGET_LWP"
18086   ;; Avoid unused variable warning.
18087   "(void) operands[0];")
18089 (define_insn "*lwp_lwpval<mode>3_1"
18090   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18091                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18092                      (match_operand:SI 2 "const_int_operand" "i")]
18093                     UNSPECV_LWPVAL_INTRINSIC)]
18094   "TARGET_LWP"
18095   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18096   [(set_attr "type" "lwp")
18097    (set_attr "mode" "<MODE>")
18098    (set (attr "length")
18099         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18101 (define_expand "lwp_lwpins<mode>3"
18102   [(set (reg:CCC FLAGS_REG)
18103         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18104                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18105                               (match_operand:SI 3 "const_int_operand" "i")]
18106                              UNSPECV_LWPINS_INTRINSIC))
18107    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18108         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18109   "TARGET_LWP")
18111 (define_insn "*lwp_lwpins<mode>3_1"
18112   [(set (reg:CCC FLAGS_REG)
18113         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18114                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18115                               (match_operand:SI 2 "const_int_operand" "i")]
18116                              UNSPECV_LWPINS_INTRINSIC))]
18117   "TARGET_LWP"
18118   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18119   [(set_attr "type" "lwp")
18120    (set_attr "mode" "<MODE>")
18121    (set (attr "length")
18122         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18124 (define_insn "rdfsbase<mode>"
18125   [(set (match_operand:SWI48 0 "register_operand" "=r")
18126         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18127   "TARGET_64BIT && TARGET_FSGSBASE"
18128   "rdfsbase %0"
18129   [(set_attr "type" "other")
18130    (set_attr "prefix_extra" "2")])
18132 (define_insn "rdgsbase<mode>"
18133   [(set (match_operand:SWI48 0 "register_operand" "=r")
18134         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18135   "TARGET_64BIT && TARGET_FSGSBASE"
18136   "rdgsbase %0"
18137   [(set_attr "type" "other")
18138    (set_attr "prefix_extra" "2")])
18140 (define_insn "wrfsbase<mode>"
18141   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18142                     UNSPECV_WRFSBASE)]
18143   "TARGET_64BIT && TARGET_FSGSBASE"
18144   "wrfsbase %0"
18145   [(set_attr "type" "other")
18146    (set_attr "prefix_extra" "2")])
18148 (define_insn "wrgsbase<mode>"
18149   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18150                     UNSPECV_WRGSBASE)]
18151   "TARGET_64BIT && TARGET_FSGSBASE"
18152   "wrgsbase %0"
18153   [(set_attr "type" "other")
18154    (set_attr "prefix_extra" "2")])
18156 (define_insn "rdrand<mode>_1"
18157   [(set (match_operand:SWI248 0 "register_operand" "=r")
18158         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18159    (set (reg:CCC FLAGS_REG)
18160         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18161   "TARGET_RDRND"
18162   "rdrand\t%0"
18163   [(set_attr "type" "other")
18164    (set_attr "prefix_extra" "1")])
18166 (define_expand "pause"
18167   [(set (match_dup 0)
18168         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18169   ""
18171   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18172   MEM_VOLATILE_P (operands[0]) = 1;
18175 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18176 ;; They have the same encoding.
18177 (define_insn "*pause"
18178   [(set (match_operand:BLK 0)
18179         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18180   ""
18181   "rep; nop"
18182   [(set_attr "length" "2")
18183    (set_attr "memory" "unknown")])
18185 (define_expand "xbegin"
18186   [(set (match_operand:SI 0 "register_operand")
18187         (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18188   "TARGET_RTM"
18190   rtx label = gen_label_rtx ();
18192   operands[1] = force_reg (SImode, constm1_rtx);
18194   emit_jump_insn (gen_xbegin_1 (operands[0], operands[1], label));
18196   emit_label (label);
18197   LABEL_NUSES (label) = 1;
18199   DONE;
18202 (define_insn "xbegin_1"
18203   [(set (pc)
18204         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18205                           (const_int 0))
18206                       (label_ref (match_operand 2))
18207                       (pc)))
18208    (set (match_operand:SI 0 "register_operand" "=a")
18209         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18210                             UNSPECV_XBEGIN))]
18211   "TARGET_RTM"
18212   "xbegin\t%l2"
18213   [(set_attr "type" "other")
18214    (set_attr "length" "6")])
18216 (define_insn "xend"
18217   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18218   "TARGET_RTM"
18219   "xend"
18220   [(set_attr "type" "other")
18221    (set_attr "length" "3")])
18223 (define_insn "xabort"
18224   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18225                     UNSPECV_XABORT)]
18226   "TARGET_RTM"
18227   "xabort\t%0"
18228   [(set_attr "type" "other")
18229    (set_attr "length" "3")])
18231 (define_expand "xtest"
18232   [(set (match_operand:QI 0 "register_operand")
18233         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18234   "TARGET_RTM"
18236   emit_insn (gen_xtest_1 ());
18238   ix86_expand_setcc (operands[0], EQ,
18239                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18240   DONE;
18243 (define_insn "xtest_1"
18244   [(set (reg:CCZ FLAGS_REG)
18245         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18246   "TARGET_RTM"
18247   "xtest"
18248   [(set_attr "type" "other")
18249    (set_attr "length" "3")])
18251 (include "mmx.md")
18252 (include "sse.md")
18253 (include "sync.md")