OSDN Git Service

0c78f92ef3a2301f5ccc3a8edb977ec69ca80f41
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; @ -- print a segment register of thread base pointer load
64
65 ;; UNSPEC usage:
66
67 (define_c_enum "unspec" [
68   ;; Relocation specifiers
69   UNSPEC_GOT
70   UNSPEC_GOTOFF
71   UNSPEC_GOTPCREL
72   UNSPEC_GOTTPOFF
73   UNSPEC_TPOFF
74   UNSPEC_NTPOFF
75   UNSPEC_DTPOFF
76   UNSPEC_GOTNTPOFF
77   UNSPEC_INDNTPOFF
78   UNSPEC_PLTOFF
79   UNSPEC_MACHOPIC_OFFSET
80   UNSPEC_PCREL
81
82   ;; Prologue support
83   UNSPEC_STACK_ALLOC
84   UNSPEC_SET_GOT
85   UNSPEC_REG_SAVE
86   UNSPEC_DEF_CFA
87   UNSPEC_SET_RIP
88   UNSPEC_SET_GOT_OFFSET
89   UNSPEC_MEMORY_BLOCKAGE
90   UNSPEC_STACK_CHECK
91
92   ;; TLS support
93   UNSPEC_TP
94   UNSPEC_TLS_GD
95   UNSPEC_TLS_LD_BASE
96   UNSPEC_TLSDESC
97   UNSPEC_TLS_IE_SUN
98
99   ;; Other random patterns
100   UNSPEC_SCAS
101   UNSPEC_FNSTSW
102   UNSPEC_SAHF
103   UNSPEC_PARITY
104   UNSPEC_FSTCW
105   UNSPEC_ADD_CARRY
106   UNSPEC_FLDCW
107   UNSPEC_REP
108   UNSPEC_LD_MPIC        ; load_macho_picbase
109   UNSPEC_TRUNC_NOOP
110   UNSPEC_DIV_ALREADY_SPLIT
111   UNSPEC_CALL_NEEDS_VZEROUPPER
112   UNSPEC_PAUSE
113
114   ;; For SSE/MMX support:
115   UNSPEC_FIX_NOTRUNC
116   UNSPEC_MASKMOV
117   UNSPEC_MOVMSK
118   UNSPEC_MOVNT
119   UNSPEC_MOVU
120   UNSPEC_RCP
121   UNSPEC_RSQRT
122   UNSPEC_SFENCE
123   UNSPEC_PFRCP
124   UNSPEC_PFRCPIT1
125   UNSPEC_PFRCPIT2
126   UNSPEC_PFRSQRT
127   UNSPEC_PFRSQIT1
128   UNSPEC_MFENCE
129   UNSPEC_LFENCE
130   UNSPEC_PSADBW
131   UNSPEC_LDDQU
132   UNSPEC_MS_TO_SYSV_CALL
133
134   ;; Generic math support
135   UNSPEC_COPYSIGN
136   UNSPEC_IEEE_MIN       ; not commutative
137   UNSPEC_IEEE_MAX       ; not commutative
138
139   ;; x87 Floating point
140   UNSPEC_SIN
141   UNSPEC_COS
142   UNSPEC_FPATAN
143   UNSPEC_FYL2X
144   UNSPEC_FYL2XP1
145   UNSPEC_FRNDINT
146   UNSPEC_FIST
147   UNSPEC_F2XM1
148   UNSPEC_TAN
149   UNSPEC_FXAM
150
151   ;; x87 Rounding
152   UNSPEC_FRNDINT_FLOOR
153   UNSPEC_FRNDINT_CEIL
154   UNSPEC_FRNDINT_TRUNC
155   UNSPEC_FRNDINT_MASK_PM
156   UNSPEC_FIST_FLOOR
157   UNSPEC_FIST_CEIL
158
159   ;; x87 Double output FP
160   UNSPEC_SINCOS_COS
161   UNSPEC_SINCOS_SIN
162   UNSPEC_XTRACT_FRACT
163   UNSPEC_XTRACT_EXP
164   UNSPEC_FSCALE_FRACT
165   UNSPEC_FSCALE_EXP
166   UNSPEC_FPREM_F
167   UNSPEC_FPREM_U
168   UNSPEC_FPREM1_F
169   UNSPEC_FPREM1_U
170
171   UNSPEC_C2_FLAG
172   UNSPEC_FXAM_MEM
173
174   ;; SSP patterns
175   UNSPEC_SP_SET
176   UNSPEC_SP_TEST
177   UNSPEC_SP_TLS_SET
178   UNSPEC_SP_TLS_TEST
179
180   ;; SSSE3
181   UNSPEC_PSHUFB
182   UNSPEC_PSIGN
183   UNSPEC_PALIGNR
184
185   ;; For SSE4A support
186   UNSPEC_EXTRQI
187   UNSPEC_EXTRQ
188   UNSPEC_INSERTQI
189   UNSPEC_INSERTQ
190
191   ;; For SSE4.1 support
192   UNSPEC_BLENDV
193   UNSPEC_INSERTPS
194   UNSPEC_DP
195   UNSPEC_MOVNTDQA
196   UNSPEC_MPSADBW
197   UNSPEC_PHMINPOSUW
198   UNSPEC_PTEST
199   UNSPEC_ROUND
200
201   ;; For SSE4.2 support
202   UNSPEC_CRC32
203   UNSPEC_PCMPESTR
204   UNSPEC_PCMPISTR
205
206   ;; For FMA4 support
207   UNSPEC_FMADDSUB
208   UNSPEC_XOP_UNSIGNED_CMP
209   UNSPEC_XOP_TRUEFALSE
210   UNSPEC_XOP_PERMUTE
211   UNSPEC_FRCZ
212
213   ;; For AES support
214   UNSPEC_AESENC
215   UNSPEC_AESENCLAST
216   UNSPEC_AESDEC
217   UNSPEC_AESDECLAST
218   UNSPEC_AESIMC
219   UNSPEC_AESKEYGENASSIST
220
221   ;; For PCLMUL support
222   UNSPEC_PCLMUL
223
224   ;; For AVX support
225   UNSPEC_PCMP
226   UNSPEC_VPERMIL
227   UNSPEC_VPERMIL2
228   UNSPEC_VPERMIL2F128
229   UNSPEC_CAST
230   UNSPEC_VTESTP
231   UNSPEC_VCVTPH2PS
232   UNSPEC_VCVTPS2PH
233
234   ;; For BMI support
235   UNSPEC_BEXTR
236
237   ;; For RDRAND support
238   UNSPEC_RDRAND
239 ])
240
241 (define_c_enum "unspecv" [
242   UNSPECV_BLOCKAGE
243   UNSPECV_STACK_PROBE
244   UNSPECV_PROBE_STACK_RANGE
245   UNSPECV_EMMS
246   UNSPECV_LDMXCSR
247   UNSPECV_STMXCSR
248   UNSPECV_FEMMS
249   UNSPECV_CLFLUSH
250   UNSPECV_ALIGN
251   UNSPECV_MONITOR
252   UNSPECV_MWAIT
253   UNSPECV_CMPXCHG
254   UNSPECV_XCHG
255   UNSPECV_LOCK
256   UNSPECV_PROLOGUE_USE
257   UNSPECV_CLD
258   UNSPECV_NOPS
259   UNSPECV_VZEROALL
260   UNSPECV_VZEROUPPER
261   UNSPECV_RDTSC
262   UNSPECV_RDTSCP
263   UNSPECV_RDPMC
264   UNSPECV_LLWP_INTRINSIC
265   UNSPECV_SLWP_INTRINSIC
266   UNSPECV_LWPVAL_INTRINSIC
267   UNSPECV_LWPINS_INTRINSIC
268   UNSPECV_RDFSBASE
269   UNSPECV_RDGSBASE
270   UNSPECV_WRFSBASE
271   UNSPECV_WRGSBASE
272   UNSPECV_SPLIT_STACK_RETURN
273 ])
274
275 ;; Constants to represent rounding modes in the ROUND instruction
276 (define_constants
277   [(ROUND_FLOOR                 0x1)
278    (ROUND_CEIL                  0x2)
279    (ROUND_TRUNC                 0x3)
280    (ROUND_MXCSR                 0x4)
281    (ROUND_NO_EXC                0x8)
282   ])
283
284 ;; Constants to represent pcomtrue/pcomfalse variants
285 (define_constants
286   [(PCOM_FALSE                  0)
287    (PCOM_TRUE                   1)
288    (COM_FALSE_S                 2)
289    (COM_FALSE_P                 3)
290    (COM_TRUE_S                  4)
291    (COM_TRUE_P                  5)
292   ])
293
294 ;; Constants used in the XOP pperm instruction
295 (define_constants
296   [(PPERM_SRC                   0x00)   /* copy source */
297    (PPERM_INVERT                0x20)   /* invert source */
298    (PPERM_REVERSE               0x40)   /* bit reverse source */
299    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
300    (PPERM_ZERO                  0x80)   /* all 0's */
301    (PPERM_ONES                  0xa0)   /* all 1's */
302    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
303    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
304    (PPERM_SRC1                  0x00)   /* use first source byte */
305    (PPERM_SRC2                  0x10)   /* use second source byte */
306    ])
307
308 ;; Registers by name.
309 (define_constants
310   [(AX_REG                       0)
311    (DX_REG                       1)
312    (CX_REG                       2)
313    (BX_REG                       3)
314    (SI_REG                       4)
315    (DI_REG                       5)
316    (BP_REG                       6)
317    (SP_REG                       7)
318    (ST0_REG                      8)
319    (ST1_REG                      9)
320    (ST2_REG                     10)
321    (ST3_REG                     11)
322    (ST4_REG                     12)
323    (ST5_REG                     13)
324    (ST6_REG                     14)
325    (ST7_REG                     15)
326    (FLAGS_REG                   17)
327    (FPSR_REG                    18)
328    (FPCR_REG                    19)
329    (XMM0_REG                    21)
330    (XMM1_REG                    22)
331    (XMM2_REG                    23)
332    (XMM3_REG                    24)
333    (XMM4_REG                    25)
334    (XMM5_REG                    26)
335    (XMM6_REG                    27)
336    (XMM7_REG                    28)
337    (MM0_REG                     29)
338    (MM1_REG                     30)
339    (MM2_REG                     31)
340    (MM3_REG                     32)
341    (MM4_REG                     33)
342    (MM5_REG                     34)
343    (MM6_REG                     35)
344    (MM7_REG                     36)
345    (R8_REG                      37)
346    (R9_REG                      38)
347    (R10_REG                     39)
348    (R11_REG                     40)
349    (R12_REG                     41)
350    (R13_REG                     42)
351    (XMM8_REG                    45)
352    (XMM9_REG                    46)
353    (XMM10_REG                   47)
354    (XMM11_REG                   48)
355    (XMM12_REG                   49)
356    (XMM13_REG                   50)
357    (XMM14_REG                   51)
358    (XMM15_REG                   52)
359   ])
360
361 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
362 ;; from i386.c.
363
364 ;; In C guard expressions, put expressions which may be compile-time
365 ;; constants first.  This allows for better optimization.  For
366 ;; example, write "TARGET_64BIT && reload_completed", not
367 ;; "reload_completed && TARGET_64BIT".
368
369 \f
370 ;; Processor type.
371 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
372                     atom,generic64,amdfam10,bdver1,bdver2,btver1"
373   (const (symbol_ref "ix86_schedule")))
374
375 ;; A basic instruction type.  Refinements due to arguments to be
376 ;; provided in other attributes.
377 (define_attr "type"
378   "other,multi,
379    alu,alu1,negnot,imov,imovx,lea,
380    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
381    icmp,test,ibr,setcc,icmov,
382    push,pop,call,callv,leave,
383    str,bitmanip,
384    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
385    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
386    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
387    ssemuladd,sse4arg,lwp,
388    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
389   (const_string "other"))
390
391 ;; Main data type used by the insn
392 (define_attr "mode"
393   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
394   (const_string "unknown"))
395
396 ;; The CPU unit operations uses.
397 (define_attr "unit" "integer,i387,sse,mmx,unknown"
398   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
399            (const_string "i387")
400          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
401                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
402                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
403            (const_string "sse")
404          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
405            (const_string "mmx")
406          (eq_attr "type" "other")
407            (const_string "unknown")]
408          (const_string "integer")))
409
410 ;; The (bounding maximum) length of an instruction immediate.
411 (define_attr "length_immediate" ""
412   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
413                           bitmanip")
414            (const_int 0)
415          (eq_attr "unit" "i387,sse,mmx")
416            (const_int 0)
417          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
418                           imul,icmp,push,pop")
419            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
420          (eq_attr "type" "imov,test")
421            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
422          (eq_attr "type" "call")
423            (if_then_else (match_operand 0 "constant_call_address_operand" "")
424              (const_int 4)
425              (const_int 0))
426          (eq_attr "type" "callv")
427            (if_then_else (match_operand 1 "constant_call_address_operand" "")
428              (const_int 4)
429              (const_int 0))
430          ;; We don't know the size before shorten_branches.  Expect
431          ;; the instruction to fit for better scheduling.
432          (eq_attr "type" "ibr")
433            (const_int 1)
434          ]
435          (symbol_ref "/* Update immediate_length and other attributes! */
436                       gcc_unreachable (),1")))
437
438 ;; The (bounding maximum) length of an instruction address.
439 (define_attr "length_address" ""
440   (cond [(eq_attr "type" "str,other,multi,fxch")
441            (const_int 0)
442          (and (eq_attr "type" "call")
443               (match_operand 0 "constant_call_address_operand" ""))
444              (const_int 0)
445          (and (eq_attr "type" "callv")
446               (match_operand 1 "constant_call_address_operand" ""))
447              (const_int 0)
448          ]
449          (symbol_ref "ix86_attr_length_address_default (insn)")))
450
451 ;; Set when length prefix is used.
452 (define_attr "prefix_data16" ""
453   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
454            (const_int 0)
455          (eq_attr "mode" "HI")
456            (const_int 1)
457          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
458            (const_int 1)
459         ]
460         (const_int 0)))
461
462 ;; Set when string REP prefix is used.
463 (define_attr "prefix_rep" ""
464   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
465            (const_int 0)
466          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
467            (const_int 1)
468         ]
469         (const_int 0)))
470
471 ;; Set when 0f opcode prefix is used.
472 (define_attr "prefix_0f" ""
473   (if_then_else
474     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
475          (eq_attr "unit" "sse,mmx"))
476     (const_int 1)
477     (const_int 0)))
478
479 ;; Set when REX opcode prefix is used.
480 (define_attr "prefix_rex" ""
481   (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
482            (const_int 0)
483          (and (eq_attr "mode" "DI")
484               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
485                    (eq_attr "unit" "!mmx")))
486            (const_int 1)
487          (and (eq_attr "mode" "QI")
488               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
489                   (const_int 0)))
490            (const_int 1)
491          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
492              (const_int 0))
493            (const_int 1)
494          (and (eq_attr "type" "imovx")
495               (match_operand:QI 1 "ext_QIreg_operand" ""))
496            (const_int 1)
497         ]
498         (const_int 0)))
499
500 ;; There are also additional prefixes in 3DNOW, SSSE3.
501 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
502 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
503 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
504 (define_attr "prefix_extra" ""
505   (cond [(eq_attr "type" "ssemuladd,sse4arg")
506            (const_int 2)
507          (eq_attr "type" "sseiadd1,ssecvt1")
508            (const_int 1)
509         ]
510         (const_int 0)))
511
512 ;; Prefix used: original, VEX or maybe VEX.
513 (define_attr "prefix" "orig,vex,maybe_vex"
514   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
515     (const_string "vex")
516     (const_string "orig")))
517
518 ;; VEX W bit is used.
519 (define_attr "prefix_vex_w" "" (const_int 0))
520
521 ;; The length of VEX prefix
522 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
523 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
524 ;; still prefix_0f 1, with prefix_extra 1.
525 (define_attr "length_vex" ""
526   (if_then_else (and (eq_attr "prefix_0f" "1")
527                      (eq_attr "prefix_extra" "0"))
528     (if_then_else (eq_attr "prefix_vex_w" "1")
529       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
530       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
531     (if_then_else (eq_attr "prefix_vex_w" "1")
532       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
533       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
534
535 ;; Set when modrm byte is used.
536 (define_attr "modrm" ""
537   (cond [(eq_attr "type" "str,leave")
538            (const_int 0)
539          (eq_attr "unit" "i387")
540            (const_int 0)
541          (and (eq_attr "type" "incdec")
542               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
543                    (ior (match_operand:SI 1 "register_operand" "")
544                         (match_operand:HI 1 "register_operand" ""))))
545            (const_int 0)
546          (and (eq_attr "type" "push")
547               (not (match_operand 1 "memory_operand" "")))
548            (const_int 0)
549          (and (eq_attr "type" "pop")
550               (not (match_operand 0 "memory_operand" "")))
551            (const_int 0)
552          (and (eq_attr "type" "imov")
553               (and (not (eq_attr "mode" "DI"))
554                    (ior (and (match_operand 0 "register_operand" "")
555                              (match_operand 1 "immediate_operand" ""))
556                         (ior (and (match_operand 0 "ax_reg_operand" "")
557                                   (match_operand 1 "memory_displacement_only_operand" ""))
558                              (and (match_operand 0 "memory_displacement_only_operand" "")
559                                   (match_operand 1 "ax_reg_operand" ""))))))
560            (const_int 0)
561          (and (eq_attr "type" "call")
562               (match_operand 0 "constant_call_address_operand" ""))
563              (const_int 0)
564          (and (eq_attr "type" "callv")
565               (match_operand 1 "constant_call_address_operand" ""))
566              (const_int 0)
567          (and (eq_attr "type" "alu,alu1,icmp,test")
568               (match_operand 0 "ax_reg_operand" ""))
569              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
570          ]
571          (const_int 1)))
572
573 ;; The (bounding maximum) length of an instruction in bytes.
574 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
575 ;; Later we may want to split them and compute proper length as for
576 ;; other insns.
577 (define_attr "length" ""
578   (cond [(eq_attr "type" "other,multi,fistp,frndint")
579            (const_int 16)
580          (eq_attr "type" "fcmp")
581            (const_int 4)
582          (eq_attr "unit" "i387")
583            (plus (const_int 2)
584                  (plus (attr "prefix_data16")
585                        (attr "length_address")))
586          (ior (eq_attr "prefix" "vex")
587               (and (eq_attr "prefix" "maybe_vex")
588                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
589            (plus (attr "length_vex")
590                  (plus (attr "length_immediate")
591                        (plus (attr "modrm")
592                              (attr "length_address"))))]
593          (plus (plus (attr "modrm")
594                      (plus (attr "prefix_0f")
595                            (plus (attr "prefix_rex")
596                                  (plus (attr "prefix_extra")
597                                        (const_int 1)))))
598                (plus (attr "prefix_rep")
599                      (plus (attr "prefix_data16")
600                            (plus (attr "length_immediate")
601                                  (attr "length_address")))))))
602
603 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
604 ;; `store' if there is a simple memory reference therein, or `unknown'
605 ;; if the instruction is complex.
606
607 (define_attr "memory" "none,load,store,both,unknown"
608   (cond [(eq_attr "type" "other,multi,str,lwp")
609            (const_string "unknown")
610          (eq_attr "type" "lea,fcmov,fpspc")
611            (const_string "none")
612          (eq_attr "type" "fistp,leave")
613            (const_string "both")
614          (eq_attr "type" "frndint")
615            (const_string "load")
616          (eq_attr "type" "push")
617            (if_then_else (match_operand 1 "memory_operand" "")
618              (const_string "both")
619              (const_string "store"))
620          (eq_attr "type" "pop")
621            (if_then_else (match_operand 0 "memory_operand" "")
622              (const_string "both")
623              (const_string "load"))
624          (eq_attr "type" "setcc")
625            (if_then_else (match_operand 0 "memory_operand" "")
626              (const_string "store")
627              (const_string "none"))
628          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
629            (if_then_else (ior (match_operand 0 "memory_operand" "")
630                               (match_operand 1 "memory_operand" ""))
631              (const_string "load")
632              (const_string "none"))
633          (eq_attr "type" "ibr")
634            (if_then_else (match_operand 0 "memory_operand" "")
635              (const_string "load")
636              (const_string "none"))
637          (eq_attr "type" "call")
638            (if_then_else (match_operand 0 "constant_call_address_operand" "")
639              (const_string "none")
640              (const_string "load"))
641          (eq_attr "type" "callv")
642            (if_then_else (match_operand 1 "constant_call_address_operand" "")
643              (const_string "none")
644              (const_string "load"))
645          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
646               (match_operand 1 "memory_operand" ""))
647            (const_string "both")
648          (and (match_operand 0 "memory_operand" "")
649               (match_operand 1 "memory_operand" ""))
650            (const_string "both")
651          (match_operand 0 "memory_operand" "")
652            (const_string "store")
653          (match_operand 1 "memory_operand" "")
654            (const_string "load")
655          (and (eq_attr "type"
656                  "!alu1,negnot,ishift1,
657                    imov,imovx,icmp,test,bitmanip,
658                    fmov,fcmp,fsgn,
659                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
660                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
661               (match_operand 2 "memory_operand" ""))
662            (const_string "load")
663          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
664               (match_operand 3 "memory_operand" ""))
665            (const_string "load")
666         ]
667         (const_string "none")))
668
669 ;; Indicates if an instruction has both an immediate and a displacement.
670
671 (define_attr "imm_disp" "false,true,unknown"
672   (cond [(eq_attr "type" "other,multi")
673            (const_string "unknown")
674          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
675               (and (match_operand 0 "memory_displacement_operand" "")
676                    (match_operand 1 "immediate_operand" "")))
677            (const_string "true")
678          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
679               (and (match_operand 0 "memory_displacement_operand" "")
680                    (match_operand 2 "immediate_operand" "")))
681            (const_string "true")
682         ]
683         (const_string "false")))
684
685 ;; Indicates if an FP operation has an integer source.
686
687 (define_attr "fp_int_src" "false,true"
688   (const_string "false"))
689
690 ;; Defines rounding mode of an FP operation.
691
692 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
693   (const_string "any"))
694
695 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
696 (define_attr "use_carry" "0,1" (const_string "0"))
697
698 ;; Define attribute to indicate unaligned ssemov insns
699 (define_attr "movu" "0,1" (const_string "0"))
700
701 ;; Used to control the "enabled" attribute on a per-instruction basis.
702 (define_attr "isa" "base,noavx,avx"
703   (const_string "base"))
704
705 (define_attr "enabled" ""
706   (cond [(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
707          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
708         ]
709         (const_int 1)))
710
711 ;; Describe a user's asm statement.
712 (define_asm_attributes
713   [(set_attr "length" "128")
714    (set_attr "type" "multi")])
715
716 (define_code_iterator plusminus [plus minus])
717
718 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
719
720 ;; Base name for define_insn
721 (define_code_attr plusminus_insn
722   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
723    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
724
725 ;; Base name for insn mnemonic.
726 (define_code_attr plusminus_mnemonic
727   [(plus "add") (ss_plus "adds") (us_plus "addus")
728    (minus "sub") (ss_minus "subs") (us_minus "subus")])
729 (define_code_attr plusminus_carry_mnemonic
730   [(plus "adc") (minus "sbb")])
731
732 ;; Mark commutative operators as such in constraints.
733 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
734                         (minus "") (ss_minus "") (us_minus "")])
735
736 ;; Mapping of signed max and min
737 (define_code_iterator smaxmin [smax smin])
738
739 ;; Mapping of unsigned max and min
740 (define_code_iterator umaxmin [umax umin])
741
742 ;; Base name for integer and FP insn mnemonic
743 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
744                               (umax "maxu") (umin "minu")])
745 (define_code_attr maxmin_float [(smax "max") (smin "min")])
746
747 ;; Mapping of logic operators
748 (define_code_iterator any_logic [and ior xor])
749 (define_code_iterator any_or [ior xor])
750
751 ;; Base name for insn mnemonic.
752 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
753
754 ;; Mapping of shift-right operators
755 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
756
757 ;; Base name for define_insn
758 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
759
760 ;; Base name for insn mnemonic.
761 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
762
763 ;; Mapping of rotate operators
764 (define_code_iterator any_rotate [rotate rotatert])
765
766 ;; Base name for define_insn
767 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
768
769 ;; Base name for insn mnemonic.
770 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
771
772 ;; Mapping of abs neg operators
773 (define_code_iterator absneg [abs neg])
774
775 ;; Base name for x87 insn mnemonic.
776 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
777
778 ;; Used in signed and unsigned widening multiplications.
779 (define_code_iterator any_extend [sign_extend zero_extend])
780
781 ;; Various insn prefixes for signed and unsigned operations.
782 (define_code_attr u [(sign_extend "") (zero_extend "u")
783                      (div "") (udiv "u")])
784 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
785
786 ;; Used in signed and unsigned divisions.
787 (define_code_iterator any_div [div udiv])
788
789 ;; Instruction prefix for signed and unsigned operations.
790 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
791                              (div "i") (udiv "")])
792
793 ;; All integer modes.
794 (define_mode_iterator SWI1248x [QI HI SI DI])
795
796 ;; All integer modes without QImode.
797 (define_mode_iterator SWI248x [HI SI DI])
798
799 ;; All integer modes without QImode and HImode.
800 (define_mode_iterator SWI48x [SI DI])
801
802 ;; All integer modes without SImode and DImode.
803 (define_mode_iterator SWI12 [QI HI])
804
805 ;; All integer modes without DImode.
806 (define_mode_iterator SWI124 [QI HI SI])
807
808 ;; All integer modes without QImode and DImode.
809 (define_mode_iterator SWI24 [HI SI])
810
811 ;; Single word integer modes.
812 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
813
814 ;; Single word integer modes without QImode.
815 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
816
817 ;; Single word integer modes without QImode and HImode.
818 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
819
820 ;; All math-dependant single and double word integer modes.
821 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
822                              (HI "TARGET_HIMODE_MATH")
823                              SI DI (TI "TARGET_64BIT")])
824
825 ;; Math-dependant single word integer modes.
826 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
827                             (HI "TARGET_HIMODE_MATH")
828                             SI (DI "TARGET_64BIT")])
829
830 ;; Math-dependant integer modes without DImode.
831 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
832                                (HI "TARGET_HIMODE_MATH")
833                                SI])
834
835 ;; Math-dependant single word integer modes without QImode.
836 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
837                                SI (DI "TARGET_64BIT")])
838
839 ;; Double word integer modes.
840 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
841                            (TI "TARGET_64BIT")])
842
843 ;; Double word integer modes as mode attribute.
844 (define_mode_attr DWI [(SI "DI") (DI "TI")])
845 (define_mode_attr dwi [(SI "di") (DI "ti")])
846
847 ;; Half mode for double word integer modes.
848 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
849                             (DI "TARGET_64BIT")])
850
851 ;; Instruction suffix for integer modes.
852 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
853
854 ;; Pointer size prefix for integer modes (Intel asm dialect)
855 (define_mode_attr iptrsize [(QI "BYTE")
856                             (HI "WORD")
857                             (SI "DWORD")
858                             (DI "QWORD")])
859
860 ;; Register class for integer modes.
861 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
862
863 ;; Immediate operand constraint for integer modes.
864 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
865
866 ;; General operand constraint for word modes.
867 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
868
869 ;; Immediate operand constraint for double integer modes.
870 (define_mode_attr di [(SI "nF") (DI "e")])
871
872 ;; Immediate operand constraint for shifts.
873 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
874
875 ;; General operand predicate for integer modes.
876 (define_mode_attr general_operand
877         [(QI "general_operand")
878          (HI "general_operand")
879          (SI "x86_64_general_operand")
880          (DI "x86_64_general_operand")
881          (TI "x86_64_general_operand")])
882
883 ;; General sign/zero extend operand predicate for integer modes.
884 (define_mode_attr general_szext_operand
885         [(QI "general_operand")
886          (HI "general_operand")
887          (SI "x86_64_szext_general_operand")
888          (DI "x86_64_szext_general_operand")])
889
890 ;; Immediate operand predicate for integer modes.
891 (define_mode_attr immediate_operand
892         [(QI "immediate_operand")
893          (HI "immediate_operand")
894          (SI "x86_64_immediate_operand")
895          (DI "x86_64_immediate_operand")])
896
897 ;; Nonmemory operand predicate for integer modes.
898 (define_mode_attr nonmemory_operand
899         [(QI "nonmemory_operand")
900          (HI "nonmemory_operand")
901          (SI "x86_64_nonmemory_operand")
902          (DI "x86_64_nonmemory_operand")])
903
904 ;; Operand predicate for shifts.
905 (define_mode_attr shift_operand
906         [(QI "nonimmediate_operand")
907          (HI "nonimmediate_operand")
908          (SI "nonimmediate_operand")
909          (DI "shiftdi_operand")
910          (TI "register_operand")])
911
912 ;; Operand predicate for shift argument.
913 (define_mode_attr shift_immediate_operand
914         [(QI "const_1_to_31_operand")
915          (HI "const_1_to_31_operand")
916          (SI "const_1_to_31_operand")
917          (DI "const_1_to_63_operand")])
918
919 ;; Input operand predicate for arithmetic left shifts.
920 (define_mode_attr ashl_input_operand
921         [(QI "nonimmediate_operand")
922          (HI "nonimmediate_operand")
923          (SI "nonimmediate_operand")
924          (DI "ashldi_input_operand")
925          (TI "reg_or_pm1_operand")])
926
927 ;; SSE and x87 SFmode and DFmode floating point modes
928 (define_mode_iterator MODEF [SF DF])
929
930 ;; All x87 floating point modes
931 (define_mode_iterator X87MODEF [SF DF XF])
932
933 ;; SSE instruction suffix for various modes
934 (define_mode_attr ssemodesuffix
935   [(SF "ss") (DF "sd")
936    (V8SF "ps") (V4DF "pd")
937    (V4SF "ps") (V2DF "pd")
938    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
939    (V8SI "si")])
940
941 ;; SSE vector suffix for floating point modes
942 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
943
944 ;; SSE vector mode corresponding to a scalar mode
945 (define_mode_attr ssevecmode
946   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
947
948 ;; Instruction suffix for REX 64bit operators.
949 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
950
951 ;; This mode iterator allows :P to be used for patterns that operate on
952 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
953 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
954 \f
955 ;; Scheduling descriptions
956
957 (include "pentium.md")
958 (include "ppro.md")
959 (include "k6.md")
960 (include "athlon.md")
961 (include "bdver1.md")
962 (include "geode.md")
963 (include "atom.md")
964 (include "core2.md")
965
966 \f
967 ;; Operand and operator predicates and constraints
968
969 (include "predicates.md")
970 (include "constraints.md")
971
972 \f
973 ;; Compare and branch/compare and store instructions.
974
975 (define_expand "cbranch<mode>4"
976   [(set (reg:CC FLAGS_REG)
977         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
978                     (match_operand:SDWIM 2 "<general_operand>" "")))
979    (set (pc) (if_then_else
980                (match_operator 0 "ordered_comparison_operator"
981                 [(reg:CC FLAGS_REG) (const_int 0)])
982                (label_ref (match_operand 3 "" ""))
983                (pc)))]
984   ""
985 {
986   if (MEM_P (operands[1]) && MEM_P (operands[2]))
987     operands[1] = force_reg (<MODE>mode, operands[1]);
988   ix86_expand_branch (GET_CODE (operands[0]),
989                       operands[1], operands[2], operands[3]);
990   DONE;
991 })
992
993 (define_expand "cstore<mode>4"
994   [(set (reg:CC FLAGS_REG)
995         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
996                     (match_operand:SWIM 3 "<general_operand>" "")))
997    (set (match_operand:QI 0 "register_operand" "")
998         (match_operator 1 "ordered_comparison_operator"
999           [(reg:CC FLAGS_REG) (const_int 0)]))]
1000   ""
1001 {
1002   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1003     operands[2] = force_reg (<MODE>mode, operands[2]);
1004   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1005                      operands[2], operands[3]);
1006   DONE;
1007 })
1008
1009 (define_expand "cmp<mode>_1"
1010   [(set (reg:CC FLAGS_REG)
1011         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
1012                     (match_operand:SWI48 1 "<general_operand>" "")))])
1013
1014 (define_insn "*cmp<mode>_ccno_1"
1015   [(set (reg FLAGS_REG)
1016         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1017                  (match_operand:SWI 1 "const0_operand" "")))]
1018   "ix86_match_ccmode (insn, CCNOmode)"
1019   "@
1020    test{<imodesuffix>}\t%0, %0
1021    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1022   [(set_attr "type" "test,icmp")
1023    (set_attr "length_immediate" "0,1")
1024    (set_attr "mode" "<MODE>")])
1025
1026 (define_insn "*cmp<mode>_1"
1027   [(set (reg FLAGS_REG)
1028         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1029                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1030   "ix86_match_ccmode (insn, CCmode)"
1031   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1032   [(set_attr "type" "icmp")
1033    (set_attr "mode" "<MODE>")])
1034
1035 (define_insn "*cmp<mode>_minus_1"
1036   [(set (reg FLAGS_REG)
1037         (compare
1038           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1039                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1040           (const_int 0)))]
1041   "ix86_match_ccmode (insn, CCGOCmode)"
1042   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1043   [(set_attr "type" "icmp")
1044    (set_attr "mode" "<MODE>")])
1045
1046 (define_insn "*cmpqi_ext_1"
1047   [(set (reg FLAGS_REG)
1048         (compare
1049           (match_operand:QI 0 "general_operand" "Qm")
1050           (subreg:QI
1051             (zero_extract:SI
1052               (match_operand 1 "ext_register_operand" "Q")
1053               (const_int 8)
1054               (const_int 8)) 0)))]
1055   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056   "cmp{b}\t{%h1, %0|%0, %h1}"
1057   [(set_attr "type" "icmp")
1058    (set_attr "mode" "QI")])
1059
1060 (define_insn "*cmpqi_ext_1_rex64"
1061   [(set (reg FLAGS_REG)
1062         (compare
1063           (match_operand:QI 0 "register_operand" "Q")
1064           (subreg:QI
1065             (zero_extract:SI
1066               (match_operand 1 "ext_register_operand" "Q")
1067               (const_int 8)
1068               (const_int 8)) 0)))]
1069   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1070   "cmp{b}\t{%h1, %0|%0, %h1}"
1071   [(set_attr "type" "icmp")
1072    (set_attr "mode" "QI")])
1073
1074 (define_insn "*cmpqi_ext_2"
1075   [(set (reg FLAGS_REG)
1076         (compare
1077           (subreg:QI
1078             (zero_extract:SI
1079               (match_operand 0 "ext_register_operand" "Q")
1080               (const_int 8)
1081               (const_int 8)) 0)
1082           (match_operand:QI 1 "const0_operand" "")))]
1083   "ix86_match_ccmode (insn, CCNOmode)"
1084   "test{b}\t%h0, %h0"
1085   [(set_attr "type" "test")
1086    (set_attr "length_immediate" "0")
1087    (set_attr "mode" "QI")])
1088
1089 (define_expand "cmpqi_ext_3"
1090   [(set (reg:CC FLAGS_REG)
1091         (compare:CC
1092           (subreg:QI
1093             (zero_extract:SI
1094               (match_operand 0 "ext_register_operand" "")
1095               (const_int 8)
1096               (const_int 8)) 0)
1097           (match_operand:QI 1 "immediate_operand" "")))])
1098
1099 (define_insn "*cmpqi_ext_3_insn"
1100   [(set (reg FLAGS_REG)
1101         (compare
1102           (subreg:QI
1103             (zero_extract:SI
1104               (match_operand 0 "ext_register_operand" "Q")
1105               (const_int 8)
1106               (const_int 8)) 0)
1107           (match_operand:QI 1 "general_operand" "Qmn")))]
1108   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1109   "cmp{b}\t{%1, %h0|%h0, %1}"
1110   [(set_attr "type" "icmp")
1111    (set_attr "modrm" "1")
1112    (set_attr "mode" "QI")])
1113
1114 (define_insn "*cmpqi_ext_3_insn_rex64"
1115   [(set (reg FLAGS_REG)
1116         (compare
1117           (subreg:QI
1118             (zero_extract:SI
1119               (match_operand 0 "ext_register_operand" "Q")
1120               (const_int 8)
1121               (const_int 8)) 0)
1122           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1123   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1124   "cmp{b}\t{%1, %h0|%h0, %1}"
1125   [(set_attr "type" "icmp")
1126    (set_attr "modrm" "1")
1127    (set_attr "mode" "QI")])
1128
1129 (define_insn "*cmpqi_ext_4"
1130   [(set (reg FLAGS_REG)
1131         (compare
1132           (subreg:QI
1133             (zero_extract:SI
1134               (match_operand 0 "ext_register_operand" "Q")
1135               (const_int 8)
1136               (const_int 8)) 0)
1137           (subreg:QI
1138             (zero_extract:SI
1139               (match_operand 1 "ext_register_operand" "Q")
1140               (const_int 8)
1141               (const_int 8)) 0)))]
1142   "ix86_match_ccmode (insn, CCmode)"
1143   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1144   [(set_attr "type" "icmp")
1145    (set_attr "mode" "QI")])
1146
1147 ;; These implement float point compares.
1148 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1149 ;; which would allow mix and match FP modes on the compares.  Which is what
1150 ;; the old patterns did, but with many more of them.
1151
1152 (define_expand "cbranchxf4"
1153   [(set (reg:CC FLAGS_REG)
1154         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1155                     (match_operand:XF 2 "nonmemory_operand" "")))
1156    (set (pc) (if_then_else
1157               (match_operator 0 "ix86_fp_comparison_operator"
1158                [(reg:CC FLAGS_REG)
1159                 (const_int 0)])
1160               (label_ref (match_operand 3 "" ""))
1161               (pc)))]
1162   "TARGET_80387"
1163 {
1164   ix86_expand_branch (GET_CODE (operands[0]),
1165                       operands[1], operands[2], operands[3]);
1166   DONE;
1167 })
1168
1169 (define_expand "cstorexf4"
1170   [(set (reg:CC FLAGS_REG)
1171         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1172                     (match_operand:XF 3 "nonmemory_operand" "")))
1173    (set (match_operand:QI 0 "register_operand" "")
1174               (match_operator 1 "ix86_fp_comparison_operator"
1175                [(reg:CC FLAGS_REG)
1176                 (const_int 0)]))]
1177   "TARGET_80387"
1178 {
1179   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1180                      operands[2], operands[3]);
1181   DONE;
1182 })
1183
1184 (define_expand "cbranch<mode>4"
1185   [(set (reg:CC FLAGS_REG)
1186         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1187                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1188    (set (pc) (if_then_else
1189               (match_operator 0 "ix86_fp_comparison_operator"
1190                [(reg:CC FLAGS_REG)
1191                 (const_int 0)])
1192               (label_ref (match_operand 3 "" ""))
1193               (pc)))]
1194   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1195 {
1196   ix86_expand_branch (GET_CODE (operands[0]),
1197                       operands[1], operands[2], operands[3]);
1198   DONE;
1199 })
1200
1201 (define_expand "cstore<mode>4"
1202   [(set (reg:CC FLAGS_REG)
1203         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1204                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1205    (set (match_operand:QI 0 "register_operand" "")
1206               (match_operator 1 "ix86_fp_comparison_operator"
1207                [(reg:CC FLAGS_REG)
1208                 (const_int 0)]))]
1209   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1210 {
1211   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212                      operands[2], operands[3]);
1213   DONE;
1214 })
1215
1216 (define_expand "cbranchcc4"
1217   [(set (pc) (if_then_else
1218               (match_operator 0 "comparison_operator"
1219                [(match_operand 1 "flags_reg_operand" "")
1220                 (match_operand 2 "const0_operand" "")])
1221               (label_ref (match_operand 3 "" ""))
1222               (pc)))]
1223   ""
1224 {
1225   ix86_expand_branch (GET_CODE (operands[0]),
1226                       operands[1], operands[2], operands[3]);
1227   DONE;
1228 })
1229
1230 (define_expand "cstorecc4"
1231   [(set (match_operand:QI 0 "register_operand" "")
1232               (match_operator 1 "comparison_operator"
1233                [(match_operand 2 "flags_reg_operand" "")
1234                 (match_operand 3 "const0_operand" "")]))]
1235   ""
1236 {
1237   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1238                      operands[2], operands[3]);
1239   DONE;
1240 })
1241
1242
1243 ;; FP compares, step 1:
1244 ;; Set the FP condition codes.
1245 ;;
1246 ;; CCFPmode     compare with exceptions
1247 ;; CCFPUmode    compare with no exceptions
1248
1249 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1250 ;; used to manage the reg stack popping would not be preserved.
1251
1252 (define_insn "*cmpfp_0"
1253   [(set (match_operand:HI 0 "register_operand" "=a")
1254         (unspec:HI
1255           [(compare:CCFP
1256              (match_operand 1 "register_operand" "f")
1257              (match_operand 2 "const0_operand" ""))]
1258         UNSPEC_FNSTSW))]
1259   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1260    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1261   "* return output_fp_compare (insn, operands, false, false);"
1262   [(set_attr "type" "multi")
1263    (set_attr "unit" "i387")
1264    (set (attr "mode")
1265      (cond [(match_operand:SF 1 "" "")
1266               (const_string "SF")
1267             (match_operand:DF 1 "" "")
1268               (const_string "DF")
1269            ]
1270            (const_string "XF")))])
1271
1272 (define_insn_and_split "*cmpfp_0_cc"
1273   [(set (reg:CCFP FLAGS_REG)
1274         (compare:CCFP
1275           (match_operand 1 "register_operand" "f")
1276           (match_operand 2 "const0_operand" "")))
1277    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1278   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1279    && TARGET_SAHF && !TARGET_CMOVE
1280    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1281   "#"
1282   "&& reload_completed"
1283   [(set (match_dup 0)
1284         (unspec:HI
1285           [(compare:CCFP (match_dup 1)(match_dup 2))]
1286         UNSPEC_FNSTSW))
1287    (set (reg:CC FLAGS_REG)
1288         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1289   ""
1290   [(set_attr "type" "multi")
1291    (set_attr "unit" "i387")
1292    (set (attr "mode")
1293      (cond [(match_operand:SF 1 "" "")
1294               (const_string "SF")
1295             (match_operand:DF 1 "" "")
1296               (const_string "DF")
1297            ]
1298            (const_string "XF")))])
1299
1300 (define_insn "*cmpfp_xf"
1301   [(set (match_operand:HI 0 "register_operand" "=a")
1302         (unspec:HI
1303           [(compare:CCFP
1304              (match_operand:XF 1 "register_operand" "f")
1305              (match_operand:XF 2 "register_operand" "f"))]
1306           UNSPEC_FNSTSW))]
1307   "TARGET_80387"
1308   "* return output_fp_compare (insn, operands, false, false);"
1309   [(set_attr "type" "multi")
1310    (set_attr "unit" "i387")
1311    (set_attr "mode" "XF")])
1312
1313 (define_insn_and_split "*cmpfp_xf_cc"
1314   [(set (reg:CCFP FLAGS_REG)
1315         (compare:CCFP
1316           (match_operand:XF 1 "register_operand" "f")
1317           (match_operand:XF 2 "register_operand" "f")))
1318    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1319   "TARGET_80387
1320    && TARGET_SAHF && !TARGET_CMOVE"
1321   "#"
1322   "&& reload_completed"
1323   [(set (match_dup 0)
1324         (unspec:HI
1325           [(compare:CCFP (match_dup 1)(match_dup 2))]
1326         UNSPEC_FNSTSW))
1327    (set (reg:CC FLAGS_REG)
1328         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1329   ""
1330   [(set_attr "type" "multi")
1331    (set_attr "unit" "i387")
1332    (set_attr "mode" "XF")])
1333
1334 (define_insn "*cmpfp_<mode>"
1335   [(set (match_operand:HI 0 "register_operand" "=a")
1336         (unspec:HI
1337           [(compare:CCFP
1338              (match_operand:MODEF 1 "register_operand" "f")
1339              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1340           UNSPEC_FNSTSW))]
1341   "TARGET_80387"
1342   "* return output_fp_compare (insn, operands, false, false);"
1343   [(set_attr "type" "multi")
1344    (set_attr "unit" "i387")
1345    (set_attr "mode" "<MODE>")])
1346
1347 (define_insn_and_split "*cmpfp_<mode>_cc"
1348   [(set (reg:CCFP FLAGS_REG)
1349         (compare:CCFP
1350           (match_operand:MODEF 1 "register_operand" "f")
1351           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1352    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1353   "TARGET_80387
1354    && TARGET_SAHF && !TARGET_CMOVE"
1355   "#"
1356   "&& reload_completed"
1357   [(set (match_dup 0)
1358         (unspec:HI
1359           [(compare:CCFP (match_dup 1)(match_dup 2))]
1360         UNSPEC_FNSTSW))
1361    (set (reg:CC FLAGS_REG)
1362         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1363   ""
1364   [(set_attr "type" "multi")
1365    (set_attr "unit" "i387")
1366    (set_attr "mode" "<MODE>")])
1367
1368 (define_insn "*cmpfp_u"
1369   [(set (match_operand:HI 0 "register_operand" "=a")
1370         (unspec:HI
1371           [(compare:CCFPU
1372              (match_operand 1 "register_operand" "f")
1373              (match_operand 2 "register_operand" "f"))]
1374           UNSPEC_FNSTSW))]
1375   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1377   "* return output_fp_compare (insn, operands, false, true);"
1378   [(set_attr "type" "multi")
1379    (set_attr "unit" "i387")
1380    (set (attr "mode")
1381      (cond [(match_operand:SF 1 "" "")
1382               (const_string "SF")
1383             (match_operand:DF 1 "" "")
1384               (const_string "DF")
1385            ]
1386            (const_string "XF")))])
1387
1388 (define_insn_and_split "*cmpfp_u_cc"
1389   [(set (reg:CCFPU FLAGS_REG)
1390         (compare:CCFPU
1391           (match_operand 1 "register_operand" "f")
1392           (match_operand 2 "register_operand" "f")))
1393    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395    && TARGET_SAHF && !TARGET_CMOVE
1396    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1397   "#"
1398   "&& reload_completed"
1399   [(set (match_dup 0)
1400         (unspec:HI
1401           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1402         UNSPEC_FNSTSW))
1403    (set (reg:CC FLAGS_REG)
1404         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1405   ""
1406   [(set_attr "type" "multi")
1407    (set_attr "unit" "i387")
1408    (set (attr "mode")
1409      (cond [(match_operand:SF 1 "" "")
1410               (const_string "SF")
1411             (match_operand:DF 1 "" "")
1412               (const_string "DF")
1413            ]
1414            (const_string "XF")))])
1415
1416 (define_insn "*cmpfp_<mode>"
1417   [(set (match_operand:HI 0 "register_operand" "=a")
1418         (unspec:HI
1419           [(compare:CCFP
1420              (match_operand 1 "register_operand" "f")
1421              (match_operator 3 "float_operator"
1422                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1423           UNSPEC_FNSTSW))]
1424   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1425    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1426    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1427   "* return output_fp_compare (insn, operands, false, false);"
1428   [(set_attr "type" "multi")
1429    (set_attr "unit" "i387")
1430    (set_attr "fp_int_src" "true")
1431    (set_attr "mode" "<MODE>")])
1432
1433 (define_insn_and_split "*cmpfp_<mode>_cc"
1434   [(set (reg:CCFP FLAGS_REG)
1435         (compare:CCFP
1436           (match_operand 1 "register_operand" "f")
1437           (match_operator 3 "float_operator"
1438             [(match_operand:SWI24 2 "memory_operand" "m")])))
1439    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1440   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1441    && TARGET_SAHF && !TARGET_CMOVE
1442    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1443    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1444   "#"
1445   "&& reload_completed"
1446   [(set (match_dup 0)
1447         (unspec:HI
1448           [(compare:CCFP
1449              (match_dup 1)
1450              (match_op_dup 3 [(match_dup 2)]))]
1451         UNSPEC_FNSTSW))
1452    (set (reg:CC FLAGS_REG)
1453         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1454   ""
1455   [(set_attr "type" "multi")
1456    (set_attr "unit" "i387")
1457    (set_attr "fp_int_src" "true")
1458    (set_attr "mode" "<MODE>")])
1459
1460 ;; FP compares, step 2
1461 ;; Move the fpsw to ax.
1462
1463 (define_insn "x86_fnstsw_1"
1464   [(set (match_operand:HI 0 "register_operand" "=a")
1465         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1466   "TARGET_80387"
1467   "fnstsw\t%0"
1468   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1469    (set_attr "mode" "SI")
1470    (set_attr "unit" "i387")])
1471
1472 ;; FP compares, step 3
1473 ;; Get ax into flags, general case.
1474
1475 (define_insn "x86_sahf_1"
1476   [(set (reg:CC FLAGS_REG)
1477         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1478                    UNSPEC_SAHF))]
1479   "TARGET_SAHF"
1480 {
1481 #ifndef HAVE_AS_IX86_SAHF
1482   if (TARGET_64BIT)
1483     return ASM_BYTE "0x9e";
1484   else
1485 #endif
1486   return "sahf";
1487 }
1488   [(set_attr "length" "1")
1489    (set_attr "athlon_decode" "vector")
1490    (set_attr "amdfam10_decode" "direct")
1491    (set_attr "bdver1_decode" "direct")
1492    (set_attr "mode" "SI")])
1493
1494 ;; Pentium Pro can do steps 1 through 3 in one go.
1495 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1496 (define_insn "*cmpfp_i_mixed"
1497   [(set (reg:CCFP FLAGS_REG)
1498         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1499                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1500   "TARGET_MIX_SSE_I387
1501    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1502    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503   "* return output_fp_compare (insn, operands, true, false);"
1504   [(set_attr "type" "fcmp,ssecomi")
1505    (set_attr "prefix" "orig,maybe_vex")
1506    (set (attr "mode")
1507      (if_then_else (match_operand:SF 1 "" "")
1508         (const_string "SF")
1509         (const_string "DF")))
1510    (set (attr "prefix_rep")
1511         (if_then_else (eq_attr "type" "ssecomi")
1512                       (const_string "0")
1513                       (const_string "*")))
1514    (set (attr "prefix_data16")
1515         (cond [(eq_attr "type" "fcmp")
1516                  (const_string "*")
1517                (eq_attr "mode" "DF")
1518                  (const_string "1")
1519               ]
1520               (const_string "0")))
1521    (set_attr "athlon_decode" "vector")
1522    (set_attr "amdfam10_decode" "direct")
1523    (set_attr "bdver1_decode" "double")])
1524
1525 (define_insn "*cmpfp_i_sse"
1526   [(set (reg:CCFP FLAGS_REG)
1527         (compare:CCFP (match_operand 0 "register_operand" "x")
1528                       (match_operand 1 "nonimmediate_operand" "xm")))]
1529   "TARGET_SSE_MATH
1530    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532   "* return output_fp_compare (insn, operands, true, false);"
1533   [(set_attr "type" "ssecomi")
1534    (set_attr "prefix" "maybe_vex")
1535    (set (attr "mode")
1536      (if_then_else (match_operand:SF 1 "" "")
1537         (const_string "SF")
1538         (const_string "DF")))
1539    (set_attr "prefix_rep" "0")
1540    (set (attr "prefix_data16")
1541         (if_then_else (eq_attr "mode" "DF")
1542                       (const_string "1")
1543                       (const_string "0")))
1544    (set_attr "athlon_decode" "vector")
1545    (set_attr "amdfam10_decode" "direct")
1546    (set_attr "bdver1_decode" "double")])
1547
1548 (define_insn "*cmpfp_i_i387"
1549   [(set (reg:CCFP FLAGS_REG)
1550         (compare:CCFP (match_operand 0 "register_operand" "f")
1551                       (match_operand 1 "register_operand" "f")))]
1552   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1553    && TARGET_CMOVE
1554    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1555    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556   "* return output_fp_compare (insn, operands, true, false);"
1557   [(set_attr "type" "fcmp")
1558    (set (attr "mode")
1559      (cond [(match_operand:SF 1 "" "")
1560               (const_string "SF")
1561             (match_operand:DF 1 "" "")
1562               (const_string "DF")
1563            ]
1564            (const_string "XF")))
1565    (set_attr "athlon_decode" "vector")
1566    (set_attr "amdfam10_decode" "direct")
1567    (set_attr "bdver1_decode" "double")])
1568
1569 (define_insn "*cmpfp_iu_mixed"
1570   [(set (reg:CCFPU FLAGS_REG)
1571         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1572                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1573   "TARGET_MIX_SSE_I387
1574    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1575    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576   "* return output_fp_compare (insn, operands, true, true);"
1577   [(set_attr "type" "fcmp,ssecomi")
1578    (set_attr "prefix" "orig,maybe_vex")
1579    (set (attr "mode")
1580      (if_then_else (match_operand:SF 1 "" "")
1581         (const_string "SF")
1582         (const_string "DF")))
1583    (set (attr "prefix_rep")
1584         (if_then_else (eq_attr "type" "ssecomi")
1585                       (const_string "0")
1586                       (const_string "*")))
1587    (set (attr "prefix_data16")
1588         (cond [(eq_attr "type" "fcmp")
1589                  (const_string "*")
1590                (eq_attr "mode" "DF")
1591                  (const_string "1")
1592               ]
1593               (const_string "0")))
1594    (set_attr "athlon_decode" "vector")
1595    (set_attr "amdfam10_decode" "direct")
1596    (set_attr "bdver1_decode" "double")])
1597
1598 (define_insn "*cmpfp_iu_sse"
1599   [(set (reg:CCFPU FLAGS_REG)
1600         (compare:CCFPU (match_operand 0 "register_operand" "x")
1601                        (match_operand 1 "nonimmediate_operand" "xm")))]
1602   "TARGET_SSE_MATH
1603    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1604    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1605   "* return output_fp_compare (insn, operands, true, true);"
1606   [(set_attr "type" "ssecomi")
1607    (set_attr "prefix" "maybe_vex")
1608    (set (attr "mode")
1609      (if_then_else (match_operand:SF 1 "" "")
1610         (const_string "SF")
1611         (const_string "DF")))
1612    (set_attr "prefix_rep" "0")
1613    (set (attr "prefix_data16")
1614         (if_then_else (eq_attr "mode" "DF")
1615                       (const_string "1")
1616                       (const_string "0")))
1617    (set_attr "athlon_decode" "vector")
1618    (set_attr "amdfam10_decode" "direct")
1619    (set_attr "bdver1_decode" "double")])
1620
1621 (define_insn "*cmpfp_iu_387"
1622   [(set (reg:CCFPU FLAGS_REG)
1623         (compare:CCFPU (match_operand 0 "register_operand" "f")
1624                        (match_operand 1 "register_operand" "f")))]
1625   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1626    && TARGET_CMOVE
1627    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1628    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1629   "* return output_fp_compare (insn, operands, true, true);"
1630   [(set_attr "type" "fcmp")
1631    (set (attr "mode")
1632      (cond [(match_operand:SF 1 "" "")
1633               (const_string "SF")
1634             (match_operand:DF 1 "" "")
1635               (const_string "DF")
1636            ]
1637            (const_string "XF")))
1638    (set_attr "athlon_decode" "vector")
1639    (set_attr "amdfam10_decode" "direct")
1640    (set_attr "bdver1_decode" "direct")])
1641 \f
1642 ;; Push/pop instructions.
1643
1644 (define_insn "*push<mode>2"
1645   [(set (match_operand:DWI 0 "push_operand" "=<")
1646         (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1647   ""
1648   "#")
1649
1650 (define_split
1651   [(set (match_operand:TI 0 "push_operand" "")
1652         (match_operand:TI 1 "general_operand" ""))]
1653   "TARGET_64BIT && reload_completed
1654    && !SSE_REG_P (operands[1])"
1655   [(const_int 0)]
1656   "ix86_split_long_move (operands); DONE;")
1657
1658 (define_insn "*pushdi2_rex64"
1659   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1660         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1661   "TARGET_64BIT"
1662   "@
1663    push{q}\t%1
1664    #"
1665   [(set_attr "type" "push,multi")
1666    (set_attr "mode" "DI")])
1667
1668 ;; Convert impossible pushes of immediate to existing instructions.
1669 ;; First try to get scratch register and go through it.  In case this
1670 ;; fails, push sign extended lower part first and then overwrite
1671 ;; upper part by 32bit move.
1672 (define_peephole2
1673   [(match_scratch:DI 2 "r")
1674    (set (match_operand:DI 0 "push_operand" "")
1675         (match_operand:DI 1 "immediate_operand" ""))]
1676   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1677    && !x86_64_immediate_operand (operands[1], DImode)"
1678   [(set (match_dup 2) (match_dup 1))
1679    (set (match_dup 0) (match_dup 2))])
1680
1681 ;; We need to define this as both peepholer and splitter for case
1682 ;; peephole2 pass is not run.
1683 ;; "&& 1" is needed to keep it from matching the previous pattern.
1684 (define_peephole2
1685   [(set (match_operand:DI 0 "push_operand" "")
1686         (match_operand:DI 1 "immediate_operand" ""))]
1687   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1688    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1689   [(set (match_dup 0) (match_dup 1))
1690    (set (match_dup 2) (match_dup 3))]
1691 {
1692   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1693
1694   operands[1] = gen_lowpart (DImode, operands[2]);
1695   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1696                                                    GEN_INT (4)));
1697 })
1698
1699 (define_split
1700   [(set (match_operand:DI 0 "push_operand" "")
1701         (match_operand:DI 1 "immediate_operand" ""))]
1702   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1703                     ? epilogue_completed : reload_completed)
1704    && !symbolic_operand (operands[1], DImode)
1705    && !x86_64_immediate_operand (operands[1], DImode)"
1706   [(set (match_dup 0) (match_dup 1))
1707    (set (match_dup 2) (match_dup 3))]
1708 {
1709   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1710
1711   operands[1] = gen_lowpart (DImode, operands[2]);
1712   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1713                                                    GEN_INT (4)));
1714 })
1715
1716 (define_split
1717   [(set (match_operand:DI 0 "push_operand" "")
1718         (match_operand:DI 1 "general_operand" ""))]
1719   "!TARGET_64BIT && reload_completed
1720    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1721   [(const_int 0)]
1722   "ix86_split_long_move (operands); DONE;")
1723
1724 (define_insn "*pushsi2"
1725   [(set (match_operand:SI 0 "push_operand" "=<")
1726         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1727   "!TARGET_64BIT"
1728   "push{l}\t%1"
1729   [(set_attr "type" "push")
1730    (set_attr "mode" "SI")])
1731
1732 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1733 ;; "push a byte/word".  But actually we use pushl, which has the effect
1734 ;; of rounding the amount pushed up to a word.
1735
1736 ;; For TARGET_64BIT we always round up to 8 bytes.
1737 (define_insn "*push<mode>2_rex64"
1738   [(set (match_operand:SWI124 0 "push_operand" "=X")
1739         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1740   "TARGET_64BIT"
1741   "push{q}\t%q1"
1742   [(set_attr "type" "push")
1743    (set_attr "mode" "DI")])
1744
1745 (define_insn "*push<mode>2"
1746   [(set (match_operand:SWI12 0 "push_operand" "=X")
1747         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1748   "!TARGET_64BIT"
1749   "push{l}\t%k1"
1750   [(set_attr "type" "push")
1751    (set_attr "mode" "SI")])
1752
1753 (define_insn "*push<mode>2_prologue"
1754   [(set (match_operand:P 0 "push_operand" "=<")
1755         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1756    (clobber (mem:BLK (scratch)))]
1757   ""
1758   "push{<imodesuffix>}\t%1"
1759   [(set_attr "type" "push")
1760    (set_attr "mode" "<MODE>")])
1761
1762 (define_insn "*pop<mode>1"
1763   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1764         (match_operand:P 1 "pop_operand" ">"))]
1765   ""
1766   "pop{<imodesuffix>}\t%0"
1767   [(set_attr "type" "pop")
1768    (set_attr "mode" "<MODE>")])
1769
1770 (define_insn "*pop<mode>1_epilogue"
1771   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1772         (match_operand:P 1 "pop_operand" ">"))
1773    (clobber (mem:BLK (scratch)))]
1774   ""
1775   "pop{<imodesuffix>}\t%0"
1776   [(set_attr "type" "pop")
1777    (set_attr "mode" "<MODE>")])
1778 \f
1779 ;; Move instructions.
1780
1781 (define_expand "movoi"
1782   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1783         (match_operand:OI 1 "general_operand" ""))]
1784   "TARGET_AVX"
1785   "ix86_expand_move (OImode, operands); DONE;")
1786
1787 (define_expand "movti"
1788   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1789         (match_operand:TI 1 "nonimmediate_operand" ""))]
1790   "TARGET_64BIT || TARGET_SSE"
1791 {
1792   if (TARGET_64BIT)
1793     ix86_expand_move (TImode, operands);
1794   else if (push_operand (operands[0], TImode))
1795     ix86_expand_push (TImode, operands[1]);
1796   else
1797     ix86_expand_vector_move (TImode, operands);
1798   DONE;
1799 })
1800
1801 ;; This expands to what emit_move_complex would generate if we didn't
1802 ;; have a movti pattern.  Having this avoids problems with reload on
1803 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1804 ;; to have around all the time.
1805 (define_expand "movcdi"
1806   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1807         (match_operand:CDI 1 "general_operand" ""))]
1808   ""
1809 {
1810   if (push_operand (operands[0], CDImode))
1811     emit_move_complex_push (CDImode, operands[0], operands[1]);
1812   else
1813     emit_move_complex_parts (operands[0], operands[1]);
1814   DONE;
1815 })
1816
1817 (define_expand "mov<mode>"
1818   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1819         (match_operand:SWI1248x 1 "general_operand" ""))]
1820   ""
1821   "ix86_expand_move (<MODE>mode, operands); DONE;")
1822
1823 (define_insn "*mov<mode>_xor"
1824   [(set (match_operand:SWI48 0 "register_operand" "=r")
1825         (match_operand:SWI48 1 "const0_operand" ""))
1826    (clobber (reg:CC FLAGS_REG))]
1827   "reload_completed"
1828   "xor{l}\t%k0, %k0"
1829   [(set_attr "type" "alu1")
1830    (set_attr "mode" "SI")
1831    (set_attr "length_immediate" "0")])
1832
1833 (define_insn "*mov<mode>_or"
1834   [(set (match_operand:SWI48 0 "register_operand" "=r")
1835         (match_operand:SWI48 1 "const_int_operand" ""))
1836    (clobber (reg:CC FLAGS_REG))]
1837   "reload_completed
1838    && operands[1] == constm1_rtx"
1839   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1840   [(set_attr "type" "alu1")
1841    (set_attr "mode" "<MODE>")
1842    (set_attr "length_immediate" "1")])
1843
1844 (define_insn "*movoi_internal_avx"
1845   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1846         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1847   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1848 {
1849   switch (which_alternative)
1850     {
1851     case 0:
1852       return standard_sse_constant_opcode (insn, operands[1]);
1853     case 1:
1854     case 2:
1855       if (misaligned_operand (operands[0], OImode)
1856           || misaligned_operand (operands[1], OImode))
1857         return "vmovdqu\t{%1, %0|%0, %1}";
1858       else
1859         return "vmovdqa\t{%1, %0|%0, %1}";
1860     default:
1861       gcc_unreachable ();
1862     }
1863 }
1864   [(set_attr "type" "sselog1,ssemov,ssemov")
1865    (set_attr "prefix" "vex")
1866    (set_attr "mode" "OI")])
1867
1868 (define_insn "*movti_internal_rex64"
1869   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1870         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1871   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1872 {
1873   switch (which_alternative)
1874     {
1875     case 0:
1876     case 1:
1877       return "#";
1878     case 2:
1879       return standard_sse_constant_opcode (insn, operands[1]);
1880     case 3:
1881     case 4:
1882       /* TDmode values are passed as TImode on the stack.  Moving them
1883          to stack may result in unaligned memory access.  */
1884       if (misaligned_operand (operands[0], TImode)
1885           || misaligned_operand (operands[1], TImode))
1886         {
1887           if (get_attr_mode (insn) == MODE_V4SF)
1888             return "%vmovups\t{%1, %0|%0, %1}";
1889           else
1890             return "%vmovdqu\t{%1, %0|%0, %1}";
1891         }
1892       else
1893         {
1894           if (get_attr_mode (insn) == MODE_V4SF)
1895             return "%vmovaps\t{%1, %0|%0, %1}";
1896           else
1897             return "%vmovdqa\t{%1, %0|%0, %1}";
1898         }
1899     default:
1900       gcc_unreachable ();
1901     }
1902 }
1903   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1904    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1905    (set (attr "mode")
1906         (cond [(eq_attr "alternative" "2,3")
1907                  (if_then_else
1908                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1909                        (const_int 0))
1910                    (const_string "V4SF")
1911                    (const_string "TI"))
1912                (eq_attr "alternative" "4")
1913                  (if_then_else
1914                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1915                             (const_int 0))
1916                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1917                             (const_int 0)))
1918                    (const_string "V4SF")
1919                    (const_string "TI"))]
1920                (const_string "DI")))])
1921
1922 (define_split
1923   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1924         (match_operand:TI 1 "general_operand" ""))]
1925   "reload_completed
1926    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1927   [(const_int 0)]
1928   "ix86_split_long_move (operands); DONE;")
1929
1930 (define_insn "*movti_internal_sse"
1931   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1932         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1933   "TARGET_SSE && !TARGET_64BIT
1934    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935 {
1936   switch (which_alternative)
1937     {
1938     case 0:
1939       return standard_sse_constant_opcode (insn, operands[1]);
1940     case 1:
1941     case 2:
1942       /* TDmode values are passed as TImode on the stack.  Moving them
1943          to stack may result in unaligned memory access.  */
1944       if (misaligned_operand (operands[0], TImode)
1945           || misaligned_operand (operands[1], TImode))
1946         {
1947           if (get_attr_mode (insn) == MODE_V4SF)
1948             return "%vmovups\t{%1, %0|%0, %1}";
1949           else
1950             return "%vmovdqu\t{%1, %0|%0, %1}";
1951         }
1952       else
1953         {
1954           if (get_attr_mode (insn) == MODE_V4SF)
1955             return "%vmovaps\t{%1, %0|%0, %1}";
1956           else
1957             return "%vmovdqa\t{%1, %0|%0, %1}";
1958         }
1959     default:
1960       gcc_unreachable ();
1961     }
1962 }
1963   [(set_attr "type" "sselog1,ssemov,ssemov")
1964    (set_attr "prefix" "maybe_vex")
1965    (set (attr "mode")
1966         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1967                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1968                         (const_int 0)))
1969                  (const_string "V4SF")
1970                (and (eq_attr "alternative" "2")
1971                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1972                         (const_int 0)))
1973                  (const_string "V4SF")]
1974               (const_string "TI")))])
1975
1976 (define_insn "*movdi_internal_rex64"
1977   [(set (match_operand:DI 0 "nonimmediate_operand"
1978           "=r,r  ,r,m ,!m,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1979         (match_operand:DI 1 "general_operand"
1980           "Z ,rem,i,re,n ,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1981   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1982 {
1983   switch (get_attr_type (insn))
1984     {
1985     case TYPE_SSECVT:
1986       if (SSE_REG_P (operands[0]))
1987         return "movq2dq\t{%1, %0|%0, %1}";
1988       else
1989         return "movdq2q\t{%1, %0|%0, %1}";
1990
1991     case TYPE_SSEMOV:
1992       if (get_attr_mode (insn) == MODE_TI)
1993         return "%vmovdqa\t{%1, %0|%0, %1}";
1994       /* Handle broken assemblers that require movd instead of movq.  */
1995       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1996         return "%vmovd\t{%1, %0|%0, %1}";
1997       else
1998         return "%vmovq\t{%1, %0|%0, %1}";
1999
2000     case TYPE_MMXMOV:
2001       /* Handle broken assemblers that require movd instead of movq.  */
2002       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2003         return "movd\t{%1, %0|%0, %1}";
2004       else
2005         return "movq\t{%1, %0|%0, %1}";
2006
2007     case TYPE_SSELOG1:
2008       return standard_sse_constant_opcode (insn, operands[1]);
2009
2010     case TYPE_MMX:
2011       return "pxor\t%0, %0";
2012
2013     case TYPE_MULTI:
2014       return "#";
2015
2016     case TYPE_LEA:
2017       return "lea{q}\t{%a1, %0|%0, %a1}";
2018
2019     default:
2020       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2021       if (get_attr_mode (insn) == MODE_SI)
2022         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2023       else if (which_alternative == 2)
2024         return "movabs{q}\t{%1, %0|%0, %1}";
2025       else
2026         return "mov{q}\t{%1, %0|%0, %1}";
2027     }
2028 }
2029   [(set (attr "type")
2030      (cond [(eq_attr "alternative" "4")
2031               (const_string "multi")
2032             (eq_attr "alternative" "5")
2033               (const_string "mmx")
2034             (eq_attr "alternative" "6,7,8,9")
2035               (const_string "mmxmov")
2036             (eq_attr "alternative" "10")
2037               (const_string "sselog1")
2038             (eq_attr "alternative" "11,12,13,14,15")
2039               (const_string "ssemov")
2040             (eq_attr "alternative" "16,17")
2041               (const_string "ssecvt")
2042             (match_operand 1 "pic_32bit_operand" "")
2043               (const_string "lea")
2044            ]
2045            (const_string "imov")))
2046    (set (attr "modrm")
2047      (if_then_else
2048        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2049          (const_string "0")
2050          (const_string "*")))
2051    (set (attr "length_immediate")
2052      (if_then_else
2053        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2054          (const_string "8")
2055          (const_string "*")))
2056    (set (attr "prefix_rex")
2057      (if_then_else (eq_attr "alternative" "8,9")
2058        (const_string "1")
2059        (const_string "*")))
2060    (set (attr "prefix_data16")
2061      (if_then_else (eq_attr "alternative" "11")
2062        (const_string "1")
2063        (const_string "*")))
2064    (set (attr "prefix")
2065      (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2066        (const_string "maybe_vex")
2067        (const_string "orig")))
2068    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2069
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it.  In case this
2072 ;; fails, move by 32bit parts.
2073 (define_peephole2
2074   [(match_scratch:DI 2 "r")
2075    (set (match_operand:DI 0 "memory_operand" "")
2076         (match_operand:DI 1 "immediate_operand" ""))]
2077   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078    && !x86_64_immediate_operand (operands[1], DImode)"
2079   [(set (match_dup 2) (match_dup 1))
2080    (set (match_dup 0) (match_dup 2))])
2081
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 ;; "&& 1" is needed to keep it from matching the previous pattern.
2085 (define_peephole2
2086   [(set (match_operand:DI 0 "memory_operand" "")
2087         (match_operand:DI 1 "immediate_operand" ""))]
2088   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090   [(set (match_dup 2) (match_dup 3))
2091    (set (match_dup 4) (match_dup 5))]
2092   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2093
2094 (define_split
2095   [(set (match_operand:DI 0 "memory_operand" "")
2096         (match_operand:DI 1 "immediate_operand" ""))]
2097   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2098                     ? epilogue_completed : reload_completed)
2099    && !symbolic_operand (operands[1], DImode)
2100    && !x86_64_immediate_operand (operands[1], DImode)"
2101   [(set (match_dup 2) (match_dup 3))
2102    (set (match_dup 4) (match_dup 5))]
2103   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2104
2105 (define_insn "*movdi_internal"
2106   [(set (match_operand:DI 0 "nonimmediate_operand"
2107           "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x,?*Y2,?*Ym")
2108         (match_operand:DI 1 "general_operand"
2109           "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m ,*Ym ,*Y2"))]
2110   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2111 {
2112   switch (get_attr_type (insn))
2113     {
2114     case TYPE_SSECVT:
2115       if (SSE_REG_P (operands[0]))
2116         return "movq2dq\t{%1, %0|%0, %1}";
2117       else
2118         return "movdq2q\t{%1, %0|%0, %1}";
2119
2120     case TYPE_SSEMOV:
2121       switch (get_attr_mode (insn))
2122         {
2123         case MODE_TI:
2124           return "%vmovdqa\t{%1, %0|%0, %1}";
2125         case MODE_DI:
2126            return "%vmovq\t{%1, %0|%0, %1}";
2127         case MODE_V4SF:
2128           return "movaps\t{%1, %0|%0, %1}";
2129         case MODE_V2SF:
2130           return "movlps\t{%1, %0|%0, %1}";
2131         default:
2132           gcc_unreachable ();
2133         }
2134
2135     case TYPE_MMXMOV:
2136       return "movq\t{%1, %0|%0, %1}";
2137
2138     case TYPE_SSELOG1:
2139       return standard_sse_constant_opcode (insn, operands[1]);
2140
2141     case TYPE_MMX:
2142       return "pxor\t%0, %0";
2143
2144     case TYPE_MULTI:
2145       return "#";
2146
2147     default:
2148       gcc_unreachable ();
2149     }
2150 }
2151   [(set (attr "isa")
2152      (if_then_else (eq_attr "alternative" "9,10,11,12")
2153        (const_string "noavx")
2154        (const_string "*")))
2155    (set (attr "type")
2156      (cond [(eq_attr "alternative" "0,1")
2157               (const_string "multi")
2158             (eq_attr "alternative" "2")
2159               (const_string "mmx")
2160             (eq_attr "alternative" "3,4")
2161               (const_string "mmxmov")
2162             (eq_attr "alternative" "5,9")
2163               (const_string "sselog1")
2164             (eq_attr "alternative" "13,14")
2165               (const_string "ssecvt")
2166            ]
2167            (const_string "ssemov")))
2168    (set (attr "prefix")
2169      (if_then_else (eq_attr "alternative" "5,6,7,8")
2170        (const_string "maybe_vex")
2171        (const_string "orig")))
2172    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2173
2174 (define_split
2175   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2176         (match_operand:DI 1 "general_operand" ""))]
2177   "!TARGET_64BIT && reload_completed
2178    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2179    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2180   [(const_int 0)]
2181   "ix86_split_long_move (operands); DONE;")
2182
2183 (define_insn "*movsi_internal"
2184   [(set (match_operand:SI 0 "nonimmediate_operand"
2185                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2186         (match_operand:SI 1 "general_operand"
2187                         "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2188   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189 {
2190   switch (get_attr_type (insn))
2191     {
2192     case TYPE_SSELOG1:
2193       return standard_sse_constant_opcode (insn, operands[1]);
2194
2195     case TYPE_SSEMOV:
2196       switch (get_attr_mode (insn))
2197         {
2198         case MODE_TI:
2199           return "%vmovdqa\t{%1, %0|%0, %1}";
2200         case MODE_V4SF:
2201           return "%vmovaps\t{%1, %0|%0, %1}";
2202         case MODE_SI:
2203           return "%vmovd\t{%1, %0|%0, %1}";
2204         case MODE_SF:
2205           return "%vmovss\t{%1, %0|%0, %1}";
2206         default:
2207           gcc_unreachable ();
2208         }
2209
2210     case TYPE_MMX:
2211       return "pxor\t%0, %0";
2212
2213     case TYPE_MMXMOV:
2214       if (get_attr_mode (insn) == MODE_DI)
2215         return "movq\t{%1, %0|%0, %1}";
2216       return "movd\t{%1, %0|%0, %1}";
2217
2218     case TYPE_LEA:
2219       return "lea{l}\t{%a1, %0|%0, %a1}";
2220
2221     default:
2222       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2223       return "mov{l}\t{%1, %0|%0, %1}";
2224     }
2225 }
2226   [(set (attr "type")
2227      (cond [(eq_attr "alternative" "2")
2228               (const_string "mmx")
2229             (eq_attr "alternative" "3,4,5")
2230               (const_string "mmxmov")
2231             (eq_attr "alternative" "6")
2232               (const_string "sselog1")
2233             (eq_attr "alternative" "7,8,9,10,11")
2234               (const_string "ssemov")
2235             (match_operand 1 "pic_32bit_operand" "")
2236               (const_string "lea")
2237            ]
2238            (const_string "imov")))
2239    (set (attr "prefix")
2240      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2241        (const_string "orig")
2242        (const_string "maybe_vex")))
2243    (set (attr "prefix_data16")
2244      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2245        (const_string "1")
2246        (const_string "*")))
2247    (set (attr "mode")
2248      (cond [(eq_attr "alternative" "2,3")
2249               (const_string "DI")
2250             (eq_attr "alternative" "6,7")
2251               (if_then_else
2252                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2253                 (const_string "V4SF")
2254                 (const_string "TI"))
2255             (and (eq_attr "alternative" "8,9,10,11")
2256                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2257               (const_string "SF")
2258            ]
2259            (const_string "SI")))])
2260
2261 (define_insn "*movhi_internal"
2262   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2263         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2264   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2265 {
2266   switch (get_attr_type (insn))
2267     {
2268     case TYPE_IMOVX:
2269       /* movzwl is faster than movw on p2 due to partial word stalls,
2270          though not as fast as an aligned movl.  */
2271       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2272     default:
2273       if (get_attr_mode (insn) == MODE_SI)
2274         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2275       else
2276         return "mov{w}\t{%1, %0|%0, %1}";
2277     }
2278 }
2279   [(set (attr "type")
2280      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2281                 (const_int 0))
2282               (const_string "imov")
2283             (and (eq_attr "alternative" "0")
2284                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2285                           (const_int 0))
2286                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2287                           (const_int 0))))
2288               (const_string "imov")
2289             (and (eq_attr "alternative" "1,2")
2290                  (match_operand:HI 1 "aligned_operand" ""))
2291               (const_string "imov")
2292             (and (ne (symbol_ref "TARGET_MOVX")
2293                      (const_int 0))
2294                  (eq_attr "alternative" "0,2"))
2295               (const_string "imovx")
2296            ]
2297            (const_string "imov")))
2298     (set (attr "mode")
2299       (cond [(eq_attr "type" "imovx")
2300                (const_string "SI")
2301              (and (eq_attr "alternative" "1,2")
2302                   (match_operand:HI 1 "aligned_operand" ""))
2303                (const_string "SI")
2304              (and (eq_attr "alternative" "0")
2305                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2306                            (const_int 0))
2307                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2308                            (const_int 0))))
2309                (const_string "SI")
2310             ]
2311             (const_string "HI")))])
2312
2313 ;; Situation is quite tricky about when to choose full sized (SImode) move
2314 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2315 ;; partial register dependency machines (such as AMD Athlon), where QImode
2316 ;; moves issue extra dependency and for partial register stalls machines
2317 ;; that don't use QImode patterns (and QImode move cause stall on the next
2318 ;; instruction).
2319 ;;
2320 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2321 ;; register stall machines with, where we use QImode instructions, since
2322 ;; partial register stall can be caused there.  Then we use movzx.
2323 (define_insn "*movqi_internal"
2324   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2325         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2326   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2327 {
2328   switch (get_attr_type (insn))
2329     {
2330     case TYPE_IMOVX:
2331       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2332       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2333     default:
2334       if (get_attr_mode (insn) == MODE_SI)
2335         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2336       else
2337         return "mov{b}\t{%1, %0|%0, %1}";
2338     }
2339 }
2340   [(set (attr "type")
2341      (cond [(and (eq_attr "alternative" "5")
2342                  (not (match_operand:QI 1 "aligned_operand" "")))
2343               (const_string "imovx")
2344             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2345                 (const_int 0))
2346               (const_string "imov")
2347             (and (eq_attr "alternative" "3")
2348                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2349                           (const_int 0))
2350                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2351                           (const_int 0))))
2352               (const_string "imov")
2353             (eq_attr "alternative" "3,5")
2354               (const_string "imovx")
2355             (and (ne (symbol_ref "TARGET_MOVX")
2356                      (const_int 0))
2357                  (eq_attr "alternative" "2"))
2358               (const_string "imovx")
2359            ]
2360            (const_string "imov")))
2361    (set (attr "mode")
2362       (cond [(eq_attr "alternative" "3,4,5")
2363                (const_string "SI")
2364              (eq_attr "alternative" "6")
2365                (const_string "QI")
2366              (eq_attr "type" "imovx")
2367                (const_string "SI")
2368              (and (eq_attr "type" "imov")
2369                   (and (eq_attr "alternative" "0,1")
2370                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2371                                 (const_int 0))
2372                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2373                                      (const_int 0))
2374                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2375                                      (const_int 0))))))
2376                (const_string "SI")
2377              ;; Avoid partial register stalls when not using QImode arithmetic
2378              (and (eq_attr "type" "imov")
2379                   (and (eq_attr "alternative" "0,1")
2380                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2381                                 (const_int 0))
2382                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2383                                 (const_int 0)))))
2384                (const_string "SI")
2385            ]
2386            (const_string "QI")))])
2387
2388 ;; Stores and loads of ax to arbitrary constant address.
2389 ;; We fake an second form of instruction to force reload to load address
2390 ;; into register when rax is not available
2391 (define_insn "*movabs<mode>_1"
2392   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2393         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2394   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2395   "@
2396    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2397    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2398   [(set_attr "type" "imov")
2399    (set_attr "modrm" "0,*")
2400    (set_attr "length_address" "8,0")
2401    (set_attr "length_immediate" "0,*")
2402    (set_attr "memory" "store")
2403    (set_attr "mode" "<MODE>")])
2404
2405 (define_insn "*movabs<mode>_2"
2406   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2407         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2408   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2409   "@
2410    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2411    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2412   [(set_attr "type" "imov")
2413    (set_attr "modrm" "0,*")
2414    (set_attr "length_address" "8,0")
2415    (set_attr "length_immediate" "0")
2416    (set_attr "memory" "load")
2417    (set_attr "mode" "<MODE>")])
2418
2419 (define_insn "*swap<mode>"
2420   [(set (match_operand:SWI48 0 "register_operand" "+r")
2421         (match_operand:SWI48 1 "register_operand" "+r"))
2422    (set (match_dup 1)
2423         (match_dup 0))]
2424   ""
2425   "xchg{<imodesuffix>}\t%1, %0"
2426   [(set_attr "type" "imov")
2427    (set_attr "mode" "<MODE>")
2428    (set_attr "pent_pair" "np")
2429    (set_attr "athlon_decode" "vector")
2430    (set_attr "amdfam10_decode" "double")
2431    (set_attr "bdver1_decode" "double")])
2432
2433 (define_insn "*swap<mode>_1"
2434   [(set (match_operand:SWI12 0 "register_operand" "+r")
2435         (match_operand:SWI12 1 "register_operand" "+r"))
2436    (set (match_dup 1)
2437         (match_dup 0))]
2438   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2439   "xchg{l}\t%k1, %k0"
2440   [(set_attr "type" "imov")
2441    (set_attr "mode" "SI")
2442    (set_attr "pent_pair" "np")
2443    (set_attr "athlon_decode" "vector")
2444    (set_attr "amdfam10_decode" "double")
2445    (set_attr "bdver1_decode" "double")])
2446
2447 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2448 ;; is disabled for AMDFAM10
2449 (define_insn "*swap<mode>_2"
2450   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2451         (match_operand:SWI12 1 "register_operand" "+<r>"))
2452    (set (match_dup 1)
2453         (match_dup 0))]
2454   "TARGET_PARTIAL_REG_STALL"
2455   "xchg{<imodesuffix>}\t%1, %0"
2456   [(set_attr "type" "imov")
2457    (set_attr "mode" "<MODE>")
2458    (set_attr "pent_pair" "np")
2459    (set_attr "athlon_decode" "vector")])
2460
2461 (define_expand "movstrict<mode>"
2462   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2463         (match_operand:SWI12 1 "general_operand" ""))]
2464   ""
2465 {
2466   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2467     FAIL;
2468   if (GET_CODE (operands[0]) == SUBREG
2469       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2470     FAIL;
2471   /* Don't generate memory->memory moves, go through a register */
2472   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2473     operands[1] = force_reg (<MODE>mode, operands[1]);
2474 })
2475
2476 (define_insn "*movstrict<mode>_1"
2477   [(set (strict_low_part
2478           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2479         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2480   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2481    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2482   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2483   [(set_attr "type" "imov")
2484    (set_attr "mode" "<MODE>")])
2485
2486 (define_insn "*movstrict<mode>_xor"
2487   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2488         (match_operand:SWI12 1 "const0_operand" ""))
2489    (clobber (reg:CC FLAGS_REG))]
2490   "reload_completed"
2491   "xor{<imodesuffix>}\t%0, %0"
2492   [(set_attr "type" "alu1")
2493    (set_attr "mode" "<MODE>")
2494    (set_attr "length_immediate" "0")])
2495
2496 (define_insn "*mov<mode>_extv_1"
2497   [(set (match_operand:SWI24 0 "register_operand" "=R")
2498         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2499                             (const_int 8)
2500                             (const_int 8)))]
2501   ""
2502   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2503   [(set_attr "type" "imovx")
2504    (set_attr "mode" "SI")])
2505
2506 (define_insn "*movqi_extv_1_rex64"
2507   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2508         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2509                          (const_int 8)
2510                          (const_int 8)))]
2511   "TARGET_64BIT"
2512 {
2513   switch (get_attr_type (insn))
2514     {
2515     case TYPE_IMOVX:
2516       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2517     default:
2518       return "mov{b}\t{%h1, %0|%0, %h1}";
2519     }
2520 }
2521   [(set (attr "type")
2522      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2523                         (ne (symbol_ref "TARGET_MOVX")
2524                             (const_int 0)))
2525         (const_string "imovx")
2526         (const_string "imov")))
2527    (set (attr "mode")
2528      (if_then_else (eq_attr "type" "imovx")
2529         (const_string "SI")
2530         (const_string "QI")))])
2531
2532 (define_insn "*movqi_extv_1"
2533   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2534         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2535                          (const_int 8)
2536                          (const_int 8)))]
2537   "!TARGET_64BIT"
2538 {
2539   switch (get_attr_type (insn))
2540     {
2541     case TYPE_IMOVX:
2542       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2543     default:
2544       return "mov{b}\t{%h1, %0|%0, %h1}";
2545     }
2546 }
2547   [(set (attr "type")
2548      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2549                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2550                              (ne (symbol_ref "TARGET_MOVX")
2551                                  (const_int 0))))
2552         (const_string "imovx")
2553         (const_string "imov")))
2554    (set (attr "mode")
2555      (if_then_else (eq_attr "type" "imovx")
2556         (const_string "SI")
2557         (const_string "QI")))])
2558
2559 (define_insn "*mov<mode>_extzv_1"
2560   [(set (match_operand:SWI48 0 "register_operand" "=R")
2561         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2562                             (const_int 8)
2563                             (const_int 8)))]
2564   ""
2565   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2566   [(set_attr "type" "imovx")
2567    (set_attr "mode" "SI")])
2568
2569 (define_insn "*movqi_extzv_2_rex64"
2570   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2571         (subreg:QI
2572           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2573                            (const_int 8)
2574                            (const_int 8)) 0))]
2575   "TARGET_64BIT"
2576 {
2577   switch (get_attr_type (insn))
2578     {
2579     case TYPE_IMOVX:
2580       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2581     default:
2582       return "mov{b}\t{%h1, %0|%0, %h1}";
2583     }
2584 }
2585   [(set (attr "type")
2586      (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2587                         (ne (symbol_ref "TARGET_MOVX")
2588                             (const_int 0)))
2589         (const_string "imovx")
2590         (const_string "imov")))
2591    (set (attr "mode")
2592      (if_then_else (eq_attr "type" "imovx")
2593         (const_string "SI")
2594         (const_string "QI")))])
2595
2596 (define_insn "*movqi_extzv_2"
2597   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2598         (subreg:QI
2599           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2600                            (const_int 8)
2601                            (const_int 8)) 0))]
2602   "!TARGET_64BIT"
2603 {
2604   switch (get_attr_type (insn))
2605     {
2606     case TYPE_IMOVX:
2607       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2608     default:
2609       return "mov{b}\t{%h1, %0|%0, %h1}";
2610     }
2611 }
2612   [(set (attr "type")
2613      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2614                         (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2615                              (ne (symbol_ref "TARGET_MOVX")
2616                                  (const_int 0))))
2617         (const_string "imovx")
2618         (const_string "imov")))
2619    (set (attr "mode")
2620      (if_then_else (eq_attr "type" "imovx")
2621         (const_string "SI")
2622         (const_string "QI")))])
2623
2624 (define_expand "mov<mode>_insv_1"
2625   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2626                             (const_int 8)
2627                             (const_int 8))
2628         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2629
2630 (define_insn "*mov<mode>_insv_1_rex64"
2631   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2632                              (const_int 8)
2633                              (const_int 8))
2634         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2635   "TARGET_64BIT"
2636   "mov{b}\t{%b1, %h0|%h0, %b1}"
2637   [(set_attr "type" "imov")
2638    (set_attr "mode" "QI")])
2639
2640 (define_insn "*movsi_insv_1"
2641   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2642                          (const_int 8)
2643                          (const_int 8))
2644         (match_operand:SI 1 "general_operand" "Qmn"))]
2645   "!TARGET_64BIT"
2646   "mov{b}\t{%b1, %h0|%h0, %b1}"
2647   [(set_attr "type" "imov")
2648    (set_attr "mode" "QI")])
2649
2650 (define_insn "*movqi_insv_2"
2651   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2652                          (const_int 8)
2653                          (const_int 8))
2654         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2655                      (const_int 8)))]
2656   ""
2657   "mov{b}\t{%h1, %h0|%h0, %h1}"
2658   [(set_attr "type" "imov")
2659    (set_attr "mode" "QI")])
2660 \f
2661 ;; Floating point push instructions.
2662
2663 (define_insn "*pushtf"
2664   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2665         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2666   "TARGET_SSE2"
2667 {
2668   /* This insn should be already split before reg-stack.  */
2669   gcc_unreachable ();
2670 }
2671   [(set_attr "type" "multi")
2672    (set_attr "unit" "sse,*,*")
2673    (set_attr "mode" "TF,SI,SI")])
2674
2675 ;; %%% Kill this when call knows how to work this out.
2676 (define_split
2677   [(set (match_operand:TF 0 "push_operand" "")
2678         (match_operand:TF 1 "sse_reg_operand" ""))]
2679   "TARGET_SSE2 && reload_completed"
2680   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2681    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2682
2683 (define_insn "*pushxf"
2684   [(set (match_operand:XF 0 "push_operand" "=<,<")
2685         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2686   "optimize_function_for_speed_p (cfun)"
2687 {
2688   /* This insn should be already split before reg-stack.  */
2689   gcc_unreachable ();
2690 }
2691   [(set_attr "type" "multi")
2692    (set_attr "unit" "i387,*")
2693    (set_attr "mode" "XF,SI")])
2694
2695 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2696 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2697 ;; Pushing using integer instructions is longer except for constants
2698 ;; and direct memory references (assuming that any given constant is pushed
2699 ;; only once, but this ought to be handled elsewhere).
2700
2701 (define_insn "*pushxf_nointeger"
2702   [(set (match_operand:XF 0 "push_operand" "=X,X")
2703         (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2704   "optimize_function_for_size_p (cfun)"
2705 {
2706   /* This insn should be already split before reg-stack.  */
2707   gcc_unreachable ();
2708 }
2709   [(set_attr "type" "multi")
2710    (set_attr "unit" "i387,*")
2711    (set_attr "mode" "XF,SI")])
2712
2713 ;; %%% Kill this when call knows how to work this out.
2714 (define_split
2715   [(set (match_operand:XF 0 "push_operand" "")
2716         (match_operand:XF 1 "fp_register_operand" ""))]
2717   "reload_completed"
2718   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2719    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2720   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2721
2722 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2723 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2724 ;; On the average, pushdf using integers can be still shorter.
2725
2726 (define_insn "*pushdf"
2727   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2728         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
2729   ""
2730 {
2731   /* This insn should be already split before reg-stack.  */
2732   gcc_unreachable ();
2733 }
2734   [(set_attr "type" "multi")
2735    (set_attr "unit" "i387,*,*")
2736    (set_attr "mode" "DF,SI,DF")])
2737
2738 ;; %%% Kill this when call knows how to work this out.
2739 (define_split
2740   [(set (match_operand:DF 0 "push_operand" "")
2741         (match_operand:DF 1 "any_fp_register_operand" ""))]
2742   "reload_completed"
2743   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2744    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2745
2746 (define_insn "*pushsf_rex64"
2747   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2748         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2749   "TARGET_64BIT"
2750 {
2751   /* Anything else should be already split before reg-stack.  */
2752   gcc_assert (which_alternative == 1);
2753   return "push{q}\t%q1";
2754 }
2755   [(set_attr "type" "multi,push,multi")
2756    (set_attr "unit" "i387,*,*")
2757    (set_attr "mode" "SF,DI,SF")])
2758
2759 (define_insn "*pushsf"
2760   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2761         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2762   "!TARGET_64BIT"
2763 {
2764   /* Anything else should be already split before reg-stack.  */
2765   gcc_assert (which_alternative == 1);
2766   return "push{l}\t%1";
2767 }
2768   [(set_attr "type" "multi,push,multi")
2769    (set_attr "unit" "i387,*,*")
2770    (set_attr "mode" "SF,SI,SF")])
2771
2772 ;; %%% Kill this when call knows how to work this out.
2773 (define_split
2774   [(set (match_operand:SF 0 "push_operand" "")
2775         (match_operand:SF 1 "any_fp_register_operand" ""))]
2776   "reload_completed"
2777   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2778    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2779   "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2780
2781 (define_split
2782   [(set (match_operand:SF 0 "push_operand" "")
2783         (match_operand:SF 1 "memory_operand" ""))]
2784   "reload_completed
2785    && (operands[2] = find_constant_src (insn))"
2786   [(set (match_dup 0) (match_dup 2))])
2787
2788 (define_split
2789   [(set (match_operand 0 "push_operand" "")
2790         (match_operand 1 "general_operand" ""))]
2791   "reload_completed
2792    && (GET_MODE (operands[0]) == TFmode
2793        || GET_MODE (operands[0]) == XFmode
2794        || GET_MODE (operands[0]) == DFmode)
2795    && !ANY_FP_REG_P (operands[1])"
2796   [(const_int 0)]
2797   "ix86_split_long_move (operands); DONE;")
2798 \f
2799 ;; Floating point move instructions.
2800
2801 (define_expand "movtf"
2802   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2803         (match_operand:TF 1 "nonimmediate_operand" ""))]
2804   "TARGET_SSE2"
2805 {
2806   ix86_expand_move (TFmode, operands);
2807   DONE;
2808 })
2809
2810 (define_expand "mov<mode>"
2811   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2812         (match_operand:X87MODEF 1 "general_operand" ""))]
2813   ""
2814   "ix86_expand_move (<MODE>mode, operands); DONE;")
2815
2816 (define_insn "*movtf_internal"
2817   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2818         (match_operand:TF 1 "general_operand"      "xm,x,C,*roF,F*r"))]
2819   "TARGET_SSE2
2820    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2821    && (!can_create_pseudo_p ()
2822        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2823        || GET_CODE (operands[1]) != CONST_DOUBLE
2824        || (optimize_function_for_size_p (cfun)
2825            && standard_sse_constant_p (operands[1])
2826            && !memory_operand (operands[0], TFmode))
2827        || (!TARGET_MEMORY_MISMATCH_STALL
2828            && memory_operand (operands[0], TFmode)))"
2829 {
2830   switch (which_alternative)
2831     {
2832     case 0:
2833     case 1:
2834       /* Handle misaligned load/store since we
2835          don't have movmisaligntf pattern. */
2836       if (misaligned_operand (operands[0], TFmode)
2837           || misaligned_operand (operands[1], TFmode))
2838         {
2839           if (get_attr_mode (insn) == MODE_V4SF)
2840             return "%vmovups\t{%1, %0|%0, %1}";
2841           else
2842             return "%vmovdqu\t{%1, %0|%0, %1}";
2843         }
2844       else
2845         {
2846           if (get_attr_mode (insn) == MODE_V4SF)
2847             return "%vmovaps\t{%1, %0|%0, %1}";
2848           else
2849             return "%vmovdqa\t{%1, %0|%0, %1}";
2850         }
2851
2852     case 2:
2853       return standard_sse_constant_opcode (insn, operands[1]);
2854
2855     case 3:
2856     case 4:
2857         return "#";
2858
2859     default:
2860       gcc_unreachable ();
2861     }
2862 }
2863   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2864    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2865    (set (attr "mode")
2866         (cond [(eq_attr "alternative" "0,2")
2867                  (if_then_else
2868                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2869                        (const_int 0))
2870                    (const_string "V4SF")
2871                    (const_string "TI"))
2872                (eq_attr "alternative" "1")
2873                  (if_then_else
2874                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2875                             (const_int 0))
2876                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2877                             (const_int 0)))
2878                    (const_string "V4SF")
2879                    (const_string "TI"))]
2880                (const_string "DI")))])
2881
2882 ;; Possible store forwarding (partial memory) stall in alternative 4.
2883 (define_insn "*movxf_internal"
2884   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2885         (match_operand:XF 1 "general_operand"      "fm,f,G,Yx*roF,FYx*r"))]
2886   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2887    && (!can_create_pseudo_p ()
2888        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889        || GET_CODE (operands[1]) != CONST_DOUBLE
2890        || (optimize_function_for_size_p (cfun)
2891            && standard_80387_constant_p (operands[1]) > 0
2892            && !memory_operand (operands[0], XFmode))
2893        || (!TARGET_MEMORY_MISMATCH_STALL
2894            && memory_operand (operands[0], XFmode)))"
2895 {
2896   switch (which_alternative)
2897     {
2898     case 0:
2899     case 1:
2900       return output_387_reg_move (insn, operands);
2901
2902     case 2:
2903       return standard_80387_constant_opcode (operands[1]);
2904
2905     case 3:
2906     case 4:
2907       return "#";
2908
2909     default:
2910       gcc_unreachable ();
2911     }
2912 }
2913   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2914    (set_attr "mode" "XF,XF,XF,SI,SI")])
2915
2916 (define_insn "*movdf_internal_rex64"
2917   [(set (match_operand:DF 0 "nonimmediate_operand"
2918                 "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2919         (match_operand:DF 1 "general_operand"
2920                 "fm,f,G,rm,r ,F ,F ,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2921   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2922    && (!can_create_pseudo_p ()
2923        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2924        || GET_CODE (operands[1]) != CONST_DOUBLE
2925        || (optimize_function_for_size_p (cfun)
2926            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2927                 && standard_80387_constant_p (operands[1]) > 0)
2928                || (TARGET_SSE2 && TARGET_SSE_MATH
2929                    && standard_sse_constant_p (operands[1]))))
2930        || memory_operand (operands[0], DFmode))"
2931 {
2932   switch (which_alternative)
2933     {
2934     case 0:
2935     case 1:
2936       return output_387_reg_move (insn, operands);
2937
2938     case 2:
2939       return standard_80387_constant_opcode (operands[1]);
2940
2941     case 3:
2942     case 4:
2943       return "mov{q}\t{%1, %0|%0, %1}";
2944
2945     case 5:
2946       return "movabs{q}\t{%1, %0|%0, %1}";
2947
2948     case 6:
2949       return "#";
2950
2951     case 7:
2952       return standard_sse_constant_opcode (insn, operands[1]);
2953
2954     case 8:
2955     case 9:
2956     case 10:
2957       switch (get_attr_mode (insn))
2958         {
2959         case MODE_V2DF:
2960           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2961             return "%vmovapd\t{%1, %0|%0, %1}";
2962         case MODE_V4SF:
2963           return "%vmovaps\t{%1, %0|%0, %1}";
2964
2965         case MODE_DI:
2966           return "%vmovq\t{%1, %0|%0, %1}";
2967         case MODE_DF:
2968           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2969             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2970           return "%vmovsd\t{%1, %0|%0, %1}";
2971         case MODE_V1DF:
2972           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2973         case MODE_V2SF:
2974           return "%vmovlps\t{%1, %d0|%d0, %1}";
2975         default:
2976           gcc_unreachable ();
2977         }
2978
2979     case 11:
2980     case 12:
2981       /* Handle broken assemblers that require movd instead of movq.  */
2982       return "%vmovd\t{%1, %0|%0, %1}";
2983
2984     default:
2985       gcc_unreachable();
2986     }
2987 }
2988   [(set_attr "type" "fmov,fmov,fmov,imov,imov,imov,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2989    (set (attr "modrm")
2990      (if_then_else
2991        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2992          (const_string "0")
2993          (const_string "*")))
2994    (set (attr "length_immediate")
2995      (if_then_else
2996        (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2997          (const_string "8")
2998          (const_string "*")))
2999    (set (attr "prefix")
3000      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3001        (const_string "orig")
3002        (const_string "maybe_vex")))
3003    (set (attr "prefix_data16")
3004      (if_then_else (eq_attr "mode" "V1DF")
3005        (const_string "1")
3006        (const_string "*")))
3007    (set (attr "mode")
3008         (cond [(eq_attr "alternative" "0,1,2")
3009                  (const_string "DF")
3010                (eq_attr "alternative" "3,4,5,6,11,12")
3011                  (const_string "DI")
3012
3013                /* xorps is one byte shorter.  */
3014                (eq_attr "alternative" "7")
3015                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3016                             (const_int 0))
3017                           (const_string "V4SF")
3018                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3019                             (const_int 0))
3020                           (const_string "TI")
3021                        ]
3022                        (const_string "V2DF"))
3023
3024                /* For architectures resolving dependencies on
3025                   whole SSE registers use APD move to break dependency
3026                   chains, otherwise use short move to avoid extra work.
3027
3028                   movaps encodes one byte shorter.  */
3029                (eq_attr "alternative" "8")
3030                  (cond
3031                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3032                         (const_int 0))
3033                       (const_string "V4SF")
3034                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3035                         (const_int 0))
3036                       (const_string "V2DF")
3037                    ]
3038                    (const_string "DF"))
3039                /* For architectures resolving dependencies on register
3040                   parts we may avoid extra work to zero out upper part
3041                   of register.  */
3042                (eq_attr "alternative" "9")
3043                  (if_then_else
3044                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3045                        (const_int 0))
3046                    (const_string "V1DF")
3047                    (const_string "DF"))
3048               ]
3049               (const_string "DF")))])
3050
3051 ;; Possible store forwarding (partial memory) stall in alternative 4.
3052 (define_insn "*movdf_internal"
3053   [(set (match_operand:DF 0 "nonimmediate_operand"
3054                 "=f,m,f,?Yd*r ,!o   ,Y2*x,Y2*x,Y2*x,m  ")
3055         (match_operand:DF 1 "general_operand"
3056                 "fm,f,G,Yd*roF,FYd*r,C   ,Y2*x,m   ,Y2*x"))]
3057   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3058    && (!can_create_pseudo_p ()
3059        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3060        || GET_CODE (operands[1]) != CONST_DOUBLE
3061        || (optimize_function_for_size_p (cfun)
3062            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3063                 && standard_80387_constant_p (operands[1]) > 0)
3064                || (TARGET_SSE2 && TARGET_SSE_MATH
3065                    && standard_sse_constant_p (operands[1])))
3066            && !memory_operand (operands[0], DFmode))
3067        || (!TARGET_MEMORY_MISMATCH_STALL
3068            && memory_operand (operands[0], DFmode)))"
3069 {
3070   switch (which_alternative)
3071     {
3072     case 0:
3073     case 1:
3074       return output_387_reg_move (insn, operands);
3075
3076     case 2:
3077       return standard_80387_constant_opcode (operands[1]);
3078
3079     case 3:
3080     case 4:
3081       return "#";
3082
3083     case 5:
3084       return standard_sse_constant_opcode (insn, operands[1]);
3085
3086     case 6:
3087     case 7:
3088     case 8:
3089       switch (get_attr_mode (insn))
3090         {
3091         case MODE_V2DF:
3092           if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093             return "%vmovapd\t{%1, %0|%0, %1}";
3094         case MODE_V4SF:
3095           return "%vmovaps\t{%1, %0|%0, %1}";
3096
3097         case MODE_DI:
3098           return "%vmovq\t{%1, %0|%0, %1}";
3099         case MODE_DF:
3100           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3101             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3102           return "%vmovsd\t{%1, %0|%0, %1}";
3103         case MODE_V1DF:
3104           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3105         case MODE_V2SF:
3106           return "%vmovlps\t{%1, %d0|%d0, %1}";
3107         default:
3108           gcc_unreachable ();
3109         }
3110
3111     default:
3112       gcc_unreachable ();
3113     }
3114 }
3115   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3116    (set (attr "prefix")
3117      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3118        (const_string "orig")
3119        (const_string "maybe_vex")))
3120    (set (attr "prefix_data16")
3121      (if_then_else (eq_attr "mode" "V1DF")
3122        (const_string "1")
3123        (const_string "*")))
3124    (set (attr "mode")
3125         (cond [(eq_attr "alternative" "0,1,2")
3126                  (const_string "DF")
3127                (eq_attr "alternative" "3,4")
3128                  (const_string "SI")
3129
3130                /* For SSE1, we have many fewer alternatives.  */
3131                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3132                  (if_then_else
3133                    (eq_attr "alternative" "5,6")
3134                    (const_string "V4SF")
3135                    (const_string "V2SF"))
3136
3137                /* xorps is one byte shorter.  */
3138                (eq_attr "alternative" "5")
3139                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3140                             (const_int 0))
3141                           (const_string "V4SF")
3142                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3143                             (const_int 0))
3144                           (const_string "TI")
3145                        ]
3146                        (const_string "V2DF"))
3147
3148                /* For architectures resolving dependencies on
3149                   whole SSE registers use APD move to break dependency
3150                   chains, otherwise use short move to avoid extra work.
3151
3152                   movaps encodes one byte shorter.  */
3153                (eq_attr "alternative" "6")
3154                  (cond
3155                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3156                         (const_int 0))
3157                       (const_string "V4SF")
3158                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3159                         (const_int 0))
3160                       (const_string "V2DF")
3161                    ]
3162                    (const_string "DF"))
3163                /* For architectures resolving dependencies on register
3164                   parts we may avoid extra work to zero out upper part
3165                   of register.  */
3166                (eq_attr "alternative" "7")
3167                  (if_then_else
3168                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3169                        (const_int 0))
3170                    (const_string "V1DF")
3171                    (const_string "DF"))
3172               ]
3173               (const_string "DF")))])
3174
3175 (define_insn "*movsf_internal"
3176   [(set (match_operand:SF 0 "nonimmediate_operand"
3177           "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3178         (match_operand:SF 1 "general_operand"
3179           "fm,f,G,rmF,Fr,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3180   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3181    && (!can_create_pseudo_p ()
3182        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3183        || GET_CODE (operands[1]) != CONST_DOUBLE
3184        || (optimize_function_for_size_p (cfun)
3185            && ((!TARGET_SSE_MATH
3186                 && standard_80387_constant_p (operands[1]) > 0)
3187                || (TARGET_SSE_MATH
3188                    && standard_sse_constant_p (operands[1]))))
3189        || memory_operand (operands[0], SFmode))"
3190 {
3191   switch (which_alternative)
3192     {
3193     case 0:
3194     case 1:
3195       return output_387_reg_move (insn, operands);
3196
3197     case 2:
3198       return standard_80387_constant_opcode (operands[1]);
3199
3200     case 3:
3201     case 4:
3202       return "mov{l}\t{%1, %0|%0, %1}";
3203
3204     case 5:
3205       return standard_sse_constant_opcode (insn, operands[1]);
3206
3207     case 6:
3208       if (get_attr_mode (insn) == MODE_V4SF)
3209         return "%vmovaps\t{%1, %0|%0, %1}";
3210       if (TARGET_AVX)
3211         return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3212
3213     case 7:
3214     case 8:
3215       return "%vmovss\t{%1, %0|%0, %1}";
3216
3217     case 9:
3218     case 10:
3219     case 14:
3220     case 15:
3221       return "movd\t{%1, %0|%0, %1}";
3222
3223     case 11:
3224       return "movq\t{%1, %0|%0, %1}";
3225
3226     case 12:
3227     case 13:
3228       return "%vmovd\t{%1, %0|%0, %1}";
3229
3230     default:
3231       gcc_unreachable ();
3232     }
3233 }
3234   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3235    (set (attr "prefix")
3236      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3237        (const_string "maybe_vex")
3238        (const_string "orig")))
3239    (set (attr "mode")
3240         (cond [(eq_attr "alternative" "3,4,9,10")
3241                  (const_string "SI")
3242                (eq_attr "alternative" "5")
3243                  (if_then_else
3244                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3245                                  (const_int 0))
3246                              (ne (symbol_ref "TARGET_SSE2")
3247                                  (const_int 0)))
3248                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3249                             (const_int 0)))
3250                    (const_string "TI")
3251                    (const_string "V4SF"))
3252                /* For architectures resolving dependencies on
3253                   whole SSE registers use APS move to break dependency
3254                   chains, otherwise use short move to avoid extra work.
3255
3256                   Do the same for architectures resolving dependencies on
3257                   the parts.  While in DF mode it is better to always handle
3258                   just register parts, the SF mode is different due to lack
3259                   of instructions to load just part of the register.  It is
3260                   better to maintain the whole registers in single format
3261                   to avoid problems on using packed logical operations.  */
3262                (eq_attr "alternative" "6")
3263                  (if_then_else
3264                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3265                             (const_int 0))
3266                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3267                             (const_int 0)))
3268                    (const_string "V4SF")
3269                    (const_string "SF"))
3270                (eq_attr "alternative" "11")
3271                  (const_string "DI")]
3272                (const_string "SF")))])
3273
3274 (define_split
3275   [(set (match_operand 0 "any_fp_register_operand" "")
3276         (match_operand 1 "memory_operand" ""))]
3277   "reload_completed
3278    && (GET_MODE (operands[0]) == TFmode
3279        || GET_MODE (operands[0]) == XFmode
3280        || GET_MODE (operands[0]) == DFmode
3281        || GET_MODE (operands[0]) == SFmode)
3282    && (operands[2] = find_constant_src (insn))"
3283   [(set (match_dup 0) (match_dup 2))]
3284 {
3285   rtx c = operands[2];
3286   int r = REGNO (operands[0]);
3287
3288   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3289       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3290     FAIL;
3291 })
3292
3293 (define_split
3294   [(set (match_operand 0 "any_fp_register_operand" "")
3295         (float_extend (match_operand 1 "memory_operand" "")))]
3296   "reload_completed
3297    && (GET_MODE (operands[0]) == TFmode
3298        || GET_MODE (operands[0]) == XFmode
3299        || GET_MODE (operands[0]) == DFmode)
3300    && (operands[2] = find_constant_src (insn))"
3301   [(set (match_dup 0) (match_dup 2))]
3302 {
3303   rtx c = operands[2];
3304   int r = REGNO (operands[0]);
3305
3306   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3307       || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3308     FAIL;
3309 })
3310
3311 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3312 (define_split
3313   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3314         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3315   "reload_completed
3316    && (standard_80387_constant_p (operands[1]) == 8
3317        || standard_80387_constant_p (operands[1]) == 9)"
3318   [(set (match_dup 0)(match_dup 1))
3319    (set (match_dup 0)
3320         (neg:X87MODEF (match_dup 0)))]
3321 {
3322   REAL_VALUE_TYPE r;
3323
3324   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3325   if (real_isnegzero (&r))
3326     operands[1] = CONST0_RTX (<MODE>mode);
3327   else
3328     operands[1] = CONST1_RTX (<MODE>mode);
3329 })
3330
3331 (define_split
3332   [(set (match_operand 0 "nonimmediate_operand" "")
3333         (match_operand 1 "general_operand" ""))]
3334   "reload_completed
3335    && (GET_MODE (operands[0]) == TFmode
3336        || GET_MODE (operands[0]) == XFmode
3337        || GET_MODE (operands[0]) == DFmode)
3338    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3339   [(const_int 0)]
3340   "ix86_split_long_move (operands); DONE;")
3341
3342 (define_insn "swapxf"
3343   [(set (match_operand:XF 0 "register_operand" "+f")
3344         (match_operand:XF 1 "register_operand" "+f"))
3345    (set (match_dup 1)
3346         (match_dup 0))]
3347   "TARGET_80387"
3348 {
3349   if (STACK_TOP_P (operands[0]))
3350     return "fxch\t%1";
3351   else
3352     return "fxch\t%0";
3353 }
3354   [(set_attr "type" "fxch")
3355    (set_attr "mode" "XF")])
3356
3357 (define_insn "*swap<mode>"
3358   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3359         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3360    (set (match_dup 1)
3361         (match_dup 0))]
3362   "TARGET_80387 || reload_completed"
3363 {
3364   if (STACK_TOP_P (operands[0]))
3365     return "fxch\t%1";
3366   else
3367     return "fxch\t%0";
3368 }
3369   [(set_attr "type" "fxch")
3370    (set_attr "mode" "<MODE>")])
3371 \f
3372 ;; Zero extension instructions
3373
3374 (define_expand "zero_extendsidi2"
3375   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3376         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3377   ""
3378 {
3379   if (!TARGET_64BIT)
3380     {
3381       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3382       DONE;
3383     }
3384 })
3385
3386 (define_insn "*zero_extendsidi2_rex64"
3387   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3388         (zero_extend:DI
3389          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3390   "TARGET_64BIT"
3391   "@
3392    mov\t{%k1, %k0|%k0, %k1}
3393    #
3394    movd\t{%1, %0|%0, %1}
3395    movd\t{%1, %0|%0, %1}
3396    %vmovd\t{%1, %0|%0, %1}
3397    %vmovd\t{%1, %0|%0, %1}"
3398   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3399    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3400    (set_attr "prefix_0f" "0,*,*,*,*,*")
3401    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3402
3403 (define_split
3404   [(set (match_operand:DI 0 "memory_operand" "")
3405         (zero_extend:DI (match_dup 0)))]
3406   "TARGET_64BIT"
3407   [(set (match_dup 4) (const_int 0))]
3408   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3409
3410 ;; %%% Kill me once multi-word ops are sane.
3411 (define_insn "zero_extendsidi2_1"
3412   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3413         (zero_extend:DI
3414          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3415    (clobber (reg:CC FLAGS_REG))]
3416   "!TARGET_64BIT"
3417   "@
3418    #
3419    #
3420    #
3421    movd\t{%1, %0|%0, %1}
3422    movd\t{%1, %0|%0, %1}
3423    %vmovd\t{%1, %0|%0, %1}
3424    %vmovd\t{%1, %0|%0, %1}"
3425   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3426    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3427    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3428
3429 (define_split
3430   [(set (match_operand:DI 0 "register_operand" "")
3431         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3432    (clobber (reg:CC FLAGS_REG))]
3433   "!TARGET_64BIT && reload_completed
3434    && true_regnum (operands[0]) == true_regnum (operands[1])"
3435   [(set (match_dup 4) (const_int 0))]
3436   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3437
3438 (define_split
3439   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3440         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3441    (clobber (reg:CC FLAGS_REG))]
3442   "!TARGET_64BIT && reload_completed
3443    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3444   [(set (match_dup 3) (match_dup 1))
3445    (set (match_dup 4) (const_int 0))]
3446   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3447
3448 (define_insn "zero_extend<mode>di2"
3449   [(set (match_operand:DI 0 "register_operand" "=r")
3450         (zero_extend:DI
3451          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3452   "TARGET_64BIT"
3453   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3454   [(set_attr "type" "imovx")
3455    (set_attr "mode" "SI")])
3456
3457 (define_expand "zero_extendhisi2"
3458   [(set (match_operand:SI 0 "register_operand" "")
3459         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3460   ""
3461 {
3462   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3463     {
3464       operands[1] = force_reg (HImode, operands[1]);
3465       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3466       DONE;
3467     }
3468 })
3469
3470 (define_insn_and_split "zero_extendhisi2_and"
3471   [(set (match_operand:SI 0 "register_operand" "=r")
3472         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3473    (clobber (reg:CC FLAGS_REG))]
3474   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3475   "#"
3476   "&& reload_completed"
3477   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3478               (clobber (reg:CC FLAGS_REG))])]
3479   ""
3480   [(set_attr "type" "alu1")
3481    (set_attr "mode" "SI")])
3482
3483 (define_insn "*zero_extendhisi2_movzwl"
3484   [(set (match_operand:SI 0 "register_operand" "=r")
3485         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3486   "!TARGET_ZERO_EXTEND_WITH_AND
3487    || optimize_function_for_size_p (cfun)"
3488   "movz{wl|x}\t{%1, %0|%0, %1}"
3489   [(set_attr "type" "imovx")
3490    (set_attr "mode" "SI")])
3491
3492 (define_expand "zero_extendqi<mode>2"
3493   [(parallel
3494     [(set (match_operand:SWI24 0 "register_operand" "")
3495           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3496      (clobber (reg:CC FLAGS_REG))])])
3497
3498 (define_insn "*zero_extendqi<mode>2_and"
3499   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3500         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3501    (clobber (reg:CC FLAGS_REG))]
3502   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3503   "#"
3504   [(set_attr "type" "alu1")
3505    (set_attr "mode" "<MODE>")])
3506
3507 ;; When source and destination does not overlap, clear destination
3508 ;; first and then do the movb
3509 (define_split
3510   [(set (match_operand:SWI24 0 "register_operand" "")
3511         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3512    (clobber (reg:CC FLAGS_REG))]
3513   "reload_completed
3514    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3515    && ANY_QI_REG_P (operands[0])
3516    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3517    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3518   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3519 {
3520   operands[2] = gen_lowpart (QImode, operands[0]);
3521   ix86_expand_clear (operands[0]);
3522 })
3523
3524 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3525   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3526         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3527    (clobber (reg:CC FLAGS_REG))]
3528   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3529   "#"
3530   [(set_attr "type" "imovx,alu1")
3531    (set_attr "mode" "<MODE>")])
3532
3533 ;; For the movzbl case strip only the clobber
3534 (define_split
3535   [(set (match_operand:SWI24 0 "register_operand" "")
3536         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3537    (clobber (reg:CC FLAGS_REG))]
3538   "reload_completed
3539    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3540    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3541   [(set (match_dup 0)
3542         (zero_extend:SWI24 (match_dup 1)))])
3543
3544 ; zero extend to SImode to avoid partial register stalls
3545 (define_insn "*zero_extendqi<mode>2_movzbl"
3546   [(set (match_operand:SWI24 0 "register_operand" "=r")
3547         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3548   "reload_completed
3549    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3550   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3551   [(set_attr "type" "imovx")
3552    (set_attr "mode" "SI")])
3553
3554 ;; Rest is handled by single and.
3555 (define_split
3556   [(set (match_operand:SWI24 0 "register_operand" "")
3557         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3558    (clobber (reg:CC FLAGS_REG))]
3559   "reload_completed
3560    && true_regnum (operands[0]) == true_regnum (operands[1])"
3561   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3562               (clobber (reg:CC FLAGS_REG))])])
3563 \f
3564 ;; Sign extension instructions
3565
3566 (define_expand "extendsidi2"
3567   [(set (match_operand:DI 0 "register_operand" "")
3568         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3569   ""
3570 {
3571   if (!TARGET_64BIT)
3572     {
3573       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3574       DONE;
3575     }
3576 })
3577
3578 (define_insn "*extendsidi2_rex64"
3579   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3580         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3581   "TARGET_64BIT"
3582   "@
3583    {cltq|cdqe}
3584    movs{lq|x}\t{%1, %0|%0, %1}"
3585   [(set_attr "type" "imovx")
3586    (set_attr "mode" "DI")
3587    (set_attr "prefix_0f" "0")
3588    (set_attr "modrm" "0,1")])
3589
3590 (define_insn "extendsidi2_1"
3591   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3592         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3593    (clobber (reg:CC FLAGS_REG))
3594    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3595   "!TARGET_64BIT"
3596   "#")
3597
3598 ;; Extend to memory case when source register does die.
3599 (define_split
3600   [(set (match_operand:DI 0 "memory_operand" "")
3601         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3602    (clobber (reg:CC FLAGS_REG))
3603    (clobber (match_operand:SI 2 "register_operand" ""))]
3604   "(reload_completed
3605     && dead_or_set_p (insn, operands[1])
3606     && !reg_mentioned_p (operands[1], operands[0]))"
3607   [(set (match_dup 3) (match_dup 1))
3608    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3609               (clobber (reg:CC FLAGS_REG))])
3610    (set (match_dup 4) (match_dup 1))]
3611   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3612
3613 ;; Extend to memory case when source register does not die.
3614 (define_split
3615   [(set (match_operand:DI 0 "memory_operand" "")
3616         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3617    (clobber (reg:CC FLAGS_REG))
3618    (clobber (match_operand:SI 2 "register_operand" ""))]
3619   "reload_completed"
3620   [(const_int 0)]
3621 {
3622   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3623
3624   emit_move_insn (operands[3], operands[1]);
3625
3626   /* Generate a cltd if possible and doing so it profitable.  */
3627   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3628       && true_regnum (operands[1]) == AX_REG
3629       && true_regnum (operands[2]) == DX_REG)
3630     {
3631       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3632     }
3633   else
3634     {
3635       emit_move_insn (operands[2], operands[1]);
3636       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3637     }
3638   emit_move_insn (operands[4], operands[2]);
3639   DONE;
3640 })
3641
3642 ;; Extend to register case.  Optimize case where source and destination
3643 ;; registers match and cases where we can use cltd.
3644 (define_split
3645   [(set (match_operand:DI 0 "register_operand" "")
3646         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3647    (clobber (reg:CC FLAGS_REG))
3648    (clobber (match_scratch:SI 2 ""))]
3649   "reload_completed"
3650   [(const_int 0)]
3651 {
3652   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3653
3654   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3655     emit_move_insn (operands[3], operands[1]);
3656
3657   /* Generate a cltd if possible and doing so it profitable.  */
3658   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3659       && true_regnum (operands[3]) == AX_REG
3660       && true_regnum (operands[4]) == DX_REG)
3661     {
3662       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3663       DONE;
3664     }
3665
3666   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3667     emit_move_insn (operands[4], operands[1]);
3668
3669   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3670   DONE;
3671 })
3672
3673 (define_insn "extend<mode>di2"
3674   [(set (match_operand:DI 0 "register_operand" "=r")
3675         (sign_extend:DI
3676          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3677   "TARGET_64BIT"
3678   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3679   [(set_attr "type" "imovx")
3680    (set_attr "mode" "DI")])
3681
3682 (define_insn "extendhisi2"
3683   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3684         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3685   ""
3686 {
3687   switch (get_attr_prefix_0f (insn))
3688     {
3689     case 0:
3690       return "{cwtl|cwde}";
3691     default:
3692       return "movs{wl|x}\t{%1, %0|%0, %1}";
3693     }
3694 }
3695   [(set_attr "type" "imovx")
3696    (set_attr "mode" "SI")
3697    (set (attr "prefix_0f")
3698      ;; movsx is short decodable while cwtl is vector decoded.
3699      (if_then_else (and (eq_attr "cpu" "!k6")
3700                         (eq_attr "alternative" "0"))
3701         (const_string "0")
3702         (const_string "1")))
3703    (set (attr "modrm")
3704      (if_then_else (eq_attr "prefix_0f" "0")
3705         (const_string "0")
3706         (const_string "1")))])
3707
3708 (define_insn "*extendhisi2_zext"
3709   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3710         (zero_extend:DI
3711          (sign_extend:SI
3712           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3713   "TARGET_64BIT"
3714 {
3715   switch (get_attr_prefix_0f (insn))
3716     {
3717     case 0:
3718       return "{cwtl|cwde}";
3719     default:
3720       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3721     }
3722 }
3723   [(set_attr "type" "imovx")
3724    (set_attr "mode" "SI")
3725    (set (attr "prefix_0f")
3726      ;; movsx is short decodable while cwtl is vector decoded.
3727      (if_then_else (and (eq_attr "cpu" "!k6")
3728                         (eq_attr "alternative" "0"))
3729         (const_string "0")
3730         (const_string "1")))
3731    (set (attr "modrm")
3732      (if_then_else (eq_attr "prefix_0f" "0")
3733         (const_string "0")
3734         (const_string "1")))])
3735
3736 (define_insn "extendqisi2"
3737   [(set (match_operand:SI 0 "register_operand" "=r")
3738         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3739   ""
3740   "movs{bl|x}\t{%1, %0|%0, %1}"
3741    [(set_attr "type" "imovx")
3742     (set_attr "mode" "SI")])
3743
3744 (define_insn "*extendqisi2_zext"
3745   [(set (match_operand:DI 0 "register_operand" "=r")
3746         (zero_extend:DI
3747           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3748   "TARGET_64BIT"
3749   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3750    [(set_attr "type" "imovx")
3751     (set_attr "mode" "SI")])
3752
3753 (define_insn "extendqihi2"
3754   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3755         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3756   ""
3757 {
3758   switch (get_attr_prefix_0f (insn))
3759     {
3760     case 0:
3761       return "{cbtw|cbw}";
3762     default:
3763       return "movs{bw|x}\t{%1, %0|%0, %1}";
3764     }
3765 }
3766   [(set_attr "type" "imovx")
3767    (set_attr "mode" "HI")
3768    (set (attr "prefix_0f")
3769      ;; movsx is short decodable while cwtl is vector decoded.
3770      (if_then_else (and (eq_attr "cpu" "!k6")
3771                         (eq_attr "alternative" "0"))
3772         (const_string "0")
3773         (const_string "1")))
3774    (set (attr "modrm")
3775      (if_then_else (eq_attr "prefix_0f" "0")
3776         (const_string "0")
3777         (const_string "1")))])
3778 \f
3779 ;; Conversions between float and double.
3780
3781 ;; These are all no-ops in the model used for the 80387.
3782 ;; So just emit moves.
3783
3784 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3785 (define_split
3786   [(set (match_operand:DF 0 "push_operand" "")
3787         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3788   "reload_completed"
3789   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3790    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3791
3792 (define_split
3793   [(set (match_operand:XF 0 "push_operand" "")
3794         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3795   "reload_completed"
3796   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3797    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3798   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3799
3800 (define_expand "extendsfdf2"
3801   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3802         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3803   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3804 {
3805   /* ??? Needed for compress_float_constant since all fp constants
3806      are TARGET_LEGITIMATE_CONSTANT_P.  */
3807   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3808     {
3809       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3810           && standard_80387_constant_p (operands[1]) > 0)
3811         {
3812           operands[1] = simplify_const_unary_operation
3813             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3814           emit_move_insn_1 (operands[0], operands[1]);
3815           DONE;
3816         }
3817       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3818     }
3819 })
3820
3821 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3822    cvtss2sd:
3823       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3824       cvtps2pd xmm2,xmm1
3825    We do the conversion post reload to avoid producing of 128bit spills
3826    that might lead to ICE on 32bit target.  The sequence unlikely combine
3827    anyway.  */
3828 (define_split
3829   [(set (match_operand:DF 0 "register_operand" "")
3830         (float_extend:DF
3831           (match_operand:SF 1 "nonimmediate_operand" "")))]
3832   "TARGET_USE_VECTOR_FP_CONVERTS
3833    && optimize_insn_for_speed_p ()
3834    && reload_completed && SSE_REG_P (operands[0])"
3835    [(set (match_dup 2)
3836          (float_extend:V2DF
3837            (vec_select:V2SF
3838              (match_dup 3)
3839              (parallel [(const_int 0) (const_int 1)]))))]
3840 {
3841   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3842   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3843   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3844      Try to avoid move when unpacking can be done in source.  */
3845   if (REG_P (operands[1]))
3846     {
3847       /* If it is unsafe to overwrite upper half of source, we need
3848          to move to destination and unpack there.  */
3849       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3850            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3851           && true_regnum (operands[0]) != true_regnum (operands[1]))
3852         {
3853           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3854           emit_move_insn (tmp, operands[1]);
3855         }
3856       else
3857         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3858       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3859                                              operands[3]));
3860     }
3861   else
3862     emit_insn (gen_vec_setv4sf_0 (operands[3],
3863                                   CONST0_RTX (V4SFmode), operands[1]));
3864 })
3865
3866 (define_insn "*extendsfdf2_mixed"
3867   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3868         (float_extend:DF
3869           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3870   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3871 {
3872   switch (which_alternative)
3873     {
3874     case 0:
3875     case 1:
3876       return output_387_reg_move (insn, operands);
3877
3878     case 2:
3879       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3880
3881     default:
3882       gcc_unreachable ();
3883     }
3884 }
3885   [(set_attr "type" "fmov,fmov,ssecvt")
3886    (set_attr "prefix" "orig,orig,maybe_vex")
3887    (set_attr "mode" "SF,XF,DF")])
3888
3889 (define_insn "*extendsfdf2_sse"
3890   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3891         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3892   "TARGET_SSE2 && TARGET_SSE_MATH"
3893   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3894   [(set_attr "type" "ssecvt")
3895    (set_attr "prefix" "maybe_vex")
3896    (set_attr "mode" "DF")])
3897
3898 (define_insn "*extendsfdf2_i387"
3899   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3900         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3901   "TARGET_80387"
3902   "* return output_387_reg_move (insn, operands);"
3903   [(set_attr "type" "fmov")
3904    (set_attr "mode" "SF,XF")])
3905
3906 (define_expand "extend<mode>xf2"
3907   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3908         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3909   "TARGET_80387"
3910 {
3911   /* ??? Needed for compress_float_constant since all fp constants
3912      are TARGET_LEGITIMATE_CONSTANT_P.  */
3913   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3914     {
3915       if (standard_80387_constant_p (operands[1]) > 0)
3916         {
3917           operands[1] = simplify_const_unary_operation
3918             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3919           emit_move_insn_1 (operands[0], operands[1]);
3920           DONE;
3921         }
3922       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3923     }
3924 })
3925
3926 (define_insn "*extend<mode>xf2_i387"
3927   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3928         (float_extend:XF
3929           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3930   "TARGET_80387"
3931   "* return output_387_reg_move (insn, operands);"
3932   [(set_attr "type" "fmov")
3933    (set_attr "mode" "<MODE>,XF")])
3934
3935 ;; %%% This seems bad bad news.
3936 ;; This cannot output into an f-reg because there is no way to be sure
3937 ;; of truncating in that case.  Otherwise this is just like a simple move
3938 ;; insn.  So we pretend we can output to a reg in order to get better
3939 ;; register preferencing, but we really use a stack slot.
3940
3941 ;; Conversion from DFmode to SFmode.
3942
3943 (define_expand "truncdfsf2"
3944   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3945         (float_truncate:SF
3946           (match_operand:DF 1 "nonimmediate_operand" "")))]
3947   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3948 {
3949   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3950     ;
3951   else if (flag_unsafe_math_optimizations)
3952     ;
3953   else
3954     {
3955       enum ix86_stack_slot slot = (virtuals_instantiated
3956                                    ? SLOT_TEMP
3957                                    : SLOT_VIRTUAL);
3958       rtx temp = assign_386_stack_local (SFmode, slot);
3959       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3960       DONE;
3961     }
3962 })
3963
3964 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3965    cvtsd2ss:
3966       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3967       cvtpd2ps xmm2,xmm1
3968    We do the conversion post reload to avoid producing of 128bit spills
3969    that might lead to ICE on 32bit target.  The sequence unlikely combine
3970    anyway.  */
3971 (define_split
3972   [(set (match_operand:SF 0 "register_operand" "")
3973         (float_truncate:SF
3974           (match_operand:DF 1 "nonimmediate_operand" "")))]
3975   "TARGET_USE_VECTOR_FP_CONVERTS
3976    && optimize_insn_for_speed_p ()
3977    && reload_completed && SSE_REG_P (operands[0])"
3978    [(set (match_dup 2)
3979          (vec_concat:V4SF
3980            (float_truncate:V2SF
3981              (match_dup 4))
3982            (match_dup 3)))]
3983 {
3984   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3985   operands[3] = CONST0_RTX (V2SFmode);
3986   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3987   /* Use movsd for loading from memory, unpcklpd for registers.
3988      Try to avoid move when unpacking can be done in source, or SSE3
3989      movddup is available.  */
3990   if (REG_P (operands[1]))
3991     {
3992       if (!TARGET_SSE3
3993           && true_regnum (operands[0]) != true_regnum (operands[1])
3994           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3995               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3996         {
3997           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3998           emit_move_insn (tmp, operands[1]);
3999           operands[1] = tmp;
4000         }
4001       else if (!TARGET_SSE3)
4002         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4003       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4004     }
4005   else
4006     emit_insn (gen_sse2_loadlpd (operands[4],
4007                                  CONST0_RTX (V2DFmode), operands[1]));
4008 })
4009
4010 (define_expand "truncdfsf2_with_temp"
4011   [(parallel [(set (match_operand:SF 0 "" "")
4012                    (float_truncate:SF (match_operand:DF 1 "" "")))
4013               (clobber (match_operand:SF 2 "" ""))])])
4014
4015 (define_insn "*truncdfsf_fast_mixed"
4016   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4017         (float_truncate:SF
4018           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4019   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4020 {
4021   switch (which_alternative)
4022     {
4023     case 0:
4024       return output_387_reg_move (insn, operands);
4025     case 1:
4026       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4027     default:
4028       gcc_unreachable ();
4029     }
4030 }
4031   [(set_attr "type" "fmov,ssecvt")
4032    (set_attr "prefix" "orig,maybe_vex")
4033    (set_attr "mode" "SF")])
4034
4035 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4036 ;; because nothing we do here is unsafe.
4037 (define_insn "*truncdfsf_fast_sse"
4038   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4039         (float_truncate:SF
4040           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4041   "TARGET_SSE2 && TARGET_SSE_MATH"
4042   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4043   [(set_attr "type" "ssecvt")
4044    (set_attr "prefix" "maybe_vex")
4045    (set_attr "mode" "SF")])
4046
4047 (define_insn "*truncdfsf_fast_i387"
4048   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4049         (float_truncate:SF
4050           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4051   "TARGET_80387 && flag_unsafe_math_optimizations"
4052   "* return output_387_reg_move (insn, operands);"
4053   [(set_attr "type" "fmov")
4054    (set_attr "mode" "SF")])
4055
4056 (define_insn "*truncdfsf_mixed"
4057   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4058         (float_truncate:SF
4059           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4060    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4061   "TARGET_MIX_SSE_I387"
4062 {
4063   switch (which_alternative)
4064     {
4065     case 0:
4066       return output_387_reg_move (insn, operands);
4067     case 1:
4068       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4069
4070     default:
4071       return "#";
4072     }
4073 }
4074   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075    (set_attr "unit" "*,*,i387,i387,i387")
4076    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077    (set_attr "mode" "SF")])
4078
4079 (define_insn "*truncdfsf_i387"
4080   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4081         (float_truncate:SF
4082           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4084   "TARGET_80387"
4085 {
4086   switch (which_alternative)
4087     {
4088     case 0:
4089       return output_387_reg_move (insn, operands);
4090
4091     default:
4092       return "#";
4093     }
4094 }
4095   [(set_attr "type" "fmov,multi,multi,multi")
4096    (set_attr "unit" "*,i387,i387,i387")
4097    (set_attr "mode" "SF")])
4098
4099 (define_insn "*truncdfsf2_i387_1"
4100   [(set (match_operand:SF 0 "memory_operand" "=m")
4101         (float_truncate:SF
4102           (match_operand:DF 1 "register_operand" "f")))]
4103   "TARGET_80387
4104    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105    && !TARGET_MIX_SSE_I387"
4106   "* return output_387_reg_move (insn, operands);"
4107   [(set_attr "type" "fmov")
4108    (set_attr "mode" "SF")])
4109
4110 (define_split
4111   [(set (match_operand:SF 0 "register_operand" "")
4112         (float_truncate:SF
4113          (match_operand:DF 1 "fp_register_operand" "")))
4114    (clobber (match_operand 2 "" ""))]
4115   "reload_completed"
4116   [(set (match_dup 2) (match_dup 1))
4117    (set (match_dup 0) (match_dup 2))]
4118   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4119
4120 ;; Conversion from XFmode to {SF,DF}mode
4121
4122 (define_expand "truncxf<mode>2"
4123   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124                    (float_truncate:MODEF
4125                      (match_operand:XF 1 "register_operand" "")))
4126               (clobber (match_dup 2))])]
4127   "TARGET_80387"
4128 {
4129   if (flag_unsafe_math_optimizations)
4130     {
4131       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133       if (reg != operands[0])
4134         emit_move_insn (operands[0], reg);
4135       DONE;
4136     }
4137   else
4138     {
4139       enum ix86_stack_slot slot = (virtuals_instantiated
4140                                    ? SLOT_TEMP
4141                                    : SLOT_VIRTUAL);
4142       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4143     }
4144 })
4145
4146 (define_insn "*truncxfsf2_mixed"
4147   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4148         (float_truncate:SF
4149           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4150    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4151   "TARGET_80387"
4152 {
4153   gcc_assert (!which_alternative);
4154   return output_387_reg_move (insn, operands);
4155 }
4156   [(set_attr "type" "fmov,multi,multi,multi")
4157    (set_attr "unit" "*,i387,i387,i387")
4158    (set_attr "mode" "SF")])
4159
4160 (define_insn "*truncxfdf2_mixed"
4161   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4162         (float_truncate:DF
4163           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4164    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4165   "TARGET_80387"
4166 {
4167   gcc_assert (!which_alternative);
4168   return output_387_reg_move (insn, operands);
4169 }
4170   [(set_attr "type" "fmov,multi,multi,multi")
4171    (set_attr "unit" "*,i387,i387,i387")
4172    (set_attr "mode" "DF")])
4173
4174 (define_insn "truncxf<mode>2_i387_noop"
4175   [(set (match_operand:MODEF 0 "register_operand" "=f")
4176         (float_truncate:MODEF
4177           (match_operand:XF 1 "register_operand" "f")))]
4178   "TARGET_80387 && flag_unsafe_math_optimizations"
4179   "* return output_387_reg_move (insn, operands);"
4180   [(set_attr "type" "fmov")
4181    (set_attr "mode" "<MODE>")])
4182
4183 (define_insn "*truncxf<mode>2_i387"
4184   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4185         (float_truncate:MODEF
4186           (match_operand:XF 1 "register_operand" "f")))]
4187   "TARGET_80387"
4188   "* return output_387_reg_move (insn, operands);"
4189   [(set_attr "type" "fmov")
4190    (set_attr "mode" "<MODE>")])
4191
4192 (define_split
4193   [(set (match_operand:MODEF 0 "register_operand" "")
4194         (float_truncate:MODEF
4195           (match_operand:XF 1 "register_operand" "")))
4196    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4197   "TARGET_80387 && reload_completed"
4198   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4199    (set (match_dup 0) (match_dup 2))])
4200
4201 (define_split
4202   [(set (match_operand:MODEF 0 "memory_operand" "")
4203         (float_truncate:MODEF
4204           (match_operand:XF 1 "register_operand" "")))
4205    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4206   "TARGET_80387"
4207   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4208 \f
4209 ;; Signed conversion to DImode.
4210
4211 (define_expand "fix_truncxfdi2"
4212   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4213                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4214               (clobber (reg:CC FLAGS_REG))])]
4215   "TARGET_80387"
4216 {
4217   if (TARGET_FISTTP)
4218    {
4219      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4220      DONE;
4221    }
4222 })
4223
4224 (define_expand "fix_trunc<mode>di2"
4225   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4226                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4227               (clobber (reg:CC FLAGS_REG))])]
4228   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4229 {
4230   if (TARGET_FISTTP
4231       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4232    {
4233      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4234      DONE;
4235    }
4236   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4237    {
4238      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4239      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4240      if (out != operands[0])
4241         emit_move_insn (operands[0], out);
4242      DONE;
4243    }
4244 })
4245
4246 ;; Signed conversion to SImode.
4247
4248 (define_expand "fix_truncxfsi2"
4249   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4250                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4251               (clobber (reg:CC FLAGS_REG))])]
4252   "TARGET_80387"
4253 {
4254   if (TARGET_FISTTP)
4255    {
4256      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4257      DONE;
4258    }
4259 })
4260
4261 (define_expand "fix_trunc<mode>si2"
4262   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4263                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4264               (clobber (reg:CC FLAGS_REG))])]
4265   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4266 {
4267   if (TARGET_FISTTP
4268       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4269    {
4270      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4271      DONE;
4272    }
4273   if (SSE_FLOAT_MODE_P (<MODE>mode))
4274    {
4275      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4276      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4277      if (out != operands[0])
4278         emit_move_insn (operands[0], out);
4279      DONE;
4280    }
4281 })
4282
4283 ;; Signed conversion to HImode.
4284
4285 (define_expand "fix_trunc<mode>hi2"
4286   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4287                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4288               (clobber (reg:CC FLAGS_REG))])]
4289   "TARGET_80387
4290    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4291 {
4292   if (TARGET_FISTTP)
4293    {
4294      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4295      DONE;
4296    }
4297 })
4298
4299 ;; Unsigned conversion to SImode.
4300
4301 (define_expand "fixuns_trunc<mode>si2"
4302   [(parallel
4303     [(set (match_operand:SI 0 "register_operand" "")
4304           (unsigned_fix:SI
4305             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4306      (use (match_dup 2))
4307      (clobber (match_scratch:<ssevecmode> 3 ""))
4308      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4309   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4310 {
4311   enum machine_mode mode = <MODE>mode;
4312   enum machine_mode vecmode = <ssevecmode>mode;
4313   REAL_VALUE_TYPE TWO31r;
4314   rtx two31;
4315
4316   if (optimize_insn_for_size_p ())
4317     FAIL;
4318
4319   real_ldexp (&TWO31r, &dconst1, 31);
4320   two31 = const_double_from_real_value (TWO31r, mode);
4321   two31 = ix86_build_const_vector (vecmode, true, two31);
4322   operands[2] = force_reg (vecmode, two31);
4323 })
4324
4325 (define_insn_and_split "*fixuns_trunc<mode>_1"
4326   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4327         (unsigned_fix:SI
4328           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4329    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4330    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4331    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4332   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4333    && optimize_function_for_speed_p (cfun)"
4334   "#"
4335   "&& reload_completed"
4336   [(const_int 0)]
4337 {
4338   ix86_split_convert_uns_si_sse (operands);
4339   DONE;
4340 })
4341
4342 ;; Unsigned conversion to HImode.
4343 ;; Without these patterns, we'll try the unsigned SI conversion which
4344 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4345
4346 (define_expand "fixuns_trunc<mode>hi2"
4347   [(set (match_dup 2)
4348         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4349    (set (match_operand:HI 0 "nonimmediate_operand" "")
4350         (subreg:HI (match_dup 2) 0))]
4351   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4352   "operands[2] = gen_reg_rtx (SImode);")
4353
4354 ;; When SSE is available, it is always faster to use it!
4355 (define_insn "fix_trunc<mode>di_sse"
4356   [(set (match_operand:DI 0 "register_operand" "=r,r")
4357         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4358   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4359    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4360   "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4361   [(set_attr "type" "sseicvt")
4362    (set_attr "prefix" "maybe_vex")
4363    (set_attr "prefix_rex" "1")
4364    (set_attr "mode" "<MODE>")
4365    (set_attr "athlon_decode" "double,vector")
4366    (set_attr "amdfam10_decode" "double,double")
4367    (set_attr "bdver1_decode" "double,double")])
4368
4369 (define_insn "fix_trunc<mode>si_sse"
4370   [(set (match_operand:SI 0 "register_operand" "=r,r")
4371         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4372   "SSE_FLOAT_MODE_P (<MODE>mode)
4373    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4374   "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4375   [(set_attr "type" "sseicvt")
4376    (set_attr "prefix" "maybe_vex")
4377    (set_attr "mode" "<MODE>")
4378    (set_attr "athlon_decode" "double,vector")
4379    (set_attr "amdfam10_decode" "double,double")
4380    (set_attr "bdver1_decode" "double,double")])
4381
4382 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4383 (define_peephole2
4384   [(set (match_operand:MODEF 0 "register_operand" "")
4385         (match_operand:MODEF 1 "memory_operand" ""))
4386    (set (match_operand:SWI48x 2 "register_operand" "")
4387         (fix:SWI48x (match_dup 0)))]
4388   "TARGET_SHORTEN_X87_SSE
4389    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4390    && peep2_reg_dead_p (2, operands[0])"
4391   [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4392
4393 ;; Avoid vector decoded forms of the instruction.
4394 (define_peephole2
4395   [(match_scratch:DF 2 "Y2")
4396    (set (match_operand:SWI48x 0 "register_operand" "")
4397         (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4398   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4399   [(set (match_dup 2) (match_dup 1))
4400    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4401
4402 (define_peephole2
4403   [(match_scratch:SF 2 "x")
4404    (set (match_operand:SWI48x 0 "register_operand" "")
4405         (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4406   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4407   [(set (match_dup 2) (match_dup 1))
4408    (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4409
4410 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4411   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4412         (fix:SWI248x (match_operand 1 "register_operand" "")))]
4413   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4414    && TARGET_FISTTP
4415    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4416          && (TARGET_64BIT || <MODE>mode != DImode))
4417         && TARGET_SSE_MATH)
4418    && can_create_pseudo_p ()"
4419   "#"
4420   "&& 1"
4421   [(const_int 0)]
4422 {
4423   if (memory_operand (operands[0], VOIDmode))
4424     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4425   else
4426     {
4427       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4428       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4429                                                             operands[1],
4430                                                             operands[2]));
4431     }
4432   DONE;
4433 }
4434   [(set_attr "type" "fisttp")
4435    (set_attr "mode" "<MODE>")])
4436
4437 (define_insn "fix_trunc<mode>_i387_fisttp"
4438   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4439         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4440    (clobber (match_scratch:XF 2 "=&1f"))]
4441   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4442    && TARGET_FISTTP
4443    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4444          && (TARGET_64BIT || <MODE>mode != DImode))
4445         && TARGET_SSE_MATH)"
4446   "* return output_fix_trunc (insn, operands, true);"
4447   [(set_attr "type" "fisttp")
4448    (set_attr "mode" "<MODE>")])
4449
4450 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4451   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4452         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4453    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4454    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4455   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4456    && TARGET_FISTTP
4457    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4458         && (TARGET_64BIT || <MODE>mode != DImode))
4459         && TARGET_SSE_MATH)"
4460   "#"
4461   [(set_attr "type" "fisttp")
4462    (set_attr "mode" "<MODE>")])
4463
4464 (define_split
4465   [(set (match_operand:SWI248x 0 "register_operand" "")
4466         (fix:SWI248x (match_operand 1 "register_operand" "")))
4467    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4468    (clobber (match_scratch 3 ""))]
4469   "reload_completed"
4470   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4471               (clobber (match_dup 3))])
4472    (set (match_dup 0) (match_dup 2))])
4473
4474 (define_split
4475   [(set (match_operand:SWI248x 0 "memory_operand" "")
4476         (fix:SWI248x (match_operand 1 "register_operand" "")))
4477    (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4478    (clobber (match_scratch 3 ""))]
4479   "reload_completed"
4480   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4481               (clobber (match_dup 3))])])
4482
4483 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4484 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4485 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4486 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4487 ;; function in i386.c.
4488 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4489   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4490         (fix:SWI248x (match_operand 1 "register_operand" "")))
4491    (clobber (reg:CC FLAGS_REG))]
4492   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4493    && !TARGET_FISTTP
4494    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495          && (TARGET_64BIT || <MODE>mode != DImode))
4496    && can_create_pseudo_p ()"
4497   "#"
4498   "&& 1"
4499   [(const_int 0)]
4500 {
4501   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4502
4503   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4504   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4505   if (memory_operand (operands[0], VOIDmode))
4506     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4507                                          operands[2], operands[3]));
4508   else
4509     {
4510       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4511       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4512                                                      operands[2], operands[3],
4513                                                      operands[4]));
4514     }
4515   DONE;
4516 }
4517   [(set_attr "type" "fistp")
4518    (set_attr "i387_cw" "trunc")
4519    (set_attr "mode" "<MODE>")])
4520
4521 (define_insn "fix_truncdi_i387"
4522   [(set (match_operand:DI 0 "memory_operand" "=m")
4523         (fix:DI (match_operand 1 "register_operand" "f")))
4524    (use (match_operand:HI 2 "memory_operand" "m"))
4525    (use (match_operand:HI 3 "memory_operand" "m"))
4526    (clobber (match_scratch:XF 4 "=&1f"))]
4527   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528    && !TARGET_FISTTP
4529    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4530   "* return output_fix_trunc (insn, operands, false);"
4531   [(set_attr "type" "fistp")
4532    (set_attr "i387_cw" "trunc")
4533    (set_attr "mode" "DI")])
4534
4535 (define_insn "fix_truncdi_i387_with_temp"
4536   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4537         (fix:DI (match_operand 1 "register_operand" "f,f")))
4538    (use (match_operand:HI 2 "memory_operand" "m,m"))
4539    (use (match_operand:HI 3 "memory_operand" "m,m"))
4540    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4541    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4542   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4543    && !TARGET_FISTTP
4544    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4545   "#"
4546   [(set_attr "type" "fistp")
4547    (set_attr "i387_cw" "trunc")
4548    (set_attr "mode" "DI")])
4549
4550 (define_split
4551   [(set (match_operand:DI 0 "register_operand" "")
4552         (fix:DI (match_operand 1 "register_operand" "")))
4553    (use (match_operand:HI 2 "memory_operand" ""))
4554    (use (match_operand:HI 3 "memory_operand" ""))
4555    (clobber (match_operand:DI 4 "memory_operand" ""))
4556    (clobber (match_scratch 5 ""))]
4557   "reload_completed"
4558   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4559               (use (match_dup 2))
4560               (use (match_dup 3))
4561               (clobber (match_dup 5))])
4562    (set (match_dup 0) (match_dup 4))])
4563
4564 (define_split
4565   [(set (match_operand:DI 0 "memory_operand" "")
4566         (fix:DI (match_operand 1 "register_operand" "")))
4567    (use (match_operand:HI 2 "memory_operand" ""))
4568    (use (match_operand:HI 3 "memory_operand" ""))
4569    (clobber (match_operand:DI 4 "memory_operand" ""))
4570    (clobber (match_scratch 5 ""))]
4571   "reload_completed"
4572   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4573               (use (match_dup 2))
4574               (use (match_dup 3))
4575               (clobber (match_dup 5))])])
4576
4577 (define_insn "fix_trunc<mode>_i387"
4578   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4579         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4580    (use (match_operand:HI 2 "memory_operand" "m"))
4581    (use (match_operand:HI 3 "memory_operand" "m"))]
4582   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583    && !TARGET_FISTTP
4584    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4585   "* return output_fix_trunc (insn, operands, false);"
4586   [(set_attr "type" "fistp")
4587    (set_attr "i387_cw" "trunc")
4588    (set_attr "mode" "<MODE>")])
4589
4590 (define_insn "fix_trunc<mode>_i387_with_temp"
4591   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4592         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4593    (use (match_operand:HI 2 "memory_operand" "m,m"))
4594    (use (match_operand:HI 3 "memory_operand" "m,m"))
4595    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4596   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4597    && !TARGET_FISTTP
4598    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4599   "#"
4600   [(set_attr "type" "fistp")
4601    (set_attr "i387_cw" "trunc")
4602    (set_attr "mode" "<MODE>")])
4603
4604 (define_split
4605   [(set (match_operand:SWI24 0 "register_operand" "")
4606         (fix:SWI24 (match_operand 1 "register_operand" "")))
4607    (use (match_operand:HI 2 "memory_operand" ""))
4608    (use (match_operand:HI 3 "memory_operand" ""))
4609    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4610   "reload_completed"
4611   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4612               (use (match_dup 2))
4613               (use (match_dup 3))])
4614    (set (match_dup 0) (match_dup 4))])
4615
4616 (define_split
4617   [(set (match_operand:SWI24 0 "memory_operand" "")
4618         (fix:SWI24 (match_operand 1 "register_operand" "")))
4619    (use (match_operand:HI 2 "memory_operand" ""))
4620    (use (match_operand:HI 3 "memory_operand" ""))
4621    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4622   "reload_completed"
4623   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4624               (use (match_dup 2))
4625               (use (match_dup 3))])])
4626
4627 (define_insn "x86_fnstcw_1"
4628   [(set (match_operand:HI 0 "memory_operand" "=m")
4629         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4630   "TARGET_80387"
4631   "fnstcw\t%0"
4632   [(set (attr "length")
4633         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4634    (set_attr "mode" "HI")
4635    (set_attr "unit" "i387")
4636    (set_attr "bdver1_decode" "vector")])
4637
4638 (define_insn "x86_fldcw_1"
4639   [(set (reg:HI FPCR_REG)
4640         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4641   "TARGET_80387"
4642   "fldcw\t%0"
4643   [(set (attr "length")
4644         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4645    (set_attr "mode" "HI")
4646    (set_attr "unit" "i387")
4647    (set_attr "athlon_decode" "vector")
4648    (set_attr "amdfam10_decode" "vector")
4649    (set_attr "bdver1_decode" "vector")])
4650 \f
4651 ;; Conversion between fixed point and floating point.
4652
4653 ;; Even though we only accept memory inputs, the backend _really_
4654 ;; wants to be able to do this between registers.
4655
4656 (define_expand "floathi<mode>2"
4657   [(set (match_operand:X87MODEF 0 "register_operand" "")
4658         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4659   "TARGET_80387
4660    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4661        || TARGET_MIX_SSE_I387)")
4662
4663 ;; Pre-reload splitter to add memory clobber to the pattern.
4664 (define_insn_and_split "*floathi<mode>2_1"
4665   [(set (match_operand:X87MODEF 0 "register_operand" "")
4666         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4667   "TARGET_80387
4668    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4669        || TARGET_MIX_SSE_I387)
4670    && can_create_pseudo_p ()"
4671   "#"
4672   "&& 1"
4673   [(parallel [(set (match_dup 0)
4674               (float:X87MODEF (match_dup 1)))
4675    (clobber (match_dup 2))])]
4676   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4677
4678 (define_insn "*floathi<mode>2_i387_with_temp"
4679   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4680         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4681   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4682   "TARGET_80387
4683    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4684        || TARGET_MIX_SSE_I387)"
4685   "#"
4686   [(set_attr "type" "fmov,multi")
4687    (set_attr "mode" "<MODE>")
4688    (set_attr "unit" "*,i387")
4689    (set_attr "fp_int_src" "true")])
4690
4691 (define_insn "*floathi<mode>2_i387"
4692   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4693         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4694   "TARGET_80387
4695    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4696        || TARGET_MIX_SSE_I387)"
4697   "fild%Z1\t%1"
4698   [(set_attr "type" "fmov")
4699    (set_attr "mode" "<MODE>")
4700    (set_attr "fp_int_src" "true")])
4701
4702 (define_split
4703   [(set (match_operand:X87MODEF 0 "register_operand" "")
4704         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4705    (clobber (match_operand:HI 2 "memory_operand" ""))]
4706   "TARGET_80387
4707    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4708        || TARGET_MIX_SSE_I387)
4709    && reload_completed"
4710   [(set (match_dup 2) (match_dup 1))
4711    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4712
4713 (define_split
4714   [(set (match_operand:X87MODEF 0 "register_operand" "")
4715         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4716    (clobber (match_operand:HI 2 "memory_operand" ""))]
4717    "TARGET_80387
4718     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4719         || TARGET_MIX_SSE_I387)
4720     && reload_completed"
4721   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4722
4723 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4724   [(set (match_operand:X87MODEF 0 "register_operand" "")
4725         (float:X87MODEF
4726           (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4727   "TARGET_80387
4728    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4729        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4730 {
4731   if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4732         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4733       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4734     {
4735       rtx reg = gen_reg_rtx (XFmode);
4736       rtx (*insn)(rtx, rtx);
4737
4738       emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4739
4740       if (<X87MODEF:MODE>mode == SFmode)
4741         insn = gen_truncxfsf2;
4742       else if (<X87MODEF:MODE>mode == DFmode)
4743         insn = gen_truncxfdf2;
4744       else
4745         gcc_unreachable ();
4746
4747       emit_insn (insn (operands[0], reg));
4748       DONE;
4749     }
4750 })
4751
4752 ;; Pre-reload splitter to add memory clobber to the pattern.
4753 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4754   [(set (match_operand:X87MODEF 0 "register_operand" "")
4755         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4756   "((TARGET_80387
4757      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4758      && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4759            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4760          || TARGET_MIX_SSE_I387))
4761     || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4762         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4763         && ((<SWI48x:MODE>mode == SImode
4764              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4765              && optimize_function_for_speed_p (cfun)
4766              && flag_trapping_math)
4767             || !(TARGET_INTER_UNIT_CONVERSIONS
4768                  || optimize_function_for_size_p (cfun)))))
4769    && can_create_pseudo_p ()"
4770   "#"
4771   "&& 1"
4772   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4773               (clobber (match_dup 2))])]
4774 {
4775   operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4776
4777   /* Avoid store forwarding (partial memory) stall penalty
4778      by passing DImode value through XMM registers.  */
4779   if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4780       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4781       && optimize_function_for_speed_p (cfun))
4782     {
4783       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4784                                                             operands[1],
4785                                                             operands[2]));
4786       DONE;
4787     }
4788 })
4789
4790 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4791   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4792         (float:MODEF
4793           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4794    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4795   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4796    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4797   "#"
4798   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4799    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4800    (set_attr "unit" "*,i387,*,*,*")
4801    (set_attr "athlon_decode" "*,*,double,direct,double")
4802    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4803    (set_attr "bdver1_decode" "*,*,double,direct,double")
4804    (set_attr "fp_int_src" "true")])
4805
4806 (define_insn "*floatsi<mode>2_vector_mixed"
4807   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4808         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4809   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4810    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4811   "@
4812    fild%Z1\t%1
4813    #"
4814   [(set_attr "type" "fmov,sseicvt")
4815    (set_attr "mode" "<MODE>,<ssevecmode>")
4816    (set_attr "unit" "i387,*")
4817    (set_attr "athlon_decode" "*,direct")
4818    (set_attr "amdfam10_decode" "*,double")
4819    (set_attr "bdver1_decode" "*,direct")
4820    (set_attr "fp_int_src" "true")])
4821
4822 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4823   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4824         (float:MODEF
4825           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4826    (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4827   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4828    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4829   "#"
4830   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4831    (set_attr "mode" "<MODEF:MODE>")
4832    (set_attr "unit" "*,i387,*,*")
4833    (set_attr "athlon_decode" "*,*,double,direct")
4834    (set_attr "amdfam10_decode" "*,*,vector,double")
4835    (set_attr "bdver1_decode" "*,*,double,direct")
4836    (set_attr "fp_int_src" "true")])
4837
4838 (define_split
4839   [(set (match_operand:MODEF 0 "register_operand" "")
4840         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4841    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4842   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4843    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4844    && TARGET_INTER_UNIT_CONVERSIONS
4845    && reload_completed
4846    && (SSE_REG_P (operands[0])
4847        || (GET_CODE (operands[0]) == SUBREG
4848            && SSE_REG_P (operands[0])))"
4849   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4850
4851 (define_split
4852   [(set (match_operand:MODEF 0 "register_operand" "")
4853         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4854    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4855   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4856    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4857    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4858    && reload_completed
4859    && (SSE_REG_P (operands[0])
4860        || (GET_CODE (operands[0]) == SUBREG
4861            && SSE_REG_P (operands[0])))"
4862   [(set (match_dup 2) (match_dup 1))
4863    (set (match_dup 0) (float:MODEF (match_dup 2)))])
4864
4865 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4866   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4867         (float:MODEF
4868           (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4869   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4870    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4871    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4872   "@
4873    fild%Z1\t%1
4874    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4875    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4876   [(set_attr "type" "fmov,sseicvt,sseicvt")
4877    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4878    (set_attr "mode" "<MODEF:MODE>")
4879    (set (attr "prefix_rex")
4880      (if_then_else
4881        (and (eq_attr "prefix" "maybe_vex")
4882             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4883        (const_string "1")
4884        (const_string "*")))
4885    (set_attr "unit" "i387,*,*")
4886    (set_attr "athlon_decode" "*,double,direct")
4887    (set_attr "amdfam10_decode" "*,vector,double")
4888    (set_attr "bdver1_decode" "*,double,direct")
4889    (set_attr "fp_int_src" "true")])
4890
4891 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4892   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4893         (float:MODEF
4894           (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4895   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4896    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4897    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4898   "@
4899    fild%Z1\t%1
4900    %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4901   [(set_attr "type" "fmov,sseicvt")
4902    (set_attr "prefix" "orig,maybe_vex")
4903    (set_attr "mode" "<MODEF:MODE>")
4904    (set (attr "prefix_rex")
4905      (if_then_else
4906        (and (eq_attr "prefix" "maybe_vex")
4907             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
4908        (const_string "1")
4909        (const_string "*")))
4910    (set_attr "athlon_decode" "*,direct")
4911    (set_attr "amdfam10_decode" "*,double")
4912    (set_attr "bdver1_decode" "*,direct")
4913    (set_attr "fp_int_src" "true")])
4914
4915 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4916   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4917         (float:MODEF
4918           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4919    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4920   "TARGET_SSE2 && TARGET_SSE_MATH
4921    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4922   "#"
4923   [(set_attr "type" "sseicvt")
4924    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4925    (set_attr "athlon_decode" "double,direct,double")
4926    (set_attr "amdfam10_decode" "vector,double,double")
4927    (set_attr "bdver1_decode" "double,direct,double")
4928    (set_attr "fp_int_src" "true")])
4929
4930 (define_insn "*floatsi<mode>2_vector_sse"
4931   [(set (match_operand:MODEF 0 "register_operand" "=x")
4932         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4933   "TARGET_SSE2 && TARGET_SSE_MATH
4934    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4935   "#"
4936   [(set_attr "type" "sseicvt")
4937    (set_attr "mode" "<MODE>")
4938    (set_attr "athlon_decode" "direct")
4939    (set_attr "amdfam10_decode" "double")
4940    (set_attr "bdver1_decode" "direct")
4941    (set_attr "fp_int_src" "true")])
4942
4943 (define_split
4944   [(set (match_operand:MODEF 0 "register_operand" "")
4945         (float:MODEF (match_operand:SI 1 "register_operand" "")))
4946    (clobber (match_operand:SI 2 "memory_operand" ""))]
4947   "TARGET_SSE2 && TARGET_SSE_MATH
4948    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4949    && reload_completed
4950    && (SSE_REG_P (operands[0])
4951        || (GET_CODE (operands[0]) == SUBREG
4952            && SSE_REG_P (operands[0])))"
4953   [(const_int 0)]
4954 {
4955   rtx op1 = operands[1];
4956
4957   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4958                                      <MODE>mode, 0);
4959   if (GET_CODE (op1) == SUBREG)
4960     op1 = SUBREG_REG (op1);
4961
4962   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4963     {
4964       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4965       emit_insn (gen_sse2_loadld (operands[4],
4966                                   CONST0_RTX (V4SImode), operands[1]));
4967     }
4968   /* We can ignore possible trapping value in the
4969      high part of SSE register for non-trapping math. */
4970   else if (SSE_REG_P (op1) && !flag_trapping_math)
4971     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4972   else
4973     {
4974       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4975       emit_move_insn (operands[2], operands[1]);
4976       emit_insn (gen_sse2_loadld (operands[4],
4977                                   CONST0_RTX (V4SImode), operands[2]));
4978     }
4979   emit_insn
4980     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
4981   DONE;
4982 })
4983
4984 (define_split
4985   [(set (match_operand:MODEF 0 "register_operand" "")
4986         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4987    (clobber (match_operand:SI 2 "memory_operand" ""))]
4988   "TARGET_SSE2 && TARGET_SSE_MATH
4989    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4990    && reload_completed
4991    && (SSE_REG_P (operands[0])
4992        || (GET_CODE (operands[0]) == SUBREG
4993            && SSE_REG_P (operands[0])))"
4994   [(const_int 0)]
4995 {
4996   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4997                                      <MODE>mode, 0);
4998   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4999
5000   emit_insn (gen_sse2_loadld (operands[4],
5001                               CONST0_RTX (V4SImode), operands[1]));
5002   emit_insn
5003     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5004   DONE;
5005 })
5006
5007 (define_split
5008   [(set (match_operand:MODEF 0 "register_operand" "")
5009         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5010   "TARGET_SSE2 && TARGET_SSE_MATH
5011    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5012    && reload_completed
5013    && (SSE_REG_P (operands[0])
5014        || (GET_CODE (operands[0]) == SUBREG
5015            && SSE_REG_P (operands[0])))"
5016   [(const_int 0)]
5017 {
5018   rtx op1 = operands[1];
5019
5020   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5021                                      <MODE>mode, 0);
5022   if (GET_CODE (op1) == SUBREG)
5023     op1 = SUBREG_REG (op1);
5024
5025   if (GENERAL_REG_P (op1))
5026     {
5027       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5028       if (TARGET_INTER_UNIT_MOVES)
5029         emit_insn (gen_sse2_loadld (operands[4],
5030                                     CONST0_RTX (V4SImode), operands[1]));
5031       else
5032         {
5033           operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5034                                               operands[1]);
5035           emit_insn (gen_sse2_loadld (operands[4],
5036                                       CONST0_RTX (V4SImode), operands[5]));
5037           ix86_free_from_memory (GET_MODE (operands[1]));
5038         }
5039     }
5040   /* We can ignore possible trapping value in the
5041      high part of SSE register for non-trapping math. */
5042   else if (SSE_REG_P (op1) && !flag_trapping_math)
5043     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5044   else
5045     gcc_unreachable ();
5046   emit_insn
5047     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5048   DONE;
5049 })
5050
5051 (define_split
5052   [(set (match_operand:MODEF 0 "register_operand" "")
5053         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5054   "TARGET_SSE2 && TARGET_SSE_MATH
5055    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5056    && reload_completed
5057    && (SSE_REG_P (operands[0])
5058        || (GET_CODE (operands[0]) == SUBREG
5059            && SSE_REG_P (operands[0])))"
5060   [(const_int 0)]
5061 {
5062   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5063                                      <MODE>mode, 0);
5064   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5065
5066   emit_insn (gen_sse2_loadld (operands[4],
5067                               CONST0_RTX (V4SImode), operands[1]));
5068   emit_insn
5069     (gen_sse2_cvtdq2<ssevecmodesuffix> (operands[3], operands[4]));
5070   DONE;
5071 })
5072
5073 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5074   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5075         (float:MODEF
5076           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5077   (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5078   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5079    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5080   "#"
5081   [(set_attr "type" "sseicvt")
5082    (set_attr "mode" "<MODEF:MODE>")
5083    (set_attr "athlon_decode" "double,direct")
5084    (set_attr "amdfam10_decode" "vector,double")
5085    (set_attr "bdver1_decode" "double,direct")
5086    (set_attr "fp_int_src" "true")])
5087
5088 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5089   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5090         (float:MODEF
5091           (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5092   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5093    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5094    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5095   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5096   [(set_attr "type" "sseicvt")
5097    (set_attr "prefix" "maybe_vex")
5098    (set_attr "mode" "<MODEF:MODE>")
5099    (set (attr "prefix_rex")
5100      (if_then_else
5101        (and (eq_attr "prefix" "maybe_vex")
5102             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5103        (const_string "1")
5104        (const_string "*")))
5105    (set_attr "athlon_decode" "double,direct")
5106    (set_attr "amdfam10_decode" "vector,double")
5107    (set_attr "bdver1_decode" "double,direct")
5108    (set_attr "fp_int_src" "true")])
5109
5110 (define_split
5111   [(set (match_operand:MODEF 0 "register_operand" "")
5112         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5113    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5114   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5115    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5116    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5117    && reload_completed
5118    && (SSE_REG_P (operands[0])
5119        || (GET_CODE (operands[0]) == SUBREG
5120            && SSE_REG_P (operands[0])))"
5121   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5122
5123 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5124   [(set (match_operand:MODEF 0 "register_operand" "=x")
5125         (float:MODEF
5126           (match_operand:SWI48x 1 "memory_operand" "m")))]
5127   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5128    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5129    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5130   "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5131   [(set_attr "type" "sseicvt")
5132    (set_attr "prefix" "maybe_vex")
5133    (set_attr "mode" "<MODEF:MODE>")
5134    (set (attr "prefix_rex")
5135      (if_then_else
5136        (and (eq_attr "prefix" "maybe_vex")
5137             (ne (symbol_ref "<SWI48x:MODE>mode == DImode") (const_int 0)))
5138        (const_string "1")
5139        (const_string "*")))
5140    (set_attr "athlon_decode" "direct")
5141    (set_attr "amdfam10_decode" "double")
5142    (set_attr "bdver1_decode" "direct")
5143    (set_attr "fp_int_src" "true")])
5144
5145 (define_split
5146   [(set (match_operand:MODEF 0 "register_operand" "")
5147         (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5148    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5149   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5150    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5151    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5152    && reload_completed
5153    && (SSE_REG_P (operands[0])
5154        || (GET_CODE (operands[0]) == SUBREG
5155            && SSE_REG_P (operands[0])))"
5156   [(set (match_dup 2) (match_dup 1))
5157    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5158
5159 (define_split
5160   [(set (match_operand:MODEF 0 "register_operand" "")
5161         (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5162    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5163   "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5164    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5165    && reload_completed
5166    && (SSE_REG_P (operands[0])
5167        || (GET_CODE (operands[0]) == SUBREG
5168            && SSE_REG_P (operands[0])))"
5169   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5170
5171 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5172   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5173         (float:X87MODEF
5174           (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5175   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5176   "TARGET_80387
5177    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5178   "@
5179    fild%Z1\t%1
5180    #"
5181   [(set_attr "type" "fmov,multi")
5182    (set_attr "mode" "<X87MODEF:MODE>")
5183    (set_attr "unit" "*,i387")
5184    (set_attr "fp_int_src" "true")])
5185
5186 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5187   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5188         (float:X87MODEF
5189           (match_operand:SWI48x 1 "memory_operand" "m")))]
5190   "TARGET_80387
5191    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5192   "fild%Z1\t%1"
5193   [(set_attr "type" "fmov")
5194    (set_attr "mode" "<X87MODEF:MODE>")
5195    (set_attr "fp_int_src" "true")])
5196
5197 (define_split
5198   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5199         (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5200    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5201   "TARGET_80387
5202    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5203    && reload_completed"
5204   [(set (match_dup 2) (match_dup 1))
5205    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5206
5207 (define_split
5208   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5209         (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5210    (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5211   "TARGET_80387
5212    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5213    && reload_completed"
5214   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5215
5216 ;; Avoid store forwarding (partial memory) stall penalty
5217 ;; by passing DImode value through XMM registers.  */
5218
5219 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5220   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5221         (float:X87MODEF
5222           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5223    (clobber (match_scratch:V4SI 3 "=X,x"))
5224    (clobber (match_scratch:V4SI 4 "=X,x"))
5225    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5226   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5227    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5228    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5229   "#"
5230   [(set_attr "type" "multi")
5231    (set_attr "mode" "<X87MODEF:MODE>")
5232    (set_attr "unit" "i387")
5233    (set_attr "fp_int_src" "true")])
5234
5235 (define_split
5236   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5237         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5238    (clobber (match_scratch:V4SI 3 ""))
5239    (clobber (match_scratch:V4SI 4 ""))
5240    (clobber (match_operand:DI 2 "memory_operand" ""))]
5241   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5242    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5243    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5244    && reload_completed"
5245   [(set (match_dup 2) (match_dup 3))
5246    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5247 {
5248   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5249      Assemble the 64-bit DImode value in an xmm register.  */
5250   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5251                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5252   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5253                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5254   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5255                                          operands[4]));
5256
5257   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5258 })
5259
5260 (define_split
5261   [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5262         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5263    (clobber (match_scratch:V4SI 3 ""))
5264    (clobber (match_scratch:V4SI 4 ""))
5265    (clobber (match_operand:DI 2 "memory_operand" ""))]
5266   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5267    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5268    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5269    && reload_completed"
5270   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5271
5272 ;; Avoid store forwarding (partial memory) stall penalty by extending
5273 ;; SImode value to DImode through XMM register instead of pushing two
5274 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5275 ;; targets benefit from this optimization. Also note that fild
5276 ;; loads from memory only.
5277
5278 (define_insn "*floatunssi<mode>2_1"
5279   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5280         (unsigned_float:X87MODEF
5281           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5282    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5283    (clobber (match_scratch:SI 3 "=X,x"))]
5284   "!TARGET_64BIT
5285    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5286    && TARGET_SSE"
5287   "#"
5288   [(set_attr "type" "multi")
5289    (set_attr "mode" "<MODE>")])
5290
5291 (define_split
5292   [(set (match_operand:X87MODEF 0 "register_operand" "")
5293         (unsigned_float:X87MODEF
5294           (match_operand:SI 1 "register_operand" "")))
5295    (clobber (match_operand:DI 2 "memory_operand" ""))
5296    (clobber (match_scratch:SI 3 ""))]
5297   "!TARGET_64BIT
5298    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5299    && TARGET_SSE
5300    && reload_completed"
5301   [(set (match_dup 2) (match_dup 1))
5302    (set (match_dup 0)
5303         (float:X87MODEF (match_dup 2)))]
5304   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5305
5306 (define_split
5307   [(set (match_operand:X87MODEF 0 "register_operand" "")
5308         (unsigned_float:X87MODEF
5309           (match_operand:SI 1 "memory_operand" "")))
5310    (clobber (match_operand:DI 2 "memory_operand" ""))
5311    (clobber (match_scratch:SI 3 ""))]
5312   "!TARGET_64BIT
5313    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5314    && TARGET_SSE
5315    && reload_completed"
5316   [(set (match_dup 2) (match_dup 3))
5317    (set (match_dup 0)
5318         (float:X87MODEF (match_dup 2)))]
5319 {
5320   emit_move_insn (operands[3], operands[1]);
5321   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5322 })
5323
5324 (define_expand "floatunssi<mode>2"
5325   [(parallel
5326      [(set (match_operand:X87MODEF 0 "register_operand" "")
5327            (unsigned_float:X87MODEF
5328              (match_operand:SI 1 "nonimmediate_operand" "")))
5329       (clobber (match_dup 2))
5330       (clobber (match_scratch:SI 3 ""))])]
5331   "!TARGET_64BIT
5332    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5333         && TARGET_SSE)
5334        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5335 {
5336   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5337     {
5338       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5339       DONE;
5340     }
5341   else
5342     {
5343       enum ix86_stack_slot slot = (virtuals_instantiated
5344                                    ? SLOT_TEMP
5345                                    : SLOT_VIRTUAL);
5346       operands[2] = assign_386_stack_local (DImode, slot);
5347     }
5348 })
5349
5350 (define_expand "floatunsdisf2"
5351   [(use (match_operand:SF 0 "register_operand" ""))
5352    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5353   "TARGET_64BIT && TARGET_SSE_MATH"
5354   "x86_emit_floatuns (operands); DONE;")
5355
5356 (define_expand "floatunsdidf2"
5357   [(use (match_operand:DF 0 "register_operand" ""))
5358    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5359   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5360    && TARGET_SSE2 && TARGET_SSE_MATH"
5361 {
5362   if (TARGET_64BIT)
5363     x86_emit_floatuns (operands);
5364   else
5365     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5366   DONE;
5367 })
5368 \f
5369 ;; Add instructions
5370
5371 (define_expand "add<mode>3"
5372   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5373         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5374                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5375   ""
5376   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5377
5378 (define_insn_and_split "*add<dwi>3_doubleword"
5379   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5380         (plus:<DWI>
5381           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5382           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5383    (clobber (reg:CC FLAGS_REG))]
5384   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5385   "#"
5386   "reload_completed"
5387   [(parallel [(set (reg:CC FLAGS_REG)
5388                    (unspec:CC [(match_dup 1) (match_dup 2)]
5389                               UNSPEC_ADD_CARRY))
5390               (set (match_dup 0)
5391                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5392    (parallel [(set (match_dup 3)
5393                    (plus:DWIH
5394                      (match_dup 4)
5395                      (plus:DWIH
5396                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5397                        (match_dup 5))))
5398               (clobber (reg:CC FLAGS_REG))])]
5399   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5400
5401 (define_insn "*add<mode>3_cc"
5402   [(set (reg:CC FLAGS_REG)
5403         (unspec:CC
5404           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5405            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5406           UNSPEC_ADD_CARRY))
5407    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5408         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5409   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5410   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5411   [(set_attr "type" "alu")
5412    (set_attr "mode" "<MODE>")])
5413
5414 (define_insn "addqi3_cc"
5415   [(set (reg:CC FLAGS_REG)
5416         (unspec:CC
5417           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5418            (match_operand:QI 2 "general_operand" "qn,qm")]
5419           UNSPEC_ADD_CARRY))
5420    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5421         (plus:QI (match_dup 1) (match_dup 2)))]
5422   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5423   "add{b}\t{%2, %0|%0, %2}"
5424   [(set_attr "type" "alu")
5425    (set_attr "mode" "QI")])
5426
5427 (define_insn "*lea_1"
5428   [(set (match_operand:SWI48 0 "register_operand" "=r")
5429         (match_operand:SWI48 1 "no_seg_address_operand" "p"))]
5430   ""
5431   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5432   [(set_attr "type" "lea")
5433    (set_attr "mode" "<MODE>")])
5434
5435 (define_insn "*lea_1_zext"
5436   [(set (match_operand:DI 0 "register_operand" "=r")
5437         (zero_extend:DI
5438           (match_operand:SI 1 "no_seg_address_operand" "p")))]
5439   "TARGET_64BIT"
5440   "lea{l}\t{%a1, %k0|%k0, %a1}"
5441   [(set_attr "type" "lea")
5442    (set_attr "mode" "SI")])
5443
5444 (define_insn "*lea_2"
5445   [(set (match_operand:SI 0 "register_operand" "=r")
5446         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5447   "TARGET_64BIT"
5448   "lea{l}\t{%a1, %0|%0, %a1}"
5449   [(set_attr "type" "lea")
5450    (set_attr "mode" "SI")])
5451
5452 (define_insn "*lea_2_zext"
5453   [(set (match_operand:DI 0 "register_operand" "=r")
5454         (zero_extend:DI
5455           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5456   "TARGET_64BIT"
5457   "lea{l}\t{%a1, %k0|%k0, %a1}"
5458   [(set_attr "type" "lea")
5459    (set_attr "mode" "SI")])
5460
5461 (define_insn "*add<mode>_1"
5462   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5463         (plus:SWI48
5464           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5465           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5466    (clobber (reg:CC FLAGS_REG))]
5467   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5468 {
5469   switch (get_attr_type (insn))
5470     {
5471     case TYPE_LEA:
5472       return "#";
5473
5474     case TYPE_INCDEC:
5475       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5476       if (operands[2] == const1_rtx)
5477         return "inc{<imodesuffix>}\t%0";
5478       else
5479         {
5480           gcc_assert (operands[2] == constm1_rtx);
5481           return "dec{<imodesuffix>}\t%0";
5482         }
5483
5484     default:
5485       /* For most processors, ADD is faster than LEA.  This alternative
5486          was added to use ADD as much as possible.  */
5487       if (which_alternative == 2)
5488         {
5489           rtx tmp;
5490           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5491         }
5492         
5493       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5494       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5495         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5496
5497       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5498     }
5499 }
5500   [(set (attr "type")
5501      (cond [(eq_attr "alternative" "3")
5502               (const_string "lea")
5503             (match_operand:SWI48 2 "incdec_operand" "")
5504               (const_string "incdec")
5505            ]
5506            (const_string "alu")))
5507    (set (attr "length_immediate")
5508       (if_then_else
5509         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5510         (const_string "1")
5511         (const_string "*")))
5512    (set_attr "mode" "<MODE>")])
5513
5514 ;; It may seem that nonimmediate operand is proper one for operand 1.
5515 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5516 ;; we take care in ix86_binary_operator_ok to not allow two memory
5517 ;; operands so proper swapping will be done in reload.  This allow
5518 ;; patterns constructed from addsi_1 to match.
5519
5520 (define_insn "addsi_1_zext"
5521   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5522         (zero_extend:DI
5523           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5524                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5525    (clobber (reg:CC FLAGS_REG))]
5526   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5527 {
5528   switch (get_attr_type (insn))
5529     {
5530     case TYPE_LEA:
5531       return "#";
5532
5533     case TYPE_INCDEC:
5534       if (operands[2] == const1_rtx)
5535         return "inc{l}\t%k0";
5536       else
5537         {
5538           gcc_assert (operands[2] == constm1_rtx);
5539           return "dec{l}\t%k0";
5540         }
5541
5542     default:
5543       /* For most processors, ADD is faster than LEA.  This alternative
5544          was added to use ADD as much as possible.  */
5545       if (which_alternative == 1)
5546         {
5547           rtx tmp;
5548           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5549         }
5550
5551       if (x86_maybe_negate_const_int (&operands[2], SImode))
5552         return "sub{l}\t{%2, %k0|%k0, %2}";
5553
5554       return "add{l}\t{%2, %k0|%k0, %2}";
5555     }
5556 }
5557   [(set (attr "type")
5558      (cond [(eq_attr "alternative" "2")
5559               (const_string "lea")
5560             (match_operand:SI 2 "incdec_operand" "")
5561               (const_string "incdec")
5562            ]
5563            (const_string "alu")))
5564    (set (attr "length_immediate")
5565       (if_then_else
5566         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5567         (const_string "1")
5568         (const_string "*")))
5569    (set_attr "mode" "SI")])
5570
5571 (define_insn "*addhi_1"
5572   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5573         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5574                  (match_operand:HI 2 "general_operand" "rn,rm")))
5575    (clobber (reg:CC FLAGS_REG))]
5576   "TARGET_PARTIAL_REG_STALL
5577    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5578 {
5579   switch (get_attr_type (insn))
5580     {
5581     case TYPE_INCDEC:
5582       if (operands[2] == const1_rtx)
5583         return "inc{w}\t%0";
5584       else
5585         {
5586           gcc_assert (operands[2] == constm1_rtx);
5587           return "dec{w}\t%0";
5588         }
5589
5590     default:
5591       if (x86_maybe_negate_const_int (&operands[2], HImode))
5592         return "sub{w}\t{%2, %0|%0, %2}";
5593
5594       return "add{w}\t{%2, %0|%0, %2}";
5595     }
5596 }
5597   [(set (attr "type")
5598      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5599         (const_string "incdec")
5600         (const_string "alu")))
5601    (set (attr "length_immediate")
5602       (if_then_else
5603         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5604         (const_string "1")
5605         (const_string "*")))
5606    (set_attr "mode" "HI")])
5607
5608 (define_insn "*addhi_1_lea"
5609   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5610         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5611                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5612    (clobber (reg:CC FLAGS_REG))]
5613   "!TARGET_PARTIAL_REG_STALL
5614    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5615 {
5616   switch (get_attr_type (insn))
5617     {
5618     case TYPE_LEA:
5619       return "#";
5620
5621     case TYPE_INCDEC:
5622       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5623       if (operands[2] == const1_rtx)
5624         return "inc{w}\t%0";
5625       else
5626         {
5627           gcc_assert (operands[2] == constm1_rtx);
5628           return "dec{w}\t%0";
5629         }
5630
5631     default:
5632       /* For most processors, ADD is faster than LEA.  This alternative
5633          was added to use ADD as much as possible.  */
5634       if (which_alternative == 2)
5635         {
5636           rtx tmp;
5637           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5638         }
5639
5640       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641       if (x86_maybe_negate_const_int (&operands[2], HImode))
5642         return "sub{w}\t{%2, %0|%0, %2}";
5643
5644       return "add{w}\t{%2, %0|%0, %2}";
5645     }
5646 }
5647   [(set (attr "type")
5648      (cond [(eq_attr "alternative" "3")
5649               (const_string "lea")
5650             (match_operand:HI 2 "incdec_operand" "")
5651               (const_string "incdec")
5652            ]
5653            (const_string "alu")))
5654    (set (attr "length_immediate")
5655       (if_then_else
5656         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5657         (const_string "1")
5658         (const_string "*")))
5659    (set_attr "mode" "HI,HI,HI,SI")])
5660
5661 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5662 (define_insn "*addqi_1"
5663   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5664         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5665                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5666    (clobber (reg:CC FLAGS_REG))]
5667   "TARGET_PARTIAL_REG_STALL
5668    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5669 {
5670   int widen = (which_alternative == 2);
5671   switch (get_attr_type (insn))
5672     {
5673     case TYPE_INCDEC:
5674       if (operands[2] == const1_rtx)
5675         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5676       else
5677         {
5678           gcc_assert (operands[2] == constm1_rtx);
5679           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5680         }
5681
5682     default:
5683       if (x86_maybe_negate_const_int (&operands[2], QImode))
5684         {
5685           if (widen)
5686             return "sub{l}\t{%2, %k0|%k0, %2}";
5687           else
5688             return "sub{b}\t{%2, %0|%0, %2}";
5689         }
5690       if (widen)
5691         return "add{l}\t{%k2, %k0|%k0, %k2}";
5692       else
5693         return "add{b}\t{%2, %0|%0, %2}";
5694     }
5695 }
5696   [(set (attr "type")
5697      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5698         (const_string "incdec")
5699         (const_string "alu")))
5700    (set (attr "length_immediate")
5701       (if_then_else
5702         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5703         (const_string "1")
5704         (const_string "*")))
5705    (set_attr "mode" "QI,QI,SI")])
5706
5707 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5708 (define_insn "*addqi_1_lea"
5709   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5710         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5711                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5712    (clobber (reg:CC FLAGS_REG))]
5713   "!TARGET_PARTIAL_REG_STALL
5714    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5715 {
5716   int widen = (which_alternative == 3 || which_alternative == 4);
5717
5718   switch (get_attr_type (insn))
5719     {
5720     case TYPE_LEA:
5721       return "#";
5722
5723     case TYPE_INCDEC:
5724       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5725       if (operands[2] == const1_rtx)
5726         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5727       else
5728         {
5729           gcc_assert (operands[2] == constm1_rtx);
5730           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5731         }
5732
5733     default:
5734       /* For most processors, ADD is faster than LEA.  These alternatives
5735          were added to use ADD as much as possible.  */
5736       if (which_alternative == 2 || which_alternative == 4)
5737         {
5738           rtx tmp;
5739           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5740         }
5741
5742       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5743       if (x86_maybe_negate_const_int (&operands[2], QImode))
5744         {
5745           if (widen)
5746             return "sub{l}\t{%2, %k0|%k0, %2}";
5747           else
5748             return "sub{b}\t{%2, %0|%0, %2}";
5749         }
5750       if (widen)
5751         return "add{l}\t{%k2, %k0|%k0, %k2}";
5752       else
5753         return "add{b}\t{%2, %0|%0, %2}";
5754     }
5755 }
5756   [(set (attr "type")
5757      (cond [(eq_attr "alternative" "5")
5758               (const_string "lea")
5759             (match_operand:QI 2 "incdec_operand" "")
5760               (const_string "incdec")
5761            ]
5762            (const_string "alu")))
5763    (set (attr "length_immediate")
5764       (if_then_else
5765         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5766         (const_string "1")
5767         (const_string "*")))
5768    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5769
5770 (define_insn "*addqi_1_slp"
5771   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5772         (plus:QI (match_dup 0)
5773                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5774    (clobber (reg:CC FLAGS_REG))]
5775   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5776    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5777 {
5778   switch (get_attr_type (insn))
5779     {
5780     case TYPE_INCDEC:
5781       if (operands[1] == const1_rtx)
5782         return "inc{b}\t%0";
5783       else
5784         {
5785           gcc_assert (operands[1] == constm1_rtx);
5786           return "dec{b}\t%0";
5787         }
5788
5789     default:
5790       if (x86_maybe_negate_const_int (&operands[1], QImode))
5791         return "sub{b}\t{%1, %0|%0, %1}";
5792
5793       return "add{b}\t{%1, %0|%0, %1}";
5794     }
5795 }
5796   [(set (attr "type")
5797      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5798         (const_string "incdec")
5799         (const_string "alu1")))
5800    (set (attr "memory")
5801      (if_then_else (match_operand 1 "memory_operand" "")
5802         (const_string "load")
5803         (const_string "none")))
5804    (set_attr "mode" "QI")])
5805
5806 ;; Convert add to the lea pattern to avoid flags dependency.
5807 (define_split
5808   [(set (match_operand:SWI 0 "register_operand" "")
5809         (plus:SWI (match_operand:SWI 1 "register_operand" "")
5810                   (match_operand:SWI 2 "<nonmemory_operand>" "")))
5811    (clobber (reg:CC FLAGS_REG))]
5812   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5813   [(const_int 0)]
5814 {
5815   enum machine_mode mode = <MODE>mode;
5816   rtx pat;
5817
5818   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5819     { 
5820       mode = SImode; 
5821       operands[0] = gen_lowpart (mode, operands[0]);
5822       operands[1] = gen_lowpart (mode, operands[1]);
5823       operands[2] = gen_lowpart (mode, operands[2]);
5824     }
5825
5826   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5827
5828   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5829   DONE;
5830 })
5831
5832 ;; Convert add to the lea pattern to avoid flags dependency.
5833 (define_split
5834   [(set (match_operand:DI 0 "register_operand" "")
5835         (zero_extend:DI
5836           (plus:SI (match_operand:SI 1 "register_operand" "")
5837                    (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5838    (clobber (reg:CC FLAGS_REG))]
5839   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5840   [(set (match_dup 0)
5841         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5842
5843 (define_insn "*add<mode>_2"
5844   [(set (reg FLAGS_REG)
5845         (compare
5846           (plus:SWI
5847             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5848             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5849           (const_int 0)))
5850    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5851         (plus:SWI (match_dup 1) (match_dup 2)))]
5852   "ix86_match_ccmode (insn, CCGOCmode)
5853    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5854 {
5855   switch (get_attr_type (insn))
5856     {
5857     case TYPE_INCDEC:
5858       if (operands[2] == const1_rtx)
5859         return "inc{<imodesuffix>}\t%0";
5860       else
5861         {
5862           gcc_assert (operands[2] == constm1_rtx);
5863           return "dec{<imodesuffix>}\t%0";
5864         }
5865
5866     default:
5867       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5868         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5869
5870       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5871     }
5872 }
5873   [(set (attr "type")
5874      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5875         (const_string "incdec")
5876         (const_string "alu")))
5877    (set (attr "length_immediate")
5878       (if_then_else
5879         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5880         (const_string "1")
5881         (const_string "*")))
5882    (set_attr "mode" "<MODE>")])
5883
5884 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5885 (define_insn "*addsi_2_zext"
5886   [(set (reg FLAGS_REG)
5887         (compare
5888           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5889                    (match_operand:SI 2 "x86_64_general_operand" "rme"))
5890           (const_int 0)))
5891    (set (match_operand:DI 0 "register_operand" "=r")
5892         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5893   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5894    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5895 {
5896   switch (get_attr_type (insn))
5897     {
5898     case TYPE_INCDEC:
5899       if (operands[2] == const1_rtx)
5900         return "inc{l}\t%k0";
5901       else
5902         {
5903           gcc_assert (operands[2] == constm1_rtx);
5904           return "dec{l}\t%k0";
5905         }
5906
5907     default:
5908       if (x86_maybe_negate_const_int (&operands[2], SImode))
5909         return "sub{l}\t{%2, %k0|%k0, %2}";
5910
5911       return "add{l}\t{%2, %k0|%k0, %2}";
5912     }
5913 }
5914   [(set (attr "type")
5915      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5916         (const_string "incdec")
5917         (const_string "alu")))
5918    (set (attr "length_immediate")
5919       (if_then_else
5920         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5921         (const_string "1")
5922         (const_string "*")))
5923    (set_attr "mode" "SI")])
5924
5925 (define_insn "*add<mode>_3"
5926   [(set (reg FLAGS_REG)
5927         (compare
5928           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5929           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5930    (clobber (match_scratch:SWI 0 "=<r>"))]
5931   "ix86_match_ccmode (insn, CCZmode)
5932    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5933 {
5934   switch (get_attr_type (insn))
5935     {
5936     case TYPE_INCDEC:
5937       if (operands[2] == const1_rtx)
5938         return "inc{<imodesuffix>}\t%0";
5939       else
5940         {
5941           gcc_assert (operands[2] == constm1_rtx);
5942           return "dec{<imodesuffix>}\t%0";
5943         }
5944
5945     default:
5946       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5947         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5948
5949       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5950     }
5951 }
5952   [(set (attr "type")
5953      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5954         (const_string "incdec")
5955         (const_string "alu")))
5956    (set (attr "length_immediate")
5957       (if_then_else
5958         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5959         (const_string "1")
5960         (const_string "*")))
5961    (set_attr "mode" "<MODE>")])
5962
5963 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5964 (define_insn "*addsi_3_zext"
5965   [(set (reg FLAGS_REG)
5966         (compare
5967           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5968           (match_operand:SI 1 "nonimmediate_operand" "%0")))
5969    (set (match_operand:DI 0 "register_operand" "=r")
5970         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5971   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5972    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5973 {
5974   switch (get_attr_type (insn))
5975     {
5976     case TYPE_INCDEC:
5977       if (operands[2] == const1_rtx)
5978         return "inc{l}\t%k0";
5979       else
5980         {
5981           gcc_assert (operands[2] == constm1_rtx);
5982           return "dec{l}\t%k0";
5983         }
5984
5985     default:
5986       if (x86_maybe_negate_const_int (&operands[2], SImode))
5987         return "sub{l}\t{%2, %k0|%k0, %2}";
5988
5989       return "add{l}\t{%2, %k0|%k0, %2}";
5990     }
5991 }
5992   [(set (attr "type")
5993      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5994         (const_string "incdec")
5995         (const_string "alu")))
5996    (set (attr "length_immediate")
5997       (if_then_else
5998         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5999         (const_string "1")
6000         (const_string "*")))
6001    (set_attr "mode" "SI")])
6002
6003 ; For comparisons against 1, -1 and 128, we may generate better code
6004 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6005 ; is matched then.  We can't accept general immediate, because for
6006 ; case of overflows,  the result is messed up.
6007 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6008 ; only for comparisons not depending on it.
6009
6010 (define_insn "*adddi_4"
6011   [(set (reg FLAGS_REG)
6012         (compare
6013           (match_operand:DI 1 "nonimmediate_operand" "0")
6014           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6015    (clobber (match_scratch:DI 0 "=rm"))]
6016   "TARGET_64BIT
6017    && ix86_match_ccmode (insn, CCGCmode)"
6018 {
6019   switch (get_attr_type (insn))
6020     {
6021     case TYPE_INCDEC:
6022       if (operands[2] == constm1_rtx)
6023         return "inc{q}\t%0";
6024       else
6025         {
6026           gcc_assert (operands[2] == const1_rtx);
6027           return "dec{q}\t%0";
6028         }
6029
6030     default:
6031       if (x86_maybe_negate_const_int (&operands[2], DImode))
6032         return "add{q}\t{%2, %0|%0, %2}";
6033
6034       return "sub{q}\t{%2, %0|%0, %2}";
6035     }
6036 }
6037   [(set (attr "type")
6038      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6039         (const_string "incdec")
6040         (const_string "alu")))
6041    (set (attr "length_immediate")
6042       (if_then_else
6043         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6044         (const_string "1")
6045         (const_string "*")))
6046    (set_attr "mode" "DI")])
6047
6048 ; For comparisons against 1, -1 and 128, we may generate better code
6049 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6050 ; is matched then.  We can't accept general immediate, because for
6051 ; case of overflows,  the result is messed up.
6052 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6053 ; only for comparisons not depending on it.
6054
6055 (define_insn "*add<mode>_4"
6056   [(set (reg FLAGS_REG)
6057         (compare
6058           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6059           (match_operand:SWI124 2 "const_int_operand" "n")))
6060    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6061   "ix86_match_ccmode (insn, CCGCmode)"
6062 {
6063   switch (get_attr_type (insn))
6064     {
6065     case TYPE_INCDEC:
6066       if (operands[2] == constm1_rtx)
6067         return "inc{<imodesuffix>}\t%0";
6068       else
6069         {
6070           gcc_assert (operands[2] == const1_rtx);
6071           return "dec{<imodesuffix>}\t%0";
6072         }
6073
6074     default:
6075       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6076         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6077
6078       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6079     }
6080 }
6081   [(set (attr "type")
6082      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6083         (const_string "incdec")
6084         (const_string "alu")))
6085    (set (attr "length_immediate")
6086       (if_then_else
6087         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6088         (const_string "1")
6089         (const_string "*")))
6090    (set_attr "mode" "<MODE>")])
6091
6092 (define_insn "*add<mode>_5"
6093   [(set (reg FLAGS_REG)
6094         (compare
6095           (plus:SWI
6096             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6097             (match_operand:SWI 2 "<general_operand>" "<g>"))
6098           (const_int 0)))
6099    (clobber (match_scratch:SWI 0 "=<r>"))]
6100   "ix86_match_ccmode (insn, CCGOCmode)
6101    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6102 {
6103   switch (get_attr_type (insn))
6104     {
6105     case TYPE_INCDEC:
6106       if (operands[2] == const1_rtx)
6107         return "inc{<imodesuffix>}\t%0";
6108       else
6109         {
6110           gcc_assert (operands[2] == constm1_rtx);
6111           return "dec{<imodesuffix>}\t%0";
6112         }
6113
6114     default:
6115       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6116         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6117
6118       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6119     }
6120 }
6121   [(set (attr "type")
6122      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6123         (const_string "incdec")
6124         (const_string "alu")))
6125    (set (attr "length_immediate")
6126       (if_then_else
6127         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6128         (const_string "1")
6129         (const_string "*")))
6130    (set_attr "mode" "<MODE>")])
6131
6132 (define_insn "*addqi_ext_1_rex64"
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 "nonmemory_operand" "Qn")))
6142    (clobber (reg:CC FLAGS_REG))]
6143   "TARGET_64BIT"
6144 {
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         }
6155
6156     default:
6157       return "add{b}\t{%2, %h0|%h0, %2}";
6158     }
6159 }
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")])
6166
6167 (define_insn "addqi_ext_1"
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           (match_operand:QI 2 "general_operand" "Qmn")))
6177    (clobber (reg:CC FLAGS_REG))]
6178   "!TARGET_64BIT"
6179 {
6180   switch (get_attr_type (insn))
6181     {
6182     case TYPE_INCDEC:
6183       if (operands[2] == const1_rtx)
6184         return "inc{b}\t%h0";
6185       else
6186         {
6187           gcc_assert (operands[2] == constm1_rtx);
6188           return "dec{b}\t%h0";
6189         }
6190
6191     default:
6192       return "add{b}\t{%2, %h0|%h0, %2}";
6193     }
6194 }
6195   [(set (attr "type")
6196      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6197         (const_string "incdec")
6198         (const_string "alu")))
6199    (set_attr "modrm" "1")
6200    (set_attr "mode" "QI")])
6201
6202 (define_insn "*addqi_ext_2"
6203   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6204                          (const_int 8)
6205                          (const_int 8))
6206         (plus:SI
6207           (zero_extract:SI
6208             (match_operand 1 "ext_register_operand" "%0")
6209             (const_int 8)
6210             (const_int 8))
6211           (zero_extract:SI
6212             (match_operand 2 "ext_register_operand" "Q")
6213             (const_int 8)
6214             (const_int 8))))
6215    (clobber (reg:CC FLAGS_REG))]
6216   ""
6217   "add{b}\t{%h2, %h0|%h0, %h2}"
6218   [(set_attr "type" "alu")
6219    (set_attr "mode" "QI")])
6220
6221 ;; The lea patterns for modes less than 32 bits need to be matched by
6222 ;; several insns converted to real lea by splitters.
6223
6224 (define_insn_and_split "*lea_general_1"
6225   [(set (match_operand 0 "register_operand" "=r")
6226         (plus (plus (match_operand 1 "index_register_operand" "l")
6227                     (match_operand 2 "register_operand" "r"))
6228               (match_operand 3 "immediate_operand" "i")))]
6229   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6230    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6231    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6232    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6233    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6234        || GET_MODE (operands[3]) == VOIDmode)"
6235   "#"
6236   "&& reload_completed"
6237   [(const_int 0)]
6238 {
6239   enum machine_mode mode = SImode;
6240   rtx pat;
6241
6242   operands[0] = gen_lowpart (mode, operands[0]);
6243   operands[1] = gen_lowpart (mode, operands[1]);
6244   operands[2] = gen_lowpart (mode, operands[2]);
6245   operands[3] = gen_lowpart (mode, operands[3]);
6246
6247   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6248                       operands[3]);
6249
6250   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6251   DONE;
6252 }
6253   [(set_attr "type" "lea")
6254    (set_attr "mode" "SI")])
6255
6256 (define_insn_and_split "*lea_general_2"
6257   [(set (match_operand 0 "register_operand" "=r")
6258         (plus (mult (match_operand 1 "index_register_operand" "l")
6259                     (match_operand 2 "const248_operand" "n"))
6260               (match_operand 3 "nonmemory_operand" "ri")))]
6261   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6262    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6263    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6264    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6265        || GET_MODE (operands[3]) == VOIDmode)"
6266   "#"
6267   "&& reload_completed"
6268   [(const_int 0)]
6269 {
6270   enum machine_mode mode = SImode;
6271   rtx pat;
6272
6273   operands[0] = gen_lowpart (mode, operands[0]);
6274   operands[1] = gen_lowpart (mode, operands[1]);
6275   operands[3] = gen_lowpart (mode, operands[3]);
6276
6277   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6278                       operands[3]);
6279
6280   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6281   DONE;
6282 }
6283   [(set_attr "type" "lea")
6284    (set_attr "mode" "SI")])
6285
6286 (define_insn_and_split "*lea_general_3"
6287   [(set (match_operand 0 "register_operand" "=r")
6288         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6289                           (match_operand 2 "const248_operand" "n"))
6290                     (match_operand 3 "register_operand" "r"))
6291               (match_operand 4 "immediate_operand" "i")))]
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]) == GET_MODE (operands[1])
6295    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6296   "#"
6297   "&& reload_completed"
6298   [(const_int 0)]
6299 {
6300   enum machine_mode mode = SImode;
6301   rtx pat;
6302
6303   operands[0] = gen_lowpart (mode, operands[0]);
6304   operands[1] = gen_lowpart (mode, operands[1]);
6305   operands[3] = gen_lowpart (mode, operands[3]);
6306   operands[4] = gen_lowpart (mode, operands[4]);
6307
6308   pat = gen_rtx_PLUS (mode,
6309                       gen_rtx_PLUS (mode,
6310                                     gen_rtx_MULT (mode, operands[1],
6311                                                         operands[2]),
6312                                     operands[3]),
6313                       operands[4]);
6314
6315   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6316   DONE;
6317 }
6318   [(set_attr "type" "lea")
6319    (set_attr "mode" "SI")])
6320
6321 (define_insn_and_split "*lea_general_4"
6322   [(set (match_operand 0 "register_operand" "=r")
6323         (any_or (ashift
6324                   (match_operand 1 "index_register_operand" "l")
6325                   (match_operand 2 "const_int_operand" "n"))
6326                 (match_operand 3 "const_int_operand" "n")))]
6327   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6328       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6329     || GET_MODE (operands[0]) == SImode
6330     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6331    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6332    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6333    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6334        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6335   "#"
6336   "&& reload_completed"
6337   [(const_int 0)]
6338 {
6339   enum machine_mode mode = GET_MODE (operands[0]);
6340   rtx pat;
6341
6342   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6343     { 
6344       mode = SImode; 
6345       operands[0] = gen_lowpart (mode, operands[0]);
6346       operands[1] = gen_lowpart (mode, operands[1]);
6347     }
6348
6349   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6350
6351   pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6352                        INTVAL (operands[3]));
6353
6354   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6355   DONE;
6356 }
6357   [(set_attr "type" "lea")
6358    (set (attr "mode")
6359       (if_then_else (match_operand:DI 0 "" "")
6360         (const_string "DI")
6361         (const_string "SI")))])
6362 \f
6363 ;; Subtract instructions
6364
6365 (define_expand "sub<mode>3"
6366   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6367         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6368                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6369   ""
6370   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6371
6372 (define_insn_and_split "*sub<dwi>3_doubleword"
6373   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6374         (minus:<DWI>
6375           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6376           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6377    (clobber (reg:CC FLAGS_REG))]
6378   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6379   "#"
6380   "reload_completed"
6381   [(parallel [(set (reg:CC FLAGS_REG)
6382                    (compare:CC (match_dup 1) (match_dup 2)))
6383               (set (match_dup 0)
6384                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6385    (parallel [(set (match_dup 3)
6386                    (minus:DWIH
6387                      (match_dup 4)
6388                      (plus:DWIH
6389                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6390                        (match_dup 5))))
6391               (clobber (reg:CC FLAGS_REG))])]
6392   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6393
6394 (define_insn "*sub<mode>_1"
6395   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6396         (minus:SWI
6397           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6398           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6399    (clobber (reg:CC FLAGS_REG))]
6400   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6401   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6402   [(set_attr "type" "alu")
6403    (set_attr "mode" "<MODE>")])
6404
6405 (define_insn "*subsi_1_zext"
6406   [(set (match_operand:DI 0 "register_operand" "=r")
6407         (zero_extend:DI
6408           (minus:SI (match_operand:SI 1 "register_operand" "0")
6409                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6410    (clobber (reg:CC FLAGS_REG))]
6411   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6412   "sub{l}\t{%2, %k0|%k0, %2}"
6413   [(set_attr "type" "alu")
6414    (set_attr "mode" "SI")])
6415
6416 (define_insn "*subqi_1_slp"
6417   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6418         (minus:QI (match_dup 0)
6419                   (match_operand:QI 1 "general_operand" "qn,qm")))
6420    (clobber (reg:CC FLAGS_REG))]
6421   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6422    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6423   "sub{b}\t{%1, %0|%0, %1}"
6424   [(set_attr "type" "alu1")
6425    (set_attr "mode" "QI")])
6426
6427 (define_insn "*sub<mode>_2"
6428   [(set (reg FLAGS_REG)
6429         (compare
6430           (minus:SWI
6431             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6432             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6433           (const_int 0)))
6434    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6435         (minus:SWI (match_dup 1) (match_dup 2)))]
6436   "ix86_match_ccmode (insn, CCGOCmode)
6437    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6438   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6439   [(set_attr "type" "alu")
6440    (set_attr "mode" "<MODE>")])
6441
6442 (define_insn "*subsi_2_zext"
6443   [(set (reg FLAGS_REG)
6444         (compare
6445           (minus:SI (match_operand:SI 1 "register_operand" "0")
6446                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6447           (const_int 0)))
6448    (set (match_operand:DI 0 "register_operand" "=r")
6449         (zero_extend:DI
6450           (minus:SI (match_dup 1)
6451                     (match_dup 2))))]
6452   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6453    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6454   "sub{l}\t{%2, %k0|%k0, %2}"
6455   [(set_attr "type" "alu")
6456    (set_attr "mode" "SI")])
6457
6458 (define_insn "*sub<mode>_3"
6459   [(set (reg FLAGS_REG)
6460         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6461                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6462    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6463         (minus:SWI (match_dup 1) (match_dup 2)))]
6464   "ix86_match_ccmode (insn, CCmode)
6465    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6466   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6467   [(set_attr "type" "alu")
6468    (set_attr "mode" "<MODE>")])
6469
6470 (define_insn "*subsi_3_zext"
6471   [(set (reg FLAGS_REG)
6472         (compare (match_operand:SI 1 "register_operand" "0")
6473                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6474    (set (match_operand:DI 0 "register_operand" "=r")
6475         (zero_extend:DI
6476           (minus:SI (match_dup 1)
6477                     (match_dup 2))))]
6478   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6479    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6480   "sub{l}\t{%2, %1|%1, %2}"
6481   [(set_attr "type" "alu")
6482    (set_attr "mode" "SI")])
6483 \f
6484 ;; Add with carry and subtract with borrow
6485
6486 (define_expand "<plusminus_insn><mode>3_carry"
6487   [(parallel
6488     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6489           (plusminus:SWI
6490             (match_operand:SWI 1 "nonimmediate_operand" "")
6491             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6492                        [(match_operand 3 "flags_reg_operand" "")
6493                         (const_int 0)])
6494                       (match_operand:SWI 2 "<general_operand>" ""))))
6495      (clobber (reg:CC FLAGS_REG))])]
6496   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6497
6498 (define_insn "*<plusminus_insn><mode>3_carry"
6499   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6500         (plusminus:SWI
6501           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6502           (plus:SWI
6503             (match_operator 3 "ix86_carry_flag_operator"
6504              [(reg FLAGS_REG) (const_int 0)])
6505             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6506    (clobber (reg:CC FLAGS_REG))]
6507   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6508   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6509   [(set_attr "type" "alu")
6510    (set_attr "use_carry" "1")
6511    (set_attr "pent_pair" "pu")
6512    (set_attr "mode" "<MODE>")])
6513
6514 (define_insn "*addsi3_carry_zext"
6515   [(set (match_operand:DI 0 "register_operand" "=r")
6516         (zero_extend:DI
6517           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6518                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6519                              [(reg FLAGS_REG) (const_int 0)])
6520                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6521    (clobber (reg:CC FLAGS_REG))]
6522   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6523   "adc{l}\t{%2, %k0|%k0, %2}"
6524   [(set_attr "type" "alu")
6525    (set_attr "use_carry" "1")
6526    (set_attr "pent_pair" "pu")
6527    (set_attr "mode" "SI")])
6528
6529 (define_insn "*subsi3_carry_zext"
6530   [(set (match_operand:DI 0 "register_operand" "=r")
6531         (zero_extend:DI
6532           (minus:SI (match_operand:SI 1 "register_operand" "0")
6533                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6534                               [(reg FLAGS_REG) (const_int 0)])
6535                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6536    (clobber (reg:CC FLAGS_REG))]
6537   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6538   "sbb{l}\t{%2, %k0|%k0, %2}"
6539   [(set_attr "type" "alu")
6540    (set_attr "pent_pair" "pu")
6541    (set_attr "mode" "SI")])
6542 \f
6543 ;; Overflow setting add and subtract instructions
6544
6545 (define_insn "*add<mode>3_cconly_overflow"
6546   [(set (reg:CCC FLAGS_REG)
6547         (compare:CCC
6548           (plus:SWI
6549             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6550             (match_operand:SWI 2 "<general_operand>" "<g>"))
6551           (match_dup 1)))
6552    (clobber (match_scratch:SWI 0 "=<r>"))]
6553   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6554   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6555   [(set_attr "type" "alu")
6556    (set_attr "mode" "<MODE>")])
6557
6558 (define_insn "*sub<mode>3_cconly_overflow"
6559   [(set (reg:CCC FLAGS_REG)
6560         (compare:CCC
6561           (minus:SWI
6562             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6563             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6564           (match_dup 0)))]
6565   ""
6566   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6567   [(set_attr "type" "icmp")
6568    (set_attr "mode" "<MODE>")])
6569
6570 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6571   [(set (reg:CCC FLAGS_REG)
6572         (compare:CCC
6573             (plusminus:SWI
6574                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6575                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6576             (match_dup 1)))
6577    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6578         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6579   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6580   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6581   [(set_attr "type" "alu")
6582    (set_attr "mode" "<MODE>")])
6583
6584 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6585   [(set (reg:CCC FLAGS_REG)
6586         (compare:CCC
6587           (plusminus:SI
6588             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6589             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6590           (match_dup 1)))
6591    (set (match_operand:DI 0 "register_operand" "=r")
6592         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6593   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6594   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6595   [(set_attr "type" "alu")
6596    (set_attr "mode" "SI")])
6597
6598 ;; The patterns that match these are at the end of this file.
6599
6600 (define_expand "<plusminus_insn>xf3"
6601   [(set (match_operand:XF 0 "register_operand" "")
6602         (plusminus:XF
6603           (match_operand:XF 1 "register_operand" "")
6604           (match_operand:XF 2 "register_operand" "")))]
6605   "TARGET_80387")
6606
6607 (define_expand "<plusminus_insn><mode>3"
6608   [(set (match_operand:MODEF 0 "register_operand" "")
6609         (plusminus:MODEF
6610           (match_operand:MODEF 1 "register_operand" "")
6611           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6612   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6613     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6614 \f
6615 ;; Multiply instructions
6616
6617 (define_expand "mul<mode>3"
6618   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6619                    (mult:SWIM248
6620                      (match_operand:SWIM248 1 "register_operand" "")
6621                      (match_operand:SWIM248 2 "<general_operand>" "")))
6622               (clobber (reg:CC FLAGS_REG))])])
6623
6624 (define_expand "mulqi3"
6625   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6626                    (mult:QI
6627                      (match_operand:QI 1 "register_operand" "")
6628                      (match_operand:QI 2 "nonimmediate_operand" "")))
6629               (clobber (reg:CC FLAGS_REG))])]
6630   "TARGET_QIMODE_MATH")
6631
6632 ;; On AMDFAM10
6633 ;; IMUL reg32/64, reg32/64, imm8        Direct
6634 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6635 ;; IMUL reg32/64, reg32/64, imm32       Direct
6636 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6637 ;; IMUL reg32/64, reg32/64              Direct
6638 ;; IMUL reg32/64, mem32/64              Direct
6639 ;;
6640 ;; On BDVER1, all above IMULs use DirectPath
6641
6642 (define_insn "*mul<mode>3_1"
6643   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6644         (mult:SWI48
6645           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6646           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6647    (clobber (reg:CC FLAGS_REG))]
6648   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6649   "@
6650    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6651    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6652    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6653   [(set_attr "type" "imul")
6654    (set_attr "prefix_0f" "0,0,1")
6655    (set (attr "athlon_decode")
6656         (cond [(eq_attr "cpu" "athlon")
6657                   (const_string "vector")
6658                (eq_attr "alternative" "1")
6659                   (const_string "vector")
6660                (and (eq_attr "alternative" "2")
6661                     (match_operand 1 "memory_operand" ""))
6662                   (const_string "vector")]
6663               (const_string "direct")))
6664    (set (attr "amdfam10_decode")
6665         (cond [(and (eq_attr "alternative" "0,1")
6666                     (match_operand 1 "memory_operand" ""))
6667                   (const_string "vector")]
6668               (const_string "direct")))
6669    (set_attr "bdver1_decode" "direct")
6670    (set_attr "mode" "<MODE>")])
6671
6672 (define_insn "*mulsi3_1_zext"
6673   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6674         (zero_extend:DI
6675           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6676                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6677    (clobber (reg:CC FLAGS_REG))]
6678   "TARGET_64BIT
6679    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6680   "@
6681    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6682    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6683    imul{l}\t{%2, %k0|%k0, %2}"
6684   [(set_attr "type" "imul")
6685    (set_attr "prefix_0f" "0,0,1")
6686    (set (attr "athlon_decode")
6687         (cond [(eq_attr "cpu" "athlon")
6688                   (const_string "vector")
6689                (eq_attr "alternative" "1")
6690                   (const_string "vector")
6691                (and (eq_attr "alternative" "2")
6692                     (match_operand 1 "memory_operand" ""))
6693                   (const_string "vector")]
6694               (const_string "direct")))
6695    (set (attr "amdfam10_decode")
6696         (cond [(and (eq_attr "alternative" "0,1")
6697                     (match_operand 1 "memory_operand" ""))
6698                   (const_string "vector")]
6699               (const_string "direct")))
6700    (set_attr "bdver1_decode" "direct")
6701    (set_attr "mode" "SI")])
6702
6703 ;; On AMDFAM10
6704 ;; IMUL reg16, reg16, imm8      VectorPath
6705 ;; IMUL reg16, mem16, imm8      VectorPath
6706 ;; IMUL reg16, reg16, imm16     VectorPath
6707 ;; IMUL reg16, mem16, imm16     VectorPath
6708 ;; IMUL reg16, reg16            Direct
6709 ;; IMUL reg16, mem16            Direct
6710 ;;
6711 ;; On BDVER1, all HI MULs use DoublePath
6712
6713 (define_insn "*mulhi3_1"
6714   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6715         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6716                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6717    (clobber (reg:CC FLAGS_REG))]
6718   "TARGET_HIMODE_MATH
6719    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6720   "@
6721    imul{w}\t{%2, %1, %0|%0, %1, %2}
6722    imul{w}\t{%2, %1, %0|%0, %1, %2}
6723    imul{w}\t{%2, %0|%0, %2}"
6724   [(set_attr "type" "imul")
6725    (set_attr "prefix_0f" "0,0,1")
6726    (set (attr "athlon_decode")
6727         (cond [(eq_attr "cpu" "athlon")
6728                   (const_string "vector")
6729                (eq_attr "alternative" "1,2")
6730                   (const_string "vector")]
6731               (const_string "direct")))
6732    (set (attr "amdfam10_decode")
6733         (cond [(eq_attr "alternative" "0,1")
6734                   (const_string "vector")]
6735               (const_string "direct")))
6736    (set_attr "bdver1_decode" "double")
6737    (set_attr "mode" "HI")])
6738
6739 ;;On AMDFAM10 and BDVER1
6740 ;; MUL reg8     Direct
6741 ;; MUL mem8     Direct
6742
6743 (define_insn "*mulqi3_1"
6744   [(set (match_operand:QI 0 "register_operand" "=a")
6745         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6746                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6747    (clobber (reg:CC FLAGS_REG))]
6748   "TARGET_QIMODE_MATH
6749    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6750   "mul{b}\t%2"
6751   [(set_attr "type" "imul")
6752    (set_attr "length_immediate" "0")
6753    (set (attr "athlon_decode")
6754      (if_then_else (eq_attr "cpu" "athlon")
6755         (const_string "vector")
6756         (const_string "direct")))
6757    (set_attr "amdfam10_decode" "direct")
6758    (set_attr "bdver1_decode" "direct")
6759    (set_attr "mode" "QI")])
6760
6761 (define_expand "<u>mul<mode><dwi>3"
6762   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6763                    (mult:<DWI>
6764                      (any_extend:<DWI>
6765                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6766                      (any_extend:<DWI>
6767                        (match_operand:DWIH 2 "register_operand" ""))))
6768               (clobber (reg:CC FLAGS_REG))])])
6769
6770 (define_expand "<u>mulqihi3"
6771   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6772                    (mult:HI
6773                      (any_extend:HI
6774                        (match_operand:QI 1 "nonimmediate_operand" ""))
6775                      (any_extend:HI
6776                        (match_operand:QI 2 "register_operand" ""))))
6777               (clobber (reg:CC FLAGS_REG))])]
6778   "TARGET_QIMODE_MATH")
6779
6780 (define_insn "*<u>mul<mode><dwi>3_1"
6781   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6782         (mult:<DWI>
6783           (any_extend:<DWI>
6784             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6785           (any_extend:<DWI>
6786             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6787    (clobber (reg:CC FLAGS_REG))]
6788   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6789   "<sgnprefix>mul{<imodesuffix>}\t%2"
6790   [(set_attr "type" "imul")
6791    (set_attr "length_immediate" "0")
6792    (set (attr "athlon_decode")
6793      (if_then_else (eq_attr "cpu" "athlon")
6794         (const_string "vector")
6795         (const_string "double")))
6796    (set_attr "amdfam10_decode" "double")
6797    (set_attr "bdver1_decode" "direct")
6798    (set_attr "mode" "<MODE>")])
6799
6800 (define_insn "*<u>mulqihi3_1"
6801   [(set (match_operand:HI 0 "register_operand" "=a")
6802         (mult:HI
6803           (any_extend:HI
6804             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6805           (any_extend:HI
6806             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6807    (clobber (reg:CC FLAGS_REG))]
6808   "TARGET_QIMODE_MATH
6809    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6810   "<sgnprefix>mul{b}\t%2"
6811   [(set_attr "type" "imul")
6812    (set_attr "length_immediate" "0")
6813    (set (attr "athlon_decode")
6814      (if_then_else (eq_attr "cpu" "athlon")
6815         (const_string "vector")
6816         (const_string "direct")))
6817    (set_attr "amdfam10_decode" "direct")
6818    (set_attr "bdver1_decode" "direct")
6819    (set_attr "mode" "QI")])
6820
6821 (define_expand "<s>mul<mode>3_highpart"
6822   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6823                    (truncate:SWI48
6824                      (lshiftrt:<DWI>
6825                        (mult:<DWI>
6826                          (any_extend:<DWI>
6827                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
6828                          (any_extend:<DWI>
6829                            (match_operand:SWI48 2 "register_operand" "")))
6830                        (match_dup 4))))
6831               (clobber (match_scratch:SWI48 3 ""))
6832               (clobber (reg:CC FLAGS_REG))])]
6833   ""
6834   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6835
6836 (define_insn "*<s>muldi3_highpart_1"
6837   [(set (match_operand:DI 0 "register_operand" "=d")
6838         (truncate:DI
6839           (lshiftrt:TI
6840             (mult:TI
6841               (any_extend:TI
6842                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6843               (any_extend:TI
6844                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6845             (const_int 64))))
6846    (clobber (match_scratch:DI 3 "=1"))
6847    (clobber (reg:CC FLAGS_REG))]
6848   "TARGET_64BIT
6849    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6850   "<sgnprefix>mul{q}\t%2"
6851   [(set_attr "type" "imul")
6852    (set_attr "length_immediate" "0")
6853    (set (attr "athlon_decode")
6854      (if_then_else (eq_attr "cpu" "athlon")
6855         (const_string "vector")
6856         (const_string "double")))
6857    (set_attr "amdfam10_decode" "double")
6858    (set_attr "bdver1_decode" "direct")
6859    (set_attr "mode" "DI")])
6860
6861 (define_insn "*<s>mulsi3_highpart_1"
6862   [(set (match_operand:SI 0 "register_operand" "=d")
6863         (truncate:SI
6864           (lshiftrt:DI
6865             (mult:DI
6866               (any_extend:DI
6867                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6868               (any_extend:DI
6869                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6870             (const_int 32))))
6871    (clobber (match_scratch:SI 3 "=1"))
6872    (clobber (reg:CC FLAGS_REG))]
6873   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6874   "<sgnprefix>mul{l}\t%2"
6875   [(set_attr "type" "imul")
6876    (set_attr "length_immediate" "0")
6877    (set (attr "athlon_decode")
6878      (if_then_else (eq_attr "cpu" "athlon")
6879         (const_string "vector")
6880         (const_string "double")))
6881    (set_attr "amdfam10_decode" "double")
6882    (set_attr "bdver1_decode" "direct")
6883    (set_attr "mode" "SI")])
6884
6885 (define_insn "*<s>mulsi3_highpart_zext"
6886   [(set (match_operand:DI 0 "register_operand" "=d")
6887         (zero_extend:DI (truncate:SI
6888           (lshiftrt:DI
6889             (mult:DI (any_extend:DI
6890                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6891                      (any_extend:DI
6892                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6893             (const_int 32)))))
6894    (clobber (match_scratch:SI 3 "=1"))
6895    (clobber (reg:CC FLAGS_REG))]
6896   "TARGET_64BIT
6897    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6898   "<sgnprefix>mul{l}\t%2"
6899   [(set_attr "type" "imul")
6900    (set_attr "length_immediate" "0")
6901    (set (attr "athlon_decode")
6902      (if_then_else (eq_attr "cpu" "athlon")
6903         (const_string "vector")
6904         (const_string "double")))
6905    (set_attr "amdfam10_decode" "double")
6906    (set_attr "bdver1_decode" "direct")
6907    (set_attr "mode" "SI")])
6908
6909 ;; The patterns that match these are at the end of this file.
6910
6911 (define_expand "mulxf3"
6912   [(set (match_operand:XF 0 "register_operand" "")
6913         (mult:XF (match_operand:XF 1 "register_operand" "")
6914                  (match_operand:XF 2 "register_operand" "")))]
6915   "TARGET_80387")
6916
6917 (define_expand "mul<mode>3"
6918   [(set (match_operand:MODEF 0 "register_operand" "")
6919         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6920                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6921   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6922     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6923 \f
6924 ;; Divide instructions
6925
6926 ;; The patterns that match these are at the end of this file.
6927
6928 (define_expand "divxf3"
6929   [(set (match_operand:XF 0 "register_operand" "")
6930         (div:XF (match_operand:XF 1 "register_operand" "")
6931                 (match_operand:XF 2 "register_operand" "")))]
6932   "TARGET_80387")
6933
6934 (define_expand "divdf3"
6935   [(set (match_operand:DF 0 "register_operand" "")
6936         (div:DF (match_operand:DF 1 "register_operand" "")
6937                 (match_operand:DF 2 "nonimmediate_operand" "")))]
6938    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6939     || (TARGET_SSE2 && TARGET_SSE_MATH)")
6940
6941 (define_expand "divsf3"
6942   [(set (match_operand:SF 0 "register_operand" "")
6943         (div:SF (match_operand:SF 1 "register_operand" "")
6944                 (match_operand:SF 2 "nonimmediate_operand" "")))]
6945   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6946     || TARGET_SSE_MATH"
6947 {
6948   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
6949       && flag_finite_math_only && !flag_trapping_math
6950       && flag_unsafe_math_optimizations)
6951     {
6952       ix86_emit_swdivsf (operands[0], operands[1],
6953                          operands[2], SFmode);
6954       DONE;
6955     }
6956 })
6957 \f
6958 ;; Divmod instructions.
6959
6960 (define_expand "divmod<mode>4"
6961   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6962                    (div:SWIM248
6963                      (match_operand:SWIM248 1 "register_operand" "")
6964                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
6965               (set (match_operand:SWIM248 3 "register_operand" "")
6966                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
6967               (clobber (reg:CC FLAGS_REG))])])
6968
6969 ;; Split with 8bit unsigned divide:
6970 ;;      if (dividend an divisor are in [0-255])
6971 ;;         use 8bit unsigned integer divide
6972 ;;       else
6973 ;;         use original integer divide
6974 (define_split
6975   [(set (match_operand:SWI48 0 "register_operand" "")
6976         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
6977                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
6978    (set (match_operand:SWI48 1 "register_operand" "")
6979         (mod:SWI48 (match_dup 2) (match_dup 3)))
6980    (clobber (reg:CC FLAGS_REG))]
6981   "TARGET_USE_8BIT_IDIV
6982    && TARGET_QIMODE_MATH
6983    && can_create_pseudo_p ()
6984    && !optimize_insn_for_size_p ()"
6985   [(const_int 0)]
6986   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6987
6988 (define_insn_and_split "divmod<mode>4_1"
6989   [(set (match_operand:SWI48 0 "register_operand" "=a")
6990         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6991                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6992    (set (match_operand:SWI48 1 "register_operand" "=&d")
6993         (mod:SWI48 (match_dup 2) (match_dup 3)))
6994    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6995    (clobber (reg:CC FLAGS_REG))]
6996   ""
6997   "#"
6998   "reload_completed"
6999   [(parallel [(set (match_dup 1)
7000                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7001               (clobber (reg:CC FLAGS_REG))])
7002    (parallel [(set (match_dup 0)
7003                    (div:SWI48 (match_dup 2) (match_dup 3)))
7004               (set (match_dup 1)
7005                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7006               (use (match_dup 1))
7007               (clobber (reg:CC FLAGS_REG))])]
7008 {
7009   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7010
7011   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7012     operands[4] = operands[2];
7013   else
7014     {
7015       /* Avoid use of cltd in favor of a mov+shift.  */
7016       emit_move_insn (operands[1], operands[2]);
7017       operands[4] = operands[1];
7018     }
7019 }
7020   [(set_attr "type" "multi")
7021    (set_attr "mode" "<MODE>")])
7022
7023 (define_insn_and_split "*divmod<mode>4"
7024   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7025         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7026                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7027    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7028         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7029    (clobber (reg:CC FLAGS_REG))]
7030   ""
7031   "#"
7032   "reload_completed"
7033   [(parallel [(set (match_dup 1)
7034                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7035               (clobber (reg:CC FLAGS_REG))])
7036    (parallel [(set (match_dup 0)
7037                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7038               (set (match_dup 1)
7039                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7040               (use (match_dup 1))
7041               (clobber (reg:CC FLAGS_REG))])]
7042 {
7043   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7044
7045   if (<MODE>mode != HImode
7046       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7047     operands[4] = operands[2];
7048   else
7049     {
7050       /* Avoid use of cltd in favor of a mov+shift.  */
7051       emit_move_insn (operands[1], operands[2]);
7052       operands[4] = operands[1];
7053     }
7054 }
7055   [(set_attr "type" "multi")
7056    (set_attr "mode" "<MODE>")])
7057
7058 (define_insn "*divmod<mode>4_noext"
7059   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7060         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7061                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7062    (set (match_operand:SWIM248 1 "register_operand" "=d")
7063         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7064    (use (match_operand:SWIM248 4 "register_operand" "1"))
7065    (clobber (reg:CC FLAGS_REG))]
7066   ""
7067   "idiv{<imodesuffix>}\t%3"
7068   [(set_attr "type" "idiv")
7069    (set_attr "mode" "<MODE>")])
7070
7071 (define_expand "divmodqi4"
7072   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7073                    (div:QI
7074                      (match_operand:QI 1 "register_operand" "")
7075                      (match_operand:QI 2 "nonimmediate_operand" "")))
7076               (set (match_operand:QI 3 "register_operand" "")
7077                    (mod:QI (match_dup 1) (match_dup 2)))
7078               (clobber (reg:CC FLAGS_REG))])]
7079   "TARGET_QIMODE_MATH"
7080 {
7081   rtx div, mod, insn;
7082   rtx tmp0, tmp1;
7083   
7084   tmp0 = gen_reg_rtx (HImode);
7085   tmp1 = gen_reg_rtx (HImode);
7086
7087   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7088      in AX.  */
7089   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7090   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7091
7092   /* Extract remainder from AH.  */
7093   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7094   insn = emit_move_insn (operands[3], tmp1);
7095
7096   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7097   set_unique_reg_note (insn, REG_EQUAL, mod);
7098
7099   /* Extract quotient from AL.  */
7100   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7101
7102   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7103   set_unique_reg_note (insn, REG_EQUAL, div);
7104
7105   DONE;
7106 })
7107
7108 ;; Divide AX by r/m8, with result stored in
7109 ;; AL <- Quotient
7110 ;; AH <- Remainder
7111 ;; Change div/mod to HImode and extend the second argument to HImode
7112 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7113 ;; combine may fail.
7114 (define_insn "divmodhiqi3"
7115   [(set (match_operand:HI 0 "register_operand" "=a")
7116         (ior:HI
7117           (ashift:HI
7118             (zero_extend:HI
7119               (truncate:QI
7120                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7121                         (sign_extend:HI
7122                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7123             (const_int 8))
7124           (zero_extend:HI
7125             (truncate:QI
7126               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7127    (clobber (reg:CC FLAGS_REG))]
7128   "TARGET_QIMODE_MATH"
7129   "idiv{b}\t%2"
7130   [(set_attr "type" "idiv")
7131    (set_attr "mode" "QI")])
7132
7133 (define_expand "udivmod<mode>4"
7134   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7135                    (udiv:SWIM248
7136                      (match_operand:SWIM248 1 "register_operand" "")
7137                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7138               (set (match_operand:SWIM248 3 "register_operand" "")
7139                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7140               (clobber (reg:CC FLAGS_REG))])])
7141
7142 ;; Split with 8bit unsigned divide:
7143 ;;      if (dividend an divisor are in [0-255])
7144 ;;         use 8bit unsigned integer divide
7145 ;;       else
7146 ;;         use original integer divide
7147 (define_split
7148   [(set (match_operand:SWI48 0 "register_operand" "")
7149         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7150                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7151    (set (match_operand:SWI48 1 "register_operand" "")
7152         (umod:SWI48 (match_dup 2) (match_dup 3)))
7153    (clobber (reg:CC FLAGS_REG))]
7154   "TARGET_USE_8BIT_IDIV
7155    && TARGET_QIMODE_MATH
7156    && can_create_pseudo_p ()
7157    && !optimize_insn_for_size_p ()"
7158   [(const_int 0)]
7159   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7160
7161 (define_insn_and_split "udivmod<mode>4_1"
7162   [(set (match_operand:SWI48 0 "register_operand" "=a")
7163         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7164                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7165    (set (match_operand:SWI48 1 "register_operand" "=&d")
7166         (umod:SWI48 (match_dup 2) (match_dup 3)))
7167    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7168    (clobber (reg:CC FLAGS_REG))]
7169   ""
7170   "#"
7171   "reload_completed"
7172   [(set (match_dup 1) (const_int 0))
7173    (parallel [(set (match_dup 0)
7174                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7175               (set (match_dup 1)
7176                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7177               (use (match_dup 1))
7178               (clobber (reg:CC FLAGS_REG))])]
7179   ""
7180   [(set_attr "type" "multi")
7181    (set_attr "mode" "<MODE>")])
7182
7183 (define_insn_and_split "*udivmod<mode>4"
7184   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7185         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7186                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7187    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7188         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7189    (clobber (reg:CC FLAGS_REG))]
7190   ""
7191   "#"
7192   "reload_completed"
7193   [(set (match_dup 1) (const_int 0))
7194    (parallel [(set (match_dup 0)
7195                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7196               (set (match_dup 1)
7197                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7198               (use (match_dup 1))
7199               (clobber (reg:CC FLAGS_REG))])]
7200   ""
7201   [(set_attr "type" "multi")
7202    (set_attr "mode" "<MODE>")])
7203
7204 (define_insn "*udivmod<mode>4_noext"
7205   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7206         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7207                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7208    (set (match_operand:SWIM248 1 "register_operand" "=d")
7209         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7210    (use (match_operand:SWIM248 4 "register_operand" "1"))
7211    (clobber (reg:CC FLAGS_REG))]
7212   ""
7213   "div{<imodesuffix>}\t%3"
7214   [(set_attr "type" "idiv")
7215    (set_attr "mode" "<MODE>")])
7216
7217 (define_expand "udivmodqi4"
7218   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7219                    (udiv:QI
7220                      (match_operand:QI 1 "register_operand" "")
7221                      (match_operand:QI 2 "nonimmediate_operand" "")))
7222               (set (match_operand:QI 3 "register_operand" "")
7223                    (umod:QI (match_dup 1) (match_dup 2)))
7224               (clobber (reg:CC FLAGS_REG))])]
7225   "TARGET_QIMODE_MATH"
7226 {
7227   rtx div, mod, insn;
7228   rtx tmp0, tmp1;
7229   
7230   tmp0 = gen_reg_rtx (HImode);
7231   tmp1 = gen_reg_rtx (HImode);
7232
7233   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7234      in AX.  */
7235   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7236   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7237
7238   /* Extract remainder from AH.  */
7239   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7240   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7241   insn = emit_move_insn (operands[3], tmp1);
7242
7243   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7244   set_unique_reg_note (insn, REG_EQUAL, mod);
7245
7246   /* Extract quotient from AL.  */
7247   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7248
7249   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7250   set_unique_reg_note (insn, REG_EQUAL, div);
7251
7252   DONE;
7253 })
7254
7255 (define_insn "udivmodhiqi3"
7256   [(set (match_operand:HI 0 "register_operand" "=a")
7257         (ior:HI
7258           (ashift:HI
7259             (zero_extend:HI
7260               (truncate:QI
7261                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7262                         (zero_extend:HI
7263                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7264             (const_int 8))
7265           (zero_extend:HI
7266             (truncate:QI
7267               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7268    (clobber (reg:CC FLAGS_REG))]
7269   "TARGET_QIMODE_MATH"
7270   "div{b}\t%2"
7271   [(set_attr "type" "idiv")
7272    (set_attr "mode" "QI")])
7273
7274 ;; We cannot use div/idiv for double division, because it causes
7275 ;; "division by zero" on the overflow and that's not what we expect
7276 ;; from truncate.  Because true (non truncating) double division is
7277 ;; never generated, we can't create this insn anyway.
7278 ;
7279 ;(define_insn ""
7280 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7281 ;       (truncate:SI
7282 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7283 ;                  (zero_extend:DI
7284 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7285 ;   (set (match_operand:SI 3 "register_operand" "=d")
7286 ;       (truncate:SI
7287 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7288 ;   (clobber (reg:CC FLAGS_REG))]
7289 ;  ""
7290 ;  "div{l}\t{%2, %0|%0, %2}"
7291 ;  [(set_attr "type" "idiv")])
7292 \f
7293 ;;- Logical AND instructions
7294
7295 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7296 ;; Note that this excludes ah.
7297
7298 (define_expand "testsi_ccno_1"
7299   [(set (reg:CCNO FLAGS_REG)
7300         (compare:CCNO
7301           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7302                   (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7303           (const_int 0)))])
7304
7305 (define_expand "testqi_ccz_1"
7306   [(set (reg:CCZ FLAGS_REG)
7307         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7308                              (match_operand:QI 1 "nonmemory_operand" ""))
7309                  (const_int 0)))])
7310
7311 (define_expand "testdi_ccno_1"
7312   [(set (reg:CCNO FLAGS_REG)
7313         (compare:CCNO
7314           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7315                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7316           (const_int 0)))]
7317   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7318
7319 (define_insn "*testdi_1"
7320   [(set (reg FLAGS_REG)
7321         (compare
7322          (and:DI
7323           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7324           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7325          (const_int 0)))]
7326   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7327    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7328   "@
7329    test{l}\t{%k1, %k0|%k0, %k1}
7330    test{l}\t{%k1, %k0|%k0, %k1}
7331    test{q}\t{%1, %0|%0, %1}
7332    test{q}\t{%1, %0|%0, %1}
7333    test{q}\t{%1, %0|%0, %1}"
7334   [(set_attr "type" "test")
7335    (set_attr "modrm" "0,1,0,1,1")
7336    (set_attr "mode" "SI,SI,DI,DI,DI")])
7337
7338 (define_insn "*testqi_1_maybe_si"
7339   [(set (reg FLAGS_REG)
7340         (compare
7341           (and:QI
7342             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7343             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7344           (const_int 0)))]
7345    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7346     && ix86_match_ccmode (insn,
7347                          CONST_INT_P (operands[1])
7348                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7349 {
7350   if (which_alternative == 3)
7351     {
7352       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7353         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7354       return "test{l}\t{%1, %k0|%k0, %1}";
7355     }
7356   return "test{b}\t{%1, %0|%0, %1}";
7357 }
7358   [(set_attr "type" "test")
7359    (set_attr "modrm" "0,1,1,1")
7360    (set_attr "mode" "QI,QI,QI,SI")
7361    (set_attr "pent_pair" "uv,np,uv,np")])
7362
7363 (define_insn "*test<mode>_1"
7364   [(set (reg FLAGS_REG)
7365         (compare
7366          (and:SWI124
7367           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7368           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7369          (const_int 0)))]
7370   "ix86_match_ccmode (insn, CCNOmode)
7371    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7372   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7373   [(set_attr "type" "test")
7374    (set_attr "modrm" "0,1,1")
7375    (set_attr "mode" "<MODE>")
7376    (set_attr "pent_pair" "uv,np,uv")])
7377
7378 (define_expand "testqi_ext_ccno_0"
7379   [(set (reg:CCNO FLAGS_REG)
7380         (compare:CCNO
7381           (and:SI
7382             (zero_extract:SI
7383               (match_operand 0 "ext_register_operand" "")
7384               (const_int 8)
7385               (const_int 8))
7386             (match_operand 1 "const_int_operand" ""))
7387           (const_int 0)))])
7388
7389 (define_insn "*testqi_ext_0"
7390   [(set (reg FLAGS_REG)
7391         (compare
7392           (and:SI
7393             (zero_extract:SI
7394               (match_operand 0 "ext_register_operand" "Q")
7395               (const_int 8)
7396               (const_int 8))
7397             (match_operand 1 "const_int_operand" "n"))
7398           (const_int 0)))]
7399   "ix86_match_ccmode (insn, CCNOmode)"
7400   "test{b}\t{%1, %h0|%h0, %1}"
7401   [(set_attr "type" "test")
7402    (set_attr "mode" "QI")
7403    (set_attr "length_immediate" "1")
7404    (set_attr "modrm" "1")
7405    (set_attr "pent_pair" "np")])
7406
7407 (define_insn "*testqi_ext_1_rex64"
7408   [(set (reg FLAGS_REG)
7409         (compare
7410           (and:SI
7411             (zero_extract:SI
7412               (match_operand 0 "ext_register_operand" "Q")
7413               (const_int 8)
7414               (const_int 8))
7415             (zero_extend:SI
7416               (match_operand:QI 1 "register_operand" "Q")))
7417           (const_int 0)))]
7418   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7419   "test{b}\t{%1, %h0|%h0, %1}"
7420   [(set_attr "type" "test")
7421    (set_attr "mode" "QI")])
7422
7423 (define_insn "*testqi_ext_1"
7424   [(set (reg FLAGS_REG)
7425         (compare
7426           (and:SI
7427             (zero_extract:SI
7428               (match_operand 0 "ext_register_operand" "Q")
7429               (const_int 8)
7430               (const_int 8))
7431             (zero_extend:SI
7432               (match_operand:QI 1 "general_operand" "Qm")))
7433           (const_int 0)))]
7434   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7435   "test{b}\t{%1, %h0|%h0, %1}"
7436   [(set_attr "type" "test")
7437    (set_attr "mode" "QI")])
7438
7439 (define_insn "*testqi_ext_2"
7440   [(set (reg FLAGS_REG)
7441         (compare
7442           (and:SI
7443             (zero_extract:SI
7444               (match_operand 0 "ext_register_operand" "Q")
7445               (const_int 8)
7446               (const_int 8))
7447             (zero_extract:SI
7448               (match_operand 1 "ext_register_operand" "Q")
7449               (const_int 8)
7450               (const_int 8)))
7451           (const_int 0)))]
7452   "ix86_match_ccmode (insn, CCNOmode)"
7453   "test{b}\t{%h1, %h0|%h0, %h1}"
7454   [(set_attr "type" "test")
7455    (set_attr "mode" "QI")])
7456
7457 (define_insn "*testqi_ext_3_rex64"
7458   [(set (reg FLAGS_REG)
7459         (compare (zero_extract:DI
7460                    (match_operand 0 "nonimmediate_operand" "rm")
7461                    (match_operand:DI 1 "const_int_operand" "")
7462                    (match_operand:DI 2 "const_int_operand" ""))
7463                  (const_int 0)))]
7464   "TARGET_64BIT
7465    && ix86_match_ccmode (insn, CCNOmode)
7466    && INTVAL (operands[1]) > 0
7467    && INTVAL (operands[2]) >= 0
7468    /* Ensure that resulting mask is zero or sign extended operand.  */
7469    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7470        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7471            && INTVAL (operands[1]) > 32))
7472    && (GET_MODE (operands[0]) == SImode
7473        || GET_MODE (operands[0]) == DImode
7474        || GET_MODE (operands[0]) == HImode
7475        || GET_MODE (operands[0]) == QImode)"
7476   "#")
7477
7478 ;; Combine likes to form bit extractions for some tests.  Humor it.
7479 (define_insn "*testqi_ext_3"
7480   [(set (reg FLAGS_REG)
7481         (compare (zero_extract:SI
7482                    (match_operand 0 "nonimmediate_operand" "rm")
7483                    (match_operand:SI 1 "const_int_operand" "")
7484                    (match_operand:SI 2 "const_int_operand" ""))
7485                  (const_int 0)))]
7486   "ix86_match_ccmode (insn, CCNOmode)
7487    && INTVAL (operands[1]) > 0
7488    && INTVAL (operands[2]) >= 0
7489    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7490    && (GET_MODE (operands[0]) == SImode
7491        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7492        || GET_MODE (operands[0]) == HImode
7493        || GET_MODE (operands[0]) == QImode)"
7494   "#")
7495
7496 (define_split
7497   [(set (match_operand 0 "flags_reg_operand" "")
7498         (match_operator 1 "compare_operator"
7499           [(zero_extract
7500              (match_operand 2 "nonimmediate_operand" "")
7501              (match_operand 3 "const_int_operand" "")
7502              (match_operand 4 "const_int_operand" ""))
7503            (const_int 0)]))]
7504   "ix86_match_ccmode (insn, CCNOmode)"
7505   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7506 {
7507   rtx val = operands[2];
7508   HOST_WIDE_INT len = INTVAL (operands[3]);
7509   HOST_WIDE_INT pos = INTVAL (operands[4]);
7510   HOST_WIDE_INT mask;
7511   enum machine_mode mode, submode;
7512
7513   mode = GET_MODE (val);
7514   if (MEM_P (val))
7515     {
7516       /* ??? Combine likes to put non-volatile mem extractions in QImode
7517          no matter the size of the test.  So find a mode that works.  */
7518       if (! MEM_VOLATILE_P (val))
7519         {
7520           mode = smallest_mode_for_size (pos + len, MODE_INT);
7521           val = adjust_address (val, mode, 0);
7522         }
7523     }
7524   else if (GET_CODE (val) == SUBREG
7525            && (submode = GET_MODE (SUBREG_REG (val)),
7526                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7527            && pos + len <= GET_MODE_BITSIZE (submode)
7528            && GET_MODE_CLASS (submode) == MODE_INT)
7529     {
7530       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7531       mode = submode;
7532       val = SUBREG_REG (val);
7533     }
7534   else if (mode == HImode && pos + len <= 8)
7535     {
7536       /* Small HImode tests can be converted to QImode.  */
7537       mode = QImode;
7538       val = gen_lowpart (QImode, val);
7539     }
7540
7541   if (len == HOST_BITS_PER_WIDE_INT)
7542     mask = -1;
7543   else
7544     mask = ((HOST_WIDE_INT)1 << len) - 1;
7545   mask <<= pos;
7546
7547   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7548 })
7549
7550 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7551 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7552 ;; this is relatively important trick.
7553 ;; Do the conversion only post-reload to avoid limiting of the register class
7554 ;; to QI regs.
7555 (define_split
7556   [(set (match_operand 0 "flags_reg_operand" "")
7557         (match_operator 1 "compare_operator"
7558           [(and (match_operand 2 "register_operand" "")
7559                 (match_operand 3 "const_int_operand" ""))
7560            (const_int 0)]))]
7561    "reload_completed
7562     && QI_REG_P (operands[2])
7563     && GET_MODE (operands[2]) != QImode
7564     && ((ix86_match_ccmode (insn, CCZmode)
7565          && !(INTVAL (operands[3]) & ~(255 << 8)))
7566         || (ix86_match_ccmode (insn, CCNOmode)
7567             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7568   [(set (match_dup 0)
7569         (match_op_dup 1
7570           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7571                    (match_dup 3))
7572            (const_int 0)]))]
7573   "operands[2] = gen_lowpart (SImode, operands[2]);
7574    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7575
7576 (define_split
7577   [(set (match_operand 0 "flags_reg_operand" "")
7578         (match_operator 1 "compare_operator"
7579           [(and (match_operand 2 "nonimmediate_operand" "")
7580                 (match_operand 3 "const_int_operand" ""))
7581            (const_int 0)]))]
7582    "reload_completed
7583     && GET_MODE (operands[2]) != QImode
7584     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7585     && ((ix86_match_ccmode (insn, CCZmode)
7586          && !(INTVAL (operands[3]) & ~255))
7587         || (ix86_match_ccmode (insn, CCNOmode)
7588             && !(INTVAL (operands[3]) & ~127)))"
7589   [(set (match_dup 0)
7590         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7591                          (const_int 0)]))]
7592   "operands[2] = gen_lowpart (QImode, operands[2]);
7593    operands[3] = gen_lowpart (QImode, operands[3]);")
7594
7595 ;; %%% This used to optimize known byte-wide and operations to memory,
7596 ;; and sometimes to QImode registers.  If this is considered useful,
7597 ;; it should be done with splitters.
7598
7599 (define_expand "and<mode>3"
7600   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7601         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7602                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7603   ""
7604   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7605
7606 (define_insn "*anddi_1"
7607   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7608         (and:DI
7609          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7610          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7611    (clobber (reg:CC FLAGS_REG))]
7612   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7613 {
7614   switch (get_attr_type (insn))
7615     {
7616     case TYPE_IMOVX:
7617       {
7618         enum machine_mode mode;
7619
7620         gcc_assert (CONST_INT_P (operands[2]));
7621         if (INTVAL (operands[2]) == 0xff)
7622           mode = QImode;
7623         else
7624           {
7625             gcc_assert (INTVAL (operands[2]) == 0xffff);
7626             mode = HImode;
7627           }
7628
7629         operands[1] = gen_lowpart (mode, operands[1]);
7630         if (mode == QImode)
7631           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7632         else
7633           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7634       }
7635
7636     default:
7637       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7638       if (get_attr_mode (insn) == MODE_SI)
7639         return "and{l}\t{%k2, %k0|%k0, %k2}";
7640       else
7641         return "and{q}\t{%2, %0|%0, %2}";
7642     }
7643 }
7644   [(set_attr "type" "alu,alu,alu,imovx")
7645    (set_attr "length_immediate" "*,*,*,0")
7646    (set (attr "prefix_rex")
7647      (if_then_else
7648        (and (eq_attr "type" "imovx")
7649             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7650                  (match_operand 1 "ext_QIreg_operand" "")))
7651        (const_string "1")
7652        (const_string "*")))
7653    (set_attr "mode" "SI,DI,DI,SI")])
7654
7655 (define_insn "*andsi_1"
7656   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7657         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7658                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7659    (clobber (reg:CC FLAGS_REG))]
7660   "ix86_binary_operator_ok (AND, SImode, operands)"
7661 {
7662   switch (get_attr_type (insn))
7663     {
7664     case TYPE_IMOVX:
7665       {
7666         enum machine_mode mode;
7667
7668         gcc_assert (CONST_INT_P (operands[2]));
7669         if (INTVAL (operands[2]) == 0xff)
7670           mode = QImode;
7671         else
7672           {
7673             gcc_assert (INTVAL (operands[2]) == 0xffff);
7674             mode = HImode;
7675           }
7676
7677         operands[1] = gen_lowpart (mode, operands[1]);
7678         if (mode == QImode)
7679           return "movz{bl|x}\t{%1, %0|%0, %1}";
7680         else
7681           return "movz{wl|x}\t{%1, %0|%0, %1}";
7682       }
7683
7684     default:
7685       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7686       return "and{l}\t{%2, %0|%0, %2}";
7687     }
7688 }
7689   [(set_attr "type" "alu,alu,imovx")
7690    (set (attr "prefix_rex")
7691      (if_then_else
7692        (and (eq_attr "type" "imovx")
7693             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7694                  (match_operand 1 "ext_QIreg_operand" "")))
7695        (const_string "1")
7696        (const_string "*")))
7697    (set_attr "length_immediate" "*,*,0")
7698    (set_attr "mode" "SI")])
7699
7700 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7701 (define_insn "*andsi_1_zext"
7702   [(set (match_operand:DI 0 "register_operand" "=r")
7703         (zero_extend:DI
7704           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7705                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7706    (clobber (reg:CC FLAGS_REG))]
7707   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7708   "and{l}\t{%2, %k0|%k0, %2}"
7709   [(set_attr "type" "alu")
7710    (set_attr "mode" "SI")])
7711
7712 (define_insn "*andhi_1"
7713   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7714         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7715                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7716    (clobber (reg:CC FLAGS_REG))]
7717   "ix86_binary_operator_ok (AND, HImode, operands)"
7718 {
7719   switch (get_attr_type (insn))
7720     {
7721     case TYPE_IMOVX:
7722       gcc_assert (CONST_INT_P (operands[2]));
7723       gcc_assert (INTVAL (operands[2]) == 0xff);
7724       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7725
7726     default:
7727       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7728
7729       return "and{w}\t{%2, %0|%0, %2}";
7730     }
7731 }
7732   [(set_attr "type" "alu,alu,imovx")
7733    (set_attr "length_immediate" "*,*,0")
7734    (set (attr "prefix_rex")
7735      (if_then_else
7736        (and (eq_attr "type" "imovx")
7737             (match_operand 1 "ext_QIreg_operand" ""))
7738        (const_string "1")
7739        (const_string "*")))
7740    (set_attr "mode" "HI,HI,SI")])
7741
7742 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7743 (define_insn "*andqi_1"
7744   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7745         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7746                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7747    (clobber (reg:CC FLAGS_REG))]
7748   "ix86_binary_operator_ok (AND, QImode, operands)"
7749   "@
7750    and{b}\t{%2, %0|%0, %2}
7751    and{b}\t{%2, %0|%0, %2}
7752    and{l}\t{%k2, %k0|%k0, %k2}"
7753   [(set_attr "type" "alu")
7754    (set_attr "mode" "QI,QI,SI")])
7755
7756 (define_insn "*andqi_1_slp"
7757   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7758         (and:QI (match_dup 0)
7759                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7760    (clobber (reg:CC FLAGS_REG))]
7761   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7762    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7763   "and{b}\t{%1, %0|%0, %1}"
7764   [(set_attr "type" "alu1")
7765    (set_attr "mode" "QI")])
7766
7767 (define_split
7768   [(set (match_operand 0 "register_operand" "")
7769         (and (match_dup 0)
7770              (const_int -65536)))
7771    (clobber (reg:CC FLAGS_REG))]
7772   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7773     || optimize_function_for_size_p (cfun)"
7774   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7775   "operands[1] = gen_lowpart (HImode, operands[0]);")
7776
7777 (define_split
7778   [(set (match_operand 0 "ext_register_operand" "")
7779         (and (match_dup 0)
7780              (const_int -256)))
7781    (clobber (reg:CC FLAGS_REG))]
7782   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7783    && reload_completed"
7784   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7785   "operands[1] = gen_lowpart (QImode, operands[0]);")
7786
7787 (define_split
7788   [(set (match_operand 0 "ext_register_operand" "")
7789         (and (match_dup 0)
7790              (const_int -65281)))
7791    (clobber (reg:CC FLAGS_REG))]
7792   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7793    && reload_completed"
7794   [(parallel [(set (zero_extract:SI (match_dup 0)
7795                                     (const_int 8)
7796                                     (const_int 8))
7797                    (xor:SI
7798                      (zero_extract:SI (match_dup 0)
7799                                       (const_int 8)
7800                                       (const_int 8))
7801                      (zero_extract:SI (match_dup 0)
7802                                       (const_int 8)
7803                                       (const_int 8))))
7804               (clobber (reg:CC FLAGS_REG))])]
7805   "operands[0] = gen_lowpart (SImode, operands[0]);")
7806
7807 (define_insn "*anddi_2"
7808   [(set (reg FLAGS_REG)
7809         (compare
7810          (and:DI
7811           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7812           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7813          (const_int 0)))
7814    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7815         (and:DI (match_dup 1) (match_dup 2)))]
7816   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7817    && ix86_binary_operator_ok (AND, DImode, operands)"
7818   "@
7819    and{l}\t{%k2, %k0|%k0, %k2}
7820    and{q}\t{%2, %0|%0, %2}
7821    and{q}\t{%2, %0|%0, %2}"
7822   [(set_attr "type" "alu")
7823    (set_attr "mode" "SI,DI,DI")])
7824
7825 (define_insn "*andqi_2_maybe_si"
7826   [(set (reg FLAGS_REG)
7827         (compare (and:QI
7828                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7829                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7830                  (const_int 0)))
7831    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7832         (and:QI (match_dup 1) (match_dup 2)))]
7833   "ix86_binary_operator_ok (AND, QImode, operands)
7834    && ix86_match_ccmode (insn,
7835                          CONST_INT_P (operands[2])
7836                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7837 {
7838   if (which_alternative == 2)
7839     {
7840       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7841         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7842       return "and{l}\t{%2, %k0|%k0, %2}";
7843     }
7844   return "and{b}\t{%2, %0|%0, %2}";
7845 }
7846   [(set_attr "type" "alu")
7847    (set_attr "mode" "QI,QI,SI")])
7848
7849 (define_insn "*and<mode>_2"
7850   [(set (reg FLAGS_REG)
7851         (compare (and:SWI124
7852                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7853                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7854                  (const_int 0)))
7855    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7856         (and:SWI124 (match_dup 1) (match_dup 2)))]
7857   "ix86_match_ccmode (insn, CCNOmode)
7858    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7859   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7860   [(set_attr "type" "alu")
7861    (set_attr "mode" "<MODE>")])
7862
7863 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7864 (define_insn "*andsi_2_zext"
7865   [(set (reg FLAGS_REG)
7866         (compare (and:SI
7867                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7868                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7869                  (const_int 0)))
7870    (set (match_operand:DI 0 "register_operand" "=r")
7871         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7872   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7873    && ix86_binary_operator_ok (AND, SImode, operands)"
7874   "and{l}\t{%2, %k0|%k0, %2}"
7875   [(set_attr "type" "alu")
7876    (set_attr "mode" "SI")])
7877
7878 (define_insn "*andqi_2_slp"
7879   [(set (reg FLAGS_REG)
7880         (compare (and:QI
7881                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7882                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7883                  (const_int 0)))
7884    (set (strict_low_part (match_dup 0))
7885         (and:QI (match_dup 0) (match_dup 1)))]
7886   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7887    && ix86_match_ccmode (insn, CCNOmode)
7888    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7889   "and{b}\t{%1, %0|%0, %1}"
7890   [(set_attr "type" "alu1")
7891    (set_attr "mode" "QI")])
7892
7893 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7894 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
7895 ;; for a QImode operand, which of course failed.
7896 (define_insn "andqi_ext_0"
7897   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7898                          (const_int 8)
7899                          (const_int 8))
7900         (and:SI
7901           (zero_extract:SI
7902             (match_operand 1 "ext_register_operand" "0")
7903             (const_int 8)
7904             (const_int 8))
7905           (match_operand 2 "const_int_operand" "n")))
7906    (clobber (reg:CC FLAGS_REG))]
7907   ""
7908   "and{b}\t{%2, %h0|%h0, %2}"
7909   [(set_attr "type" "alu")
7910    (set_attr "length_immediate" "1")
7911    (set_attr "modrm" "1")
7912    (set_attr "mode" "QI")])
7913
7914 ;; Generated by peephole translating test to and.  This shows up
7915 ;; often in fp comparisons.
7916 (define_insn "*andqi_ext_0_cc"
7917   [(set (reg FLAGS_REG)
7918         (compare
7919           (and:SI
7920             (zero_extract:SI
7921               (match_operand 1 "ext_register_operand" "0")
7922               (const_int 8)
7923               (const_int 8))
7924             (match_operand 2 "const_int_operand" "n"))
7925           (const_int 0)))
7926    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7927                          (const_int 8)
7928                          (const_int 8))
7929         (and:SI
7930           (zero_extract:SI
7931             (match_dup 1)
7932             (const_int 8)
7933             (const_int 8))
7934           (match_dup 2)))]
7935   "ix86_match_ccmode (insn, CCNOmode)"
7936   "and{b}\t{%2, %h0|%h0, %2}"
7937   [(set_attr "type" "alu")
7938    (set_attr "length_immediate" "1")
7939    (set_attr "modrm" "1")
7940    (set_attr "mode" "QI")])
7941
7942 (define_insn "*andqi_ext_1_rex64"
7943   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7944                          (const_int 8)
7945                          (const_int 8))
7946         (and:SI
7947           (zero_extract:SI
7948             (match_operand 1 "ext_register_operand" "0")
7949             (const_int 8)
7950             (const_int 8))
7951           (zero_extend:SI
7952             (match_operand 2 "ext_register_operand" "Q"))))
7953    (clobber (reg:CC FLAGS_REG))]
7954   "TARGET_64BIT"
7955   "and{b}\t{%2, %h0|%h0, %2}"
7956   [(set_attr "type" "alu")
7957    (set_attr "length_immediate" "0")
7958    (set_attr "mode" "QI")])
7959
7960 (define_insn "*andqi_ext_1"
7961   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7962                          (const_int 8)
7963                          (const_int 8))
7964         (and:SI
7965           (zero_extract:SI
7966             (match_operand 1 "ext_register_operand" "0")
7967             (const_int 8)
7968             (const_int 8))
7969           (zero_extend:SI
7970             (match_operand:QI 2 "general_operand" "Qm"))))
7971    (clobber (reg:CC FLAGS_REG))]
7972   "!TARGET_64BIT"
7973   "and{b}\t{%2, %h0|%h0, %2}"
7974   [(set_attr "type" "alu")
7975    (set_attr "length_immediate" "0")
7976    (set_attr "mode" "QI")])
7977
7978 (define_insn "*andqi_ext_2"
7979   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7980                          (const_int 8)
7981                          (const_int 8))
7982         (and:SI
7983           (zero_extract:SI
7984             (match_operand 1 "ext_register_operand" "%0")
7985             (const_int 8)
7986             (const_int 8))
7987           (zero_extract:SI
7988             (match_operand 2 "ext_register_operand" "Q")
7989             (const_int 8)
7990             (const_int 8))))
7991    (clobber (reg:CC FLAGS_REG))]
7992   ""
7993   "and{b}\t{%h2, %h0|%h0, %h2}"
7994   [(set_attr "type" "alu")
7995    (set_attr "length_immediate" "0")
7996    (set_attr "mode" "QI")])
7997
7998 ;; Convert wide AND instructions with immediate operand to shorter QImode
7999 ;; equivalents when possible.
8000 ;; Don't do the splitting with memory operands, since it introduces risk
8001 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8002 ;; for size, but that can (should?) be handled by generic code instead.
8003 (define_split
8004   [(set (match_operand 0 "register_operand" "")
8005         (and (match_operand 1 "register_operand" "")
8006              (match_operand 2 "const_int_operand" "")))
8007    (clobber (reg:CC FLAGS_REG))]
8008    "reload_completed
8009     && QI_REG_P (operands[0])
8010     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8011     && !(~INTVAL (operands[2]) & ~(255 << 8))
8012     && GET_MODE (operands[0]) != QImode"
8013   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8014                    (and:SI (zero_extract:SI (match_dup 1)
8015                                             (const_int 8) (const_int 8))
8016                            (match_dup 2)))
8017               (clobber (reg:CC FLAGS_REG))])]
8018   "operands[0] = gen_lowpart (SImode, operands[0]);
8019    operands[1] = gen_lowpart (SImode, operands[1]);
8020    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8021
8022 ;; Since AND can be encoded with sign extended immediate, this is only
8023 ;; profitable when 7th bit is not set.
8024 (define_split
8025   [(set (match_operand 0 "register_operand" "")
8026         (and (match_operand 1 "general_operand" "")
8027              (match_operand 2 "const_int_operand" "")))
8028    (clobber (reg:CC FLAGS_REG))]
8029    "reload_completed
8030     && ANY_QI_REG_P (operands[0])
8031     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8032     && !(~INTVAL (operands[2]) & ~255)
8033     && !(INTVAL (operands[2]) & 128)
8034     && GET_MODE (operands[0]) != QImode"
8035   [(parallel [(set (strict_low_part (match_dup 0))
8036                    (and:QI (match_dup 1)
8037                            (match_dup 2)))
8038               (clobber (reg:CC FLAGS_REG))])]
8039   "operands[0] = gen_lowpart (QImode, operands[0]);
8040    operands[1] = gen_lowpart (QImode, operands[1]);
8041    operands[2] = gen_lowpart (QImode, operands[2]);")
8042 \f
8043 ;; Logical inclusive and exclusive OR instructions
8044
8045 ;; %%% This used to optimize known byte-wide and operations to memory.
8046 ;; If this is considered useful, it should be done with splitters.
8047
8048 (define_expand "<code><mode>3"
8049   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8050         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8051                      (match_operand:SWIM 2 "<general_operand>" "")))]
8052   ""
8053   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8054
8055 (define_insn "*<code><mode>_1"
8056   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8057         (any_or:SWI248
8058          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8059          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8060    (clobber (reg:CC FLAGS_REG))]
8061   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8062   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8063   [(set_attr "type" "alu")
8064    (set_attr "mode" "<MODE>")])
8065
8066 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8067 (define_insn "*<code>qi_1"
8068   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8069         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8070                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8071    (clobber (reg:CC FLAGS_REG))]
8072   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8073   "@
8074    <logic>{b}\t{%2, %0|%0, %2}
8075    <logic>{b}\t{%2, %0|%0, %2}
8076    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8077   [(set_attr "type" "alu")
8078    (set_attr "mode" "QI,QI,SI")])
8079
8080 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8081 (define_insn "*<code>si_1_zext"
8082   [(set (match_operand:DI 0 "register_operand" "=r")
8083         (zero_extend:DI
8084          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8085                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8086    (clobber (reg:CC FLAGS_REG))]
8087   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8088   "<logic>{l}\t{%2, %k0|%k0, %2}"
8089   [(set_attr "type" "alu")
8090    (set_attr "mode" "SI")])
8091
8092 (define_insn "*<code>si_1_zext_imm"
8093   [(set (match_operand:DI 0 "register_operand" "=r")
8094         (any_or:DI
8095          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8096          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8097    (clobber (reg:CC FLAGS_REG))]
8098   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8099   "<logic>{l}\t{%2, %k0|%k0, %2}"
8100   [(set_attr "type" "alu")
8101    (set_attr "mode" "SI")])
8102
8103 (define_insn "*<code>qi_1_slp"
8104   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8105         (any_or:QI (match_dup 0)
8106                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8107    (clobber (reg:CC FLAGS_REG))]
8108   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8109    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8110   "<logic>{b}\t{%1, %0|%0, %1}"
8111   [(set_attr "type" "alu1")
8112    (set_attr "mode" "QI")])
8113
8114 (define_insn "*<code><mode>_2"
8115   [(set (reg FLAGS_REG)
8116         (compare (any_or:SWI
8117                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8118                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8119                  (const_int 0)))
8120    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8121         (any_or:SWI (match_dup 1) (match_dup 2)))]
8122   "ix86_match_ccmode (insn, CCNOmode)
8123    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8124   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8125   [(set_attr "type" "alu")
8126    (set_attr "mode" "<MODE>")])
8127
8128 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8129 ;; ??? Special case for immediate operand is missing - it is tricky.
8130 (define_insn "*<code>si_2_zext"
8131   [(set (reg FLAGS_REG)
8132         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8133                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8134                  (const_int 0)))
8135    (set (match_operand:DI 0 "register_operand" "=r")
8136         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8137   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8138    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8139   "<logic>{l}\t{%2, %k0|%k0, %2}"
8140   [(set_attr "type" "alu")
8141    (set_attr "mode" "SI")])
8142
8143 (define_insn "*<code>si_2_zext_imm"
8144   [(set (reg FLAGS_REG)
8145         (compare (any_or:SI
8146                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8147                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8148                  (const_int 0)))
8149    (set (match_operand:DI 0 "register_operand" "=r")
8150         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8151   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8152    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8153   "<logic>{l}\t{%2, %k0|%k0, %2}"
8154   [(set_attr "type" "alu")
8155    (set_attr "mode" "SI")])
8156
8157 (define_insn "*<code>qi_2_slp"
8158   [(set (reg FLAGS_REG)
8159         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8160                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8161                  (const_int 0)))
8162    (set (strict_low_part (match_dup 0))
8163         (any_or:QI (match_dup 0) (match_dup 1)))]
8164   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8165    && ix86_match_ccmode (insn, CCNOmode)
8166    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8167   "<logic>{b}\t{%1, %0|%0, %1}"
8168   [(set_attr "type" "alu1")
8169    (set_attr "mode" "QI")])
8170
8171 (define_insn "*<code><mode>_3"
8172   [(set (reg FLAGS_REG)
8173         (compare (any_or:SWI
8174                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8175                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8176                  (const_int 0)))
8177    (clobber (match_scratch:SWI 0 "=<r>"))]
8178   "ix86_match_ccmode (insn, CCNOmode)
8179    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8180   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8181   [(set_attr "type" "alu")
8182    (set_attr "mode" "<MODE>")])
8183
8184 (define_insn "*<code>qi_ext_0"
8185   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8186                          (const_int 8)
8187                          (const_int 8))
8188         (any_or:SI
8189           (zero_extract:SI
8190             (match_operand 1 "ext_register_operand" "0")
8191             (const_int 8)
8192             (const_int 8))
8193           (match_operand 2 "const_int_operand" "n")))
8194    (clobber (reg:CC FLAGS_REG))]
8195   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8196   "<logic>{b}\t{%2, %h0|%h0, %2}"
8197   [(set_attr "type" "alu")
8198    (set_attr "length_immediate" "1")
8199    (set_attr "modrm" "1")
8200    (set_attr "mode" "QI")])
8201
8202 (define_insn "*<code>qi_ext_1_rex64"
8203   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8204                          (const_int 8)
8205                          (const_int 8))
8206         (any_or:SI
8207           (zero_extract:SI
8208             (match_operand 1 "ext_register_operand" "0")
8209             (const_int 8)
8210             (const_int 8))
8211           (zero_extend:SI
8212             (match_operand 2 "ext_register_operand" "Q"))))
8213    (clobber (reg:CC FLAGS_REG))]
8214   "TARGET_64BIT
8215    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8216   "<logic>{b}\t{%2, %h0|%h0, %2}"
8217   [(set_attr "type" "alu")
8218    (set_attr "length_immediate" "0")
8219    (set_attr "mode" "QI")])
8220
8221 (define_insn "*<code>qi_ext_1"
8222   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8223                          (const_int 8)
8224                          (const_int 8))
8225         (any_or:SI
8226           (zero_extract:SI
8227             (match_operand 1 "ext_register_operand" "0")
8228             (const_int 8)
8229             (const_int 8))
8230           (zero_extend:SI
8231             (match_operand:QI 2 "general_operand" "Qm"))))
8232    (clobber (reg:CC FLAGS_REG))]
8233   "!TARGET_64BIT
8234    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8235   "<logic>{b}\t{%2, %h0|%h0, %2}"
8236   [(set_attr "type" "alu")
8237    (set_attr "length_immediate" "0")
8238    (set_attr "mode" "QI")])
8239
8240 (define_insn "*<code>qi_ext_2"
8241   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8242                          (const_int 8)
8243                          (const_int 8))
8244         (any_or:SI
8245           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8246                            (const_int 8)
8247                            (const_int 8))
8248           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8249                            (const_int 8)
8250                            (const_int 8))))
8251    (clobber (reg:CC FLAGS_REG))]
8252   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8253   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8254   [(set_attr "type" "alu")
8255    (set_attr "length_immediate" "0")
8256    (set_attr "mode" "QI")])
8257
8258 (define_split
8259   [(set (match_operand 0 "register_operand" "")
8260         (any_or (match_operand 1 "register_operand" "")
8261                 (match_operand 2 "const_int_operand" "")))
8262    (clobber (reg:CC FLAGS_REG))]
8263    "reload_completed
8264     && QI_REG_P (operands[0])
8265     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8266     && !(INTVAL (operands[2]) & ~(255 << 8))
8267     && GET_MODE (operands[0]) != QImode"
8268   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8269                    (any_or:SI (zero_extract:SI (match_dup 1)
8270                                                (const_int 8) (const_int 8))
8271                               (match_dup 2)))
8272               (clobber (reg:CC FLAGS_REG))])]
8273   "operands[0] = gen_lowpart (SImode, operands[0]);
8274    operands[1] = gen_lowpart (SImode, operands[1]);
8275    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8276
8277 ;; Since OR can be encoded with sign extended immediate, this is only
8278 ;; profitable when 7th bit is set.
8279 (define_split
8280   [(set (match_operand 0 "register_operand" "")
8281         (any_or (match_operand 1 "general_operand" "")
8282                 (match_operand 2 "const_int_operand" "")))
8283    (clobber (reg:CC FLAGS_REG))]
8284    "reload_completed
8285     && ANY_QI_REG_P (operands[0])
8286     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8287     && !(INTVAL (operands[2]) & ~255)
8288     && (INTVAL (operands[2]) & 128)
8289     && GET_MODE (operands[0]) != QImode"
8290   [(parallel [(set (strict_low_part (match_dup 0))
8291                    (any_or:QI (match_dup 1)
8292                               (match_dup 2)))
8293               (clobber (reg:CC FLAGS_REG))])]
8294   "operands[0] = gen_lowpart (QImode, operands[0]);
8295    operands[1] = gen_lowpart (QImode, operands[1]);
8296    operands[2] = gen_lowpart (QImode, operands[2]);")
8297
8298 (define_expand "xorqi_cc_ext_1"
8299   [(parallel [
8300      (set (reg:CCNO FLAGS_REG)
8301           (compare:CCNO
8302             (xor:SI
8303               (zero_extract:SI
8304                 (match_operand 1 "ext_register_operand" "")
8305                 (const_int 8)
8306                 (const_int 8))
8307               (match_operand:QI 2 "general_operand" ""))
8308             (const_int 0)))
8309      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8310                            (const_int 8)
8311                            (const_int 8))
8312           (xor:SI
8313             (zero_extract:SI
8314              (match_dup 1)
8315              (const_int 8)
8316              (const_int 8))
8317             (match_dup 2)))])])
8318
8319 (define_insn "*xorqi_cc_ext_1_rex64"
8320   [(set (reg FLAGS_REG)
8321         (compare
8322           (xor:SI
8323             (zero_extract:SI
8324               (match_operand 1 "ext_register_operand" "0")
8325               (const_int 8)
8326               (const_int 8))
8327             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8328           (const_int 0)))
8329    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8330                          (const_int 8)
8331                          (const_int 8))
8332         (xor:SI
8333           (zero_extract:SI
8334            (match_dup 1)
8335            (const_int 8)
8336            (const_int 8))
8337           (match_dup 2)))]
8338   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8339   "xor{b}\t{%2, %h0|%h0, %2}"
8340   [(set_attr "type" "alu")
8341    (set_attr "modrm" "1")
8342    (set_attr "mode" "QI")])
8343
8344 (define_insn "*xorqi_cc_ext_1"
8345   [(set (reg FLAGS_REG)
8346         (compare
8347           (xor:SI
8348             (zero_extract:SI
8349               (match_operand 1 "ext_register_operand" "0")
8350               (const_int 8)
8351               (const_int 8))
8352             (match_operand:QI 2 "general_operand" "qmn"))
8353           (const_int 0)))
8354    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8355                          (const_int 8)
8356                          (const_int 8))
8357         (xor:SI
8358           (zero_extract:SI
8359            (match_dup 1)
8360            (const_int 8)
8361            (const_int 8))
8362           (match_dup 2)))]
8363   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8364   "xor{b}\t{%2, %h0|%h0, %2}"
8365   [(set_attr "type" "alu")
8366    (set_attr "modrm" "1")
8367    (set_attr "mode" "QI")])
8368 \f
8369 ;; Negation instructions
8370
8371 (define_expand "neg<mode>2"
8372   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8373         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8374   ""
8375   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8376
8377 (define_insn_and_split "*neg<dwi>2_doubleword"
8378   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8379         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8380    (clobber (reg:CC FLAGS_REG))]
8381   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8382   "#"
8383   "reload_completed"
8384   [(parallel
8385     [(set (reg:CCZ FLAGS_REG)
8386           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8387      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8388    (parallel
8389     [(set (match_dup 2)
8390           (plus:DWIH (match_dup 3)
8391                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8392                                 (const_int 0))))
8393      (clobber (reg:CC FLAGS_REG))])
8394    (parallel
8395     [(set (match_dup 2)
8396           (neg:DWIH (match_dup 2)))
8397      (clobber (reg:CC FLAGS_REG))])]
8398   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8399
8400 (define_insn "*neg<mode>2_1"
8401   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8402         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8403    (clobber (reg:CC FLAGS_REG))]
8404   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8405   "neg{<imodesuffix>}\t%0"
8406   [(set_attr "type" "negnot")
8407    (set_attr "mode" "<MODE>")])
8408
8409 ;; Combine is quite creative about this pattern.
8410 (define_insn "*negsi2_1_zext"
8411   [(set (match_operand:DI 0 "register_operand" "=r")
8412         (lshiftrt:DI
8413           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8414                              (const_int 32)))
8415         (const_int 32)))
8416    (clobber (reg:CC FLAGS_REG))]
8417   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8418   "neg{l}\t%k0"
8419   [(set_attr "type" "negnot")
8420    (set_attr "mode" "SI")])
8421
8422 ;; The problem with neg is that it does not perform (compare x 0),
8423 ;; it really performs (compare 0 x), which leaves us with the zero
8424 ;; flag being the only useful item.
8425
8426 (define_insn "*neg<mode>2_cmpz"
8427   [(set (reg:CCZ FLAGS_REG)
8428         (compare:CCZ
8429           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8430                    (const_int 0)))
8431    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8432         (neg:SWI (match_dup 1)))]
8433   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8434   "neg{<imodesuffix>}\t%0"
8435   [(set_attr "type" "negnot")
8436    (set_attr "mode" "<MODE>")])
8437
8438 (define_insn "*negsi2_cmpz_zext"
8439   [(set (reg:CCZ FLAGS_REG)
8440         (compare:CCZ
8441           (lshiftrt:DI
8442             (neg:DI (ashift:DI
8443                       (match_operand:DI 1 "register_operand" "0")
8444                       (const_int 32)))
8445             (const_int 32))
8446           (const_int 0)))
8447    (set (match_operand:DI 0 "register_operand" "=r")
8448         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8449                                         (const_int 32)))
8450                      (const_int 32)))]
8451   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8452   "neg{l}\t%k0"
8453   [(set_attr "type" "negnot")
8454    (set_attr "mode" "SI")])
8455
8456 ;; Changing of sign for FP values is doable using integer unit too.
8457
8458 (define_expand "<code><mode>2"
8459   [(set (match_operand:X87MODEF 0 "register_operand" "")
8460         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8461   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8462   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8463
8464 (define_insn "*absneg<mode>2_mixed"
8465   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8466         (match_operator:MODEF 3 "absneg_operator"
8467           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8468    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8469    (clobber (reg:CC FLAGS_REG))]
8470   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8471   "#")
8472
8473 (define_insn "*absneg<mode>2_sse"
8474   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8475         (match_operator:MODEF 3 "absneg_operator"
8476           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8477    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8480   "#")
8481
8482 (define_insn "*absneg<mode>2_i387"
8483   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8484         (match_operator:X87MODEF 3 "absneg_operator"
8485           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8486    (use (match_operand 2 "" ""))
8487    (clobber (reg:CC FLAGS_REG))]
8488   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8489   "#")
8490
8491 (define_expand "<code>tf2"
8492   [(set (match_operand:TF 0 "register_operand" "")
8493         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8494   "TARGET_SSE2"
8495   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8496
8497 (define_insn "*absnegtf2_sse"
8498   [(set (match_operand:TF 0 "register_operand" "=x,x")
8499         (match_operator:TF 3 "absneg_operator"
8500           [(match_operand:TF 1 "register_operand" "0,x")]))
8501    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8502    (clobber (reg:CC FLAGS_REG))]
8503   "TARGET_SSE2"
8504   "#")
8505
8506 ;; Splitters for fp abs and neg.
8507
8508 (define_split
8509   [(set (match_operand 0 "fp_register_operand" "")
8510         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8511    (use (match_operand 2 "" ""))
8512    (clobber (reg:CC FLAGS_REG))]
8513   "reload_completed"
8514   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8515
8516 (define_split
8517   [(set (match_operand 0 "register_operand" "")
8518         (match_operator 3 "absneg_operator"
8519           [(match_operand 1 "register_operand" "")]))
8520    (use (match_operand 2 "nonimmediate_operand" ""))
8521    (clobber (reg:CC FLAGS_REG))]
8522   "reload_completed && SSE_REG_P (operands[0])"
8523   [(set (match_dup 0) (match_dup 3))]
8524 {
8525   enum machine_mode mode = GET_MODE (operands[0]);
8526   enum machine_mode vmode = GET_MODE (operands[2]);
8527   rtx tmp;
8528
8529   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8530   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8531   if (operands_match_p (operands[0], operands[2]))
8532     {
8533       tmp = operands[1];
8534       operands[1] = operands[2];
8535       operands[2] = tmp;
8536     }
8537   if (GET_CODE (operands[3]) == ABS)
8538     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8539   else
8540     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8541   operands[3] = tmp;
8542 })
8543
8544 (define_split
8545   [(set (match_operand:SF 0 "register_operand" "")
8546         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8547    (use (match_operand:V4SF 2 "" ""))
8548    (clobber (reg:CC FLAGS_REG))]
8549   "reload_completed"
8550   [(parallel [(set (match_dup 0) (match_dup 1))
8551               (clobber (reg:CC FLAGS_REG))])]
8552 {
8553   rtx tmp;
8554   operands[0] = gen_lowpart (SImode, operands[0]);
8555   if (GET_CODE (operands[1]) == ABS)
8556     {
8557       tmp = gen_int_mode (0x7fffffff, SImode);
8558       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8559     }
8560   else
8561     {
8562       tmp = gen_int_mode (0x80000000, SImode);
8563       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8564     }
8565   operands[1] = tmp;
8566 })
8567
8568 (define_split
8569   [(set (match_operand:DF 0 "register_operand" "")
8570         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8571    (use (match_operand 2 "" ""))
8572    (clobber (reg:CC FLAGS_REG))]
8573   "reload_completed"
8574   [(parallel [(set (match_dup 0) (match_dup 1))
8575               (clobber (reg:CC FLAGS_REG))])]
8576 {
8577   rtx tmp;
8578   if (TARGET_64BIT)
8579     {
8580       tmp = gen_lowpart (DImode, operands[0]);
8581       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8582       operands[0] = tmp;
8583
8584       if (GET_CODE (operands[1]) == ABS)
8585         tmp = const0_rtx;
8586       else
8587         tmp = gen_rtx_NOT (DImode, tmp);
8588     }
8589   else
8590     {
8591       operands[0] = gen_highpart (SImode, operands[0]);
8592       if (GET_CODE (operands[1]) == ABS)
8593         {
8594           tmp = gen_int_mode (0x7fffffff, SImode);
8595           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8596         }
8597       else
8598         {
8599           tmp = gen_int_mode (0x80000000, SImode);
8600           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8601         }
8602     }
8603   operands[1] = tmp;
8604 })
8605
8606 (define_split
8607   [(set (match_operand:XF 0 "register_operand" "")
8608         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8609    (use (match_operand 2 "" ""))
8610    (clobber (reg:CC FLAGS_REG))]
8611   "reload_completed"
8612   [(parallel [(set (match_dup 0) (match_dup 1))
8613               (clobber (reg:CC FLAGS_REG))])]
8614 {
8615   rtx tmp;
8616   operands[0] = gen_rtx_REG (SImode,
8617                              true_regnum (operands[0])
8618                              + (TARGET_64BIT ? 1 : 2));
8619   if (GET_CODE (operands[1]) == ABS)
8620     {
8621       tmp = GEN_INT (0x7fff);
8622       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8623     }
8624   else
8625     {
8626       tmp = GEN_INT (0x8000);
8627       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8628     }
8629   operands[1] = tmp;
8630 })
8631
8632 ;; Conditionalize these after reload. If they match before reload, we
8633 ;; lose the clobber and ability to use integer instructions.
8634
8635 (define_insn "*<code><mode>2_1"
8636   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8637         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8638   "TARGET_80387
8639    && (reload_completed
8640        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8641   "f<absneg_mnemonic>"
8642   [(set_attr "type" "fsgn")
8643    (set_attr "mode" "<MODE>")])
8644
8645 (define_insn "*<code>extendsfdf2"
8646   [(set (match_operand:DF 0 "register_operand" "=f")
8647         (absneg:DF (float_extend:DF
8648                      (match_operand:SF 1 "register_operand" "0"))))]
8649   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8650   "f<absneg_mnemonic>"
8651   [(set_attr "type" "fsgn")
8652    (set_attr "mode" "DF")])
8653
8654 (define_insn "*<code>extendsfxf2"
8655   [(set (match_operand:XF 0 "register_operand" "=f")
8656         (absneg:XF (float_extend:XF
8657                      (match_operand:SF 1 "register_operand" "0"))))]
8658   "TARGET_80387"
8659   "f<absneg_mnemonic>"
8660   [(set_attr "type" "fsgn")
8661    (set_attr "mode" "XF")])
8662
8663 (define_insn "*<code>extenddfxf2"
8664   [(set (match_operand:XF 0 "register_operand" "=f")
8665         (absneg:XF (float_extend:XF
8666                      (match_operand:DF 1 "register_operand" "0"))))]
8667   "TARGET_80387"
8668   "f<absneg_mnemonic>"
8669   [(set_attr "type" "fsgn")
8670    (set_attr "mode" "XF")])
8671
8672 ;; Copysign instructions
8673
8674 (define_mode_iterator CSGNMODE [SF DF TF])
8675 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8676
8677 (define_expand "copysign<mode>3"
8678   [(match_operand:CSGNMODE 0 "register_operand" "")
8679    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8680    (match_operand:CSGNMODE 2 "register_operand" "")]
8681   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8682    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8683   "ix86_expand_copysign (operands); DONE;")
8684
8685 (define_insn_and_split "copysign<mode>3_const"
8686   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8687         (unspec:CSGNMODE
8688           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8689            (match_operand:CSGNMODE 2 "register_operand" "0")
8690            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8691           UNSPEC_COPYSIGN))]
8692   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8693    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8694   "#"
8695   "&& reload_completed"
8696   [(const_int 0)]
8697   "ix86_split_copysign_const (operands); DONE;")
8698
8699 (define_insn "copysign<mode>3_var"
8700   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8701         (unspec:CSGNMODE
8702           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8703            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8704            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8705            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8706           UNSPEC_COPYSIGN))
8707    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8708   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8709    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8710   "#")
8711
8712 (define_split
8713   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8714         (unspec:CSGNMODE
8715           [(match_operand:CSGNMODE 2 "register_operand" "")
8716            (match_operand:CSGNMODE 3 "register_operand" "")
8717            (match_operand:<CSGNVMODE> 4 "" "")
8718            (match_operand:<CSGNVMODE> 5 "" "")]
8719           UNSPEC_COPYSIGN))
8720    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8721   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8722     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8723    && reload_completed"
8724   [(const_int 0)]
8725   "ix86_split_copysign_var (operands); DONE;")
8726 \f
8727 ;; One complement instructions
8728
8729 (define_expand "one_cmpl<mode>2"
8730   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8731         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8732   ""
8733   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8734
8735 (define_insn "*one_cmpl<mode>2_1"
8736   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8737         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8738   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8739   "not{<imodesuffix>}\t%0"
8740   [(set_attr "type" "negnot")
8741    (set_attr "mode" "<MODE>")])
8742
8743 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8744 (define_insn "*one_cmplqi2_1"
8745   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8746         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8747   "ix86_unary_operator_ok (NOT, QImode, operands)"
8748   "@
8749    not{b}\t%0
8750    not{l}\t%k0"
8751   [(set_attr "type" "negnot")
8752    (set_attr "mode" "QI,SI")])
8753
8754 ;; ??? Currently never generated - xor is used instead.
8755 (define_insn "*one_cmplsi2_1_zext"
8756   [(set (match_operand:DI 0 "register_operand" "=r")
8757         (zero_extend:DI
8758           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8759   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8760   "not{l}\t%k0"
8761   [(set_attr "type" "negnot")
8762    (set_attr "mode" "SI")])
8763
8764 (define_insn "*one_cmpl<mode>2_2"
8765   [(set (reg FLAGS_REG)
8766         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8767                  (const_int 0)))
8768    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8769         (not:SWI (match_dup 1)))]
8770   "ix86_match_ccmode (insn, CCNOmode)
8771    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8772   "#"
8773   [(set_attr "type" "alu1")
8774    (set_attr "mode" "<MODE>")])
8775
8776 (define_split
8777   [(set (match_operand 0 "flags_reg_operand" "")
8778         (match_operator 2 "compare_operator"
8779           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8780            (const_int 0)]))
8781    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8782         (not:SWI (match_dup 3)))]
8783   "ix86_match_ccmode (insn, CCNOmode)"
8784   [(parallel [(set (match_dup 0)
8785                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8786                                     (const_int 0)]))
8787               (set (match_dup 1)
8788                    (xor:SWI (match_dup 3) (const_int -1)))])])
8789
8790 ;; ??? Currently never generated - xor is used instead.
8791 (define_insn "*one_cmplsi2_2_zext"
8792   [(set (reg FLAGS_REG)
8793         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8794                  (const_int 0)))
8795    (set (match_operand:DI 0 "register_operand" "=r")
8796         (zero_extend:DI (not:SI (match_dup 1))))]
8797   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8798    && ix86_unary_operator_ok (NOT, SImode, operands)"
8799   "#"
8800   [(set_attr "type" "alu1")
8801    (set_attr "mode" "SI")])
8802
8803 (define_split
8804   [(set (match_operand 0 "flags_reg_operand" "")
8805         (match_operator 2 "compare_operator"
8806           [(not:SI (match_operand:SI 3 "register_operand" ""))
8807            (const_int 0)]))
8808    (set (match_operand:DI 1 "register_operand" "")
8809         (zero_extend:DI (not:SI (match_dup 3))))]
8810   "ix86_match_ccmode (insn, CCNOmode)"
8811   [(parallel [(set (match_dup 0)
8812                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8813                                     (const_int 0)]))
8814               (set (match_dup 1)
8815                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8816 \f
8817 ;; Shift instructions
8818
8819 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8820 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8821 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8822 ;; from the assembler input.
8823 ;;
8824 ;; This instruction shifts the target reg/mem as usual, but instead of
8825 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8826 ;; is a left shift double, bits are taken from the high order bits of
8827 ;; reg, else if the insn is a shift right double, bits are taken from the
8828 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8829 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8830 ;;
8831 ;; Since sh[lr]d does not change the `reg' operand, that is done
8832 ;; separately, making all shifts emit pairs of shift double and normal
8833 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8834 ;; support a 63 bit shift, each shift where the count is in a reg expands
8835 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8836 ;;
8837 ;; If the shift count is a constant, we need never emit more than one
8838 ;; shift pair, instead using moves and sign extension for counts greater
8839 ;; than 31.
8840
8841 (define_expand "ashl<mode>3"
8842   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8843         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8844                       (match_operand:QI 2 "nonmemory_operand" "")))]
8845   ""
8846   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8847
8848 (define_insn "*ashl<mode>3_doubleword"
8849   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8850         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8851                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8852    (clobber (reg:CC FLAGS_REG))]
8853   ""
8854   "#"
8855   [(set_attr "type" "multi")])
8856
8857 (define_split
8858   [(set (match_operand:DWI 0 "register_operand" "")
8859         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8860                     (match_operand:QI 2 "nonmemory_operand" "")))
8861    (clobber (reg:CC FLAGS_REG))]
8862   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8863   [(const_int 0)]
8864   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8865
8866 ;; By default we don't ask for a scratch register, because when DWImode
8867 ;; values are manipulated, registers are already at a premium.  But if
8868 ;; we have one handy, we won't turn it away.
8869
8870 (define_peephole2
8871   [(match_scratch:DWIH 3 "r")
8872    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8873                    (ashift:<DWI>
8874                      (match_operand:<DWI> 1 "nonmemory_operand" "")
8875                      (match_operand:QI 2 "nonmemory_operand" "")))
8876               (clobber (reg:CC FLAGS_REG))])
8877    (match_dup 3)]
8878   "TARGET_CMOVE"
8879   [(const_int 0)]
8880   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8881
8882 (define_insn "x86_64_shld"
8883   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8884         (ior:DI (ashift:DI (match_dup 0)
8885                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
8886                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8887                   (minus:QI (const_int 64) (match_dup 2)))))
8888    (clobber (reg:CC FLAGS_REG))]
8889   "TARGET_64BIT"
8890   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8891   [(set_attr "type" "ishift")
8892    (set_attr "prefix_0f" "1")
8893    (set_attr "mode" "DI")
8894    (set_attr "athlon_decode" "vector")
8895    (set_attr "amdfam10_decode" "vector")
8896    (set_attr "bdver1_decode" "vector")])
8897
8898 (define_insn "x86_shld"
8899   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8900         (ior:SI (ashift:SI (match_dup 0)
8901                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
8902                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8903                   (minus:QI (const_int 32) (match_dup 2)))))
8904    (clobber (reg:CC FLAGS_REG))]
8905   ""
8906   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8907   [(set_attr "type" "ishift")
8908    (set_attr "prefix_0f" "1")
8909    (set_attr "mode" "SI")
8910    (set_attr "pent_pair" "np")
8911    (set_attr "athlon_decode" "vector")
8912    (set_attr "amdfam10_decode" "vector")
8913    (set_attr "bdver1_decode" "vector")])
8914
8915 (define_expand "x86_shift<mode>_adj_1"
8916   [(set (reg:CCZ FLAGS_REG)
8917         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8918                              (match_dup 4))
8919                      (const_int 0)))
8920    (set (match_operand:SWI48 0 "register_operand" "")
8921         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8922                             (match_operand:SWI48 1 "register_operand" "")
8923                             (match_dup 0)))
8924    (set (match_dup 1)
8925         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8926                             (match_operand:SWI48 3 "register_operand" "r")
8927                             (match_dup 1)))]
8928   "TARGET_CMOVE"
8929   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8930
8931 (define_expand "x86_shift<mode>_adj_2"
8932   [(use (match_operand:SWI48 0 "register_operand" ""))
8933    (use (match_operand:SWI48 1 "register_operand" ""))
8934    (use (match_operand:QI 2 "register_operand" ""))]
8935   ""
8936 {
8937   rtx label = gen_label_rtx ();
8938   rtx tmp;
8939
8940   emit_insn (gen_testqi_ccz_1 (operands[2],
8941                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8942
8943   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8944   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8945   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8946                               gen_rtx_LABEL_REF (VOIDmode, label),
8947                               pc_rtx);
8948   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8949   JUMP_LABEL (tmp) = label;
8950
8951   emit_move_insn (operands[0], operands[1]);
8952   ix86_expand_clear (operands[1]);
8953
8954   emit_label (label);
8955   LABEL_NUSES (label) = 1;
8956
8957   DONE;
8958 })
8959
8960 ;; Avoid useless masking of count operand.
8961 (define_insn_and_split "*ashl<mode>3_mask"
8962   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8963         (ashift:SWI48
8964           (match_operand:SWI48 1 "nonimmediate_operand" "0")
8965           (subreg:QI
8966             (and:SI
8967               (match_operand:SI 2 "nonimmediate_operand" "c")
8968               (match_operand:SI 3 "const_int_operand" "n")) 0)))
8969    (clobber (reg:CC FLAGS_REG))]
8970   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8971    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8972       == GET_MODE_BITSIZE (<MODE>mode)-1"
8973   "#"
8974   "&& 1"
8975   [(parallel [(set (match_dup 0)
8976                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
8977               (clobber (reg:CC FLAGS_REG))])]
8978 {
8979   if (can_create_pseudo_p ())
8980     operands [2] = force_reg (SImode, operands[2]);
8981
8982   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
8983 }
8984   [(set_attr "type" "ishift")
8985    (set_attr "mode" "<MODE>")])
8986
8987 (define_insn "*ashl<mode>3_1"
8988   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8989         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
8990                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
8991    (clobber (reg:CC FLAGS_REG))]
8992   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
8993 {
8994   switch (get_attr_type (insn))
8995     {
8996     case TYPE_LEA:
8997       return "#";
8998
8999     case TYPE_ALU:
9000       gcc_assert (operands[2] == const1_rtx);
9001       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9002       return "add{<imodesuffix>}\t%0, %0";
9003
9004     default:
9005       if (operands[2] == const1_rtx
9006           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9007         return "sal{<imodesuffix>}\t%0";
9008       else
9009         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9010     }
9011 }
9012   [(set (attr "type")
9013      (cond [(eq_attr "alternative" "1")
9014               (const_string "lea")
9015             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9016                           (const_int 0))
9017                       (match_operand 0 "register_operand" ""))
9018                  (match_operand 2 "const1_operand" ""))
9019               (const_string "alu")
9020            ]
9021            (const_string "ishift")))
9022    (set (attr "length_immediate")
9023      (if_then_else
9024        (ior (eq_attr "type" "alu")
9025             (and (eq_attr "type" "ishift")
9026                  (and (match_operand 2 "const1_operand" "")
9027                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9028                           (const_int 0)))))
9029        (const_string "0")
9030        (const_string "*")))
9031    (set_attr "mode" "<MODE>")])
9032
9033 (define_insn "*ashlsi3_1_zext"
9034   [(set (match_operand:DI 0 "register_operand" "=r,r")
9035         (zero_extend:DI
9036           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9037                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9038    (clobber (reg:CC FLAGS_REG))]
9039   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9040 {
9041   switch (get_attr_type (insn))
9042     {
9043     case TYPE_LEA:
9044       return "#";
9045
9046     case TYPE_ALU:
9047       gcc_assert (operands[2] == const1_rtx);
9048       return "add{l}\t%k0, %k0";
9049
9050     default:
9051       if (operands[2] == const1_rtx
9052           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9053         return "sal{l}\t%k0";
9054       else
9055         return "sal{l}\t{%2, %k0|%k0, %2}";
9056     }
9057 }
9058   [(set (attr "type")
9059      (cond [(eq_attr "alternative" "1")
9060               (const_string "lea")
9061             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9062                      (const_int 0))
9063                  (match_operand 2 "const1_operand" ""))
9064               (const_string "alu")
9065            ]
9066            (const_string "ishift")))
9067    (set (attr "length_immediate")
9068      (if_then_else
9069        (ior (eq_attr "type" "alu")
9070             (and (eq_attr "type" "ishift")
9071                  (and (match_operand 2 "const1_operand" "")
9072                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9073                           (const_int 0)))))
9074        (const_string "0")
9075        (const_string "*")))
9076    (set_attr "mode" "SI")])
9077
9078 (define_insn "*ashlhi3_1"
9079   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9080         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9081                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9082    (clobber (reg:CC FLAGS_REG))]
9083   "TARGET_PARTIAL_REG_STALL
9084    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9085 {
9086   switch (get_attr_type (insn))
9087     {
9088     case TYPE_ALU:
9089       gcc_assert (operands[2] == const1_rtx);
9090       return "add{w}\t%0, %0";
9091
9092     default:
9093       if (operands[2] == const1_rtx
9094           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9095         return "sal{w}\t%0";
9096       else
9097         return "sal{w}\t{%2, %0|%0, %2}";
9098     }
9099 }
9100   [(set (attr "type")
9101      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9102                           (const_int 0))
9103                       (match_operand 0 "register_operand" ""))
9104                  (match_operand 2 "const1_operand" ""))
9105               (const_string "alu")
9106            ]
9107            (const_string "ishift")))
9108    (set (attr "length_immediate")
9109      (if_then_else
9110        (ior (eq_attr "type" "alu")
9111             (and (eq_attr "type" "ishift")
9112                  (and (match_operand 2 "const1_operand" "")
9113                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9114                           (const_int 0)))))
9115        (const_string "0")
9116        (const_string "*")))
9117    (set_attr "mode" "HI")])
9118
9119 (define_insn "*ashlhi3_1_lea"
9120   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9121         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9122                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9123    (clobber (reg:CC FLAGS_REG))]
9124   "!TARGET_PARTIAL_REG_STALL
9125    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9126 {
9127   switch (get_attr_type (insn))
9128     {
9129     case TYPE_LEA:
9130       return "#";
9131
9132     case TYPE_ALU:
9133       gcc_assert (operands[2] == const1_rtx);
9134       return "add{w}\t%0, %0";
9135
9136     default:
9137       if (operands[2] == const1_rtx
9138           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9139         return "sal{w}\t%0";
9140       else
9141         return "sal{w}\t{%2, %0|%0, %2}";
9142     }
9143 }
9144   [(set (attr "type")
9145      (cond [(eq_attr "alternative" "1")
9146               (const_string "lea")
9147             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9148                           (const_int 0))
9149                       (match_operand 0 "register_operand" ""))
9150                  (match_operand 2 "const1_operand" ""))
9151               (const_string "alu")
9152            ]
9153            (const_string "ishift")))
9154    (set (attr "length_immediate")
9155      (if_then_else
9156        (ior (eq_attr "type" "alu")
9157             (and (eq_attr "type" "ishift")
9158                  (and (match_operand 2 "const1_operand" "")
9159                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9160                           (const_int 0)))))
9161        (const_string "0")
9162        (const_string "*")))
9163    (set_attr "mode" "HI,SI")])
9164
9165 (define_insn "*ashlqi3_1"
9166   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9167         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9168                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9169    (clobber (reg:CC FLAGS_REG))]
9170   "TARGET_PARTIAL_REG_STALL
9171    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9172 {
9173   switch (get_attr_type (insn))
9174     {
9175     case TYPE_ALU:
9176       gcc_assert (operands[2] == const1_rtx);
9177       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9178         return "add{l}\t%k0, %k0";
9179       else
9180         return "add{b}\t%0, %0";
9181
9182     default:
9183       if (operands[2] == const1_rtx
9184           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9185         {
9186           if (get_attr_mode (insn) == MODE_SI)
9187             return "sal{l}\t%k0";
9188           else
9189             return "sal{b}\t%0";
9190         }
9191       else
9192         {
9193           if (get_attr_mode (insn) == MODE_SI)
9194             return "sal{l}\t{%2, %k0|%k0, %2}";
9195           else
9196             return "sal{b}\t{%2, %0|%0, %2}";
9197         }
9198     }
9199 }
9200   [(set (attr "type")
9201      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9202                           (const_int 0))
9203                       (match_operand 0 "register_operand" ""))
9204                  (match_operand 2 "const1_operand" ""))
9205               (const_string "alu")
9206            ]
9207            (const_string "ishift")))
9208    (set (attr "length_immediate")
9209      (if_then_else
9210        (ior (eq_attr "type" "alu")
9211             (and (eq_attr "type" "ishift")
9212                  (and (match_operand 2 "const1_operand" "")
9213                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9214                           (const_int 0)))))
9215        (const_string "0")
9216        (const_string "*")))
9217    (set_attr "mode" "QI,SI")])
9218
9219 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9220 (define_insn "*ashlqi3_1_lea"
9221   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9222         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9223                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9224    (clobber (reg:CC FLAGS_REG))]
9225   "!TARGET_PARTIAL_REG_STALL
9226    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9227 {
9228   switch (get_attr_type (insn))
9229     {
9230     case TYPE_LEA:
9231       return "#";
9232
9233     case TYPE_ALU:
9234       gcc_assert (operands[2] == const1_rtx);
9235       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9236         return "add{l}\t%k0, %k0";
9237       else
9238         return "add{b}\t%0, %0";
9239
9240     default:
9241       if (operands[2] == const1_rtx
9242           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9243         {
9244           if (get_attr_mode (insn) == MODE_SI)
9245             return "sal{l}\t%k0";
9246           else
9247             return "sal{b}\t%0";
9248         }
9249       else
9250         {
9251           if (get_attr_mode (insn) == MODE_SI)
9252             return "sal{l}\t{%2, %k0|%k0, %2}";
9253           else
9254             return "sal{b}\t{%2, %0|%0, %2}";
9255         }
9256     }
9257 }
9258   [(set (attr "type")
9259      (cond [(eq_attr "alternative" "2")
9260               (const_string "lea")
9261             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9262                           (const_int 0))
9263                       (match_operand 0 "register_operand" ""))
9264                  (match_operand 2 "const1_operand" ""))
9265               (const_string "alu")
9266            ]
9267            (const_string "ishift")))
9268    (set (attr "length_immediate")
9269      (if_then_else
9270        (ior (eq_attr "type" "alu")
9271             (and (eq_attr "type" "ishift")
9272                  (and (match_operand 2 "const1_operand" "")
9273                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9274                           (const_int 0)))))
9275        (const_string "0")
9276        (const_string "*")))
9277    (set_attr "mode" "QI,SI,SI")])
9278
9279 (define_insn "*ashlqi3_1_slp"
9280   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9281         (ashift:QI (match_dup 0)
9282                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9283    (clobber (reg:CC FLAGS_REG))]
9284   "(optimize_function_for_size_p (cfun)
9285     || !TARGET_PARTIAL_FLAG_REG_STALL
9286     || (operands[1] == const1_rtx
9287         && (TARGET_SHIFT1
9288             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9289 {
9290   switch (get_attr_type (insn))
9291     {
9292     case TYPE_ALU:
9293       gcc_assert (operands[1] == const1_rtx);
9294       return "add{b}\t%0, %0";
9295
9296     default:
9297       if (operands[1] == const1_rtx
9298           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9299         return "sal{b}\t%0";
9300       else
9301         return "sal{b}\t{%1, %0|%0, %1}";
9302     }
9303 }
9304   [(set (attr "type")
9305      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9306                           (const_int 0))
9307                       (match_operand 0 "register_operand" ""))
9308                  (match_operand 1 "const1_operand" ""))
9309               (const_string "alu")
9310            ]
9311            (const_string "ishift1")))
9312    (set (attr "length_immediate")
9313      (if_then_else
9314        (ior (eq_attr "type" "alu")
9315             (and (eq_attr "type" "ishift1")
9316                  (and (match_operand 1 "const1_operand" "")
9317                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9318                           (const_int 0)))))
9319        (const_string "0")
9320        (const_string "*")))
9321    (set_attr "mode" "QI")])
9322
9323 ;; Convert ashift to the lea pattern to avoid flags dependency.
9324 (define_split
9325   [(set (match_operand 0 "register_operand" "")
9326         (ashift (match_operand 1 "index_register_operand" "")
9327                 (match_operand:QI 2 "const_int_operand" "")))
9328    (clobber (reg:CC FLAGS_REG))]
9329   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9330    && reload_completed
9331    && true_regnum (operands[0]) != true_regnum (operands[1])"
9332   [(const_int 0)]
9333 {
9334   enum machine_mode mode = GET_MODE (operands[0]);
9335   rtx pat;
9336
9337   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9338     { 
9339       mode = SImode; 
9340       operands[0] = gen_lowpart (mode, operands[0]);
9341       operands[1] = gen_lowpart (mode, operands[1]);
9342     }
9343
9344   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9345
9346   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9347
9348   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9349   DONE;
9350 })
9351
9352 ;; Convert ashift to the lea pattern to avoid flags dependency.
9353 (define_split
9354   [(set (match_operand:DI 0 "register_operand" "")
9355         (zero_extend:DI
9356           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9357                      (match_operand:QI 2 "const_int_operand" ""))))
9358    (clobber (reg:CC FLAGS_REG))]
9359   "TARGET_64BIT && reload_completed
9360    && true_regnum (operands[0]) != true_regnum (operands[1])"
9361   [(set (match_dup 0)
9362         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9363 {
9364   operands[1] = gen_lowpart (DImode, operands[1]);
9365   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9366 })
9367
9368 ;; This pattern can't accept a variable shift count, since shifts by
9369 ;; zero don't affect the flags.  We assume that shifts by constant
9370 ;; zero are optimized away.
9371 (define_insn "*ashl<mode>3_cmp"
9372   [(set (reg FLAGS_REG)
9373         (compare
9374           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9375                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9376           (const_int 0)))
9377    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9378         (ashift:SWI (match_dup 1) (match_dup 2)))]
9379   "(optimize_function_for_size_p (cfun)
9380     || !TARGET_PARTIAL_FLAG_REG_STALL
9381     || (operands[2] == const1_rtx
9382         && (TARGET_SHIFT1
9383             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9384    && ix86_match_ccmode (insn, CCGOCmode)
9385    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9386 {
9387   switch (get_attr_type (insn))
9388     {
9389     case TYPE_ALU:
9390       gcc_assert (operands[2] == const1_rtx);
9391       return "add{<imodesuffix>}\t%0, %0";
9392
9393     default:
9394       if (operands[2] == const1_rtx
9395           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9396         return "sal{<imodesuffix>}\t%0";
9397       else
9398         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9399     }
9400 }
9401   [(set (attr "type")
9402      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9403                           (const_int 0))
9404                       (match_operand 0 "register_operand" ""))
9405                  (match_operand 2 "const1_operand" ""))
9406               (const_string "alu")
9407            ]
9408            (const_string "ishift")))
9409    (set (attr "length_immediate")
9410      (if_then_else
9411        (ior (eq_attr "type" "alu")
9412             (and (eq_attr "type" "ishift")
9413                  (and (match_operand 2 "const1_operand" "")
9414                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9415                           (const_int 0)))))
9416        (const_string "0")
9417        (const_string "*")))
9418    (set_attr "mode" "<MODE>")])
9419
9420 (define_insn "*ashlsi3_cmp_zext"
9421   [(set (reg FLAGS_REG)
9422         (compare
9423           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9424                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9425           (const_int 0)))
9426    (set (match_operand:DI 0 "register_operand" "=r")
9427         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9428   "TARGET_64BIT
9429    && (optimize_function_for_size_p (cfun)
9430        || !TARGET_PARTIAL_FLAG_REG_STALL
9431        || (operands[2] == const1_rtx
9432            && (TARGET_SHIFT1
9433                || TARGET_DOUBLE_WITH_ADD)))
9434    && ix86_match_ccmode (insn, CCGOCmode)
9435    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9436 {
9437   switch (get_attr_type (insn))
9438     {
9439     case TYPE_ALU:
9440       gcc_assert (operands[2] == const1_rtx);
9441       return "add{l}\t%k0, %k0";
9442
9443     default:
9444       if (operands[2] == const1_rtx
9445           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9446         return "sal{l}\t%k0";
9447       else
9448         return "sal{l}\t{%2, %k0|%k0, %2}";
9449     }
9450 }
9451   [(set (attr "type")
9452      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9453                      (const_int 0))
9454                  (match_operand 2 "const1_operand" ""))
9455               (const_string "alu")
9456            ]
9457            (const_string "ishift")))
9458    (set (attr "length_immediate")
9459      (if_then_else
9460        (ior (eq_attr "type" "alu")
9461             (and (eq_attr "type" "ishift")
9462                  (and (match_operand 2 "const1_operand" "")
9463                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9464                           (const_int 0)))))
9465        (const_string "0")
9466        (const_string "*")))
9467    (set_attr "mode" "SI")])
9468
9469 (define_insn "*ashl<mode>3_cconly"
9470   [(set (reg FLAGS_REG)
9471         (compare
9472           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9473                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9474           (const_int 0)))
9475    (clobber (match_scratch:SWI 0 "=<r>"))]
9476   "(optimize_function_for_size_p (cfun)
9477     || !TARGET_PARTIAL_FLAG_REG_STALL
9478     || (operands[2] == const1_rtx
9479         && (TARGET_SHIFT1
9480             || TARGET_DOUBLE_WITH_ADD)))
9481    && ix86_match_ccmode (insn, CCGOCmode)"
9482 {
9483   switch (get_attr_type (insn))
9484     {
9485     case TYPE_ALU:
9486       gcc_assert (operands[2] == const1_rtx);
9487       return "add{<imodesuffix>}\t%0, %0";
9488
9489     default:
9490       if (operands[2] == const1_rtx
9491           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9492         return "sal{<imodesuffix>}\t%0";
9493       else
9494         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9495     }
9496 }
9497   [(set (attr "type")
9498      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9499                           (const_int 0))
9500                       (match_operand 0 "register_operand" ""))
9501                  (match_operand 2 "const1_operand" ""))
9502               (const_string "alu")
9503            ]
9504            (const_string "ishift")))
9505    (set (attr "length_immediate")
9506      (if_then_else
9507        (ior (eq_attr "type" "alu")
9508             (and (eq_attr "type" "ishift")
9509                  (and (match_operand 2 "const1_operand" "")
9510                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9511                           (const_int 0)))))
9512        (const_string "0")
9513        (const_string "*")))
9514    (set_attr "mode" "<MODE>")])
9515
9516 ;; See comment above `ashl<mode>3' about how this works.
9517
9518 (define_expand "<shiftrt_insn><mode>3"
9519   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9520         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9521                            (match_operand:QI 2 "nonmemory_operand" "")))]
9522   ""
9523   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9524
9525 ;; Avoid useless masking of count operand.
9526 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9527   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9528         (any_shiftrt:SWI48
9529           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9530           (subreg:QI
9531             (and:SI
9532               (match_operand:SI 2 "nonimmediate_operand" "c")
9533               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9534    (clobber (reg:CC FLAGS_REG))]
9535   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9536    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9537       == GET_MODE_BITSIZE (<MODE>mode)-1"
9538   "#"
9539   "&& 1"
9540   [(parallel [(set (match_dup 0)
9541                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9542               (clobber (reg:CC FLAGS_REG))])]
9543 {
9544   if (can_create_pseudo_p ())
9545     operands [2] = force_reg (SImode, operands[2]);
9546
9547   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9548 }
9549   [(set_attr "type" "ishift")
9550    (set_attr "mode" "<MODE>")])
9551
9552 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9553   [(set (match_operand:DWI 0 "register_operand" "=r")
9554         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9555                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9556    (clobber (reg:CC FLAGS_REG))]
9557   ""
9558   "#"
9559   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9560   [(const_int 0)]
9561   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9562   [(set_attr "type" "multi")])
9563
9564 ;; By default we don't ask for a scratch register, because when DWImode
9565 ;; values are manipulated, registers are already at a premium.  But if
9566 ;; we have one handy, we won't turn it away.
9567
9568 (define_peephole2
9569   [(match_scratch:DWIH 3 "r")
9570    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9571                    (any_shiftrt:<DWI>
9572                      (match_operand:<DWI> 1 "register_operand" "")
9573                      (match_operand:QI 2 "nonmemory_operand" "")))
9574               (clobber (reg:CC FLAGS_REG))])
9575    (match_dup 3)]
9576   "TARGET_CMOVE"
9577   [(const_int 0)]
9578   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9579
9580 (define_insn "x86_64_shrd"
9581   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9582         (ior:DI (ashiftrt:DI (match_dup 0)
9583                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9584                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9585                   (minus:QI (const_int 64) (match_dup 2)))))
9586    (clobber (reg:CC FLAGS_REG))]
9587   "TARGET_64BIT"
9588   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9589   [(set_attr "type" "ishift")
9590    (set_attr "prefix_0f" "1")
9591    (set_attr "mode" "DI")
9592    (set_attr "athlon_decode" "vector")
9593    (set_attr "amdfam10_decode" "vector")
9594    (set_attr "bdver1_decode" "vector")])
9595
9596 (define_insn "x86_shrd"
9597   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9598         (ior:SI (ashiftrt:SI (match_dup 0)
9599                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9600                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9601                   (minus:QI (const_int 32) (match_dup 2)))))
9602    (clobber (reg:CC FLAGS_REG))]
9603   ""
9604   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9605   [(set_attr "type" "ishift")
9606    (set_attr "prefix_0f" "1")
9607    (set_attr "mode" "SI")
9608    (set_attr "pent_pair" "np")
9609    (set_attr "athlon_decode" "vector")
9610    (set_attr "amdfam10_decode" "vector")
9611    (set_attr "bdver1_decode" "vector")])
9612
9613 (define_insn "ashrdi3_cvt"
9614   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9615         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9616                      (match_operand:QI 2 "const_int_operand" "")))
9617    (clobber (reg:CC FLAGS_REG))]
9618   "TARGET_64BIT && INTVAL (operands[2]) == 63
9619    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9620    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9621   "@
9622    {cqto|cqo}
9623    sar{q}\t{%2, %0|%0, %2}"
9624   [(set_attr "type" "imovx,ishift")
9625    (set_attr "prefix_0f" "0,*")
9626    (set_attr "length_immediate" "0,*")
9627    (set_attr "modrm" "0,1")
9628    (set_attr "mode" "DI")])
9629
9630 (define_insn "ashrsi3_cvt"
9631   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9632         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9633                      (match_operand:QI 2 "const_int_operand" "")))
9634    (clobber (reg:CC FLAGS_REG))]
9635   "INTVAL (operands[2]) == 31
9636    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9637    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9638   "@
9639    {cltd|cdq}
9640    sar{l}\t{%2, %0|%0, %2}"
9641   [(set_attr "type" "imovx,ishift")
9642    (set_attr "prefix_0f" "0,*")
9643    (set_attr "length_immediate" "0,*")
9644    (set_attr "modrm" "0,1")
9645    (set_attr "mode" "SI")])
9646
9647 (define_insn "*ashrsi3_cvt_zext"
9648   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9649         (zero_extend:DI
9650           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9651                        (match_operand:QI 2 "const_int_operand" ""))))
9652    (clobber (reg:CC FLAGS_REG))]
9653   "TARGET_64BIT && INTVAL (operands[2]) == 31
9654    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9655    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9656   "@
9657    {cltd|cdq}
9658    sar{l}\t{%2, %k0|%k0, %2}"
9659   [(set_attr "type" "imovx,ishift")
9660    (set_attr "prefix_0f" "0,*")
9661    (set_attr "length_immediate" "0,*")
9662    (set_attr "modrm" "0,1")
9663    (set_attr "mode" "SI")])
9664
9665 (define_expand "x86_shift<mode>_adj_3"
9666   [(use (match_operand:SWI48 0 "register_operand" ""))
9667    (use (match_operand:SWI48 1 "register_operand" ""))
9668    (use (match_operand:QI 2 "register_operand" ""))]
9669   ""
9670 {
9671   rtx label = gen_label_rtx ();
9672   rtx tmp;
9673
9674   emit_insn (gen_testqi_ccz_1 (operands[2],
9675                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9676
9677   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9678   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9679   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9680                               gen_rtx_LABEL_REF (VOIDmode, label),
9681                               pc_rtx);
9682   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9683   JUMP_LABEL (tmp) = label;
9684
9685   emit_move_insn (operands[0], operands[1]);
9686   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9687                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9688   emit_label (label);
9689   LABEL_NUSES (label) = 1;
9690
9691   DONE;
9692 })
9693
9694 (define_insn "*<shiftrt_insn><mode>3_1"
9695   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9696         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9697                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9698    (clobber (reg:CC FLAGS_REG))]
9699   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9700 {
9701   if (operands[2] == const1_rtx
9702       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9703     return "<shiftrt>{<imodesuffix>}\t%0";
9704   else
9705     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9706 }
9707   [(set_attr "type" "ishift")
9708    (set (attr "length_immediate")
9709      (if_then_else
9710        (and (match_operand 2 "const1_operand" "")
9711             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9712                 (const_int 0)))
9713        (const_string "0")
9714        (const_string "*")))
9715    (set_attr "mode" "<MODE>")])
9716
9717 (define_insn "*<shiftrt_insn>si3_1_zext"
9718   [(set (match_operand:DI 0 "register_operand" "=r")
9719         (zero_extend:DI
9720           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9721                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9722    (clobber (reg:CC FLAGS_REG))]
9723   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9724 {
9725   if (operands[2] == const1_rtx
9726       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9727     return "<shiftrt>{l}\t%k0";
9728   else
9729     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9730 }
9731   [(set_attr "type" "ishift")
9732    (set (attr "length_immediate")
9733      (if_then_else
9734        (and (match_operand 2 "const1_operand" "")
9735             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9736                 (const_int 0)))
9737        (const_string "0")
9738        (const_string "*")))
9739    (set_attr "mode" "SI")])
9740
9741 (define_insn "*<shiftrt_insn>qi3_1_slp"
9742   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9743         (any_shiftrt:QI (match_dup 0)
9744                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9745    (clobber (reg:CC FLAGS_REG))]
9746   "(optimize_function_for_size_p (cfun)
9747     || !TARGET_PARTIAL_REG_STALL
9748     || (operands[1] == const1_rtx
9749         && TARGET_SHIFT1))"
9750 {
9751   if (operands[1] == const1_rtx
9752       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9753     return "<shiftrt>{b}\t%0";
9754   else
9755     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9756 }
9757   [(set_attr "type" "ishift1")
9758    (set (attr "length_immediate")
9759      (if_then_else
9760        (and (match_operand 1 "const1_operand" "")
9761             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9762                 (const_int 0)))
9763        (const_string "0")
9764        (const_string "*")))
9765    (set_attr "mode" "QI")])
9766
9767 ;; This pattern can't accept a variable shift count, since shifts by
9768 ;; zero don't affect the flags.  We assume that shifts by constant
9769 ;; zero are optimized away.
9770 (define_insn "*<shiftrt_insn><mode>3_cmp"
9771   [(set (reg FLAGS_REG)
9772         (compare
9773           (any_shiftrt:SWI
9774             (match_operand:SWI 1 "nonimmediate_operand" "0")
9775             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9776           (const_int 0)))
9777    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9778         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9779   "(optimize_function_for_size_p (cfun)
9780     || !TARGET_PARTIAL_FLAG_REG_STALL
9781     || (operands[2] == const1_rtx
9782         && TARGET_SHIFT1))
9783    && ix86_match_ccmode (insn, CCGOCmode)
9784    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9785 {
9786   if (operands[2] == const1_rtx
9787       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9788     return "<shiftrt>{<imodesuffix>}\t%0";
9789   else
9790     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9791 }
9792   [(set_attr "type" "ishift")
9793    (set (attr "length_immediate")
9794      (if_then_else
9795        (and (match_operand 2 "const1_operand" "")
9796             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9797                 (const_int 0)))
9798        (const_string "0")
9799        (const_string "*")))
9800    (set_attr "mode" "<MODE>")])
9801
9802 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9803   [(set (reg FLAGS_REG)
9804         (compare
9805           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9806                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9807           (const_int 0)))
9808    (set (match_operand:DI 0 "register_operand" "=r")
9809         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9810   "TARGET_64BIT
9811    && (optimize_function_for_size_p (cfun)
9812        || !TARGET_PARTIAL_FLAG_REG_STALL
9813        || (operands[2] == const1_rtx
9814            && TARGET_SHIFT1))
9815    && ix86_match_ccmode (insn, CCGOCmode)
9816    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9817 {
9818   if (operands[2] == const1_rtx
9819       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9820     return "<shiftrt>{l}\t%k0";
9821   else
9822     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9823 }
9824   [(set_attr "type" "ishift")
9825    (set (attr "length_immediate")
9826      (if_then_else
9827        (and (match_operand 2 "const1_operand" "")
9828             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9829                 (const_int 0)))
9830        (const_string "0")
9831        (const_string "*")))
9832    (set_attr "mode" "SI")])
9833
9834 (define_insn "*<shiftrt_insn><mode>3_cconly"
9835   [(set (reg FLAGS_REG)
9836         (compare
9837           (any_shiftrt:SWI
9838             (match_operand:SWI 1 "register_operand" "0")
9839             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9840           (const_int 0)))
9841    (clobber (match_scratch:SWI 0 "=<r>"))]
9842   "(optimize_function_for_size_p (cfun)
9843     || !TARGET_PARTIAL_FLAG_REG_STALL
9844     || (operands[2] == const1_rtx
9845         && TARGET_SHIFT1))
9846    && ix86_match_ccmode (insn, CCGOCmode)"
9847 {
9848   if (operands[2] == const1_rtx
9849       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9850     return "<shiftrt>{<imodesuffix>}\t%0";
9851   else
9852     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9853 }
9854   [(set_attr "type" "ishift")
9855    (set (attr "length_immediate")
9856      (if_then_else
9857        (and (match_operand 2 "const1_operand" "")
9858             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9859                 (const_int 0)))
9860        (const_string "0")
9861        (const_string "*")))
9862    (set_attr "mode" "<MODE>")])
9863 \f
9864 ;; Rotate instructions
9865
9866 (define_expand "<rotate_insn>ti3"
9867   [(set (match_operand:TI 0 "register_operand" "")
9868         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9869                        (match_operand:QI 2 "nonmemory_operand" "")))]
9870   "TARGET_64BIT"
9871 {
9872   if (const_1_to_63_operand (operands[2], VOIDmode))
9873     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9874                 (operands[0], operands[1], operands[2]));
9875   else
9876     FAIL;
9877
9878   DONE;
9879 })
9880
9881 (define_expand "<rotate_insn>di3"
9882   [(set (match_operand:DI 0 "shiftdi_operand" "")
9883         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9884                        (match_operand:QI 2 "nonmemory_operand" "")))]
9885  ""
9886 {
9887   if (TARGET_64BIT)
9888     ix86_expand_binary_operator (<CODE>, DImode, operands);
9889   else if (const_1_to_31_operand (operands[2], VOIDmode))
9890     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9891                 (operands[0], operands[1], operands[2]));
9892   else
9893     FAIL;
9894
9895   DONE;
9896 })
9897
9898 (define_expand "<rotate_insn><mode>3"
9899   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9900         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9901                             (match_operand:QI 2 "nonmemory_operand" "")))]
9902   ""
9903   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9904
9905 ;; Avoid useless masking of count operand.
9906 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9907   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9908         (any_rotate:SWI48
9909           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9910           (subreg:QI
9911             (and:SI
9912               (match_operand:SI 2 "nonimmediate_operand" "c")
9913               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9914    (clobber (reg:CC FLAGS_REG))]
9915   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9916    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9917       == GET_MODE_BITSIZE (<MODE>mode)-1"
9918   "#"
9919   "&& 1"
9920   [(parallel [(set (match_dup 0)
9921                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9922               (clobber (reg:CC FLAGS_REG))])]
9923 {
9924   if (can_create_pseudo_p ())
9925     operands [2] = force_reg (SImode, operands[2]);
9926
9927   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9928 }
9929   [(set_attr "type" "rotate")
9930    (set_attr "mode" "<MODE>")])
9931
9932 ;; Implement rotation using two double-precision
9933 ;; shift instructions and a scratch register.
9934
9935 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9936  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9937        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9938                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9939   (clobber (reg:CC FLAGS_REG))
9940   (clobber (match_scratch:DWIH 3 "=&r"))]
9941  ""
9942  "#"
9943  "reload_completed"
9944  [(set (match_dup 3) (match_dup 4))
9945   (parallel
9946    [(set (match_dup 4)
9947          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9948                    (lshiftrt:DWIH (match_dup 5)
9949                                   (minus:QI (match_dup 6) (match_dup 2)))))
9950     (clobber (reg:CC FLAGS_REG))])
9951   (parallel
9952    [(set (match_dup 5)
9953          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9954                    (lshiftrt:DWIH (match_dup 3)
9955                                   (minus:QI (match_dup 6) (match_dup 2)))))
9956     (clobber (reg:CC FLAGS_REG))])]
9957 {
9958   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9959
9960   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9961 })
9962
9963 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9964  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9965        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9966                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9967   (clobber (reg:CC FLAGS_REG))
9968   (clobber (match_scratch:DWIH 3 "=&r"))]
9969  ""
9970  "#"
9971  "reload_completed"
9972  [(set (match_dup 3) (match_dup 4))
9973   (parallel
9974    [(set (match_dup 4)
9975          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9976                    (ashift:DWIH (match_dup 5)
9977                                 (minus:QI (match_dup 6) (match_dup 2)))))
9978     (clobber (reg:CC FLAGS_REG))])
9979   (parallel
9980    [(set (match_dup 5)
9981          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
9982                    (ashift:DWIH (match_dup 3)
9983                                 (minus:QI (match_dup 6) (match_dup 2)))))
9984     (clobber (reg:CC FLAGS_REG))])]
9985 {
9986   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9987
9988   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9989 })
9990
9991 (define_insn "*<rotate_insn><mode>3_1"
9992   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9993         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9994                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9995    (clobber (reg:CC FLAGS_REG))]
9996   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9997 {
9998   if (operands[2] == const1_rtx
9999       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10000     return "<rotate>{<imodesuffix>}\t%0";
10001   else
10002     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10003 }
10004   [(set_attr "type" "rotate")
10005    (set (attr "length_immediate")
10006      (if_then_else
10007        (and (match_operand 2 "const1_operand" "")
10008             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10009                 (const_int 0)))
10010        (const_string "0")
10011        (const_string "*")))
10012    (set_attr "mode" "<MODE>")])
10013
10014 (define_insn "*<rotate_insn>si3_1_zext"
10015   [(set (match_operand:DI 0 "register_operand" "=r")
10016         (zero_extend:DI
10017           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10018                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10019    (clobber (reg:CC FLAGS_REG))]
10020   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10021 {
10022     if (operands[2] == const1_rtx
10023         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10024     return "<rotate>{l}\t%k0";
10025   else
10026     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10027 }
10028   [(set_attr "type" "rotate")
10029    (set (attr "length_immediate")
10030      (if_then_else
10031        (and (match_operand 2 "const1_operand" "")
10032             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10033                 (const_int 0)))
10034        (const_string "0")
10035        (const_string "*")))
10036    (set_attr "mode" "SI")])
10037
10038 (define_insn "*<rotate_insn>qi3_1_slp"
10039   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10040         (any_rotate:QI (match_dup 0)
10041                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10042    (clobber (reg:CC FLAGS_REG))]
10043   "(optimize_function_for_size_p (cfun)
10044     || !TARGET_PARTIAL_REG_STALL
10045     || (operands[1] == const1_rtx
10046         && TARGET_SHIFT1))"
10047 {
10048   if (operands[1] == const1_rtx
10049       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10050     return "<rotate>{b}\t%0";
10051   else
10052     return "<rotate>{b}\t{%1, %0|%0, %1}";
10053 }
10054   [(set_attr "type" "rotate1")
10055    (set (attr "length_immediate")
10056      (if_then_else
10057        (and (match_operand 1 "const1_operand" "")
10058             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10059                 (const_int 0)))
10060        (const_string "0")
10061        (const_string "*")))
10062    (set_attr "mode" "QI")])
10063
10064 (define_split
10065  [(set (match_operand:HI 0 "register_operand" "")
10066        (any_rotate:HI (match_dup 0) (const_int 8)))
10067   (clobber (reg:CC FLAGS_REG))]
10068  "reload_completed
10069   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10070  [(parallel [(set (strict_low_part (match_dup 0))
10071                   (bswap:HI (match_dup 0)))
10072              (clobber (reg:CC FLAGS_REG))])])
10073 \f
10074 ;; Bit set / bit test instructions
10075
10076 (define_expand "extv"
10077   [(set (match_operand:SI 0 "register_operand" "")
10078         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10079                          (match_operand:SI 2 "const8_operand" "")
10080                          (match_operand:SI 3 "const8_operand" "")))]
10081   ""
10082 {
10083   /* Handle extractions from %ah et al.  */
10084   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10085     FAIL;
10086
10087   /* From mips.md: extract_bit_field doesn't verify that our source
10088      matches the predicate, so check it again here.  */
10089   if (! ext_register_operand (operands[1], VOIDmode))
10090     FAIL;
10091 })
10092
10093 (define_expand "extzv"
10094   [(set (match_operand:SI 0 "register_operand" "")
10095         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10096                          (match_operand:SI 2 "const8_operand" "")
10097                          (match_operand:SI 3 "const8_operand" "")))]
10098   ""
10099 {
10100   /* Handle extractions from %ah et al.  */
10101   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10102     FAIL;
10103
10104   /* From mips.md: extract_bit_field doesn't verify that our source
10105      matches the predicate, so check it again here.  */
10106   if (! ext_register_operand (operands[1], VOIDmode))
10107     FAIL;
10108 })
10109
10110 (define_expand "insv"
10111   [(set (zero_extract (match_operand 0 "register_operand" "")
10112                       (match_operand 1 "const_int_operand" "")
10113                       (match_operand 2 "const_int_operand" ""))
10114         (match_operand 3 "register_operand" ""))]
10115   ""
10116 {
10117   rtx (*gen_mov_insv_1) (rtx, rtx);
10118
10119   if (ix86_expand_pinsr (operands))
10120     DONE;
10121
10122   /* Handle insertions to %ah et al.  */
10123   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10124     FAIL;
10125
10126   /* From mips.md: insert_bit_field doesn't verify that our source
10127      matches the predicate, so check it again here.  */
10128   if (! ext_register_operand (operands[0], VOIDmode))
10129     FAIL;
10130
10131   gen_mov_insv_1 = (TARGET_64BIT
10132                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10133
10134   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10135   DONE;
10136 })
10137
10138 ;; %%% bts, btr, btc, bt.
10139 ;; In general these instructions are *slow* when applied to memory,
10140 ;; since they enforce atomic operation.  When applied to registers,
10141 ;; it depends on the cpu implementation.  They're never faster than
10142 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10143 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10144 ;; within the instruction itself, so operating on bits in the high
10145 ;; 32-bits of a register becomes easier.
10146 ;;
10147 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10148 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10149 ;; negdf respectively, so they can never be disabled entirely.
10150
10151 (define_insn "*btsq"
10152   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10153                          (const_int 1)
10154                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10155         (const_int 1))
10156    (clobber (reg:CC FLAGS_REG))]
10157   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10158   "bts{q}\t{%1, %0|%0, %1}"
10159   [(set_attr "type" "alu1")
10160    (set_attr "prefix_0f" "1")
10161    (set_attr "mode" "DI")])
10162
10163 (define_insn "*btrq"
10164   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10165                          (const_int 1)
10166                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10167         (const_int 0))
10168    (clobber (reg:CC FLAGS_REG))]
10169   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10170   "btr{q}\t{%1, %0|%0, %1}"
10171   [(set_attr "type" "alu1")
10172    (set_attr "prefix_0f" "1")
10173    (set_attr "mode" "DI")])
10174
10175 (define_insn "*btcq"
10176   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10177                          (const_int 1)
10178                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10179         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10180    (clobber (reg:CC FLAGS_REG))]
10181   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10182   "btc{q}\t{%1, %0|%0, %1}"
10183   [(set_attr "type" "alu1")
10184    (set_attr "prefix_0f" "1")
10185    (set_attr "mode" "DI")])
10186
10187 ;; Allow Nocona to avoid these instructions if a register is available.
10188
10189 (define_peephole2
10190   [(match_scratch:DI 2 "r")
10191    (parallel [(set (zero_extract:DI
10192                      (match_operand:DI 0 "register_operand" "")
10193                      (const_int 1)
10194                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10195                    (const_int 1))
10196               (clobber (reg:CC FLAGS_REG))])]
10197   "TARGET_64BIT && !TARGET_USE_BT"
10198   [(const_int 0)]
10199 {
10200   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10201   rtx op1;
10202
10203   if (HOST_BITS_PER_WIDE_INT >= 64)
10204     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10205   else if (i < HOST_BITS_PER_WIDE_INT)
10206     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10207   else
10208     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10209
10210   op1 = immed_double_const (lo, hi, DImode);
10211   if (i >= 31)
10212     {
10213       emit_move_insn (operands[2], op1);
10214       op1 = operands[2];
10215     }
10216
10217   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10218   DONE;
10219 })
10220
10221 (define_peephole2
10222   [(match_scratch:DI 2 "r")
10223    (parallel [(set (zero_extract:DI
10224                      (match_operand:DI 0 "register_operand" "")
10225                      (const_int 1)
10226                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10227                    (const_int 0))
10228               (clobber (reg:CC FLAGS_REG))])]
10229   "TARGET_64BIT && !TARGET_USE_BT"
10230   [(const_int 0)]
10231 {
10232   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10233   rtx op1;
10234
10235   if (HOST_BITS_PER_WIDE_INT >= 64)
10236     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10237   else if (i < HOST_BITS_PER_WIDE_INT)
10238     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10239   else
10240     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10241
10242   op1 = immed_double_const (~lo, ~hi, DImode);
10243   if (i >= 32)
10244     {
10245       emit_move_insn (operands[2], op1);
10246       op1 = operands[2];
10247     }
10248
10249   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10250   DONE;
10251 })
10252
10253 (define_peephole2
10254   [(match_scratch:DI 2 "r")
10255    (parallel [(set (zero_extract:DI
10256                      (match_operand:DI 0 "register_operand" "")
10257                      (const_int 1)
10258                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10259               (not:DI (zero_extract:DI
10260                         (match_dup 0) (const_int 1) (match_dup 1))))
10261               (clobber (reg:CC FLAGS_REG))])]
10262   "TARGET_64BIT && !TARGET_USE_BT"
10263   [(const_int 0)]
10264 {
10265   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10266   rtx op1;
10267
10268   if (HOST_BITS_PER_WIDE_INT >= 64)
10269     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10270   else if (i < HOST_BITS_PER_WIDE_INT)
10271     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10272   else
10273     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10274
10275   op1 = immed_double_const (lo, hi, DImode);
10276   if (i >= 31)
10277     {
10278       emit_move_insn (operands[2], op1);
10279       op1 = operands[2];
10280     }
10281
10282   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10283   DONE;
10284 })
10285
10286 (define_insn "*bt<mode>"
10287   [(set (reg:CCC FLAGS_REG)
10288         (compare:CCC
10289           (zero_extract:SWI48
10290             (match_operand:SWI48 0 "register_operand" "r")
10291             (const_int 1)
10292             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10293           (const_int 0)))]
10294   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10295   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10296   [(set_attr "type" "alu1")
10297    (set_attr "prefix_0f" "1")
10298    (set_attr "mode" "<MODE>")])
10299 \f
10300 ;; Store-flag instructions.
10301
10302 ;; For all sCOND expanders, also expand the compare or test insn that
10303 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10304
10305 (define_insn_and_split "*setcc_di_1"
10306   [(set (match_operand:DI 0 "register_operand" "=q")
10307         (match_operator:DI 1 "ix86_comparison_operator"
10308           [(reg FLAGS_REG) (const_int 0)]))]
10309   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10310   "#"
10311   "&& reload_completed"
10312   [(set (match_dup 2) (match_dup 1))
10313    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10314 {
10315   PUT_MODE (operands[1], QImode);
10316   operands[2] = gen_lowpart (QImode, operands[0]);
10317 })
10318
10319 (define_insn_and_split "*setcc_si_1_and"
10320   [(set (match_operand:SI 0 "register_operand" "=q")
10321         (match_operator:SI 1 "ix86_comparison_operator"
10322           [(reg FLAGS_REG) (const_int 0)]))
10323    (clobber (reg:CC FLAGS_REG))]
10324   "!TARGET_PARTIAL_REG_STALL
10325    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10326   "#"
10327   "&& reload_completed"
10328   [(set (match_dup 2) (match_dup 1))
10329    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10330               (clobber (reg:CC FLAGS_REG))])]
10331 {
10332   PUT_MODE (operands[1], QImode);
10333   operands[2] = gen_lowpart (QImode, operands[0]);
10334 })
10335
10336 (define_insn_and_split "*setcc_si_1_movzbl"
10337   [(set (match_operand:SI 0 "register_operand" "=q")
10338         (match_operator:SI 1 "ix86_comparison_operator"
10339           [(reg FLAGS_REG) (const_int 0)]))]
10340   "!TARGET_PARTIAL_REG_STALL
10341    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10342   "#"
10343   "&& reload_completed"
10344   [(set (match_dup 2) (match_dup 1))
10345    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10346 {
10347   PUT_MODE (operands[1], QImode);
10348   operands[2] = gen_lowpart (QImode, operands[0]);
10349 })
10350
10351 (define_insn "*setcc_qi"
10352   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10353         (match_operator:QI 1 "ix86_comparison_operator"
10354           [(reg FLAGS_REG) (const_int 0)]))]
10355   ""
10356   "set%C1\t%0"
10357   [(set_attr "type" "setcc")
10358    (set_attr "mode" "QI")])
10359
10360 (define_insn "*setcc_qi_slp"
10361   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10362         (match_operator:QI 1 "ix86_comparison_operator"
10363           [(reg FLAGS_REG) (const_int 0)]))]
10364   ""
10365   "set%C1\t%0"
10366   [(set_attr "type" "setcc")
10367    (set_attr "mode" "QI")])
10368
10369 ;; In general it is not safe to assume too much about CCmode registers,
10370 ;; so simplify-rtx stops when it sees a second one.  Under certain
10371 ;; conditions this is safe on x86, so help combine not create
10372 ;;
10373 ;;      seta    %al
10374 ;;      testb   %al, %al
10375 ;;      sete    %al
10376
10377 (define_split
10378   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10379         (ne:QI (match_operator 1 "ix86_comparison_operator"
10380                  [(reg FLAGS_REG) (const_int 0)])
10381             (const_int 0)))]
10382   ""
10383   [(set (match_dup 0) (match_dup 1))]
10384   "PUT_MODE (operands[1], QImode);")
10385
10386 (define_split
10387   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10388         (ne:QI (match_operator 1 "ix86_comparison_operator"
10389                  [(reg FLAGS_REG) (const_int 0)])
10390             (const_int 0)))]
10391   ""
10392   [(set (match_dup 0) (match_dup 1))]
10393   "PUT_MODE (operands[1], QImode);")
10394
10395 (define_split
10396   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10397         (eq:QI (match_operator 1 "ix86_comparison_operator"
10398                  [(reg FLAGS_REG) (const_int 0)])
10399             (const_int 0)))]
10400   ""
10401   [(set (match_dup 0) (match_dup 1))]
10402 {
10403   rtx new_op1 = copy_rtx (operands[1]);
10404   operands[1] = new_op1;
10405   PUT_MODE (new_op1, QImode);
10406   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10407                                              GET_MODE (XEXP (new_op1, 0))));
10408
10409   /* Make sure that (a) the CCmode we have for the flags is strong
10410      enough for the reversed compare or (b) we have a valid FP compare.  */
10411   if (! ix86_comparison_operator (new_op1, VOIDmode))
10412     FAIL;
10413 })
10414
10415 (define_split
10416   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10417         (eq:QI (match_operator 1 "ix86_comparison_operator"
10418                  [(reg FLAGS_REG) (const_int 0)])
10419             (const_int 0)))]
10420   ""
10421   [(set (match_dup 0) (match_dup 1))]
10422 {
10423   rtx new_op1 = copy_rtx (operands[1]);
10424   operands[1] = new_op1;
10425   PUT_MODE (new_op1, QImode);
10426   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10427                                              GET_MODE (XEXP (new_op1, 0))));
10428
10429   /* Make sure that (a) the CCmode we have for the flags is strong
10430      enough for the reversed compare or (b) we have a valid FP compare.  */
10431   if (! ix86_comparison_operator (new_op1, VOIDmode))
10432     FAIL;
10433 })
10434
10435 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10436 ;; subsequent logical operations are used to imitate conditional moves.
10437 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10438 ;; it directly.
10439
10440 (define_insn "setcc_<mode>_sse"
10441   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10442         (match_operator:MODEF 3 "sse_comparison_operator"
10443           [(match_operand:MODEF 1 "register_operand" "0,x")
10444            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10445   "SSE_FLOAT_MODE_P (<MODE>mode)"
10446   "@
10447    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10448    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10449   [(set_attr "isa" "noavx,avx")
10450    (set_attr "type" "ssecmp")
10451    (set_attr "length_immediate" "1")
10452    (set_attr "prefix" "orig,vex")
10453    (set_attr "mode" "<MODE>")])
10454 \f
10455 ;; Basic conditional jump instructions.
10456 ;; We ignore the overflow flag for signed branch instructions.
10457
10458 (define_insn "*jcc_1"
10459   [(set (pc)
10460         (if_then_else (match_operator 1 "ix86_comparison_operator"
10461                                       [(reg FLAGS_REG) (const_int 0)])
10462                       (label_ref (match_operand 0 "" ""))
10463                       (pc)))]
10464   ""
10465   "%+j%C1\t%l0"
10466   [(set_attr "type" "ibr")
10467    (set_attr "modrm" "0")
10468    (set (attr "length")
10469            (if_then_else (and (ge (minus (match_dup 0) (pc))
10470                                   (const_int -126))
10471                               (lt (minus (match_dup 0) (pc))
10472                                   (const_int 128)))
10473              (const_int 2)
10474              (const_int 6)))])
10475
10476 (define_insn "*jcc_2"
10477   [(set (pc)
10478         (if_then_else (match_operator 1 "ix86_comparison_operator"
10479                                       [(reg FLAGS_REG) (const_int 0)])
10480                       (pc)
10481                       (label_ref (match_operand 0 "" ""))))]
10482   ""
10483   "%+j%c1\t%l0"
10484   [(set_attr "type" "ibr")
10485    (set_attr "modrm" "0")
10486    (set (attr "length")
10487            (if_then_else (and (ge (minus (match_dup 0) (pc))
10488                                   (const_int -126))
10489                               (lt (minus (match_dup 0) (pc))
10490                                   (const_int 128)))
10491              (const_int 2)
10492              (const_int 6)))])
10493
10494 ;; In general it is not safe to assume too much about CCmode registers,
10495 ;; so simplify-rtx stops when it sees a second one.  Under certain
10496 ;; conditions this is safe on x86, so help combine not create
10497 ;;
10498 ;;      seta    %al
10499 ;;      testb   %al, %al
10500 ;;      je      Lfoo
10501
10502 (define_split
10503   [(set (pc)
10504         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10505                                       [(reg FLAGS_REG) (const_int 0)])
10506                           (const_int 0))
10507                       (label_ref (match_operand 1 "" ""))
10508                       (pc)))]
10509   ""
10510   [(set (pc)
10511         (if_then_else (match_dup 0)
10512                       (label_ref (match_dup 1))
10513                       (pc)))]
10514   "PUT_MODE (operands[0], VOIDmode);")
10515
10516 (define_split
10517   [(set (pc)
10518         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10519                                       [(reg FLAGS_REG) (const_int 0)])
10520                           (const_int 0))
10521                       (label_ref (match_operand 1 "" ""))
10522                       (pc)))]
10523   ""
10524   [(set (pc)
10525         (if_then_else (match_dup 0)
10526                       (label_ref (match_dup 1))
10527                       (pc)))]
10528 {
10529   rtx new_op0 = copy_rtx (operands[0]);
10530   operands[0] = new_op0;
10531   PUT_MODE (new_op0, VOIDmode);
10532   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10533                                              GET_MODE (XEXP (new_op0, 0))));
10534
10535   /* Make sure that (a) the CCmode we have for the flags is strong
10536      enough for the reversed compare or (b) we have a valid FP compare.  */
10537   if (! ix86_comparison_operator (new_op0, VOIDmode))
10538     FAIL;
10539 })
10540
10541 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10542 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10543 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10544 ;; appropriate modulo of the bit offset value.
10545
10546 (define_insn_and_split "*jcc_bt<mode>"
10547   [(set (pc)
10548         (if_then_else (match_operator 0 "bt_comparison_operator"
10549                         [(zero_extract:SWI48
10550                            (match_operand:SWI48 1 "register_operand" "r")
10551                            (const_int 1)
10552                            (zero_extend:SI
10553                              (match_operand:QI 2 "register_operand" "r")))
10554                          (const_int 0)])
10555                       (label_ref (match_operand 3 "" ""))
10556                       (pc)))
10557    (clobber (reg:CC FLAGS_REG))]
10558   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10559   "#"
10560   "&& 1"
10561   [(set (reg:CCC FLAGS_REG)
10562         (compare:CCC
10563           (zero_extract:SWI48
10564             (match_dup 1)
10565             (const_int 1)
10566             (match_dup 2))
10567           (const_int 0)))
10568    (set (pc)
10569         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10570                       (label_ref (match_dup 3))
10571                       (pc)))]
10572 {
10573   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10574
10575   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10576 })
10577
10578 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10579 ;; also for DImode, this is what combine produces.
10580 (define_insn_and_split "*jcc_bt<mode>_mask"
10581   [(set (pc)
10582         (if_then_else (match_operator 0 "bt_comparison_operator"
10583                         [(zero_extract:SWI48
10584                            (match_operand:SWI48 1 "register_operand" "r")
10585                            (const_int 1)
10586                            (and:SI
10587                              (match_operand:SI 2 "register_operand" "r")
10588                              (match_operand:SI 3 "const_int_operand" "n")))])
10589                       (label_ref (match_operand 4 "" ""))
10590                       (pc)))
10591    (clobber (reg:CC FLAGS_REG))]
10592   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10593    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10594       == GET_MODE_BITSIZE (<MODE>mode)-1"
10595   "#"
10596   "&& 1"
10597   [(set (reg:CCC FLAGS_REG)
10598         (compare:CCC
10599           (zero_extract:SWI48
10600             (match_dup 1)
10601             (const_int 1)
10602             (match_dup 2))
10603           (const_int 0)))
10604    (set (pc)
10605         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10606                       (label_ref (match_dup 4))
10607                       (pc)))]
10608 {
10609   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10610
10611   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10612 })
10613
10614 (define_insn_and_split "*jcc_btsi_1"
10615   [(set (pc)
10616         (if_then_else (match_operator 0 "bt_comparison_operator"
10617                         [(and:SI
10618                            (lshiftrt:SI
10619                              (match_operand:SI 1 "register_operand" "r")
10620                              (match_operand:QI 2 "register_operand" "r"))
10621                            (const_int 1))
10622                          (const_int 0)])
10623                       (label_ref (match_operand 3 "" ""))
10624                       (pc)))
10625    (clobber (reg:CC FLAGS_REG))]
10626   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10627   "#"
10628   "&& 1"
10629   [(set (reg:CCC FLAGS_REG)
10630         (compare:CCC
10631           (zero_extract:SI
10632             (match_dup 1)
10633             (const_int 1)
10634             (match_dup 2))
10635           (const_int 0)))
10636    (set (pc)
10637         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10638                       (label_ref (match_dup 3))
10639                       (pc)))]
10640 {
10641   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10642
10643   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10644 })
10645
10646 ;; avoid useless masking of bit offset operand
10647 (define_insn_and_split "*jcc_btsi_mask_1"
10648   [(set (pc)
10649         (if_then_else
10650           (match_operator 0 "bt_comparison_operator"
10651             [(and:SI
10652                (lshiftrt:SI
10653                  (match_operand:SI 1 "register_operand" "r")
10654                  (subreg:QI
10655                    (and:SI
10656                      (match_operand:SI 2 "register_operand" "r")
10657                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10658                (const_int 1))
10659              (const_int 0)])
10660           (label_ref (match_operand 4 "" ""))
10661           (pc)))
10662    (clobber (reg:CC FLAGS_REG))]
10663   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10664    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10665   "#"
10666   "&& 1"
10667   [(set (reg:CCC FLAGS_REG)
10668         (compare:CCC
10669           (zero_extract:SI
10670             (match_dup 1)
10671             (const_int 1)
10672             (match_dup 2))
10673           (const_int 0)))
10674    (set (pc)
10675         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10676                       (label_ref (match_dup 4))
10677                       (pc)))]
10678   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10679
10680 ;; Define combination compare-and-branch fp compare instructions to help
10681 ;; combine.
10682
10683 (define_insn "*fp_jcc_1_387"
10684   [(set (pc)
10685         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10686                         [(match_operand 1 "register_operand" "f")
10687                          (match_operand 2 "nonimmediate_operand" "fm")])
10688           (label_ref (match_operand 3 "" ""))
10689           (pc)))
10690    (clobber (reg:CCFP FPSR_REG))
10691    (clobber (reg:CCFP FLAGS_REG))
10692    (clobber (match_scratch:HI 4 "=a"))]
10693   "TARGET_80387
10694    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10695    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10696    && SELECT_CC_MODE (GET_CODE (operands[0]),
10697                       operands[1], operands[2]) == CCFPmode
10698    && !TARGET_CMOVE"
10699   "#")
10700
10701 (define_insn "*fp_jcc_1r_387"
10702   [(set (pc)
10703         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10704                         [(match_operand 1 "register_operand" "f")
10705                          (match_operand 2 "nonimmediate_operand" "fm")])
10706           (pc)
10707           (label_ref (match_operand 3 "" ""))))
10708    (clobber (reg:CCFP FPSR_REG))
10709    (clobber (reg:CCFP FLAGS_REG))
10710    (clobber (match_scratch:HI 4 "=a"))]
10711   "TARGET_80387
10712    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10713    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10714    && SELECT_CC_MODE (GET_CODE (operands[0]),
10715                       operands[1], operands[2]) == CCFPmode
10716    && !TARGET_CMOVE"
10717   "#")
10718
10719 (define_insn "*fp_jcc_2_387"
10720   [(set (pc)
10721         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10722                         [(match_operand 1 "register_operand" "f")
10723                          (match_operand 2 "register_operand" "f")])
10724           (label_ref (match_operand 3 "" ""))
10725           (pc)))
10726    (clobber (reg:CCFP FPSR_REG))
10727    (clobber (reg:CCFP FLAGS_REG))
10728    (clobber (match_scratch:HI 4 "=a"))]
10729   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10730    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10731    && !TARGET_CMOVE"
10732   "#")
10733
10734 (define_insn "*fp_jcc_2r_387"
10735   [(set (pc)
10736         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10737                         [(match_operand 1 "register_operand" "f")
10738                          (match_operand 2 "register_operand" "f")])
10739           (pc)
10740           (label_ref (match_operand 3 "" ""))))
10741    (clobber (reg:CCFP FPSR_REG))
10742    (clobber (reg:CCFP FLAGS_REG))
10743    (clobber (match_scratch:HI 4 "=a"))]
10744   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10745    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10746    && !TARGET_CMOVE"
10747   "#")
10748
10749 (define_insn "*fp_jcc_3_387"
10750   [(set (pc)
10751         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10752                         [(match_operand 1 "register_operand" "f")
10753                          (match_operand 2 "const0_operand" "")])
10754           (label_ref (match_operand 3 "" ""))
10755           (pc)))
10756    (clobber (reg:CCFP FPSR_REG))
10757    (clobber (reg:CCFP FLAGS_REG))
10758    (clobber (match_scratch:HI 4 "=a"))]
10759   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10760    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10761    && SELECT_CC_MODE (GET_CODE (operands[0]),
10762                       operands[1], operands[2]) == CCFPmode
10763    && !TARGET_CMOVE"
10764   "#")
10765
10766 (define_split
10767   [(set (pc)
10768         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10769                         [(match_operand 1 "register_operand" "")
10770                          (match_operand 2 "nonimmediate_operand" "")])
10771           (match_operand 3 "" "")
10772           (match_operand 4 "" "")))
10773    (clobber (reg:CCFP FPSR_REG))
10774    (clobber (reg:CCFP FLAGS_REG))]
10775   "reload_completed"
10776   [(const_int 0)]
10777 {
10778   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10779                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10780   DONE;
10781 })
10782
10783 (define_split
10784   [(set (pc)
10785         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10786                         [(match_operand 1 "register_operand" "")
10787                          (match_operand 2 "general_operand" "")])
10788           (match_operand 3 "" "")
10789           (match_operand 4 "" "")))
10790    (clobber (reg:CCFP FPSR_REG))
10791    (clobber (reg:CCFP FLAGS_REG))
10792    (clobber (match_scratch:HI 5 "=a"))]
10793   "reload_completed"
10794   [(const_int 0)]
10795 {
10796   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10797                         operands[3], operands[4], operands[5], NULL_RTX);
10798   DONE;
10799 })
10800
10801 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10802 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10803 ;; with a precedence over other operators and is always put in the first
10804 ;; place. Swap condition and operands to match ficom instruction.
10805
10806 (define_insn "*fp_jcc_4_<mode>_387"
10807   [(set (pc)
10808         (if_then_else
10809           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10810             [(match_operator 1 "float_operator"
10811               [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10812              (match_operand 3 "register_operand" "f,f")])
10813           (label_ref (match_operand 4 "" ""))
10814           (pc)))
10815    (clobber (reg:CCFP FPSR_REG))
10816    (clobber (reg:CCFP FLAGS_REG))
10817    (clobber (match_scratch:HI 5 "=a,a"))]
10818   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10819    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10820    && GET_MODE (operands[1]) == GET_MODE (operands[3])
10821    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10822    && !TARGET_CMOVE"
10823   "#")
10824
10825 (define_split
10826   [(set (pc)
10827         (if_then_else
10828           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10829             [(match_operator 1 "float_operator"
10830               [(match_operand:SWI24 2 "memory_operand" "")])
10831              (match_operand 3 "register_operand" "")])
10832           (match_operand 4 "" "")
10833           (match_operand 5 "" "")))
10834    (clobber (reg:CCFP FPSR_REG))
10835    (clobber (reg:CCFP FLAGS_REG))
10836    (clobber (match_scratch:HI 6 "=a"))]
10837   "reload_completed"
10838   [(const_int 0)]
10839 {
10840   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10841
10842   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10843                         operands[3], operands[7],
10844                         operands[4], operands[5], operands[6], NULL_RTX);
10845   DONE;
10846 })
10847
10848 ;; %%% Kill this when reload knows how to do it.
10849 (define_split
10850   [(set (pc)
10851         (if_then_else
10852           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10853             [(match_operator 1 "float_operator"
10854               [(match_operand:SWI24 2 "register_operand" "")])
10855              (match_operand 3 "register_operand" "")])
10856           (match_operand 4 "" "")
10857           (match_operand 5 "" "")))
10858    (clobber (reg:CCFP FPSR_REG))
10859    (clobber (reg:CCFP FLAGS_REG))
10860    (clobber (match_scratch:HI 6 "=a"))]
10861   "reload_completed"
10862   [(const_int 0)]
10863 {
10864   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10865   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10866
10867   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10868                         operands[3], operands[7],
10869                         operands[4], operands[5], operands[6], operands[2]);
10870   DONE;
10871 })
10872 \f
10873 ;; Unconditional and other jump instructions
10874
10875 (define_insn "jump"
10876   [(set (pc)
10877         (label_ref (match_operand 0 "" "")))]
10878   ""
10879   "jmp\t%l0"
10880   [(set_attr "type" "ibr")
10881    (set (attr "length")
10882            (if_then_else (and (ge (minus (match_dup 0) (pc))
10883                                   (const_int -126))
10884                               (lt (minus (match_dup 0) (pc))
10885                                   (const_int 128)))
10886              (const_int 2)
10887              (const_int 5)))
10888    (set_attr "modrm" "0")])
10889
10890 (define_expand "indirect_jump"
10891   [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
10892
10893 (define_insn "*indirect_jump"
10894   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
10895   ""
10896   "jmp\t%A0"
10897   [(set_attr "type" "ibr")
10898    (set_attr "length_immediate" "0")])
10899
10900 (define_expand "tablejump"
10901   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
10902               (use (label_ref (match_operand 1 "" "")))])]
10903   ""
10904 {
10905   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10906      relative.  Convert the relative address to an absolute address.  */
10907   if (flag_pic)
10908     {
10909       rtx op0, op1;
10910       enum rtx_code code;
10911
10912       /* We can't use @GOTOFF for text labels on VxWorks;
10913          see gotoff_operand.  */
10914       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10915         {
10916           code = PLUS;
10917           op0 = operands[0];
10918           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10919         }
10920       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10921         {
10922           code = PLUS;
10923           op0 = operands[0];
10924           op1 = pic_offset_table_rtx;
10925         }
10926       else
10927         {
10928           code = MINUS;
10929           op0 = pic_offset_table_rtx;
10930           op1 = operands[0];
10931         }
10932
10933       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10934                                          OPTAB_DIRECT);
10935     }
10936   else if (TARGET_X32)
10937     operands[0] = convert_memory_address (Pmode, operands[0]);
10938 })
10939
10940 (define_insn "*tablejump_1"
10941   [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
10942    (use (label_ref (match_operand 1 "" "")))]
10943   ""
10944   "jmp\t%A0"
10945   [(set_attr "type" "ibr")
10946    (set_attr "length_immediate" "0")])
10947 \f
10948 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10949
10950 (define_peephole2
10951   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
10952    (set (match_operand:QI 1 "register_operand" "")
10953         (match_operator:QI 2 "ix86_comparison_operator"
10954           [(reg FLAGS_REG) (const_int 0)]))
10955    (set (match_operand 3 "q_regs_operand" "")
10956         (zero_extend (match_dup 1)))]
10957   "(peep2_reg_dead_p (3, operands[1])
10958     || operands_match_p (operands[1], operands[3]))
10959    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10960   [(set (match_dup 4) (match_dup 0))
10961    (set (strict_low_part (match_dup 5))
10962         (match_dup 2))]
10963 {
10964   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10965   operands[5] = gen_lowpart (QImode, operands[3]);
10966   ix86_expand_clear (operands[3]);
10967 })
10968
10969 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
10970
10971 (define_peephole2
10972   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
10973    (set (match_operand:QI 1 "register_operand" "")
10974         (match_operator:QI 2 "ix86_comparison_operator"
10975           [(reg FLAGS_REG) (const_int 0)]))
10976    (parallel [(set (match_operand 3 "q_regs_operand" "")
10977                    (zero_extend (match_dup 1)))
10978               (clobber (reg:CC FLAGS_REG))])]
10979   "(peep2_reg_dead_p (3, operands[1])
10980     || operands_match_p (operands[1], operands[3]))
10981    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10982   [(set (match_dup 4) (match_dup 0))
10983    (set (strict_low_part (match_dup 5))
10984         (match_dup 2))]
10985 {
10986   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10987   operands[5] = gen_lowpart (QImode, operands[3]);
10988   ix86_expand_clear (operands[3]);
10989 })
10990 \f
10991 ;; Call instructions.
10992
10993 ;; The predicates normally associated with named expanders are not properly
10994 ;; checked for calls.  This is a bug in the generic code, but it isn't that
10995 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
10996
10997 ;; P6 processors will jump to the address after the decrement when %esp
10998 ;; is used as a call operand, so they will execute return address as a code.
10999 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11000
11001 ;; Register constraint for call instruction.
11002 (define_mode_attr c [(SI "l") (DI "r")])
11003
11004 ;; Call subroutine returning no value.
11005
11006 (define_expand "call"
11007   [(call (match_operand:QI 0 "" "")
11008          (match_operand 1 "" ""))
11009    (use (match_operand 2 "" ""))]
11010   ""
11011 {
11012   ix86_expand_call (NULL, operands[0], operands[1],
11013                     operands[2], NULL, false);
11014   DONE;
11015 })
11016
11017 (define_expand "sibcall"
11018   [(call (match_operand:QI 0 "" "")
11019          (match_operand 1 "" ""))
11020    (use (match_operand 2 "" ""))]
11021   ""
11022 {
11023   ix86_expand_call (NULL, operands[0], operands[1],
11024                     operands[2], NULL, true);
11025   DONE;
11026 })
11027
11028 (define_insn_and_split "*call_vzeroupper"
11029   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11030          (match_operand 1 "" ""))
11031    (unspec [(match_operand 2 "const_int_operand" "")]
11032            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11033   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11034   "#"
11035   "&& reload_completed"
11036   [(const_int 0)]
11037   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11038   [(set_attr "type" "call")])
11039
11040 (define_insn "*call"
11041   [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11042          (match_operand 1 "" ""))]
11043   "!SIBLING_CALL_P (insn)"
11044   "* return ix86_output_call_insn (insn, operands[0]);"
11045   [(set_attr "type" "call")])
11046
11047 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11048   [(parallel
11049     [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11050            (match_operand 1 "" ""))
11051      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11052      (clobber (reg:TI XMM6_REG))
11053      (clobber (reg:TI XMM7_REG))
11054      (clobber (reg:TI XMM8_REG))
11055      (clobber (reg:TI XMM9_REG))
11056      (clobber (reg:TI XMM10_REG))
11057      (clobber (reg:TI XMM11_REG))
11058      (clobber (reg:TI XMM12_REG))
11059      (clobber (reg:TI XMM13_REG))
11060      (clobber (reg:TI XMM14_REG))
11061      (clobber (reg:TI XMM15_REG))
11062      (clobber (reg:DI SI_REG))
11063      (clobber (reg:DI DI_REG))])
11064    (unspec [(match_operand 2 "const_int_operand" "")]
11065            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11066   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11067   "#"
11068   "&& reload_completed"
11069   [(const_int 0)]
11070   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11071   [(set_attr "type" "call")])
11072
11073 (define_insn "*call_rex64_ms_sysv"
11074   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11075          (match_operand 1 "" ""))
11076    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11077    (clobber (reg:TI XMM6_REG))
11078    (clobber (reg:TI XMM7_REG))
11079    (clobber (reg:TI XMM8_REG))
11080    (clobber (reg:TI XMM9_REG))
11081    (clobber (reg:TI XMM10_REG))
11082    (clobber (reg:TI XMM11_REG))
11083    (clobber (reg:TI XMM12_REG))
11084    (clobber (reg:TI XMM13_REG))
11085    (clobber (reg:TI XMM14_REG))
11086    (clobber (reg:TI XMM15_REG))
11087    (clobber (reg:DI SI_REG))
11088    (clobber (reg:DI DI_REG))]
11089   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11090   "* return ix86_output_call_insn (insn, operands[0]);"
11091   [(set_attr "type" "call")])
11092
11093 (define_insn_and_split "*sibcall_vzeroupper"
11094   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11095          (match_operand 1 "" ""))
11096    (unspec [(match_operand 2 "const_int_operand" "")]
11097            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11098   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11099   "#"
11100   "&& reload_completed"
11101   [(const_int 0)]
11102   "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11103   [(set_attr "type" "call")])
11104
11105 (define_insn "*sibcall"
11106   [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11107          (match_operand 1 "" ""))]
11108   "SIBLING_CALL_P (insn)"
11109   "* return ix86_output_call_insn (insn, operands[0]);"
11110   [(set_attr "type" "call")])
11111
11112 (define_expand "call_pop"
11113   [(parallel [(call (match_operand:QI 0 "" "")
11114                     (match_operand:SI 1 "" ""))
11115               (set (reg:SI SP_REG)
11116                    (plus:SI (reg:SI SP_REG)
11117                             (match_operand:SI 3 "" "")))])]
11118   "!TARGET_64BIT"
11119 {
11120   ix86_expand_call (NULL, operands[0], operands[1],
11121                     operands[2], operands[3], false);
11122   DONE;
11123 })
11124
11125 (define_insn_and_split "*call_pop_vzeroupper"
11126   [(parallel
11127     [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11128            (match_operand:SI 1 "" ""))
11129      (set (reg:SI SP_REG)
11130           (plus:SI (reg:SI SP_REG)
11131                    (match_operand:SI 2 "immediate_operand" "i")))])
11132    (unspec [(match_operand 3 "const_int_operand" "")]
11133            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11134   "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11135   "#"
11136   "&& reload_completed"
11137   [(const_int 0)]
11138   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11139   [(set_attr "type" "call")])
11140
11141 (define_insn "*call_pop"
11142   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11143          (match_operand 1 "" ""))
11144    (set (reg:SI SP_REG)
11145         (plus:SI (reg:SI SP_REG)
11146                  (match_operand:SI 2 "immediate_operand" "i")))]
11147   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11148   "* return ix86_output_call_insn (insn, operands[0]);"
11149   [(set_attr "type" "call")])
11150
11151 (define_insn_and_split "*sibcall_pop_vzeroupper"
11152  [(parallel
11153    [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11154           (match_operand 1 "" ""))
11155      (set (reg:SI SP_REG)
11156           (plus:SI (reg:SI SP_REG)
11157                    (match_operand:SI 2 "immediate_operand" "i")))])
11158    (unspec [(match_operand 3 "const_int_operand" "")]
11159            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11160   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11161   "#"
11162   "&& reload_completed"
11163   [(const_int 0)]
11164   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11165   [(set_attr "type" "call")])
11166
11167 (define_insn "*sibcall_pop"
11168   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11169          (match_operand 1 "" ""))
11170    (set (reg:SI SP_REG)
11171         (plus:SI (reg:SI SP_REG)
11172                  (match_operand:SI 2 "immediate_operand" "i")))]
11173   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11174   "* return ix86_output_call_insn (insn, operands[0]);"
11175   [(set_attr "type" "call")])
11176
11177 ;; Call subroutine, returning value in operand 0
11178
11179 (define_expand "call_value"
11180   [(set (match_operand 0 "" "")
11181         (call (match_operand:QI 1 "" "")
11182               (match_operand 2 "" "")))
11183    (use (match_operand 3 "" ""))]
11184   ""
11185 {
11186   ix86_expand_call (operands[0], operands[1], operands[2],
11187                     operands[3], NULL, false);
11188   DONE;
11189 })
11190
11191 (define_expand "sibcall_value"
11192   [(set (match_operand 0 "" "")
11193         (call (match_operand:QI 1 "" "")
11194               (match_operand 2 "" "")))
11195    (use (match_operand 3 "" ""))]
11196   ""
11197 {
11198   ix86_expand_call (operands[0], operands[1], operands[2],
11199                     operands[3], NULL, true);
11200   DONE;
11201 })
11202
11203 (define_insn_and_split "*call_value_vzeroupper"
11204   [(set (match_operand 0 "" "")
11205         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11206               (match_operand 2 "" "")))
11207    (unspec [(match_operand 3 "const_int_operand" "")]
11208            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11209   "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11210   "#"
11211   "&& reload_completed"
11212   [(const_int 0)]
11213   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11214   [(set_attr "type" "callv")])
11215
11216 (define_insn "*call_value"
11217   [(set (match_operand 0 "" "")
11218         (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11219               (match_operand 2 "" "")))]
11220   "!SIBLING_CALL_P (insn)"
11221   "* return ix86_output_call_insn (insn, operands[1]);"
11222   [(set_attr "type" "callv")])
11223
11224 (define_insn_and_split "*sibcall_value_vzeroupper"
11225   [(set (match_operand 0 "" "")
11226         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11227               (match_operand 2 "" "")))
11228    (unspec [(match_operand 3 "const_int_operand" "")]
11229            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11230   "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11231   "#"
11232   "&& reload_completed"
11233   [(const_int 0)]
11234   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11235   [(set_attr "type" "callv")])
11236
11237 (define_insn "*sibcall_value"
11238   [(set (match_operand 0 "" "")
11239         (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11240               (match_operand 2 "" "")))]
11241   "SIBLING_CALL_P (insn)"
11242   "* return ix86_output_call_insn (insn, operands[1]);"
11243   [(set_attr "type" "callv")])
11244
11245 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11246   [(parallel
11247     [(set (match_operand 0 "" "")
11248           (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11249                 (match_operand 2 "" "")))
11250      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11251      (clobber (reg:TI XMM6_REG))
11252      (clobber (reg:TI XMM7_REG))
11253      (clobber (reg:TI XMM8_REG))
11254      (clobber (reg:TI XMM9_REG))
11255      (clobber (reg:TI XMM10_REG))
11256      (clobber (reg:TI XMM11_REG))
11257      (clobber (reg:TI XMM12_REG))
11258      (clobber (reg:TI XMM13_REG))
11259      (clobber (reg:TI XMM14_REG))
11260      (clobber (reg:TI XMM15_REG))
11261      (clobber (reg:DI SI_REG))
11262      (clobber (reg:DI DI_REG))])
11263    (unspec [(match_operand 3 "const_int_operand" "")]
11264            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11265   "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11266   "#"
11267   "&& reload_completed"
11268   [(const_int 0)]
11269   "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11270   [(set_attr "type" "callv")])
11271
11272 (define_insn "*call_value_rex64_ms_sysv"
11273   [(set (match_operand 0 "" "")
11274         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11275               (match_operand 2 "" "")))
11276    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11277    (clobber (reg:TI XMM6_REG))
11278    (clobber (reg:TI XMM7_REG))
11279    (clobber (reg:TI XMM8_REG))
11280    (clobber (reg:TI XMM9_REG))
11281    (clobber (reg:TI XMM10_REG))
11282    (clobber (reg:TI XMM11_REG))
11283    (clobber (reg:TI XMM12_REG))
11284    (clobber (reg:TI XMM13_REG))
11285    (clobber (reg:TI XMM14_REG))
11286    (clobber (reg:TI XMM15_REG))
11287    (clobber (reg:DI SI_REG))
11288    (clobber (reg:DI DI_REG))]
11289   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11290   "* return ix86_output_call_insn (insn, operands[1]);"
11291   [(set_attr "type" "callv")])
11292
11293 (define_expand "call_value_pop"
11294   [(parallel [(set (match_operand 0 "" "")
11295                    (call (match_operand:QI 1 "" "")
11296                          (match_operand:SI 2 "" "")))
11297               (set (reg:SI SP_REG)
11298                    (plus:SI (reg:SI SP_REG)
11299                             (match_operand:SI 4 "" "")))])]
11300   "!TARGET_64BIT"
11301 {
11302   ix86_expand_call (operands[0], operands[1], operands[2],
11303                     operands[3], operands[4], false);
11304   DONE;
11305 })
11306
11307 (define_insn_and_split "*call_value_pop_vzeroupper"
11308   [(parallel
11309     [(set (match_operand 0 "" "")
11310           (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11311                 (match_operand 2 "" "")))
11312      (set (reg:SI SP_REG)
11313           (plus:SI (reg:SI SP_REG)
11314                    (match_operand:SI 3 "immediate_operand" "i")))])
11315    (unspec [(match_operand 4 "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[4]); DONE;"
11322   [(set_attr "type" "callv")])
11323
11324 (define_insn "*call_value_pop"
11325   [(set (match_operand 0 "" "")
11326         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11327               (match_operand 2 "" "")))
11328    (set (reg:SI SP_REG)
11329         (plus:SI (reg:SI SP_REG)
11330                  (match_operand:SI 3 "immediate_operand" "i")))]
11331   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11332   "* return ix86_output_call_insn (insn, operands[1]);"
11333   [(set_attr "type" "callv")])
11334
11335 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11336  [(parallel
11337    [(set (match_operand 0 "" "")
11338           (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11339                 (match_operand 2 "" "")))
11340      (set (reg:SI SP_REG)
11341           (plus:SI (reg:SI SP_REG)
11342                    (match_operand:SI 3 "immediate_operand" "i")))])
11343    (unspec [(match_operand 4 "const_int_operand" "")]
11344            UNSPEC_CALL_NEEDS_VZEROUPPER)]
11345   "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11346   "#"
11347   "&& reload_completed"
11348   [(const_int 0)]
11349   "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11350   [(set_attr "type" "callv")])
11351
11352 (define_insn "*sibcall_value_pop"
11353   [(set (match_operand 0 "" "")
11354         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11355               (match_operand 2 "" "")))
11356    (set (reg:SI SP_REG)
11357         (plus:SI (reg:SI SP_REG)
11358                  (match_operand:SI 3 "immediate_operand" "i")))]
11359   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11360   "* return ix86_output_call_insn (insn, operands[1]);"
11361   [(set_attr "type" "callv")])
11362
11363 ;; Call subroutine returning any type.
11364
11365 (define_expand "untyped_call"
11366   [(parallel [(call (match_operand 0 "" "")
11367                     (const_int 0))
11368               (match_operand 1 "" "")
11369               (match_operand 2 "" "")])]
11370   ""
11371 {
11372   int i;
11373
11374   /* In order to give reg-stack an easier job in validating two
11375      coprocessor registers as containing a possible return value,
11376      simply pretend the untyped call returns a complex long double
11377      value. 
11378
11379      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11380      and should have the default ABI.  */
11381
11382   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11383                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11384                     operands[0], const0_rtx,
11385                     GEN_INT ((TARGET_64BIT
11386                               ? (ix86_abi == SYSV_ABI
11387                                  ? X86_64_SSE_REGPARM_MAX
11388                                  : X86_64_MS_SSE_REGPARM_MAX)
11389                               : X86_32_SSE_REGPARM_MAX)
11390                              - 1),
11391                     NULL, false);
11392
11393   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11394     {
11395       rtx set = XVECEXP (operands[2], 0, i);
11396       emit_move_insn (SET_DEST (set), SET_SRC (set));
11397     }
11398
11399   /* The optimizer does not know that the call sets the function value
11400      registers we stored in the result block.  We avoid problems by
11401      claiming that all hard registers are used and clobbered at this
11402      point.  */
11403   emit_insn (gen_blockage ());
11404
11405   DONE;
11406 })
11407 \f
11408 ;; Prologue and epilogue instructions
11409
11410 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11411 ;; all of memory.  This blocks insns from being moved across this point.
11412
11413 (define_insn "blockage"
11414   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11415   ""
11416   ""
11417   [(set_attr "length" "0")])
11418
11419 ;; Do not schedule instructions accessing memory across this point.
11420
11421 (define_expand "memory_blockage"
11422   [(set (match_dup 0)
11423         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11424   ""
11425 {
11426   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11427   MEM_VOLATILE_P (operands[0]) = 1;
11428 })
11429
11430 (define_insn "*memory_blockage"
11431   [(set (match_operand:BLK 0 "" "")
11432         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11433   ""
11434   ""
11435   [(set_attr "length" "0")])
11436
11437 ;; As USE insns aren't meaningful after reload, this is used instead
11438 ;; to prevent deleting instructions setting registers for PIC code
11439 (define_insn "prologue_use"
11440   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11441   ""
11442   ""
11443   [(set_attr "length" "0")])
11444
11445 ;; Insn emitted into the body of a function to return from a function.
11446 ;; This is only done if the function's epilogue is known to be simple.
11447 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11448
11449 (define_expand "return"
11450   [(return)]
11451   "ix86_can_use_return_insn_p ()"
11452 {
11453   if (crtl->args.pops_args)
11454     {
11455       rtx popc = GEN_INT (crtl->args.pops_args);
11456       emit_jump_insn (gen_return_pop_internal (popc));
11457       DONE;
11458     }
11459 })
11460
11461 (define_insn "return_internal"
11462   [(return)]
11463   "reload_completed"
11464   "ret"
11465   [(set_attr "length" "1")
11466    (set_attr "atom_unit" "jeu")
11467    (set_attr "length_immediate" "0")
11468    (set_attr "modrm" "0")])
11469
11470 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11471 ;; instruction Athlon and K8 have.
11472
11473 (define_insn "return_internal_long"
11474   [(return)
11475    (unspec [(const_int 0)] UNSPEC_REP)]
11476   "reload_completed"
11477   "rep\;ret"
11478   [(set_attr "length" "2")
11479    (set_attr "atom_unit" "jeu")
11480    (set_attr "length_immediate" "0")
11481    (set_attr "prefix_rep" "1")
11482    (set_attr "modrm" "0")])
11483
11484 (define_insn "return_pop_internal"
11485   [(return)
11486    (use (match_operand:SI 0 "const_int_operand" ""))]
11487   "reload_completed"
11488   "ret\t%0"
11489   [(set_attr "length" "3")
11490    (set_attr "atom_unit" "jeu")
11491    (set_attr "length_immediate" "2")
11492    (set_attr "modrm" "0")])
11493
11494 (define_insn "return_indirect_internal"
11495   [(return)
11496    (use (match_operand:SI 0 "register_operand" "r"))]
11497   "reload_completed"
11498   "jmp\t%A0"
11499   [(set_attr "type" "ibr")
11500    (set_attr "length_immediate" "0")])
11501
11502 (define_insn "nop"
11503   [(const_int 0)]
11504   ""
11505   "nop"
11506   [(set_attr "length" "1")
11507    (set_attr "length_immediate" "0")
11508    (set_attr "modrm" "0")])
11509
11510 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11511 (define_insn "nops"
11512   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11513                     UNSPECV_NOPS)]
11514   "reload_completed"
11515 {
11516   int num = INTVAL (operands[0]);
11517
11518   gcc_assert (num >= 1 && num <= 8);
11519
11520   while (num--)
11521     fputs ("\tnop\n", asm_out_file);
11522
11523   return "";
11524 }
11525   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11526    (set_attr "length_immediate" "0")
11527    (set_attr "modrm" "0")])
11528
11529 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11530 ;; branch prediction penalty for the third jump in a 16-byte
11531 ;; block on K8.
11532
11533 (define_insn "pad"
11534   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11535   ""
11536 {
11537 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11538   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11539 #else
11540   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11541      The align insn is used to avoid 3 jump instructions in the row to improve
11542      branch prediction and the benefits hardly outweigh the cost of extra 8
11543      nops on the average inserted by full alignment pseudo operation.  */
11544 #endif
11545   return "";
11546 }
11547   [(set_attr "length" "16")])
11548
11549 (define_expand "prologue"
11550   [(const_int 0)]
11551   ""
11552   "ix86_expand_prologue (); DONE;")
11553
11554 (define_insn "set_got"
11555   [(set (match_operand:SI 0 "register_operand" "=r")
11556         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11557    (clobber (reg:CC FLAGS_REG))]
11558   "!TARGET_64BIT"
11559   "* return output_set_got (operands[0], NULL_RTX);"
11560   [(set_attr "type" "multi")
11561    (set_attr "length" "12")])
11562
11563 (define_insn "set_got_labelled"
11564   [(set (match_operand:SI 0 "register_operand" "=r")
11565         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11566          UNSPEC_SET_GOT))
11567    (clobber (reg:CC FLAGS_REG))]
11568   "!TARGET_64BIT"
11569   "* return output_set_got (operands[0], operands[1]);"
11570   [(set_attr "type" "multi")
11571    (set_attr "length" "12")])
11572
11573 (define_insn "set_got_rex64"
11574   [(set (match_operand:DI 0 "register_operand" "=r")
11575         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11576   "TARGET_64BIT"
11577   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11578   [(set_attr "type" "lea")
11579    (set_attr "length_address" "4")
11580    (set_attr "mode" "DI")])
11581
11582 (define_insn "set_rip_rex64"
11583   [(set (match_operand:DI 0 "register_operand" "=r")
11584         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11585   "TARGET_64BIT"
11586   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11587   [(set_attr "type" "lea")
11588    (set_attr "length_address" "4")
11589    (set_attr "mode" "DI")])
11590
11591 (define_insn "set_got_offset_rex64"
11592   [(set (match_operand:DI 0 "register_operand" "=r")
11593         (unspec:DI
11594           [(label_ref (match_operand 1 "" ""))]
11595           UNSPEC_SET_GOT_OFFSET))]
11596   "TARGET_LP64"
11597   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11598   [(set_attr "type" "imov")
11599    (set_attr "length_immediate" "0")
11600    (set_attr "length_address" "8")
11601    (set_attr "mode" "DI")])
11602
11603 (define_expand "epilogue"
11604   [(const_int 0)]
11605   ""
11606   "ix86_expand_epilogue (1); DONE;")
11607
11608 (define_expand "sibcall_epilogue"
11609   [(const_int 0)]
11610   ""
11611   "ix86_expand_epilogue (0); DONE;")
11612
11613 (define_expand "eh_return"
11614   [(use (match_operand 0 "register_operand" ""))]
11615   ""
11616 {
11617   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11618
11619   /* Tricky bit: we write the address of the handler to which we will
11620      be returning into someone else's stack frame, one word below the
11621      stack address we wish to restore.  */
11622   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11623   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11624   tmp = gen_rtx_MEM (Pmode, tmp);
11625   emit_move_insn (tmp, ra);
11626
11627   emit_jump_insn (gen_eh_return_internal ());
11628   emit_barrier ();
11629   DONE;
11630 })
11631
11632 (define_insn_and_split "eh_return_internal"
11633   [(eh_return)]
11634   ""
11635   "#"
11636   "epilogue_completed"
11637   [(const_int 0)]
11638   "ix86_expand_epilogue (2); DONE;")
11639
11640 (define_insn "leave"
11641   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11642    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11643    (clobber (mem:BLK (scratch)))]
11644   "!TARGET_64BIT"
11645   "leave"
11646   [(set_attr "type" "leave")])
11647
11648 (define_insn "leave_rex64"
11649   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11650    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11651    (clobber (mem:BLK (scratch)))]
11652   "TARGET_64BIT"
11653   "leave"
11654   [(set_attr "type" "leave")])
11655 \f
11656 ;; Handle -fsplit-stack.
11657
11658 (define_expand "split_stack_prologue"
11659   [(const_int 0)]
11660   ""
11661 {
11662   ix86_expand_split_stack_prologue ();
11663   DONE;
11664 })
11665
11666 ;; In order to support the call/return predictor, we use a return
11667 ;; instruction which the middle-end doesn't see.
11668 (define_insn "split_stack_return"
11669   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11670                      UNSPECV_SPLIT_STACK_RETURN)]
11671   ""
11672 {
11673   if (operands[0] == const0_rtx)
11674     return "ret";
11675   else
11676     return "ret\t%0";
11677 }
11678   [(set_attr "atom_unit" "jeu")
11679    (set_attr "modrm" "0")
11680    (set (attr "length")
11681         (if_then_else (match_operand:SI 0 "const0_operand" "")
11682                       (const_int 1)
11683                       (const_int 3)))
11684    (set (attr "length_immediate")
11685         (if_then_else (match_operand:SI 0 "const0_operand" "")
11686                       (const_int 0)
11687                       (const_int 2)))])
11688
11689 ;; If there are operand 0 bytes available on the stack, jump to
11690 ;; operand 1.
11691
11692 (define_expand "split_stack_space_check"
11693   [(set (pc) (if_then_else
11694               (ltu (minus (reg SP_REG)
11695                           (match_operand 0 "register_operand" ""))
11696                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11697               (label_ref (match_operand 1 "" ""))
11698               (pc)))]
11699   ""
11700 {
11701   rtx reg, size, limit;
11702
11703   reg = gen_reg_rtx (Pmode);
11704   size = force_reg (Pmode, operands[0]);
11705   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11706   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11707                           UNSPEC_STACK_CHECK);
11708   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11709   ix86_expand_branch (GEU, reg, limit, operands[1]);
11710
11711   DONE;
11712 })
11713 \f
11714 ;; Bit manipulation instructions.
11715
11716 (define_expand "ffs<mode>2"
11717   [(set (match_dup 2) (const_int -1))
11718    (parallel [(set (reg:CCZ FLAGS_REG)
11719                    (compare:CCZ
11720                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11721                      (const_int 0)))
11722               (set (match_operand:SWI48 0 "register_operand" "")
11723                    (ctz:SWI48 (match_dup 1)))])
11724    (set (match_dup 0) (if_then_else:SWI48
11725                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11726                         (match_dup 2)
11727                         (match_dup 0)))
11728    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11729               (clobber (reg:CC FLAGS_REG))])]
11730   ""
11731 {
11732   if (<MODE>mode == SImode && !TARGET_CMOVE)
11733     {
11734       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11735       DONE;
11736     }
11737   operands[2] = gen_reg_rtx (<MODE>mode);
11738 })
11739
11740 (define_insn_and_split "ffssi2_no_cmove"
11741   [(set (match_operand:SI 0 "register_operand" "=r")
11742         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11743    (clobber (match_scratch:SI 2 "=&q"))
11744    (clobber (reg:CC FLAGS_REG))]
11745   "!TARGET_CMOVE"
11746   "#"
11747   "&& reload_completed"
11748   [(parallel [(set (reg:CCZ FLAGS_REG)
11749                    (compare:CCZ (match_dup 1) (const_int 0)))
11750               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11751    (set (strict_low_part (match_dup 3))
11752         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11753    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11754               (clobber (reg:CC FLAGS_REG))])
11755    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11756               (clobber (reg:CC FLAGS_REG))])
11757    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11758               (clobber (reg:CC FLAGS_REG))])]
11759 {
11760   operands[3] = gen_lowpart (QImode, operands[2]);
11761   ix86_expand_clear (operands[2]);
11762 })
11763
11764 (define_insn "*ffs<mode>_1"
11765   [(set (reg:CCZ FLAGS_REG)
11766         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11767                      (const_int 0)))
11768    (set (match_operand:SWI48 0 "register_operand" "=r")
11769         (ctz:SWI48 (match_dup 1)))]
11770   ""
11771   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11772   [(set_attr "type" "alu1")
11773    (set_attr "prefix_0f" "1")
11774    (set_attr "mode" "<MODE>")])
11775
11776 (define_insn "ctz<mode>2"
11777   [(set (match_operand:SWI248 0 "register_operand" "=r")
11778         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11779    (clobber (reg:CC FLAGS_REG))]
11780   ""
11781 {
11782   if (TARGET_BMI)
11783     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11784   else
11785     return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11786 }
11787   [(set_attr "type" "alu1")
11788    (set_attr "prefix_0f" "1")
11789    (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11790    (set_attr "mode" "<MODE>")])
11791
11792 (define_expand "clz<mode>2"
11793   [(parallel
11794      [(set (match_operand:SWI248 0 "register_operand" "")
11795            (minus:SWI248
11796              (match_dup 2)
11797              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11798       (clobber (reg:CC FLAGS_REG))])
11799    (parallel
11800      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11801       (clobber (reg:CC FLAGS_REG))])]
11802   ""
11803 {
11804   if (TARGET_LZCNT)
11805     {
11806       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
11807       DONE;
11808     }
11809   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11810 })
11811
11812 (define_insn "clz<mode>2_lzcnt"
11813   [(set (match_operand:SWI248 0 "register_operand" "=r")
11814         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11815    (clobber (reg:CC FLAGS_REG))]
11816   "TARGET_LZCNT"
11817   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11818   [(set_attr "prefix_rep" "1")
11819    (set_attr "type" "bitmanip")
11820    (set_attr "mode" "<MODE>")])
11821
11822 ;; BMI instructions.
11823 (define_insn "*bmi_andn_<mode>"
11824   [(set (match_operand:SWI48 0 "register_operand" "=r")
11825         (and:SWI48
11826           (not:SWI48
11827             (match_operand:SWI48 1 "register_operand" "r"))
11828             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
11829    (clobber (reg:CC FLAGS_REG))]
11830   "TARGET_BMI"
11831   "andn\t{%2, %1, %0|%0, %1, %2}"
11832   [(set_attr "type" "bitmanip")
11833    (set_attr "mode" "<MODE>")])
11834
11835 (define_insn "bmi_bextr_<mode>"
11836   [(set (match_operand:SWI48 0 "register_operand" "=r")
11837         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
11838                        (match_operand:SWI48 2 "register_operand" "r")]
11839                        UNSPEC_BEXTR))
11840    (clobber (reg:CC FLAGS_REG))]
11841   "TARGET_BMI"
11842   "bextr\t{%2, %1, %0|%0, %1, %2}"
11843   [(set_attr "type" "bitmanip")
11844    (set_attr "mode" "<MODE>")])
11845
11846 (define_insn "*bmi_blsi_<mode>"
11847   [(set (match_operand:SWI48 0 "register_operand" "=r")
11848         (and:SWI48
11849           (neg:SWI48
11850             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11851           (match_dup 1)))
11852    (clobber (reg:CC FLAGS_REG))]
11853   "TARGET_BMI"
11854   "blsi\t{%1, %0|%0, %1}"
11855   [(set_attr "type" "bitmanip")
11856    (set_attr "mode" "<MODE>")])
11857
11858 (define_insn "*bmi_blsmsk_<mode>"
11859   [(set (match_operand:SWI48 0 "register_operand" "=r")
11860         (xor:SWI48
11861           (plus:SWI48
11862             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11863             (const_int -1))
11864           (match_dup 1)))
11865    (clobber (reg:CC FLAGS_REG))]
11866   "TARGET_BMI"
11867   "blsmsk\t{%1, %0|%0, %1}"
11868   [(set_attr "type" "bitmanip")
11869    (set_attr "mode" "<MODE>")])
11870
11871 (define_insn "*bmi_blsr_<mode>"
11872   [(set (match_operand:SWI48 0 "register_operand" "=r")
11873         (and:SWI48
11874           (plus:SWI48
11875             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11876             (const_int -1))
11877           (match_dup 1)))
11878    (clobber (reg:CC FLAGS_REG))]
11879    "TARGET_BMI"
11880    "blsr\t{%1, %0|%0, %1}"
11881   [(set_attr "type" "bitmanip")
11882    (set_attr "mode" "<MODE>")])
11883
11884 ;; TBM instructions.
11885 (define_insn "tbm_bextri_<mode>"
11886   [(set (match_operand:SWI48 0 "register_operand" "=r")
11887         (zero_extract:SWI48
11888           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11889           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11890           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11891    (clobber (reg:CC FLAGS_REG))]
11892    "TARGET_TBM"
11893 {
11894   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11895   return "bextr\t{%2, %1, %0|%0, %1, %2}";
11896 }
11897   [(set_attr "type" "bitmanip")
11898    (set_attr "mode" "<MODE>")])
11899
11900 (define_insn "*tbm_blcfill_<mode>"
11901   [(set (match_operand:SWI48 0 "register_operand" "=r")
11902         (and:SWI48
11903           (plus:SWI48
11904             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11905             (const_int 1))
11906           (match_dup 1)))
11907    (clobber (reg:CC FLAGS_REG))]
11908    "TARGET_TBM"
11909    "blcfill\t{%1, %0|%0, %1}"
11910   [(set_attr "type" "bitmanip")
11911    (set_attr "mode" "<MODE>")])
11912
11913 (define_insn "*tbm_blci_<mode>"
11914   [(set (match_operand:SWI48 0 "register_operand" "=r")
11915         (ior:SWI48
11916           (not:SWI48
11917             (plus:SWI48
11918               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11919               (const_int 1)))
11920           (match_dup 1)))
11921    (clobber (reg:CC FLAGS_REG))]
11922    "TARGET_TBM"
11923    "blci\t{%1, %0|%0, %1}"
11924   [(set_attr "type" "bitmanip")
11925    (set_attr "mode" "<MODE>")])
11926
11927 (define_insn "*tbm_blcic_<mode>"
11928   [(set (match_operand:SWI48 0 "register_operand" "=r")
11929         (and:SWI48
11930           (plus:SWI48
11931             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11932             (const_int 1))
11933           (not:SWI48
11934             (match_dup 1))))
11935    (clobber (reg:CC FLAGS_REG))]
11936    "TARGET_TBM"
11937    "blcic\t{%1, %0|%0, %1}"
11938   [(set_attr "type" "bitmanip")
11939    (set_attr "mode" "<MODE>")])
11940
11941 (define_insn "*tbm_blcmsk_<mode>"
11942   [(set (match_operand:SWI48 0 "register_operand" "=r")
11943         (xor:SWI48
11944           (plus:SWI48
11945             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11946             (const_int 1))
11947           (match_dup 1)))
11948    (clobber (reg:CC FLAGS_REG))]
11949    "TARGET_TBM"
11950    "blcmsk\t{%1, %0|%0, %1}"
11951   [(set_attr "type" "bitmanip")
11952    (set_attr "mode" "<MODE>")])
11953
11954 (define_insn "*tbm_blcs_<mode>"
11955   [(set (match_operand:SWI48 0 "register_operand" "=r")
11956         (ior:SWI48
11957           (plus:SWI48
11958             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11959             (const_int 1))
11960           (match_dup 1)))
11961    (clobber (reg:CC FLAGS_REG))]
11962    "TARGET_TBM"
11963    "blcs\t{%1, %0|%0, %1}"
11964   [(set_attr "type" "bitmanip")
11965    (set_attr "mode" "<MODE>")])
11966
11967 (define_insn "*tbm_blsfill_<mode>"
11968   [(set (match_operand:SWI48 0 "register_operand" "=r")
11969         (ior:SWI48
11970           (plus:SWI48
11971             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11972             (const_int -1))
11973           (match_dup 1)))
11974    (clobber (reg:CC FLAGS_REG))]
11975    "TARGET_TBM"
11976    "blsfill\t{%1, %0|%0, %1}"
11977   [(set_attr "type" "bitmanip")
11978    (set_attr "mode" "<MODE>")])
11979
11980 (define_insn "*tbm_blsic_<mode>"
11981   [(set (match_operand:SWI48 0 "register_operand" "=r")
11982         (ior:SWI48
11983           (plus:SWI48
11984             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11985             (const_int -1))
11986           (not:SWI48
11987             (match_dup 1))))
11988    (clobber (reg:CC FLAGS_REG))]
11989    "TARGET_TBM"
11990    "blsic\t{%1, %0|%0, %1}"
11991   [(set_attr "type" "bitmanip")
11992    (set_attr "mode" "<MODE>")])
11993
11994 (define_insn "*tbm_t1mskc_<mode>"
11995   [(set (match_operand:SWI48 0 "register_operand" "=r")
11996         (ior:SWI48
11997           (plus:SWI48
11998             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11999             (const_int 1))
12000           (not:SWI48
12001             (match_dup 1))))
12002    (clobber (reg:CC FLAGS_REG))]
12003    "TARGET_TBM"
12004    "t1mskc\t{%1, %0|%0, %1}"
12005   [(set_attr "type" "bitmanip")
12006    (set_attr "mode" "<MODE>")])
12007
12008 (define_insn "*tbm_tzmsk_<mode>"
12009   [(set (match_operand:SWI48 0 "register_operand" "=r")
12010         (and:SWI48
12011           (plus:SWI48
12012             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12013             (const_int -1))
12014           (not:SWI48
12015             (match_dup 1))))
12016    (clobber (reg:CC FLAGS_REG))]
12017    "TARGET_TBM"
12018    "tzmsk\t{%1, %0|%0, %1}"
12019   [(set_attr "type" "bitmanip")
12020    (set_attr "mode" "<MODE>")])
12021
12022 (define_insn "bsr_rex64"
12023   [(set (match_operand:DI 0 "register_operand" "=r")
12024         (minus:DI (const_int 63)
12025                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12026    (clobber (reg:CC FLAGS_REG))]
12027   "TARGET_64BIT"
12028   "bsr{q}\t{%1, %0|%0, %1}"
12029   [(set_attr "type" "alu1")
12030    (set_attr "prefix_0f" "1")
12031    (set_attr "mode" "DI")])
12032
12033 (define_insn "bsr"
12034   [(set (match_operand:SI 0 "register_operand" "=r")
12035         (minus:SI (const_int 31)
12036                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12037    (clobber (reg:CC FLAGS_REG))]
12038   ""
12039   "bsr{l}\t{%1, %0|%0, %1}"
12040   [(set_attr "type" "alu1")
12041    (set_attr "prefix_0f" "1")
12042    (set_attr "mode" "SI")])
12043
12044 (define_insn "*bsrhi"
12045   [(set (match_operand:HI 0 "register_operand" "=r")
12046         (minus:HI (const_int 15)
12047                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12048    (clobber (reg:CC FLAGS_REG))]
12049   ""
12050   "bsr{w}\t{%1, %0|%0, %1}"
12051   [(set_attr "type" "alu1")
12052    (set_attr "prefix_0f" "1")
12053    (set_attr "mode" "HI")])
12054
12055 (define_insn "popcount<mode>2"
12056   [(set (match_operand:SWI248 0 "register_operand" "=r")
12057         (popcount:SWI248
12058           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12059    (clobber (reg:CC FLAGS_REG))]
12060   "TARGET_POPCNT"
12061 {
12062 #if TARGET_MACHO
12063   return "popcnt\t{%1, %0|%0, %1}";
12064 #else
12065   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12066 #endif
12067 }
12068   [(set_attr "prefix_rep" "1")
12069    (set_attr "type" "bitmanip")
12070    (set_attr "mode" "<MODE>")])
12071
12072 (define_insn "*popcount<mode>2_cmp"
12073   [(set (reg FLAGS_REG)
12074         (compare
12075           (popcount:SWI248
12076             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12077           (const_int 0)))
12078    (set (match_operand:SWI248 0 "register_operand" "=r")
12079         (popcount:SWI248 (match_dup 1)))]
12080   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12081 {
12082 #if TARGET_MACHO
12083   return "popcnt\t{%1, %0|%0, %1}";
12084 #else
12085   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12086 #endif
12087 }
12088   [(set_attr "prefix_rep" "1")
12089    (set_attr "type" "bitmanip")
12090    (set_attr "mode" "<MODE>")])
12091
12092 (define_insn "*popcountsi2_cmp_zext"
12093   [(set (reg FLAGS_REG)
12094         (compare
12095           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12096           (const_int 0)))
12097    (set (match_operand:DI 0 "register_operand" "=r")
12098         (zero_extend:DI(popcount:SI (match_dup 1))))]
12099   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12100 {
12101 #if TARGET_MACHO
12102   return "popcnt\t{%1, %0|%0, %1}";
12103 #else
12104   return "popcnt{l}\t{%1, %0|%0, %1}";
12105 #endif
12106 }
12107   [(set_attr "prefix_rep" "1")
12108    (set_attr "type" "bitmanip")
12109    (set_attr "mode" "SI")])
12110
12111 (define_expand "bswap<mode>2"
12112   [(set (match_operand:SWI48 0 "register_operand" "")
12113         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12114   ""
12115 {
12116   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12117     {
12118       rtx x = operands[0];
12119
12120       emit_move_insn (x, operands[1]);
12121       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12122       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12123       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12124       DONE;
12125     }
12126 })
12127
12128 (define_insn "*bswap<mode>2_movbe"
12129   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12130         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12131   "TARGET_MOVBE
12132    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12133   "@
12134     bswap\t%0
12135     movbe\t{%1, %0|%0, %1}
12136     movbe\t{%1, %0|%0, %1}"
12137   [(set_attr "type" "bitmanip,imov,imov")
12138    (set_attr "modrm" "0,1,1")
12139    (set_attr "prefix_0f" "*,1,1")
12140    (set_attr "prefix_extra" "*,1,1")
12141    (set_attr "mode" "<MODE>")])
12142
12143 (define_insn "*bswap<mode>2_1"
12144   [(set (match_operand:SWI48 0 "register_operand" "=r")
12145         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12146   "TARGET_BSWAP"
12147   "bswap\t%0"
12148   [(set_attr "type" "bitmanip")
12149    (set_attr "modrm" "0")
12150    (set_attr "mode" "<MODE>")])
12151
12152 (define_insn "*bswaphi_lowpart_1"
12153   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12154         (bswap:HI (match_dup 0)))
12155    (clobber (reg:CC FLAGS_REG))]
12156   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12157   "@
12158     xchg{b}\t{%h0, %b0|%b0, %h0}
12159     rol{w}\t{$8, %0|%0, 8}"
12160   [(set_attr "length" "2,4")
12161    (set_attr "mode" "QI,HI")])
12162
12163 (define_insn "bswaphi_lowpart"
12164   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12165         (bswap:HI (match_dup 0)))
12166    (clobber (reg:CC FLAGS_REG))]
12167   ""
12168   "rol{w}\t{$8, %0|%0, 8}"
12169   [(set_attr "length" "4")
12170    (set_attr "mode" "HI")])
12171
12172 (define_expand "paritydi2"
12173   [(set (match_operand:DI 0 "register_operand" "")
12174         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12175   "! TARGET_POPCNT"
12176 {
12177   rtx scratch = gen_reg_rtx (QImode);
12178   rtx cond;
12179
12180   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12181                                 NULL_RTX, operands[1]));
12182
12183   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12184                          gen_rtx_REG (CCmode, FLAGS_REG),
12185                          const0_rtx);
12186   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12187
12188   if (TARGET_64BIT)
12189     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12190   else
12191     {
12192       rtx tmp = gen_reg_rtx (SImode);
12193
12194       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12195       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12196     }
12197   DONE;
12198 })
12199
12200 (define_expand "paritysi2"
12201   [(set (match_operand:SI 0 "register_operand" "")
12202         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12203   "! TARGET_POPCNT"
12204 {
12205   rtx scratch = gen_reg_rtx (QImode);
12206   rtx cond;
12207
12208   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12209
12210   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12211                          gen_rtx_REG (CCmode, FLAGS_REG),
12212                          const0_rtx);
12213   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12214
12215   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12216   DONE;
12217 })
12218
12219 (define_insn_and_split "paritydi2_cmp"
12220   [(set (reg:CC FLAGS_REG)
12221         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12222                    UNSPEC_PARITY))
12223    (clobber (match_scratch:DI 0 "=r"))
12224    (clobber (match_scratch:SI 1 "=&r"))
12225    (clobber (match_scratch:HI 2 "=Q"))]
12226   "! TARGET_POPCNT"
12227   "#"
12228   "&& reload_completed"
12229   [(parallel
12230      [(set (match_dup 1)
12231            (xor:SI (match_dup 1) (match_dup 4)))
12232       (clobber (reg:CC FLAGS_REG))])
12233    (parallel
12234      [(set (reg:CC FLAGS_REG)
12235            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12236       (clobber (match_dup 1))
12237       (clobber (match_dup 2))])]
12238 {
12239   operands[4] = gen_lowpart (SImode, operands[3]);
12240
12241   if (TARGET_64BIT)
12242     {
12243       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12244       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12245     }
12246   else
12247     operands[1] = gen_highpart (SImode, operands[3]);
12248 })
12249
12250 (define_insn_and_split "paritysi2_cmp"
12251   [(set (reg:CC FLAGS_REG)
12252         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12253                    UNSPEC_PARITY))
12254    (clobber (match_scratch:SI 0 "=r"))
12255    (clobber (match_scratch:HI 1 "=&Q"))]
12256   "! TARGET_POPCNT"
12257   "#"
12258   "&& reload_completed"
12259   [(parallel
12260      [(set (match_dup 1)
12261            (xor:HI (match_dup 1) (match_dup 3)))
12262       (clobber (reg:CC FLAGS_REG))])
12263    (parallel
12264      [(set (reg:CC FLAGS_REG)
12265            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12266       (clobber (match_dup 1))])]
12267 {
12268   operands[3] = gen_lowpart (HImode, operands[2]);
12269
12270   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12271   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12272 })
12273
12274 (define_insn "*parityhi2_cmp"
12275   [(set (reg:CC FLAGS_REG)
12276         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12277                    UNSPEC_PARITY))
12278    (clobber (match_scratch:HI 0 "=Q"))]
12279   "! TARGET_POPCNT"
12280   "xor{b}\t{%h0, %b0|%b0, %h0}"
12281   [(set_attr "length" "2")
12282    (set_attr "mode" "HI")])
12283 \f
12284 ;; Thread-local storage patterns for ELF.
12285 ;;
12286 ;; Note that these code sequences must appear exactly as shown
12287 ;; in order to allow linker relaxation.
12288
12289 (define_insn "*tls_global_dynamic_32_gnu"
12290   [(set (match_operand:SI 0 "register_operand" "=a")
12291         (unspec:SI
12292          [(match_operand:SI 1 "register_operand" "b")
12293           (match_operand:SI 2 "tls_symbolic_operand" "")
12294           (match_operand:SI 3 "constant_call_address_operand" "z")]
12295          UNSPEC_TLS_GD))
12296    (clobber (match_scratch:SI 4 "=d"))
12297    (clobber (match_scratch:SI 5 "=c"))
12298    (clobber (reg:CC FLAGS_REG))]
12299   "!TARGET_64BIT && TARGET_GNU_TLS"
12300 {
12301   output_asm_insn
12302     ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12303   if (TARGET_SUN_TLS)
12304 #ifdef HAVE_AS_IX86_TLSGDPLT
12305     return "call\t%a2@tlsgdplt";
12306 #else
12307     return "call\t%p3@plt";
12308 #endif
12309   return "call\t%P3";
12310 }
12311   [(set_attr "type" "multi")
12312    (set_attr "length" "12")])
12313
12314 (define_expand "tls_global_dynamic_32"
12315   [(parallel
12316     [(set (match_operand:SI 0 "register_operand" "")
12317           (unspec:SI [(match_operand:SI 2 "register_operand" "")
12318                       (match_operand:SI 1 "tls_symbolic_operand" "")
12319                       (match_operand:SI 3 "constant_call_address_operand" "")]
12320                      UNSPEC_TLS_GD))
12321      (clobber (match_scratch:SI 4 ""))
12322      (clobber (match_scratch:SI 5 ""))
12323      (clobber (reg:CC FLAGS_REG))])])
12324
12325 (define_insn "*tls_global_dynamic_64"
12326   [(set (match_operand:DI 0 "register_operand" "=a")
12327         (call:DI
12328          (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12329          (match_operand:DI 3 "" "")))
12330    (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12331               UNSPEC_TLS_GD)]
12332   "TARGET_64BIT"
12333 {
12334   if (!TARGET_X32)
12335     fputs (ASM_BYTE "0x66\n", asm_out_file);
12336   output_asm_insn
12337     ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12338   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12339   fputs ("\trex64\n", asm_out_file);
12340   if (TARGET_SUN_TLS)
12341     return "call\t%p2@plt";
12342   return "call\t%P2";
12343 }
12344   [(set_attr "type" "multi")
12345    (set (attr "length")
12346         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12347
12348 (define_expand "tls_global_dynamic_64"
12349   [(parallel
12350     [(set (match_operand:DI 0 "register_operand" "")
12351           (call:DI
12352            (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12353            (const_int 0)))
12354      (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12355                 UNSPEC_TLS_GD)])])
12356
12357 (define_insn "*tls_local_dynamic_base_32_gnu"
12358   [(set (match_operand:SI 0 "register_operand" "=a")
12359         (unspec:SI
12360          [(match_operand:SI 1 "register_operand" "b")
12361           (match_operand:SI 2 "constant_call_address_operand" "z")]
12362          UNSPEC_TLS_LD_BASE))
12363    (clobber (match_scratch:SI 3 "=d"))
12364    (clobber (match_scratch:SI 4 "=c"))
12365    (clobber (reg:CC FLAGS_REG))]
12366   "!TARGET_64BIT && TARGET_GNU_TLS"
12367 {
12368   output_asm_insn
12369     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12370   if (TARGET_SUN_TLS)
12371 #ifdef HAVE_AS_IX86_TLSLDMPLT
12372     return "call\t%&@tlsldmplt";
12373 #else
12374     return "call\t%p2@plt";
12375 #endif
12376   return "call\t%P2";
12377 }
12378   [(set_attr "type" "multi")
12379    (set_attr "length" "11")])
12380
12381 (define_expand "tls_local_dynamic_base_32"
12382   [(parallel
12383      [(set (match_operand:SI 0 "register_operand" "")
12384            (unspec:SI
12385             [(match_operand:SI 1 "register_operand" "")
12386              (match_operand:SI 2 "constant_call_address_operand" "")]
12387             UNSPEC_TLS_LD_BASE))
12388       (clobber (match_scratch:SI 3 ""))
12389       (clobber (match_scratch:SI 4 ""))
12390       (clobber (reg:CC FLAGS_REG))])])
12391
12392 (define_insn "*tls_local_dynamic_base_64"
12393   [(set (match_operand:DI 0 "register_operand" "=a")
12394         (call:DI
12395          (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12396          (match_operand:DI 2 "" "")))
12397    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12398   "TARGET_64BIT"
12399 {
12400   output_asm_insn
12401     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12402   if (TARGET_SUN_TLS)
12403     return "call\t%p1@plt";
12404   return "call\t%P1";
12405 }
12406   [(set_attr "type" "multi")
12407    (set_attr "length" "12")])
12408
12409 (define_expand "tls_local_dynamic_base_64"
12410   [(parallel
12411      [(set (match_operand:DI 0 "register_operand" "")
12412            (call:DI
12413             (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12414             (const_int 0)))
12415       (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12416
12417 ;; Local dynamic of a single variable is a lose.  Show combine how
12418 ;; to convert that back to global dynamic.
12419
12420 (define_insn_and_split "*tls_local_dynamic_32_once"
12421   [(set (match_operand:SI 0 "register_operand" "=a")
12422         (plus:SI
12423          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12424                      (match_operand:SI 2 "constant_call_address_operand" "z")]
12425                     UNSPEC_TLS_LD_BASE)
12426          (const:SI (unspec:SI
12427                     [(match_operand:SI 3 "tls_symbolic_operand" "")]
12428                     UNSPEC_DTPOFF))))
12429    (clobber (match_scratch:SI 4 "=d"))
12430    (clobber (match_scratch:SI 5 "=c"))
12431    (clobber (reg:CC FLAGS_REG))]
12432   ""
12433   "#"
12434   ""
12435   [(parallel
12436      [(set (match_dup 0)
12437            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12438                       UNSPEC_TLS_GD))
12439       (clobber (match_dup 4))
12440       (clobber (match_dup 5))
12441       (clobber (reg:CC FLAGS_REG))])])
12442
12443 ;; Segment register for the thread base ptr load
12444 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12445
12446 ;; Load and add the thread base pointer from %<tp_seg>:0.
12447 (define_insn "*load_tp_x32"
12448   [(set (match_operand:SI 0 "register_operand" "=r")
12449         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12450   "TARGET_X32"
12451   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12452   [(set_attr "type" "imov")
12453    (set_attr "modrm" "0")
12454    (set_attr "length" "7")
12455    (set_attr "memory" "load")
12456    (set_attr "imm_disp" "false")])
12457
12458 (define_insn "*load_tp_x32_zext"
12459   [(set (match_operand:DI 0 "register_operand" "=r")
12460         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12461   "TARGET_X32"
12462   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12463   [(set_attr "type" "imov")
12464    (set_attr "modrm" "0")
12465    (set_attr "length" "7")
12466    (set_attr "memory" "load")
12467    (set_attr "imm_disp" "false")])
12468
12469 (define_insn "*load_tp_<mode>"
12470   [(set (match_operand:P 0 "register_operand" "=r")
12471         (unspec:P [(const_int 0)] UNSPEC_TP))]
12472   "!TARGET_X32"
12473   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12474   [(set_attr "type" "imov")
12475    (set_attr "modrm" "0")
12476    (set_attr "length" "7")
12477    (set_attr "memory" "load")
12478    (set_attr "imm_disp" "false")])
12479
12480 (define_insn "*add_tp_x32"
12481   [(set (match_operand:SI 0 "register_operand" "=r")
12482         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12483                  (match_operand:SI 1 "register_operand" "0")))
12484    (clobber (reg:CC FLAGS_REG))]
12485   "TARGET_X32"
12486   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12487   [(set_attr "type" "alu")
12488    (set_attr "modrm" "0")
12489    (set_attr "length" "7")
12490    (set_attr "memory" "load")
12491    (set_attr "imm_disp" "false")])
12492
12493 (define_insn "*add_tp_x32_zext"
12494   [(set (match_operand:DI 0 "register_operand" "=r")
12495         (zero_extend:DI
12496           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12497                    (match_operand:SI 1 "register_operand" "0"))))
12498    (clobber (reg:CC FLAGS_REG))]
12499   "TARGET_X32"
12500   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12501   [(set_attr "type" "alu")
12502    (set_attr "modrm" "0")
12503    (set_attr "length" "7")
12504    (set_attr "memory" "load")
12505    (set_attr "imm_disp" "false")])
12506
12507 (define_insn "*add_tp_<mode>"
12508   [(set (match_operand:P 0 "register_operand" "=r")
12509         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12510                 (match_operand:P 1 "register_operand" "0")))
12511    (clobber (reg:CC FLAGS_REG))]
12512   "!TARGET_X32"
12513   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12514   [(set_attr "type" "alu")
12515    (set_attr "modrm" "0")
12516    (set_attr "length" "7")
12517    (set_attr "memory" "load")
12518    (set_attr "imm_disp" "false")])
12519
12520 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12521 ;; %rax as destination of the initial executable code sequence.
12522 (define_insn "tls_initial_exec_64_sun"
12523   [(set (match_operand:DI 0 "register_operand" "=a")
12524         (unspec:DI
12525          [(match_operand:DI 1 "tls_symbolic_operand" "")]
12526          UNSPEC_TLS_IE_SUN))
12527    (clobber (reg:CC FLAGS_REG))]
12528   "TARGET_64BIT && TARGET_SUN_TLS"
12529 {
12530   output_asm_insn
12531     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12532   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12533 }
12534   [(set_attr "type" "multi")])
12535
12536 ;; GNU2 TLS patterns can be split.
12537
12538 (define_expand "tls_dynamic_gnu2_32"
12539   [(set (match_dup 3)
12540         (plus:SI (match_operand:SI 2 "register_operand" "")
12541                  (const:SI
12542                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12543                              UNSPEC_TLSDESC))))
12544    (parallel
12545     [(set (match_operand:SI 0 "register_operand" "")
12546           (unspec:SI [(match_dup 1) (match_dup 3)
12547                       (match_dup 2) (reg:SI SP_REG)]
12548                       UNSPEC_TLSDESC))
12549      (clobber (reg:CC FLAGS_REG))])]
12550   "!TARGET_64BIT && TARGET_GNU2_TLS"
12551 {
12552   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12553   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12554 })
12555
12556 (define_insn "*tls_dynamic_gnu2_lea_32"
12557   [(set (match_operand:SI 0 "register_operand" "=r")
12558         (plus:SI (match_operand:SI 1 "register_operand" "b")
12559                  (const:SI
12560                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12561                               UNSPEC_TLSDESC))))]
12562   "!TARGET_64BIT && TARGET_GNU2_TLS"
12563   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12564   [(set_attr "type" "lea")
12565    (set_attr "mode" "SI")
12566    (set_attr "length" "6")
12567    (set_attr "length_address" "4")])
12568
12569 (define_insn "*tls_dynamic_gnu2_call_32"
12570   [(set (match_operand:SI 0 "register_operand" "=a")
12571         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12572                     (match_operand:SI 2 "register_operand" "0")
12573                     ;; we have to make sure %ebx still points to the GOT
12574                     (match_operand:SI 3 "register_operand" "b")
12575                     (reg:SI SP_REG)]
12576                    UNSPEC_TLSDESC))
12577    (clobber (reg:CC FLAGS_REG))]
12578   "!TARGET_64BIT && TARGET_GNU2_TLS"
12579   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12580   [(set_attr "type" "call")
12581    (set_attr "length" "2")
12582    (set_attr "length_address" "0")])
12583
12584 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12585   [(set (match_operand:SI 0 "register_operand" "=&a")
12586         (plus:SI
12587          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12588                      (match_operand:SI 4 "" "")
12589                      (match_operand:SI 2 "register_operand" "b")
12590                      (reg:SI SP_REG)]
12591                     UNSPEC_TLSDESC)
12592          (const:SI (unspec:SI
12593                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12594                     UNSPEC_DTPOFF))))
12595    (clobber (reg:CC FLAGS_REG))]
12596   "!TARGET_64BIT && TARGET_GNU2_TLS"
12597   "#"
12598   ""
12599   [(set (match_dup 0) (match_dup 5))]
12600 {
12601   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12602   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12603 })
12604
12605 (define_expand "tls_dynamic_gnu2_64"
12606   [(set (match_dup 2)
12607         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12608                    UNSPEC_TLSDESC))
12609    (parallel
12610     [(set (match_operand:DI 0 "register_operand" "")
12611           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12612                      UNSPEC_TLSDESC))
12613      (clobber (reg:CC FLAGS_REG))])]
12614   "TARGET_64BIT && TARGET_GNU2_TLS"
12615 {
12616   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12617   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12618 })
12619
12620 (define_insn "*tls_dynamic_gnu2_lea_64"
12621   [(set (match_operand:DI 0 "register_operand" "=r")
12622         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12623                    UNSPEC_TLSDESC))]
12624   "TARGET_64BIT && TARGET_GNU2_TLS"
12625   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12626   [(set_attr "type" "lea")
12627    (set_attr "mode" "DI")
12628    (set_attr "length" "7")
12629    (set_attr "length_address" "4")])
12630
12631 (define_insn "*tls_dynamic_gnu2_call_64"
12632   [(set (match_operand:DI 0 "register_operand" "=a")
12633         (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12634                     (match_operand:DI 2 "register_operand" "0")
12635                     (reg:DI SP_REG)]
12636                    UNSPEC_TLSDESC))
12637    (clobber (reg:CC FLAGS_REG))]
12638   "TARGET_64BIT && TARGET_GNU2_TLS"
12639   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12640   [(set_attr "type" "call")
12641    (set_attr "length" "2")
12642    (set_attr "length_address" "0")])
12643
12644 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12645   [(set (match_operand:DI 0 "register_operand" "=&a")
12646         (plus:DI
12647          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12648                      (match_operand:DI 3 "" "")
12649                      (reg:DI SP_REG)]
12650                     UNSPEC_TLSDESC)
12651          (const:DI (unspec:DI
12652                     [(match_operand 1 "tls_symbolic_operand" "")]
12653                     UNSPEC_DTPOFF))))
12654    (clobber (reg:CC FLAGS_REG))]
12655   "TARGET_64BIT && TARGET_GNU2_TLS"
12656   "#"
12657   ""
12658   [(set (match_dup 0) (match_dup 4))]
12659 {
12660   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12661   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12662 })
12663 \f
12664 ;; These patterns match the binary 387 instructions for addM3, subM3,
12665 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12666 ;; SFmode.  The first is the normal insn, the second the same insn but
12667 ;; with one operand a conversion, and the third the same insn but with
12668 ;; the other operand a conversion.  The conversion may be SFmode or
12669 ;; SImode if the target mode DFmode, but only SImode if the target mode
12670 ;; is SFmode.
12671
12672 ;; Gcc is slightly more smart about handling normal two address instructions
12673 ;; so use special patterns for add and mull.
12674
12675 (define_insn "*fop_<mode>_comm_mixed"
12676   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12677         (match_operator:MODEF 3 "binary_fp_operator"
12678           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12679            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12680   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12681    && COMMUTATIVE_ARITH_P (operands[3])
12682    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12683   "* return output_387_binary_op (insn, operands);"
12684   [(set (attr "type")
12685         (if_then_else (eq_attr "alternative" "1,2")
12686            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12687               (const_string "ssemul")
12688               (const_string "sseadd"))
12689            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12690               (const_string "fmul")
12691               (const_string "fop"))))
12692    (set_attr "isa" "*,noavx,avx")
12693    (set_attr "prefix" "orig,orig,vex")
12694    (set_attr "mode" "<MODE>")])
12695
12696 (define_insn "*fop_<mode>_comm_sse"
12697   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12698         (match_operator:MODEF 3 "binary_fp_operator"
12699           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12700            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12701   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12702    && COMMUTATIVE_ARITH_P (operands[3])
12703    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12704   "* return output_387_binary_op (insn, operands);"
12705   [(set (attr "type")
12706         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12707            (const_string "ssemul")
12708            (const_string "sseadd")))
12709    (set_attr "isa" "noavx,avx")
12710    (set_attr "prefix" "orig,vex")
12711    (set_attr "mode" "<MODE>")])
12712
12713 (define_insn "*fop_<mode>_comm_i387"
12714   [(set (match_operand:MODEF 0 "register_operand" "=f")
12715         (match_operator:MODEF 3 "binary_fp_operator"
12716           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12717            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12718   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12719    && COMMUTATIVE_ARITH_P (operands[3])
12720    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12721   "* return output_387_binary_op (insn, operands);"
12722   [(set (attr "type")
12723         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12724            (const_string "fmul")
12725            (const_string "fop")))
12726    (set_attr "mode" "<MODE>")])
12727
12728 (define_insn "*fop_<mode>_1_mixed"
12729   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12730         (match_operator:MODEF 3 "binary_fp_operator"
12731           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12732            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12733   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12734    && !COMMUTATIVE_ARITH_P (operands[3])
12735    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12736   "* return output_387_binary_op (insn, operands);"
12737   [(set (attr "type")
12738         (cond [(and (eq_attr "alternative" "2,3")
12739                     (match_operand:MODEF 3 "mult_operator" ""))
12740                  (const_string "ssemul")
12741                (and (eq_attr "alternative" "2,3")
12742                     (match_operand:MODEF 3 "div_operator" ""))
12743                  (const_string "ssediv")
12744                (eq_attr "alternative" "2,3")
12745                  (const_string "sseadd")
12746                (match_operand:MODEF 3 "mult_operator" "")
12747                  (const_string "fmul")
12748                (match_operand:MODEF 3 "div_operator" "")
12749                  (const_string "fdiv")
12750               ]
12751               (const_string "fop")))
12752    (set_attr "isa" "*,*,noavx,avx")
12753    (set_attr "prefix" "orig,orig,orig,vex")
12754    (set_attr "mode" "<MODE>")])
12755
12756 (define_insn "*rcpsf2_sse"
12757   [(set (match_operand:SF 0 "register_operand" "=x")
12758         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12759                    UNSPEC_RCP))]
12760   "TARGET_SSE_MATH"
12761   "%vrcpss\t{%1, %d0|%d0, %1}"
12762   [(set_attr "type" "sse")
12763    (set_attr "atom_sse_attr" "rcp")
12764    (set_attr "prefix" "maybe_vex")
12765    (set_attr "mode" "SF")])
12766
12767 (define_insn "*fop_<mode>_1_sse"
12768   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12769         (match_operator:MODEF 3 "binary_fp_operator"
12770           [(match_operand:MODEF 1 "register_operand" "0,x")
12771            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12772   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12773    && !COMMUTATIVE_ARITH_P (operands[3])"
12774   "* return output_387_binary_op (insn, operands);"
12775   [(set (attr "type")
12776         (cond [(match_operand:MODEF 3 "mult_operator" "")
12777                  (const_string "ssemul")
12778                (match_operand:MODEF 3 "div_operator" "")
12779                  (const_string "ssediv")
12780               ]
12781               (const_string "sseadd")))
12782    (set_attr "isa" "noavx,avx")
12783    (set_attr "prefix" "orig,vex")
12784    (set_attr "mode" "<MODE>")])
12785
12786 ;; This pattern is not fully shadowed by the pattern above.
12787 (define_insn "*fop_<mode>_1_i387"
12788   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12789         (match_operator:MODEF 3 "binary_fp_operator"
12790           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12791            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12792   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12793    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12794    && !COMMUTATIVE_ARITH_P (operands[3])
12795    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12796   "* return output_387_binary_op (insn, operands);"
12797   [(set (attr "type")
12798         (cond [(match_operand:MODEF 3 "mult_operator" "")
12799                  (const_string "fmul")
12800                (match_operand:MODEF 3 "div_operator" "")
12801                  (const_string "fdiv")
12802               ]
12803               (const_string "fop")))
12804    (set_attr "mode" "<MODE>")])
12805
12806 ;; ??? Add SSE splitters for these!
12807 (define_insn "*fop_<MODEF:mode>_2_i387"
12808   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12809         (match_operator:MODEF 3 "binary_fp_operator"
12810           [(float:MODEF
12811              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12812            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12813   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12814    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12815    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12816   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12817   [(set (attr "type")
12818         (cond [(match_operand:MODEF 3 "mult_operator" "")
12819                  (const_string "fmul")
12820                (match_operand:MODEF 3 "div_operator" "")
12821                  (const_string "fdiv")
12822               ]
12823               (const_string "fop")))
12824    (set_attr "fp_int_src" "true")
12825    (set_attr "mode" "<SWI24:MODE>")])
12826
12827 (define_insn "*fop_<MODEF:mode>_3_i387"
12828   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12829         (match_operator:MODEF 3 "binary_fp_operator"
12830           [(match_operand:MODEF 1 "register_operand" "0,0")
12831            (float:MODEF
12832              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12833   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12834    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12835    && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12836   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12837   [(set (attr "type")
12838         (cond [(match_operand:MODEF 3 "mult_operator" "")
12839                  (const_string "fmul")
12840                (match_operand:MODEF 3 "div_operator" "")
12841                  (const_string "fdiv")
12842               ]
12843               (const_string "fop")))
12844    (set_attr "fp_int_src" "true")
12845    (set_attr "mode" "<MODE>")])
12846
12847 (define_insn "*fop_df_4_i387"
12848   [(set (match_operand:DF 0 "register_operand" "=f,f")
12849         (match_operator:DF 3 "binary_fp_operator"
12850            [(float_extend:DF
12851              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12852             (match_operand:DF 2 "register_operand" "0,f")]))]
12853   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12854    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12855    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12856   "* return output_387_binary_op (insn, operands);"
12857   [(set (attr "type")
12858         (cond [(match_operand:DF 3 "mult_operator" "")
12859                  (const_string "fmul")
12860                (match_operand:DF 3 "div_operator" "")
12861                  (const_string "fdiv")
12862               ]
12863               (const_string "fop")))
12864    (set_attr "mode" "SF")])
12865
12866 (define_insn "*fop_df_5_i387"
12867   [(set (match_operand:DF 0 "register_operand" "=f,f")
12868         (match_operator:DF 3 "binary_fp_operator"
12869           [(match_operand:DF 1 "register_operand" "0,f")
12870            (float_extend:DF
12871             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12872   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12873    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12874   "* return output_387_binary_op (insn, operands);"
12875   [(set (attr "type")
12876         (cond [(match_operand:DF 3 "mult_operator" "")
12877                  (const_string "fmul")
12878                (match_operand:DF 3 "div_operator" "")
12879                  (const_string "fdiv")
12880               ]
12881               (const_string "fop")))
12882    (set_attr "mode" "SF")])
12883
12884 (define_insn "*fop_df_6_i387"
12885   [(set (match_operand:DF 0 "register_operand" "=f,f")
12886         (match_operator:DF 3 "binary_fp_operator"
12887           [(float_extend:DF
12888             (match_operand:SF 1 "register_operand" "0,f"))
12889            (float_extend:DF
12890             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12891   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12892    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12893   "* return output_387_binary_op (insn, operands);"
12894   [(set (attr "type")
12895         (cond [(match_operand:DF 3 "mult_operator" "")
12896                  (const_string "fmul")
12897                (match_operand:DF 3 "div_operator" "")
12898                  (const_string "fdiv")
12899               ]
12900               (const_string "fop")))
12901    (set_attr "mode" "SF")])
12902
12903 (define_insn "*fop_xf_comm_i387"
12904   [(set (match_operand:XF 0 "register_operand" "=f")
12905         (match_operator:XF 3 "binary_fp_operator"
12906                         [(match_operand:XF 1 "register_operand" "%0")
12907                          (match_operand:XF 2 "register_operand" "f")]))]
12908   "TARGET_80387
12909    && COMMUTATIVE_ARITH_P (operands[3])"
12910   "* return output_387_binary_op (insn, operands);"
12911   [(set (attr "type")
12912         (if_then_else (match_operand:XF 3 "mult_operator" "")
12913            (const_string "fmul")
12914            (const_string "fop")))
12915    (set_attr "mode" "XF")])
12916
12917 (define_insn "*fop_xf_1_i387"
12918   [(set (match_operand:XF 0 "register_operand" "=f,f")
12919         (match_operator:XF 3 "binary_fp_operator"
12920                         [(match_operand:XF 1 "register_operand" "0,f")
12921                          (match_operand:XF 2 "register_operand" "f,0")]))]
12922   "TARGET_80387
12923    && !COMMUTATIVE_ARITH_P (operands[3])"
12924   "* return output_387_binary_op (insn, operands);"
12925   [(set (attr "type")
12926         (cond [(match_operand:XF 3 "mult_operator" "")
12927                  (const_string "fmul")
12928                (match_operand:XF 3 "div_operator" "")
12929                  (const_string "fdiv")
12930               ]
12931               (const_string "fop")))
12932    (set_attr "mode" "XF")])
12933
12934 (define_insn "*fop_xf_2_i387"
12935   [(set (match_operand:XF 0 "register_operand" "=f,f")
12936         (match_operator:XF 3 "binary_fp_operator"
12937           [(float:XF
12938              (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12939            (match_operand:XF 2 "register_operand" "0,0")]))]
12940   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12941   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12942   [(set (attr "type")
12943         (cond [(match_operand:XF 3 "mult_operator" "")
12944                  (const_string "fmul")
12945                (match_operand:XF 3 "div_operator" "")
12946                  (const_string "fdiv")
12947               ]
12948               (const_string "fop")))
12949    (set_attr "fp_int_src" "true")
12950    (set_attr "mode" "<MODE>")])
12951
12952 (define_insn "*fop_xf_3_i387"
12953   [(set (match_operand:XF 0 "register_operand" "=f,f")
12954         (match_operator:XF 3 "binary_fp_operator"
12955           [(match_operand:XF 1 "register_operand" "0,0")
12956            (float:XF
12957              (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12958   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12959   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12960   [(set (attr "type")
12961         (cond [(match_operand:XF 3 "mult_operator" "")
12962                  (const_string "fmul")
12963                (match_operand:XF 3 "div_operator" "")
12964                  (const_string "fdiv")
12965               ]
12966               (const_string "fop")))
12967    (set_attr "fp_int_src" "true")
12968    (set_attr "mode" "<MODE>")])
12969
12970 (define_insn "*fop_xf_4_i387"
12971   [(set (match_operand:XF 0 "register_operand" "=f,f")
12972         (match_operator:XF 3 "binary_fp_operator"
12973            [(float_extend:XF
12974               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12975             (match_operand:XF 2 "register_operand" "0,f")]))]
12976   "TARGET_80387"
12977   "* return output_387_binary_op (insn, operands);"
12978   [(set (attr "type")
12979         (cond [(match_operand:XF 3 "mult_operator" "")
12980                  (const_string "fmul")
12981                (match_operand:XF 3 "div_operator" "")
12982                  (const_string "fdiv")
12983               ]
12984               (const_string "fop")))
12985    (set_attr "mode" "<MODE>")])
12986
12987 (define_insn "*fop_xf_5_i387"
12988   [(set (match_operand:XF 0 "register_operand" "=f,f")
12989         (match_operator:XF 3 "binary_fp_operator"
12990           [(match_operand:XF 1 "register_operand" "0,f")
12991            (float_extend:XF
12992              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12993   "TARGET_80387"
12994   "* return output_387_binary_op (insn, operands);"
12995   [(set (attr "type")
12996         (cond [(match_operand:XF 3 "mult_operator" "")
12997                  (const_string "fmul")
12998                (match_operand:XF 3 "div_operator" "")
12999                  (const_string "fdiv")
13000               ]
13001               (const_string "fop")))
13002    (set_attr "mode" "<MODE>")])
13003
13004 (define_insn "*fop_xf_6_i387"
13005   [(set (match_operand:XF 0 "register_operand" "=f,f")
13006         (match_operator:XF 3 "binary_fp_operator"
13007           [(float_extend:XF
13008              (match_operand:MODEF 1 "register_operand" "0,f"))
13009            (float_extend:XF
13010              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13011   "TARGET_80387"
13012   "* return output_387_binary_op (insn, operands);"
13013   [(set (attr "type")
13014         (cond [(match_operand:XF 3 "mult_operator" "")
13015                  (const_string "fmul")
13016                (match_operand:XF 3 "div_operator" "")
13017                  (const_string "fdiv")
13018               ]
13019               (const_string "fop")))
13020    (set_attr "mode" "<MODE>")])
13021
13022 (define_split
13023   [(set (match_operand 0 "register_operand" "")
13024         (match_operator 3 "binary_fp_operator"
13025            [(float (match_operand:SWI24 1 "register_operand" ""))
13026             (match_operand 2 "register_operand" "")]))]
13027   "reload_completed
13028    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13029    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13030   [(const_int 0)]
13031 {
13032   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13033   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13034   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13035                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13036                                           GET_MODE (operands[3]),
13037                                           operands[4],
13038                                           operands[2])));
13039   ix86_free_from_memory (GET_MODE (operands[1]));
13040   DONE;
13041 })
13042
13043 (define_split
13044   [(set (match_operand 0 "register_operand" "")
13045         (match_operator 3 "binary_fp_operator"
13046            [(match_operand 1 "register_operand" "")
13047             (float (match_operand:SWI24 2 "register_operand" ""))]))]
13048   "reload_completed
13049    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13050    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13051   [(const_int 0)]
13052 {
13053   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13054   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13055   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13056                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13057                                           GET_MODE (operands[3]),
13058                                           operands[1],
13059                                           operands[4])));
13060   ix86_free_from_memory (GET_MODE (operands[2]));
13061   DONE;
13062 })
13063 \f
13064 ;; FPU special functions.
13065
13066 ;; This pattern implements a no-op XFmode truncation for
13067 ;; all fancy i386 XFmode math functions.
13068
13069 (define_insn "truncxf<mode>2_i387_noop_unspec"
13070   [(set (match_operand:MODEF 0 "register_operand" "=f")
13071         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13072         UNSPEC_TRUNC_NOOP))]
13073   "TARGET_USE_FANCY_MATH_387"
13074   "* return output_387_reg_move (insn, operands);"
13075   [(set_attr "type" "fmov")
13076    (set_attr "mode" "<MODE>")])
13077
13078 (define_insn "sqrtxf2"
13079   [(set (match_operand:XF 0 "register_operand" "=f")
13080         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13081   "TARGET_USE_FANCY_MATH_387"
13082   "fsqrt"
13083   [(set_attr "type" "fpspc")
13084    (set_attr "mode" "XF")
13085    (set_attr "athlon_decode" "direct")
13086    (set_attr "amdfam10_decode" "direct")
13087    (set_attr "bdver1_decode" "direct")])
13088
13089 (define_insn "sqrt_extend<mode>xf2_i387"
13090   [(set (match_operand:XF 0 "register_operand" "=f")
13091         (sqrt:XF
13092           (float_extend:XF
13093             (match_operand:MODEF 1 "register_operand" "0"))))]
13094   "TARGET_USE_FANCY_MATH_387"
13095   "fsqrt"
13096   [(set_attr "type" "fpspc")
13097    (set_attr "mode" "XF")
13098    (set_attr "athlon_decode" "direct")
13099    (set_attr "amdfam10_decode" "direct")
13100    (set_attr "bdver1_decode" "direct")])
13101
13102 (define_insn "*rsqrtsf2_sse"
13103   [(set (match_operand:SF 0 "register_operand" "=x")
13104         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13105                    UNSPEC_RSQRT))]
13106   "TARGET_SSE_MATH"
13107   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13108   [(set_attr "type" "sse")
13109    (set_attr "atom_sse_attr" "rcp")
13110    (set_attr "prefix" "maybe_vex")
13111    (set_attr "mode" "SF")])
13112
13113 (define_expand "rsqrtsf2"
13114   [(set (match_operand:SF 0 "register_operand" "")
13115         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13116                    UNSPEC_RSQRT))]
13117   "TARGET_SSE_MATH"
13118 {
13119   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13120   DONE;
13121 })
13122
13123 (define_insn "*sqrt<mode>2_sse"
13124   [(set (match_operand:MODEF 0 "register_operand" "=x")
13125         (sqrt:MODEF
13126           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13127   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13128   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13129   [(set_attr "type" "sse")
13130    (set_attr "atom_sse_attr" "sqrt")
13131    (set_attr "prefix" "maybe_vex")
13132    (set_attr "mode" "<MODE>")
13133    (set_attr "athlon_decode" "*")
13134    (set_attr "amdfam10_decode" "*")
13135    (set_attr "bdver1_decode" "*")])
13136
13137 (define_expand "sqrt<mode>2"
13138   [(set (match_operand:MODEF 0 "register_operand" "")
13139         (sqrt:MODEF
13140           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13141   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13142    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13143 {
13144   if (<MODE>mode == SFmode
13145       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13146       && flag_finite_math_only && !flag_trapping_math
13147       && flag_unsafe_math_optimizations)
13148     {
13149       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13150       DONE;
13151     }
13152
13153   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13154     {
13155       rtx op0 = gen_reg_rtx (XFmode);
13156       rtx op1 = force_reg (<MODE>mode, operands[1]);
13157
13158       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13159       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13160       DONE;
13161    }
13162 })
13163
13164 (define_insn "fpremxf4_i387"
13165   [(set (match_operand:XF 0 "register_operand" "=f")
13166         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13167                     (match_operand:XF 3 "register_operand" "1")]
13168                    UNSPEC_FPREM_F))
13169    (set (match_operand:XF 1 "register_operand" "=u")
13170         (unspec:XF [(match_dup 2) (match_dup 3)]
13171                    UNSPEC_FPREM_U))
13172    (set (reg:CCFP FPSR_REG)
13173         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13174                      UNSPEC_C2_FLAG))]
13175   "TARGET_USE_FANCY_MATH_387"
13176   "fprem"
13177   [(set_attr "type" "fpspc")
13178    (set_attr "mode" "XF")])
13179
13180 (define_expand "fmodxf3"
13181   [(use (match_operand:XF 0 "register_operand" ""))
13182    (use (match_operand:XF 1 "general_operand" ""))
13183    (use (match_operand:XF 2 "general_operand" ""))]
13184   "TARGET_USE_FANCY_MATH_387"
13185 {
13186   rtx label = gen_label_rtx ();
13187
13188   rtx op1 = gen_reg_rtx (XFmode);
13189   rtx op2 = gen_reg_rtx (XFmode);
13190
13191   emit_move_insn (op2, operands[2]);
13192   emit_move_insn (op1, operands[1]);
13193
13194   emit_label (label);
13195   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13196   ix86_emit_fp_unordered_jump (label);
13197   LABEL_NUSES (label) = 1;
13198
13199   emit_move_insn (operands[0], op1);
13200   DONE;
13201 })
13202
13203 (define_expand "fmod<mode>3"
13204   [(use (match_operand:MODEF 0 "register_operand" ""))
13205    (use (match_operand:MODEF 1 "general_operand" ""))
13206    (use (match_operand:MODEF 2 "general_operand" ""))]
13207   "TARGET_USE_FANCY_MATH_387"
13208 {
13209   rtx (*gen_truncxf) (rtx, rtx);
13210
13211   rtx label = gen_label_rtx ();
13212
13213   rtx op1 = gen_reg_rtx (XFmode);
13214   rtx op2 = gen_reg_rtx (XFmode);
13215
13216   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13217   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13218
13219   emit_label (label);
13220   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13221   ix86_emit_fp_unordered_jump (label);
13222   LABEL_NUSES (label) = 1;
13223
13224   /* Truncate the result properly for strict SSE math.  */
13225   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13226       && !TARGET_MIX_SSE_I387)
13227     gen_truncxf = gen_truncxf<mode>2;
13228   else
13229     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13230
13231   emit_insn (gen_truncxf (operands[0], op1));
13232   DONE;
13233 })
13234
13235 (define_insn "fprem1xf4_i387"
13236   [(set (match_operand:XF 0 "register_operand" "=f")
13237         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13238                     (match_operand:XF 3 "register_operand" "1")]
13239                    UNSPEC_FPREM1_F))
13240    (set (match_operand:XF 1 "register_operand" "=u")
13241         (unspec:XF [(match_dup 2) (match_dup 3)]
13242                    UNSPEC_FPREM1_U))
13243    (set (reg:CCFP FPSR_REG)
13244         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13245                      UNSPEC_C2_FLAG))]
13246   "TARGET_USE_FANCY_MATH_387"
13247   "fprem1"
13248   [(set_attr "type" "fpspc")
13249    (set_attr "mode" "XF")])
13250
13251 (define_expand "remainderxf3"
13252   [(use (match_operand:XF 0 "register_operand" ""))
13253    (use (match_operand:XF 1 "general_operand" ""))
13254    (use (match_operand:XF 2 "general_operand" ""))]
13255   "TARGET_USE_FANCY_MATH_387"
13256 {
13257   rtx label = gen_label_rtx ();
13258
13259   rtx op1 = gen_reg_rtx (XFmode);
13260   rtx op2 = gen_reg_rtx (XFmode);
13261
13262   emit_move_insn (op2, operands[2]);
13263   emit_move_insn (op1, operands[1]);
13264
13265   emit_label (label);
13266   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13267   ix86_emit_fp_unordered_jump (label);
13268   LABEL_NUSES (label) = 1;
13269
13270   emit_move_insn (operands[0], op1);
13271   DONE;
13272 })
13273
13274 (define_expand "remainder<mode>3"
13275   [(use (match_operand:MODEF 0 "register_operand" ""))
13276    (use (match_operand:MODEF 1 "general_operand" ""))
13277    (use (match_operand:MODEF 2 "general_operand" ""))]
13278   "TARGET_USE_FANCY_MATH_387"
13279 {
13280   rtx (*gen_truncxf) (rtx, rtx);
13281
13282   rtx label = gen_label_rtx ();
13283
13284   rtx op1 = gen_reg_rtx (XFmode);
13285   rtx op2 = gen_reg_rtx (XFmode);
13286
13287   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13288   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13289
13290   emit_label (label);
13291
13292   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13293   ix86_emit_fp_unordered_jump (label);
13294   LABEL_NUSES (label) = 1;
13295
13296   /* Truncate the result properly for strict SSE math.  */
13297   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13298       && !TARGET_MIX_SSE_I387)
13299     gen_truncxf = gen_truncxf<mode>2;
13300   else
13301     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13302
13303   emit_insn (gen_truncxf (operands[0], op1));
13304   DONE;
13305 })
13306
13307 (define_insn "*sinxf2_i387"
13308   [(set (match_operand:XF 0 "register_operand" "=f")
13309         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13310   "TARGET_USE_FANCY_MATH_387
13311    && flag_unsafe_math_optimizations"
13312   "fsin"
13313   [(set_attr "type" "fpspc")
13314    (set_attr "mode" "XF")])
13315
13316 (define_insn "*sin_extend<mode>xf2_i387"
13317   [(set (match_operand:XF 0 "register_operand" "=f")
13318         (unspec:XF [(float_extend:XF
13319                       (match_operand:MODEF 1 "register_operand" "0"))]
13320                    UNSPEC_SIN))]
13321   "TARGET_USE_FANCY_MATH_387
13322    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13323        || TARGET_MIX_SSE_I387)
13324    && flag_unsafe_math_optimizations"
13325   "fsin"
13326   [(set_attr "type" "fpspc")
13327    (set_attr "mode" "XF")])
13328
13329 (define_insn "*cosxf2_i387"
13330   [(set (match_operand:XF 0 "register_operand" "=f")
13331         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13332   "TARGET_USE_FANCY_MATH_387
13333    && flag_unsafe_math_optimizations"
13334   "fcos"
13335   [(set_attr "type" "fpspc")
13336    (set_attr "mode" "XF")])
13337
13338 (define_insn "*cos_extend<mode>xf2_i387"
13339   [(set (match_operand:XF 0 "register_operand" "=f")
13340         (unspec:XF [(float_extend:XF
13341                       (match_operand:MODEF 1 "register_operand" "0"))]
13342                    UNSPEC_COS))]
13343   "TARGET_USE_FANCY_MATH_387
13344    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13345        || TARGET_MIX_SSE_I387)
13346    && flag_unsafe_math_optimizations"
13347   "fcos"
13348   [(set_attr "type" "fpspc")
13349    (set_attr "mode" "XF")])
13350
13351 ;; When sincos pattern is defined, sin and cos builtin functions will be
13352 ;; expanded to sincos pattern with one of its outputs left unused.
13353 ;; CSE pass will figure out if two sincos patterns can be combined,
13354 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13355 ;; depending on the unused output.
13356
13357 (define_insn "sincosxf3"
13358   [(set (match_operand:XF 0 "register_operand" "=f")
13359         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13360                    UNSPEC_SINCOS_COS))
13361    (set (match_operand:XF 1 "register_operand" "=u")
13362         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13363   "TARGET_USE_FANCY_MATH_387
13364    && flag_unsafe_math_optimizations"
13365   "fsincos"
13366   [(set_attr "type" "fpspc")
13367    (set_attr "mode" "XF")])
13368
13369 (define_split
13370   [(set (match_operand:XF 0 "register_operand" "")
13371         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13372                    UNSPEC_SINCOS_COS))
13373    (set (match_operand:XF 1 "register_operand" "")
13374         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13375   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13376    && can_create_pseudo_p ()"
13377   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13378
13379 (define_split
13380   [(set (match_operand:XF 0 "register_operand" "")
13381         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13382                    UNSPEC_SINCOS_COS))
13383    (set (match_operand:XF 1 "register_operand" "")
13384         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13385   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13386    && can_create_pseudo_p ()"
13387   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13388
13389 (define_insn "sincos_extend<mode>xf3_i387"
13390   [(set (match_operand:XF 0 "register_operand" "=f")
13391         (unspec:XF [(float_extend:XF
13392                       (match_operand:MODEF 2 "register_operand" "0"))]
13393                    UNSPEC_SINCOS_COS))
13394    (set (match_operand:XF 1 "register_operand" "=u")
13395         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13396   "TARGET_USE_FANCY_MATH_387
13397    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13398        || TARGET_MIX_SSE_I387)
13399    && flag_unsafe_math_optimizations"
13400   "fsincos"
13401   [(set_attr "type" "fpspc")
13402    (set_attr "mode" "XF")])
13403
13404 (define_split
13405   [(set (match_operand:XF 0 "register_operand" "")
13406         (unspec:XF [(float_extend:XF
13407                       (match_operand:MODEF 2 "register_operand" ""))]
13408                    UNSPEC_SINCOS_COS))
13409    (set (match_operand:XF 1 "register_operand" "")
13410         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13411   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13412    && can_create_pseudo_p ()"
13413   [(set (match_dup 1)
13414         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13415
13416 (define_split
13417   [(set (match_operand:XF 0 "register_operand" "")
13418         (unspec:XF [(float_extend:XF
13419                       (match_operand:MODEF 2 "register_operand" ""))]
13420                    UNSPEC_SINCOS_COS))
13421    (set (match_operand:XF 1 "register_operand" "")
13422         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13423   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13424    && can_create_pseudo_p ()"
13425   [(set (match_dup 0)
13426         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13427
13428 (define_expand "sincos<mode>3"
13429   [(use (match_operand:MODEF 0 "register_operand" ""))
13430    (use (match_operand:MODEF 1 "register_operand" ""))
13431    (use (match_operand:MODEF 2 "register_operand" ""))]
13432   "TARGET_USE_FANCY_MATH_387
13433    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13434        || TARGET_MIX_SSE_I387)
13435    && flag_unsafe_math_optimizations"
13436 {
13437   rtx op0 = gen_reg_rtx (XFmode);
13438   rtx op1 = gen_reg_rtx (XFmode);
13439
13440   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13441   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13442   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13443   DONE;
13444 })
13445
13446 (define_insn "fptanxf4_i387"
13447   [(set (match_operand:XF 0 "register_operand" "=f")
13448         (match_operand:XF 3 "const_double_operand" "F"))
13449    (set (match_operand:XF 1 "register_operand" "=u")
13450         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13451                    UNSPEC_TAN))]
13452   "TARGET_USE_FANCY_MATH_387
13453    && flag_unsafe_math_optimizations
13454    && standard_80387_constant_p (operands[3]) == 2"
13455   "fptan"
13456   [(set_attr "type" "fpspc")
13457    (set_attr "mode" "XF")])
13458
13459 (define_insn "fptan_extend<mode>xf4_i387"
13460   [(set (match_operand:MODEF 0 "register_operand" "=f")
13461         (match_operand:MODEF 3 "const_double_operand" "F"))
13462    (set (match_operand:XF 1 "register_operand" "=u")
13463         (unspec:XF [(float_extend:XF
13464                       (match_operand:MODEF 2 "register_operand" "0"))]
13465                    UNSPEC_TAN))]
13466   "TARGET_USE_FANCY_MATH_387
13467    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13468        || TARGET_MIX_SSE_I387)
13469    && flag_unsafe_math_optimizations
13470    && standard_80387_constant_p (operands[3]) == 2"
13471   "fptan"
13472   [(set_attr "type" "fpspc")
13473    (set_attr "mode" "XF")])
13474
13475 (define_expand "tanxf2"
13476   [(use (match_operand:XF 0 "register_operand" ""))
13477    (use (match_operand:XF 1 "register_operand" ""))]
13478   "TARGET_USE_FANCY_MATH_387
13479    && flag_unsafe_math_optimizations"
13480 {
13481   rtx one = gen_reg_rtx (XFmode);
13482   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13483
13484   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13485   DONE;
13486 })
13487
13488 (define_expand "tan<mode>2"
13489   [(use (match_operand:MODEF 0 "register_operand" ""))
13490    (use (match_operand:MODEF 1 "register_operand" ""))]
13491   "TARGET_USE_FANCY_MATH_387
13492    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13493        || TARGET_MIX_SSE_I387)
13494    && flag_unsafe_math_optimizations"
13495 {
13496   rtx op0 = gen_reg_rtx (XFmode);
13497
13498   rtx one = gen_reg_rtx (<MODE>mode);
13499   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13500
13501   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13502                                              operands[1], op2));
13503   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13504   DONE;
13505 })
13506
13507 (define_insn "*fpatanxf3_i387"
13508   [(set (match_operand:XF 0 "register_operand" "=f")
13509         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13510                     (match_operand:XF 2 "register_operand" "u")]
13511                    UNSPEC_FPATAN))
13512    (clobber (match_scratch:XF 3 "=2"))]
13513   "TARGET_USE_FANCY_MATH_387
13514    && flag_unsafe_math_optimizations"
13515   "fpatan"
13516   [(set_attr "type" "fpspc")
13517    (set_attr "mode" "XF")])
13518
13519 (define_insn "fpatan_extend<mode>xf3_i387"
13520   [(set (match_operand:XF 0 "register_operand" "=f")
13521         (unspec:XF [(float_extend:XF
13522                       (match_operand:MODEF 1 "register_operand" "0"))
13523                     (float_extend:XF
13524                       (match_operand:MODEF 2 "register_operand" "u"))]
13525                    UNSPEC_FPATAN))
13526    (clobber (match_scratch:XF 3 "=2"))]
13527   "TARGET_USE_FANCY_MATH_387
13528    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13529        || TARGET_MIX_SSE_I387)
13530    && flag_unsafe_math_optimizations"
13531   "fpatan"
13532   [(set_attr "type" "fpspc")
13533    (set_attr "mode" "XF")])
13534
13535 (define_expand "atan2xf3"
13536   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13537                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13538                                (match_operand:XF 1 "register_operand" "")]
13539                               UNSPEC_FPATAN))
13540               (clobber (match_scratch:XF 3 ""))])]
13541   "TARGET_USE_FANCY_MATH_387
13542    && flag_unsafe_math_optimizations")
13543
13544 (define_expand "atan2<mode>3"
13545   [(use (match_operand:MODEF 0 "register_operand" ""))
13546    (use (match_operand:MODEF 1 "register_operand" ""))
13547    (use (match_operand:MODEF 2 "register_operand" ""))]
13548   "TARGET_USE_FANCY_MATH_387
13549    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13550        || TARGET_MIX_SSE_I387)
13551    && flag_unsafe_math_optimizations"
13552 {
13553   rtx op0 = gen_reg_rtx (XFmode);
13554
13555   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13556   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13557   DONE;
13558 })
13559
13560 (define_expand "atanxf2"
13561   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13562                    (unspec:XF [(match_dup 2)
13563                                (match_operand:XF 1 "register_operand" "")]
13564                               UNSPEC_FPATAN))
13565               (clobber (match_scratch:XF 3 ""))])]
13566   "TARGET_USE_FANCY_MATH_387
13567    && flag_unsafe_math_optimizations"
13568 {
13569   operands[2] = gen_reg_rtx (XFmode);
13570   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13571 })
13572
13573 (define_expand "atan<mode>2"
13574   [(use (match_operand:MODEF 0 "register_operand" ""))
13575    (use (match_operand:MODEF 1 "register_operand" ""))]
13576   "TARGET_USE_FANCY_MATH_387
13577    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13578        || TARGET_MIX_SSE_I387)
13579    && flag_unsafe_math_optimizations"
13580 {
13581   rtx op0 = gen_reg_rtx (XFmode);
13582
13583   rtx op2 = gen_reg_rtx (<MODE>mode);
13584   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13585
13586   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13587   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13588   DONE;
13589 })
13590
13591 (define_expand "asinxf2"
13592   [(set (match_dup 2)
13593         (mult:XF (match_operand:XF 1 "register_operand" "")
13594                  (match_dup 1)))
13595    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13596    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13597    (parallel [(set (match_operand:XF 0 "register_operand" "")
13598                    (unspec:XF [(match_dup 5) (match_dup 1)]
13599                               UNSPEC_FPATAN))
13600               (clobber (match_scratch:XF 6 ""))])]
13601   "TARGET_USE_FANCY_MATH_387
13602    && flag_unsafe_math_optimizations"
13603 {
13604   int i;
13605
13606   if (optimize_insn_for_size_p ())
13607     FAIL;
13608
13609   for (i = 2; i < 6; i++)
13610     operands[i] = gen_reg_rtx (XFmode);
13611
13612   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13613 })
13614
13615 (define_expand "asin<mode>2"
13616   [(use (match_operand:MODEF 0 "register_operand" ""))
13617    (use (match_operand:MODEF 1 "general_operand" ""))]
13618  "TARGET_USE_FANCY_MATH_387
13619    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13620        || TARGET_MIX_SSE_I387)
13621    && flag_unsafe_math_optimizations"
13622 {
13623   rtx op0 = gen_reg_rtx (XFmode);
13624   rtx op1 = gen_reg_rtx (XFmode);
13625
13626   if (optimize_insn_for_size_p ())
13627     FAIL;
13628
13629   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13630   emit_insn (gen_asinxf2 (op0, op1));
13631   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13632   DONE;
13633 })
13634
13635 (define_expand "acosxf2"
13636   [(set (match_dup 2)
13637         (mult:XF (match_operand:XF 1 "register_operand" "")
13638                  (match_dup 1)))
13639    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13640    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13641    (parallel [(set (match_operand:XF 0 "register_operand" "")
13642                    (unspec:XF [(match_dup 1) (match_dup 5)]
13643                               UNSPEC_FPATAN))
13644               (clobber (match_scratch:XF 6 ""))])]
13645   "TARGET_USE_FANCY_MATH_387
13646    && flag_unsafe_math_optimizations"
13647 {
13648   int i;
13649
13650   if (optimize_insn_for_size_p ())
13651     FAIL;
13652
13653   for (i = 2; i < 6; i++)
13654     operands[i] = gen_reg_rtx (XFmode);
13655
13656   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13657 })
13658
13659 (define_expand "acos<mode>2"
13660   [(use (match_operand:MODEF 0 "register_operand" ""))
13661    (use (match_operand:MODEF 1 "general_operand" ""))]
13662  "TARGET_USE_FANCY_MATH_387
13663    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13664        || TARGET_MIX_SSE_I387)
13665    && flag_unsafe_math_optimizations"
13666 {
13667   rtx op0 = gen_reg_rtx (XFmode);
13668   rtx op1 = gen_reg_rtx (XFmode);
13669
13670   if (optimize_insn_for_size_p ())
13671     FAIL;
13672
13673   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13674   emit_insn (gen_acosxf2 (op0, op1));
13675   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13676   DONE;
13677 })
13678
13679 (define_insn "fyl2xxf3_i387"
13680   [(set (match_operand:XF 0 "register_operand" "=f")
13681         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13682                     (match_operand:XF 2 "register_operand" "u")]
13683                    UNSPEC_FYL2X))
13684    (clobber (match_scratch:XF 3 "=2"))]
13685   "TARGET_USE_FANCY_MATH_387
13686    && flag_unsafe_math_optimizations"
13687   "fyl2x"
13688   [(set_attr "type" "fpspc")
13689    (set_attr "mode" "XF")])
13690
13691 (define_insn "fyl2x_extend<mode>xf3_i387"
13692   [(set (match_operand:XF 0 "register_operand" "=f")
13693         (unspec:XF [(float_extend:XF
13694                       (match_operand:MODEF 1 "register_operand" "0"))
13695                     (match_operand:XF 2 "register_operand" "u")]
13696                    UNSPEC_FYL2X))
13697    (clobber (match_scratch:XF 3 "=2"))]
13698   "TARGET_USE_FANCY_MATH_387
13699    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13700        || TARGET_MIX_SSE_I387)
13701    && flag_unsafe_math_optimizations"
13702   "fyl2x"
13703   [(set_attr "type" "fpspc")
13704    (set_attr "mode" "XF")])
13705
13706 (define_expand "logxf2"
13707   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13708                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13709                                (match_dup 2)] UNSPEC_FYL2X))
13710               (clobber (match_scratch:XF 3 ""))])]
13711   "TARGET_USE_FANCY_MATH_387
13712    && flag_unsafe_math_optimizations"
13713 {
13714   operands[2] = gen_reg_rtx (XFmode);
13715   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13716 })
13717
13718 (define_expand "log<mode>2"
13719   [(use (match_operand:MODEF 0 "register_operand" ""))
13720    (use (match_operand:MODEF 1 "register_operand" ""))]
13721   "TARGET_USE_FANCY_MATH_387
13722    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13723        || TARGET_MIX_SSE_I387)
13724    && flag_unsafe_math_optimizations"
13725 {
13726   rtx op0 = gen_reg_rtx (XFmode);
13727
13728   rtx op2 = gen_reg_rtx (XFmode);
13729   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13730
13731   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13732   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13733   DONE;
13734 })
13735
13736 (define_expand "log10xf2"
13737   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13738                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13739                                (match_dup 2)] UNSPEC_FYL2X))
13740               (clobber (match_scratch:XF 3 ""))])]
13741   "TARGET_USE_FANCY_MATH_387
13742    && flag_unsafe_math_optimizations"
13743 {
13744   operands[2] = gen_reg_rtx (XFmode);
13745   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13746 })
13747
13748 (define_expand "log10<mode>2"
13749   [(use (match_operand:MODEF 0 "register_operand" ""))
13750    (use (match_operand:MODEF 1 "register_operand" ""))]
13751   "TARGET_USE_FANCY_MATH_387
13752    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13753        || TARGET_MIX_SSE_I387)
13754    && flag_unsafe_math_optimizations"
13755 {
13756   rtx op0 = gen_reg_rtx (XFmode);
13757
13758   rtx op2 = gen_reg_rtx (XFmode);
13759   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13760
13761   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13762   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13763   DONE;
13764 })
13765
13766 (define_expand "log2xf2"
13767   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13768                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13769                                (match_dup 2)] UNSPEC_FYL2X))
13770               (clobber (match_scratch:XF 3 ""))])]
13771   "TARGET_USE_FANCY_MATH_387
13772    && flag_unsafe_math_optimizations"
13773 {
13774   operands[2] = gen_reg_rtx (XFmode);
13775   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13776 })
13777
13778 (define_expand "log2<mode>2"
13779   [(use (match_operand:MODEF 0 "register_operand" ""))
13780    (use (match_operand:MODEF 1 "register_operand" ""))]
13781   "TARGET_USE_FANCY_MATH_387
13782    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13783        || TARGET_MIX_SSE_I387)
13784    && flag_unsafe_math_optimizations"
13785 {
13786   rtx op0 = gen_reg_rtx (XFmode);
13787
13788   rtx op2 = gen_reg_rtx (XFmode);
13789   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13790
13791   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13792   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13793   DONE;
13794 })
13795
13796 (define_insn "fyl2xp1xf3_i387"
13797   [(set (match_operand:XF 0 "register_operand" "=f")
13798         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13799                     (match_operand:XF 2 "register_operand" "u")]
13800                    UNSPEC_FYL2XP1))
13801    (clobber (match_scratch:XF 3 "=2"))]
13802   "TARGET_USE_FANCY_MATH_387
13803    && flag_unsafe_math_optimizations"
13804   "fyl2xp1"
13805   [(set_attr "type" "fpspc")
13806    (set_attr "mode" "XF")])
13807
13808 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13809   [(set (match_operand:XF 0 "register_operand" "=f")
13810         (unspec:XF [(float_extend:XF
13811                       (match_operand:MODEF 1 "register_operand" "0"))
13812                     (match_operand:XF 2 "register_operand" "u")]
13813                    UNSPEC_FYL2XP1))
13814    (clobber (match_scratch:XF 3 "=2"))]
13815   "TARGET_USE_FANCY_MATH_387
13816    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13817        || TARGET_MIX_SSE_I387)
13818    && flag_unsafe_math_optimizations"
13819   "fyl2xp1"
13820   [(set_attr "type" "fpspc")
13821    (set_attr "mode" "XF")])
13822
13823 (define_expand "log1pxf2"
13824   [(use (match_operand:XF 0 "register_operand" ""))
13825    (use (match_operand:XF 1 "register_operand" ""))]
13826   "TARGET_USE_FANCY_MATH_387
13827    && flag_unsafe_math_optimizations"
13828 {
13829   if (optimize_insn_for_size_p ())
13830     FAIL;
13831
13832   ix86_emit_i387_log1p (operands[0], operands[1]);
13833   DONE;
13834 })
13835
13836 (define_expand "log1p<mode>2"
13837   [(use (match_operand:MODEF 0 "register_operand" ""))
13838    (use (match_operand:MODEF 1 "register_operand" ""))]
13839   "TARGET_USE_FANCY_MATH_387
13840    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13841        || TARGET_MIX_SSE_I387)
13842    && flag_unsafe_math_optimizations"
13843 {
13844   rtx op0;
13845
13846   if (optimize_insn_for_size_p ())
13847     FAIL;
13848
13849   op0 = gen_reg_rtx (XFmode);
13850
13851   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13852
13853   ix86_emit_i387_log1p (op0, operands[1]);
13854   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13855   DONE;
13856 })
13857
13858 (define_insn "fxtractxf3_i387"
13859   [(set (match_operand:XF 0 "register_operand" "=f")
13860         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13861                    UNSPEC_XTRACT_FRACT))
13862    (set (match_operand:XF 1 "register_operand" "=u")
13863         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13864   "TARGET_USE_FANCY_MATH_387
13865    && flag_unsafe_math_optimizations"
13866   "fxtract"
13867   [(set_attr "type" "fpspc")
13868    (set_attr "mode" "XF")])
13869
13870 (define_insn "fxtract_extend<mode>xf3_i387"
13871   [(set (match_operand:XF 0 "register_operand" "=f")
13872         (unspec:XF [(float_extend:XF
13873                       (match_operand:MODEF 2 "register_operand" "0"))]
13874                    UNSPEC_XTRACT_FRACT))
13875    (set (match_operand:XF 1 "register_operand" "=u")
13876         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13877   "TARGET_USE_FANCY_MATH_387
13878    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13879        || TARGET_MIX_SSE_I387)
13880    && flag_unsafe_math_optimizations"
13881   "fxtract"
13882   [(set_attr "type" "fpspc")
13883    (set_attr "mode" "XF")])
13884
13885 (define_expand "logbxf2"
13886   [(parallel [(set (match_dup 2)
13887                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13888                               UNSPEC_XTRACT_FRACT))
13889               (set (match_operand:XF 0 "register_operand" "")
13890                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13891   "TARGET_USE_FANCY_MATH_387
13892    && flag_unsafe_math_optimizations"
13893   "operands[2] = gen_reg_rtx (XFmode);")
13894
13895 (define_expand "logb<mode>2"
13896   [(use (match_operand:MODEF 0 "register_operand" ""))
13897    (use (match_operand:MODEF 1 "register_operand" ""))]
13898   "TARGET_USE_FANCY_MATH_387
13899    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13900        || TARGET_MIX_SSE_I387)
13901    && flag_unsafe_math_optimizations"
13902 {
13903   rtx op0 = gen_reg_rtx (XFmode);
13904   rtx op1 = gen_reg_rtx (XFmode);
13905
13906   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13907   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13908   DONE;
13909 })
13910
13911 (define_expand "ilogbxf2"
13912   [(use (match_operand:SI 0 "register_operand" ""))
13913    (use (match_operand:XF 1 "register_operand" ""))]
13914   "TARGET_USE_FANCY_MATH_387
13915    && flag_unsafe_math_optimizations"
13916 {
13917   rtx op0, op1;
13918
13919   if (optimize_insn_for_size_p ())
13920     FAIL;
13921
13922   op0 = gen_reg_rtx (XFmode);
13923   op1 = gen_reg_rtx (XFmode);
13924
13925   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13926   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13927   DONE;
13928 })
13929
13930 (define_expand "ilogb<mode>2"
13931   [(use (match_operand:SI 0 "register_operand" ""))
13932    (use (match_operand:MODEF 1 "register_operand" ""))]
13933   "TARGET_USE_FANCY_MATH_387
13934    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13935        || TARGET_MIX_SSE_I387)
13936    && flag_unsafe_math_optimizations"
13937 {
13938   rtx op0, op1;
13939
13940   if (optimize_insn_for_size_p ())
13941     FAIL;
13942
13943   op0 = gen_reg_rtx (XFmode);
13944   op1 = gen_reg_rtx (XFmode);
13945
13946   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13947   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13948   DONE;
13949 })
13950
13951 (define_insn "*f2xm1xf2_i387"
13952   [(set (match_operand:XF 0 "register_operand" "=f")
13953         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13954                    UNSPEC_F2XM1))]
13955   "TARGET_USE_FANCY_MATH_387
13956    && flag_unsafe_math_optimizations"
13957   "f2xm1"
13958   [(set_attr "type" "fpspc")
13959    (set_attr "mode" "XF")])
13960
13961 (define_insn "*fscalexf4_i387"
13962   [(set (match_operand:XF 0 "register_operand" "=f")
13963         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13964                     (match_operand:XF 3 "register_operand" "1")]
13965                    UNSPEC_FSCALE_FRACT))
13966    (set (match_operand:XF 1 "register_operand" "=u")
13967         (unspec:XF [(match_dup 2) (match_dup 3)]
13968                    UNSPEC_FSCALE_EXP))]
13969   "TARGET_USE_FANCY_MATH_387
13970    && flag_unsafe_math_optimizations"
13971   "fscale"
13972   [(set_attr "type" "fpspc")
13973    (set_attr "mode" "XF")])
13974
13975 (define_expand "expNcorexf3"
13976   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13977                                (match_operand:XF 2 "register_operand" "")))
13978    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13979    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13980    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13981    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13982    (parallel [(set (match_operand:XF 0 "register_operand" "")
13983                    (unspec:XF [(match_dup 8) (match_dup 4)]
13984                               UNSPEC_FSCALE_FRACT))
13985               (set (match_dup 9)
13986                    (unspec:XF [(match_dup 8) (match_dup 4)]
13987                               UNSPEC_FSCALE_EXP))])]
13988   "TARGET_USE_FANCY_MATH_387
13989    && flag_unsafe_math_optimizations"
13990 {
13991   int i;
13992
13993   if (optimize_insn_for_size_p ())
13994     FAIL;
13995
13996   for (i = 3; i < 10; i++)
13997     operands[i] = gen_reg_rtx (XFmode);
13998
13999   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14000 })
14001
14002 (define_expand "expxf2"
14003   [(use (match_operand:XF 0 "register_operand" ""))
14004    (use (match_operand:XF 1 "register_operand" ""))]
14005   "TARGET_USE_FANCY_MATH_387
14006    && flag_unsafe_math_optimizations"
14007 {
14008   rtx op2;
14009
14010   if (optimize_insn_for_size_p ())
14011     FAIL;
14012
14013   op2 = gen_reg_rtx (XFmode);
14014   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14015
14016   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14017   DONE;
14018 })
14019
14020 (define_expand "exp<mode>2"
14021   [(use (match_operand:MODEF 0 "register_operand" ""))
14022    (use (match_operand:MODEF 1 "general_operand" ""))]
14023  "TARGET_USE_FANCY_MATH_387
14024    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14025        || TARGET_MIX_SSE_I387)
14026    && flag_unsafe_math_optimizations"
14027 {
14028   rtx op0, op1;
14029
14030   if (optimize_insn_for_size_p ())
14031     FAIL;
14032
14033   op0 = gen_reg_rtx (XFmode);
14034   op1 = gen_reg_rtx (XFmode);
14035
14036   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14037   emit_insn (gen_expxf2 (op0, op1));
14038   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14039   DONE;
14040 })
14041
14042 (define_expand "exp10xf2"
14043   [(use (match_operand:XF 0 "register_operand" ""))
14044    (use (match_operand:XF 1 "register_operand" ""))]
14045   "TARGET_USE_FANCY_MATH_387
14046    && flag_unsafe_math_optimizations"
14047 {
14048   rtx op2;
14049
14050   if (optimize_insn_for_size_p ())
14051     FAIL;
14052
14053   op2 = gen_reg_rtx (XFmode);
14054   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14055
14056   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14057   DONE;
14058 })
14059
14060 (define_expand "exp10<mode>2"
14061   [(use (match_operand:MODEF 0 "register_operand" ""))
14062    (use (match_operand:MODEF 1 "general_operand" ""))]
14063  "TARGET_USE_FANCY_MATH_387
14064    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14065        || TARGET_MIX_SSE_I387)
14066    && flag_unsafe_math_optimizations"
14067 {
14068   rtx op0, op1;
14069
14070   if (optimize_insn_for_size_p ())
14071     FAIL;
14072
14073   op0 = gen_reg_rtx (XFmode);
14074   op1 = gen_reg_rtx (XFmode);
14075
14076   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14077   emit_insn (gen_exp10xf2 (op0, op1));
14078   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14079   DONE;
14080 })
14081
14082 (define_expand "exp2xf2"
14083   [(use (match_operand:XF 0 "register_operand" ""))
14084    (use (match_operand:XF 1 "register_operand" ""))]
14085   "TARGET_USE_FANCY_MATH_387
14086    && flag_unsafe_math_optimizations"
14087 {
14088   rtx op2;
14089
14090   if (optimize_insn_for_size_p ())
14091     FAIL;
14092
14093   op2 = gen_reg_rtx (XFmode);
14094   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14095
14096   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14097   DONE;
14098 })
14099
14100 (define_expand "exp2<mode>2"
14101   [(use (match_operand:MODEF 0 "register_operand" ""))
14102    (use (match_operand:MODEF 1 "general_operand" ""))]
14103  "TARGET_USE_FANCY_MATH_387
14104    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14105        || TARGET_MIX_SSE_I387)
14106    && flag_unsafe_math_optimizations"
14107 {
14108   rtx op0, op1;
14109
14110   if (optimize_insn_for_size_p ())
14111     FAIL;
14112
14113   op0 = gen_reg_rtx (XFmode);
14114   op1 = gen_reg_rtx (XFmode);
14115
14116   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14117   emit_insn (gen_exp2xf2 (op0, op1));
14118   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14119   DONE;
14120 })
14121
14122 (define_expand "expm1xf2"
14123   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14124                                (match_dup 2)))
14125    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14126    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14127    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14128    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14129    (parallel [(set (match_dup 7)
14130                    (unspec:XF [(match_dup 6) (match_dup 4)]
14131                               UNSPEC_FSCALE_FRACT))
14132               (set (match_dup 8)
14133                    (unspec:XF [(match_dup 6) (match_dup 4)]
14134                               UNSPEC_FSCALE_EXP))])
14135    (parallel [(set (match_dup 10)
14136                    (unspec:XF [(match_dup 9) (match_dup 8)]
14137                               UNSPEC_FSCALE_FRACT))
14138               (set (match_dup 11)
14139                    (unspec:XF [(match_dup 9) (match_dup 8)]
14140                               UNSPEC_FSCALE_EXP))])
14141    (set (match_dup 12) (minus:XF (match_dup 10)
14142                                  (float_extend:XF (match_dup 13))))
14143    (set (match_operand:XF 0 "register_operand" "")
14144         (plus:XF (match_dup 12) (match_dup 7)))]
14145   "TARGET_USE_FANCY_MATH_387
14146    && flag_unsafe_math_optimizations"
14147 {
14148   int i;
14149
14150   if (optimize_insn_for_size_p ())
14151     FAIL;
14152
14153   for (i = 2; i < 13; i++)
14154     operands[i] = gen_reg_rtx (XFmode);
14155
14156   operands[13]
14157     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14158
14159   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14160 })
14161
14162 (define_expand "expm1<mode>2"
14163   [(use (match_operand:MODEF 0 "register_operand" ""))
14164    (use (match_operand:MODEF 1 "general_operand" ""))]
14165  "TARGET_USE_FANCY_MATH_387
14166    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14167        || TARGET_MIX_SSE_I387)
14168    && flag_unsafe_math_optimizations"
14169 {
14170   rtx op0, op1;
14171
14172   if (optimize_insn_for_size_p ())
14173     FAIL;
14174
14175   op0 = gen_reg_rtx (XFmode);
14176   op1 = gen_reg_rtx (XFmode);
14177
14178   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14179   emit_insn (gen_expm1xf2 (op0, op1));
14180   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14181   DONE;
14182 })
14183
14184 (define_expand "ldexpxf3"
14185   [(set (match_dup 3)
14186         (float:XF (match_operand:SI 2 "register_operand" "")))
14187    (parallel [(set (match_operand:XF 0 " register_operand" "")
14188                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14189                                (match_dup 3)]
14190                               UNSPEC_FSCALE_FRACT))
14191               (set (match_dup 4)
14192                    (unspec:XF [(match_dup 1) (match_dup 3)]
14193                               UNSPEC_FSCALE_EXP))])]
14194   "TARGET_USE_FANCY_MATH_387
14195    && flag_unsafe_math_optimizations"
14196 {
14197   if (optimize_insn_for_size_p ())
14198     FAIL;
14199
14200   operands[3] = gen_reg_rtx (XFmode);
14201   operands[4] = gen_reg_rtx (XFmode);
14202 })
14203
14204 (define_expand "ldexp<mode>3"
14205   [(use (match_operand:MODEF 0 "register_operand" ""))
14206    (use (match_operand:MODEF 1 "general_operand" ""))
14207    (use (match_operand:SI 2 "register_operand" ""))]
14208  "TARGET_USE_FANCY_MATH_387
14209    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14210        || TARGET_MIX_SSE_I387)
14211    && flag_unsafe_math_optimizations"
14212 {
14213   rtx op0, op1;
14214
14215   if (optimize_insn_for_size_p ())
14216     FAIL;
14217
14218   op0 = gen_reg_rtx (XFmode);
14219   op1 = gen_reg_rtx (XFmode);
14220
14221   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14222   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14223   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14224   DONE;
14225 })
14226
14227 (define_expand "scalbxf3"
14228   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14229                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14230                                (match_operand:XF 2 "register_operand" "")]
14231                               UNSPEC_FSCALE_FRACT))
14232               (set (match_dup 3)
14233                    (unspec:XF [(match_dup 1) (match_dup 2)]
14234                               UNSPEC_FSCALE_EXP))])]
14235   "TARGET_USE_FANCY_MATH_387
14236    && flag_unsafe_math_optimizations"
14237 {
14238   if (optimize_insn_for_size_p ())
14239     FAIL;
14240
14241   operands[3] = gen_reg_rtx (XFmode);
14242 })
14243
14244 (define_expand "scalb<mode>3"
14245   [(use (match_operand:MODEF 0 "register_operand" ""))
14246    (use (match_operand:MODEF 1 "general_operand" ""))
14247    (use (match_operand:MODEF 2 "general_operand" ""))]
14248  "TARGET_USE_FANCY_MATH_387
14249    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14250        || TARGET_MIX_SSE_I387)
14251    && flag_unsafe_math_optimizations"
14252 {
14253   rtx op0, op1, op2;
14254
14255   if (optimize_insn_for_size_p ())
14256     FAIL;
14257
14258   op0 = gen_reg_rtx (XFmode);
14259   op1 = gen_reg_rtx (XFmode);
14260   op2 = gen_reg_rtx (XFmode);
14261
14262   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14263   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14264   emit_insn (gen_scalbxf3 (op0, op1, op2));
14265   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14266   DONE;
14267 })
14268
14269 (define_expand "significandxf2"
14270   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14271                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14272                               UNSPEC_XTRACT_FRACT))
14273               (set (match_dup 2)
14274                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14275   "TARGET_USE_FANCY_MATH_387
14276    && flag_unsafe_math_optimizations"
14277   "operands[2] = gen_reg_rtx (XFmode);")
14278
14279 (define_expand "significand<mode>2"
14280   [(use (match_operand:MODEF 0 "register_operand" ""))
14281    (use (match_operand:MODEF 1 "register_operand" ""))]
14282   "TARGET_USE_FANCY_MATH_387
14283    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14284        || TARGET_MIX_SSE_I387)
14285    && flag_unsafe_math_optimizations"
14286 {
14287   rtx op0 = gen_reg_rtx (XFmode);
14288   rtx op1 = gen_reg_rtx (XFmode);
14289
14290   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14291   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14292   DONE;
14293 })
14294 \f
14295
14296 (define_insn "sse4_1_round<mode>2"
14297   [(set (match_operand:MODEF 0 "register_operand" "=x")
14298         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14299                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14300                       UNSPEC_ROUND))]
14301   "TARGET_ROUND"
14302   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14303   [(set_attr "type" "ssecvt")
14304    (set_attr "prefix_extra" "1")
14305    (set_attr "prefix" "maybe_vex")
14306    (set_attr "mode" "<MODE>")])
14307
14308 (define_insn "rintxf2"
14309   [(set (match_operand:XF 0 "register_operand" "=f")
14310         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14311                    UNSPEC_FRNDINT))]
14312   "TARGET_USE_FANCY_MATH_387
14313    && flag_unsafe_math_optimizations"
14314   "frndint"
14315   [(set_attr "type" "fpspc")
14316    (set_attr "mode" "XF")])
14317
14318 (define_expand "rint<mode>2"
14319   [(use (match_operand:MODEF 0 "register_operand" ""))
14320    (use (match_operand:MODEF 1 "register_operand" ""))]
14321   "(TARGET_USE_FANCY_MATH_387
14322     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14323         || TARGET_MIX_SSE_I387)
14324     && flag_unsafe_math_optimizations)
14325    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14326        && !flag_trapping_math)"
14327 {
14328   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14329       && !flag_trapping_math)
14330     {
14331       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14332         FAIL;
14333       if (TARGET_ROUND)
14334         emit_insn (gen_sse4_1_round<mode>2
14335                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14336       else
14337         ix86_expand_rint (operand0, operand1);
14338     }
14339   else
14340     {
14341       rtx op0 = gen_reg_rtx (XFmode);
14342       rtx op1 = gen_reg_rtx (XFmode);
14343
14344       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14345       emit_insn (gen_rintxf2 (op0, op1));
14346
14347       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14348     }
14349   DONE;
14350 })
14351
14352 (define_expand "round<mode>2"
14353   [(match_operand:MODEF 0 "register_operand" "")
14354    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14355   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14356    && !flag_trapping_math && !flag_rounding_math"
14357 {
14358   if (optimize_insn_for_size_p ())
14359     FAIL;
14360   if (TARGET_64BIT || (<MODE>mode != DFmode))
14361     ix86_expand_round (operand0, operand1);
14362   else
14363     ix86_expand_rounddf_32 (operand0, operand1);
14364   DONE;
14365 })
14366
14367 (define_insn_and_split "*fistdi2_1"
14368   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14369         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14370                    UNSPEC_FIST))]
14371   "TARGET_USE_FANCY_MATH_387
14372    && can_create_pseudo_p ()"
14373   "#"
14374   "&& 1"
14375   [(const_int 0)]
14376 {
14377   if (memory_operand (operands[0], VOIDmode))
14378     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14379   else
14380     {
14381       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14382       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14383                                          operands[2]));
14384     }
14385   DONE;
14386 }
14387   [(set_attr "type" "fpspc")
14388    (set_attr "mode" "DI")])
14389
14390 (define_insn "fistdi2"
14391   [(set (match_operand:DI 0 "memory_operand" "=m")
14392         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14393                    UNSPEC_FIST))
14394    (clobber (match_scratch:XF 2 "=&1f"))]
14395   "TARGET_USE_FANCY_MATH_387"
14396   "* return output_fix_trunc (insn, operands, false);"
14397   [(set_attr "type" "fpspc")
14398    (set_attr "mode" "DI")])
14399
14400 (define_insn "fistdi2_with_temp"
14401   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14402         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14403                    UNSPEC_FIST))
14404    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14405    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14406   "TARGET_USE_FANCY_MATH_387"
14407   "#"
14408   [(set_attr "type" "fpspc")
14409    (set_attr "mode" "DI")])
14410
14411 (define_split
14412   [(set (match_operand:DI 0 "register_operand" "")
14413         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14414                    UNSPEC_FIST))
14415    (clobber (match_operand:DI 2 "memory_operand" ""))
14416    (clobber (match_scratch 3 ""))]
14417   "reload_completed"
14418   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14419               (clobber (match_dup 3))])
14420    (set (match_dup 0) (match_dup 2))])
14421
14422 (define_split
14423   [(set (match_operand:DI 0 "memory_operand" "")
14424         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14425                    UNSPEC_FIST))
14426    (clobber (match_operand:DI 2 "memory_operand" ""))
14427    (clobber (match_scratch 3 ""))]
14428   "reload_completed"
14429   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14430               (clobber (match_dup 3))])])
14431
14432 (define_insn_and_split "*fist<mode>2_1"
14433   [(set (match_operand:SWI24 0 "register_operand" "")
14434         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14435                       UNSPEC_FIST))]
14436   "TARGET_USE_FANCY_MATH_387
14437    && can_create_pseudo_p ()"
14438   "#"
14439   "&& 1"
14440   [(const_int 0)]
14441 {
14442   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14443   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14444                                         operands[2]));
14445   DONE;
14446 }
14447   [(set_attr "type" "fpspc")
14448    (set_attr "mode" "<MODE>")])
14449
14450 (define_insn "fist<mode>2"
14451   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14452         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14453                       UNSPEC_FIST))]
14454   "TARGET_USE_FANCY_MATH_387"
14455   "* return output_fix_trunc (insn, operands, false);"
14456   [(set_attr "type" "fpspc")
14457    (set_attr "mode" "<MODE>")])
14458
14459 (define_insn "fist<mode>2_with_temp"
14460   [(set (match_operand:SWI24 0 "register_operand" "=r")
14461         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14462                       UNSPEC_FIST))
14463    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14464   "TARGET_USE_FANCY_MATH_387"
14465   "#"
14466   [(set_attr "type" "fpspc")
14467    (set_attr "mode" "<MODE>")])
14468
14469 (define_split
14470   [(set (match_operand:SWI24 0 "register_operand" "")
14471         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14472                       UNSPEC_FIST))
14473    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14474   "reload_completed"
14475   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14476    (set (match_dup 0) (match_dup 2))])
14477
14478 (define_split
14479   [(set (match_operand:SWI24 0 "memory_operand" "")
14480         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14481                       UNSPEC_FIST))
14482    (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14483   "reload_completed"
14484   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14485
14486 (define_expand "lrintxf<mode>2"
14487   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14488      (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14489                      UNSPEC_FIST))]
14490   "TARGET_USE_FANCY_MATH_387")
14491
14492 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14493   [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14494      (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14495                         UNSPEC_FIX_NOTRUNC))]
14496   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14497    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14498
14499 (define_expand "lround<MODEF:mode><SWI48x:mode>2"
14500   [(match_operand:SWI48x 0 "nonimmediate_operand" "")
14501    (match_operand:MODEF 1 "register_operand" "")]
14502   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14503    && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)
14504    && !flag_trapping_math && !flag_rounding_math"
14505 {
14506   if (optimize_insn_for_size_p ())
14507     FAIL;
14508   ix86_expand_lround (operand0, operand1);
14509   DONE;
14510 })
14511
14512 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14513 (define_insn_and_split "frndintxf2_floor"
14514   [(set (match_operand:XF 0 "register_operand" "")
14515         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14516          UNSPEC_FRNDINT_FLOOR))
14517    (clobber (reg:CC FLAGS_REG))]
14518   "TARGET_USE_FANCY_MATH_387
14519    && flag_unsafe_math_optimizations
14520    && can_create_pseudo_p ()"
14521   "#"
14522   "&& 1"
14523   [(const_int 0)]
14524 {
14525   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14526
14527   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14528   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14529
14530   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14531                                         operands[2], operands[3]));
14532   DONE;
14533 }
14534   [(set_attr "type" "frndint")
14535    (set_attr "i387_cw" "floor")
14536    (set_attr "mode" "XF")])
14537
14538 (define_insn "frndintxf2_floor_i387"
14539   [(set (match_operand:XF 0 "register_operand" "=f")
14540         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14541          UNSPEC_FRNDINT_FLOOR))
14542    (use (match_operand:HI 2 "memory_operand" "m"))
14543    (use (match_operand:HI 3 "memory_operand" "m"))]
14544   "TARGET_USE_FANCY_MATH_387
14545    && flag_unsafe_math_optimizations"
14546   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14547   [(set_attr "type" "frndint")
14548    (set_attr "i387_cw" "floor")
14549    (set_attr "mode" "XF")])
14550
14551 (define_expand "floorxf2"
14552   [(use (match_operand:XF 0 "register_operand" ""))
14553    (use (match_operand:XF 1 "register_operand" ""))]
14554   "TARGET_USE_FANCY_MATH_387
14555    && flag_unsafe_math_optimizations"
14556 {
14557   if (optimize_insn_for_size_p ())
14558     FAIL;
14559   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14560   DONE;
14561 })
14562
14563 (define_expand "floor<mode>2"
14564   [(use (match_operand:MODEF 0 "register_operand" ""))
14565    (use (match_operand:MODEF 1 "register_operand" ""))]
14566   "(TARGET_USE_FANCY_MATH_387
14567     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14568         || TARGET_MIX_SSE_I387)
14569     && flag_unsafe_math_optimizations)
14570    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14571        && !flag_trapping_math)"
14572 {
14573   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14574       && !flag_trapping_math
14575       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14576     {
14577       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14578         FAIL;
14579       if (TARGET_ROUND)
14580         emit_insn (gen_sse4_1_round<mode>2
14581                    (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14582       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14583         ix86_expand_floorceil (operand0, operand1, true);
14584       else
14585         ix86_expand_floorceildf_32 (operand0, operand1, true);
14586     }
14587   else
14588     {
14589       rtx op0, op1;
14590
14591       if (optimize_insn_for_size_p ())
14592         FAIL;
14593
14594       op0 = gen_reg_rtx (XFmode);
14595       op1 = gen_reg_rtx (XFmode);
14596       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14597       emit_insn (gen_frndintxf2_floor (op0, op1));
14598
14599       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14600     }
14601   DONE;
14602 })
14603
14604 (define_insn_and_split "*fist<mode>2_floor_1"
14605   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14606         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14607                         UNSPEC_FIST_FLOOR))
14608    (clobber (reg:CC FLAGS_REG))]
14609   "TARGET_USE_FANCY_MATH_387
14610    && flag_unsafe_math_optimizations
14611    && can_create_pseudo_p ()"
14612   "#"
14613   "&& 1"
14614   [(const_int 0)]
14615 {
14616   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14617
14618   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14619   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14620   if (memory_operand (operands[0], VOIDmode))
14621     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14622                                       operands[2], operands[3]));
14623   else
14624     {
14625       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14626       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14627                                                   operands[2], operands[3],
14628                                                   operands[4]));
14629     }
14630   DONE;
14631 }
14632   [(set_attr "type" "fistp")
14633    (set_attr "i387_cw" "floor")
14634    (set_attr "mode" "<MODE>")])
14635
14636 (define_insn "fistdi2_floor"
14637   [(set (match_operand:DI 0 "memory_operand" "=m")
14638         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14639                    UNSPEC_FIST_FLOOR))
14640    (use (match_operand:HI 2 "memory_operand" "m"))
14641    (use (match_operand:HI 3 "memory_operand" "m"))
14642    (clobber (match_scratch:XF 4 "=&1f"))]
14643   "TARGET_USE_FANCY_MATH_387
14644    && flag_unsafe_math_optimizations"
14645   "* return output_fix_trunc (insn, operands, false);"
14646   [(set_attr "type" "fistp")
14647    (set_attr "i387_cw" "floor")
14648    (set_attr "mode" "DI")])
14649
14650 (define_insn "fistdi2_floor_with_temp"
14651   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14652         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14653                    UNSPEC_FIST_FLOOR))
14654    (use (match_operand:HI 2 "memory_operand" "m,m"))
14655    (use (match_operand:HI 3 "memory_operand" "m,m"))
14656    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14657    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14658   "TARGET_USE_FANCY_MATH_387
14659    && flag_unsafe_math_optimizations"
14660   "#"
14661   [(set_attr "type" "fistp")
14662    (set_attr "i387_cw" "floor")
14663    (set_attr "mode" "DI")])
14664
14665 (define_split
14666   [(set (match_operand:DI 0 "register_operand" "")
14667         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14668                    UNSPEC_FIST_FLOOR))
14669    (use (match_operand:HI 2 "memory_operand" ""))
14670    (use (match_operand:HI 3 "memory_operand" ""))
14671    (clobber (match_operand:DI 4 "memory_operand" ""))
14672    (clobber (match_scratch 5 ""))]
14673   "reload_completed"
14674   [(parallel [(set (match_dup 4)
14675                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14676               (use (match_dup 2))
14677               (use (match_dup 3))
14678               (clobber (match_dup 5))])
14679    (set (match_dup 0) (match_dup 4))])
14680
14681 (define_split
14682   [(set (match_operand:DI 0 "memory_operand" "")
14683         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14684                    UNSPEC_FIST_FLOOR))
14685    (use (match_operand:HI 2 "memory_operand" ""))
14686    (use (match_operand:HI 3 "memory_operand" ""))
14687    (clobber (match_operand:DI 4 "memory_operand" ""))
14688    (clobber (match_scratch 5 ""))]
14689   "reload_completed"
14690   [(parallel [(set (match_dup 0)
14691                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14692               (use (match_dup 2))
14693               (use (match_dup 3))
14694               (clobber (match_dup 5))])])
14695
14696 (define_insn "fist<mode>2_floor"
14697   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14698         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14699                       UNSPEC_FIST_FLOOR))
14700    (use (match_operand:HI 2 "memory_operand" "m"))
14701    (use (match_operand:HI 3 "memory_operand" "m"))]
14702   "TARGET_USE_FANCY_MATH_387
14703    && flag_unsafe_math_optimizations"
14704   "* return output_fix_trunc (insn, operands, false);"
14705   [(set_attr "type" "fistp")
14706    (set_attr "i387_cw" "floor")
14707    (set_attr "mode" "<MODE>")])
14708
14709 (define_insn "fist<mode>2_floor_with_temp"
14710   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14711         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14712                       UNSPEC_FIST_FLOOR))
14713    (use (match_operand:HI 2 "memory_operand" "m,m"))
14714    (use (match_operand:HI 3 "memory_operand" "m,m"))
14715    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14716   "TARGET_USE_FANCY_MATH_387
14717    && flag_unsafe_math_optimizations"
14718   "#"
14719   [(set_attr "type" "fistp")
14720    (set_attr "i387_cw" "floor")
14721    (set_attr "mode" "<MODE>")])
14722
14723 (define_split
14724   [(set (match_operand:SWI24 0 "register_operand" "")
14725         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14726                       UNSPEC_FIST_FLOOR))
14727    (use (match_operand:HI 2 "memory_operand" ""))
14728    (use (match_operand:HI 3 "memory_operand" ""))
14729    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14730   "reload_completed"
14731   [(parallel [(set (match_dup 4)
14732                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14733               (use (match_dup 2))
14734               (use (match_dup 3))])
14735    (set (match_dup 0) (match_dup 4))])
14736
14737 (define_split
14738   [(set (match_operand:SWI24 0 "memory_operand" "")
14739         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14740                       UNSPEC_FIST_FLOOR))
14741    (use (match_operand:HI 2 "memory_operand" ""))
14742    (use (match_operand:HI 3 "memory_operand" ""))
14743    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14744   "reload_completed"
14745   [(parallel [(set (match_dup 0)
14746                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
14747               (use (match_dup 2))
14748               (use (match_dup 3))])])
14749
14750 (define_expand "lfloorxf<mode>2"
14751   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14752                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14753                                    UNSPEC_FIST_FLOOR))
14754               (clobber (reg:CC FLAGS_REG))])]
14755   "TARGET_USE_FANCY_MATH_387
14756    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14757    && flag_unsafe_math_optimizations")
14758
14759 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14760   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14761    (match_operand:MODEF 1 "register_operand" "")]
14762   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14763    && !flag_trapping_math"
14764 {
14765   if (TARGET_64BIT && optimize_insn_for_size_p ())
14766     FAIL;
14767   ix86_expand_lfloorceil (operand0, operand1, true);
14768   DONE;
14769 })
14770
14771 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14772 (define_insn_and_split "frndintxf2_ceil"
14773   [(set (match_operand:XF 0 "register_operand" "")
14774         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14775          UNSPEC_FRNDINT_CEIL))
14776    (clobber (reg:CC FLAGS_REG))]
14777   "TARGET_USE_FANCY_MATH_387
14778    && flag_unsafe_math_optimizations
14779    && can_create_pseudo_p ()"
14780   "#"
14781   "&& 1"
14782   [(const_int 0)]
14783 {
14784   ix86_optimize_mode_switching[I387_CEIL] = 1;
14785
14786   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14787   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14788
14789   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14790                                        operands[2], operands[3]));
14791   DONE;
14792 }
14793   [(set_attr "type" "frndint")
14794    (set_attr "i387_cw" "ceil")
14795    (set_attr "mode" "XF")])
14796
14797 (define_insn "frndintxf2_ceil_i387"
14798   [(set (match_operand:XF 0 "register_operand" "=f")
14799         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14800          UNSPEC_FRNDINT_CEIL))
14801    (use (match_operand:HI 2 "memory_operand" "m"))
14802    (use (match_operand:HI 3 "memory_operand" "m"))]
14803   "TARGET_USE_FANCY_MATH_387
14804    && flag_unsafe_math_optimizations"
14805   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14806   [(set_attr "type" "frndint")
14807    (set_attr "i387_cw" "ceil")
14808    (set_attr "mode" "XF")])
14809
14810 (define_expand "ceilxf2"
14811   [(use (match_operand:XF 0 "register_operand" ""))
14812    (use (match_operand:XF 1 "register_operand" ""))]
14813   "TARGET_USE_FANCY_MATH_387
14814    && flag_unsafe_math_optimizations"
14815 {
14816   if (optimize_insn_for_size_p ())
14817     FAIL;
14818   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14819   DONE;
14820 })
14821
14822 (define_expand "ceil<mode>2"
14823   [(use (match_operand:MODEF 0 "register_operand" ""))
14824    (use (match_operand:MODEF 1 "register_operand" ""))]
14825   "(TARGET_USE_FANCY_MATH_387
14826     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14827         || TARGET_MIX_SSE_I387)
14828     && flag_unsafe_math_optimizations)
14829    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14830        && !flag_trapping_math)"
14831 {
14832   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14833       && !flag_trapping_math
14834       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14835     {
14836       if (TARGET_ROUND)
14837         emit_insn (gen_sse4_1_round<mode>2
14838                    (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
14839       else if (optimize_insn_for_size_p ())
14840         FAIL;
14841       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14842         ix86_expand_floorceil (operand0, operand1, false);
14843       else
14844         ix86_expand_floorceildf_32 (operand0, operand1, false);
14845     }
14846   else
14847     {
14848       rtx op0, op1;
14849
14850       if (optimize_insn_for_size_p ())
14851         FAIL;
14852
14853       op0 = gen_reg_rtx (XFmode);
14854       op1 = gen_reg_rtx (XFmode);
14855       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14856       emit_insn (gen_frndintxf2_ceil (op0, op1));
14857
14858       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14859     }
14860   DONE;
14861 })
14862
14863 (define_insn_and_split "*fist<mode>2_ceil_1"
14864   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14865         (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14866                         UNSPEC_FIST_CEIL))
14867    (clobber (reg:CC FLAGS_REG))]
14868   "TARGET_USE_FANCY_MATH_387
14869    && flag_unsafe_math_optimizations
14870    && can_create_pseudo_p ()"
14871   "#"
14872   "&& 1"
14873   [(const_int 0)]
14874 {
14875   ix86_optimize_mode_switching[I387_CEIL] = 1;
14876
14877   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14878   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14879   if (memory_operand (operands[0], VOIDmode))
14880     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14881                                      operands[2], operands[3]));
14882   else
14883     {
14884       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14885       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14886                                                  operands[2], operands[3],
14887                                                  operands[4]));
14888     }
14889   DONE;
14890 }
14891   [(set_attr "type" "fistp")
14892    (set_attr "i387_cw" "ceil")
14893    (set_attr "mode" "<MODE>")])
14894
14895 (define_insn "fistdi2_ceil"
14896   [(set (match_operand:DI 0 "memory_operand" "=m")
14897         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14898                    UNSPEC_FIST_CEIL))
14899    (use (match_operand:HI 2 "memory_operand" "m"))
14900    (use (match_operand:HI 3 "memory_operand" "m"))
14901    (clobber (match_scratch:XF 4 "=&1f"))]
14902   "TARGET_USE_FANCY_MATH_387
14903    && flag_unsafe_math_optimizations"
14904   "* return output_fix_trunc (insn, operands, false);"
14905   [(set_attr "type" "fistp")
14906    (set_attr "i387_cw" "ceil")
14907    (set_attr "mode" "DI")])
14908
14909 (define_insn "fistdi2_ceil_with_temp"
14910   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14911         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14912                    UNSPEC_FIST_CEIL))
14913    (use (match_operand:HI 2 "memory_operand" "m,m"))
14914    (use (match_operand:HI 3 "memory_operand" "m,m"))
14915    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14916    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14917   "TARGET_USE_FANCY_MATH_387
14918    && flag_unsafe_math_optimizations"
14919   "#"
14920   [(set_attr "type" "fistp")
14921    (set_attr "i387_cw" "ceil")
14922    (set_attr "mode" "DI")])
14923
14924 (define_split
14925   [(set (match_operand:DI 0 "register_operand" "")
14926         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14927                    UNSPEC_FIST_CEIL))
14928    (use (match_operand:HI 2 "memory_operand" ""))
14929    (use (match_operand:HI 3 "memory_operand" ""))
14930    (clobber (match_operand:DI 4 "memory_operand" ""))
14931    (clobber (match_scratch 5 ""))]
14932   "reload_completed"
14933   [(parallel [(set (match_dup 4)
14934                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14935               (use (match_dup 2))
14936               (use (match_dup 3))
14937               (clobber (match_dup 5))])
14938    (set (match_dup 0) (match_dup 4))])
14939
14940 (define_split
14941   [(set (match_operand:DI 0 "memory_operand" "")
14942         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14943                    UNSPEC_FIST_CEIL))
14944    (use (match_operand:HI 2 "memory_operand" ""))
14945    (use (match_operand:HI 3 "memory_operand" ""))
14946    (clobber (match_operand:DI 4 "memory_operand" ""))
14947    (clobber (match_scratch 5 ""))]
14948   "reload_completed"
14949   [(parallel [(set (match_dup 0)
14950                    (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14951               (use (match_dup 2))
14952               (use (match_dup 3))
14953               (clobber (match_dup 5))])])
14954
14955 (define_insn "fist<mode>2_ceil"
14956   [(set (match_operand:SWI24 0 "memory_operand" "=m")
14957         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14958                       UNSPEC_FIST_CEIL))
14959    (use (match_operand:HI 2 "memory_operand" "m"))
14960    (use (match_operand:HI 3 "memory_operand" "m"))]
14961   "TARGET_USE_FANCY_MATH_387
14962    && flag_unsafe_math_optimizations"
14963   "* return output_fix_trunc (insn, operands, false);"
14964   [(set_attr "type" "fistp")
14965    (set_attr "i387_cw" "ceil")
14966    (set_attr "mode" "<MODE>")])
14967
14968 (define_insn "fist<mode>2_ceil_with_temp"
14969   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14970         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14971                       UNSPEC_FIST_CEIL))
14972    (use (match_operand:HI 2 "memory_operand" "m,m"))
14973    (use (match_operand:HI 3 "memory_operand" "m,m"))
14974    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14975   "TARGET_USE_FANCY_MATH_387
14976    && flag_unsafe_math_optimizations"
14977   "#"
14978   [(set_attr "type" "fistp")
14979    (set_attr "i387_cw" "ceil")
14980    (set_attr "mode" "<MODE>")])
14981
14982 (define_split
14983   [(set (match_operand:SWI24 0 "register_operand" "")
14984         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14985                       UNSPEC_FIST_CEIL))
14986    (use (match_operand:HI 2 "memory_operand" ""))
14987    (use (match_operand:HI 3 "memory_operand" ""))
14988    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
14989   "reload_completed"
14990   [(parallel [(set (match_dup 4)
14991                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
14992               (use (match_dup 2))
14993               (use (match_dup 3))])
14994    (set (match_dup 0) (match_dup 4))])
14995
14996 (define_split
14997   [(set (match_operand:SWI24 0 "memory_operand" "")
14998         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14999                       UNSPEC_FIST_CEIL))
15000    (use (match_operand:HI 2 "memory_operand" ""))
15001    (use (match_operand:HI 3 "memory_operand" ""))
15002    (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15003   "reload_completed"
15004   [(parallel [(set (match_dup 0)
15005                    (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15006               (use (match_dup 2))
15007               (use (match_dup 3))])])
15008
15009 (define_expand "lceilxf<mode>2"
15010   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15011                    (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15012                                    UNSPEC_FIST_CEIL))
15013               (clobber (reg:CC FLAGS_REG))])]
15014   "TARGET_USE_FANCY_MATH_387
15015    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15016    && flag_unsafe_math_optimizations")
15017
15018 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15019   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15020    (match_operand:MODEF 1 "register_operand" "")]
15021   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15022    && !flag_trapping_math"
15023 {
15024   ix86_expand_lfloorceil (operand0, operand1, false);
15025   DONE;
15026 })
15027
15028 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15029 (define_insn_and_split "frndintxf2_trunc"
15030   [(set (match_operand:XF 0 "register_operand" "")
15031         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15032          UNSPEC_FRNDINT_TRUNC))
15033    (clobber (reg:CC FLAGS_REG))]
15034   "TARGET_USE_FANCY_MATH_387
15035    && flag_unsafe_math_optimizations
15036    && can_create_pseudo_p ()"
15037   "#"
15038   "&& 1"
15039   [(const_int 0)]
15040 {
15041   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15042
15043   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15044   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15045
15046   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15047                                         operands[2], operands[3]));
15048   DONE;
15049 }
15050   [(set_attr "type" "frndint")
15051    (set_attr "i387_cw" "trunc")
15052    (set_attr "mode" "XF")])
15053
15054 (define_insn "frndintxf2_trunc_i387"
15055   [(set (match_operand:XF 0 "register_operand" "=f")
15056         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15057          UNSPEC_FRNDINT_TRUNC))
15058    (use (match_operand:HI 2 "memory_operand" "m"))
15059    (use (match_operand:HI 3 "memory_operand" "m"))]
15060   "TARGET_USE_FANCY_MATH_387
15061    && flag_unsafe_math_optimizations"
15062   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15063   [(set_attr "type" "frndint")
15064    (set_attr "i387_cw" "trunc")
15065    (set_attr "mode" "XF")])
15066
15067 (define_expand "btruncxf2"
15068   [(use (match_operand:XF 0 "register_operand" ""))
15069    (use (match_operand:XF 1 "register_operand" ""))]
15070   "TARGET_USE_FANCY_MATH_387
15071    && flag_unsafe_math_optimizations"
15072 {
15073   if (optimize_insn_for_size_p ())
15074     FAIL;
15075   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15076   DONE;
15077 })
15078
15079 (define_expand "btrunc<mode>2"
15080   [(use (match_operand:MODEF 0 "register_operand" ""))
15081    (use (match_operand:MODEF 1 "register_operand" ""))]
15082   "(TARGET_USE_FANCY_MATH_387
15083     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15084         || TARGET_MIX_SSE_I387)
15085     && flag_unsafe_math_optimizations)
15086    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15087        && !flag_trapping_math)"
15088 {
15089   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15090       && !flag_trapping_math
15091       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15092     {
15093       if (TARGET_ROUND)
15094         emit_insn (gen_sse4_1_round<mode>2
15095                    (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15096       else if (optimize_insn_for_size_p ())
15097         FAIL;
15098       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15099         ix86_expand_trunc (operand0, operand1);
15100       else
15101         ix86_expand_truncdf_32 (operand0, operand1);
15102     }
15103   else
15104     {
15105       rtx op0, op1;
15106
15107       if (optimize_insn_for_size_p ())
15108         FAIL;
15109
15110       op0 = gen_reg_rtx (XFmode);
15111       op1 = gen_reg_rtx (XFmode);
15112       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15113       emit_insn (gen_frndintxf2_trunc (op0, op1));
15114
15115       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15116     }
15117   DONE;
15118 })
15119
15120 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15121 (define_insn_and_split "frndintxf2_mask_pm"
15122   [(set (match_operand:XF 0 "register_operand" "")
15123         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15124          UNSPEC_FRNDINT_MASK_PM))
15125    (clobber (reg:CC FLAGS_REG))]
15126   "TARGET_USE_FANCY_MATH_387
15127    && flag_unsafe_math_optimizations
15128    && can_create_pseudo_p ()"
15129   "#"
15130   "&& 1"
15131   [(const_int 0)]
15132 {
15133   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15134
15135   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15136   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15137
15138   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15139                                           operands[2], operands[3]));
15140   DONE;
15141 }
15142   [(set_attr "type" "frndint")
15143    (set_attr "i387_cw" "mask_pm")
15144    (set_attr "mode" "XF")])
15145
15146 (define_insn "frndintxf2_mask_pm_i387"
15147   [(set (match_operand:XF 0 "register_operand" "=f")
15148         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15149          UNSPEC_FRNDINT_MASK_PM))
15150    (use (match_operand:HI 2 "memory_operand" "m"))
15151    (use (match_operand:HI 3 "memory_operand" "m"))]
15152   "TARGET_USE_FANCY_MATH_387
15153    && flag_unsafe_math_optimizations"
15154   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15155   [(set_attr "type" "frndint")
15156    (set_attr "i387_cw" "mask_pm")
15157    (set_attr "mode" "XF")])
15158
15159 (define_expand "nearbyintxf2"
15160   [(use (match_operand:XF 0 "register_operand" ""))
15161    (use (match_operand:XF 1 "register_operand" ""))]
15162   "TARGET_USE_FANCY_MATH_387
15163    && flag_unsafe_math_optimizations"
15164 {
15165   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15166   DONE;
15167 })
15168
15169 (define_expand "nearbyint<mode>2"
15170   [(use (match_operand:MODEF 0 "register_operand" ""))
15171    (use (match_operand:MODEF 1 "register_operand" ""))]
15172   "TARGET_USE_FANCY_MATH_387
15173    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15174        || TARGET_MIX_SSE_I387)
15175    && flag_unsafe_math_optimizations"
15176 {
15177   rtx op0 = gen_reg_rtx (XFmode);
15178   rtx op1 = gen_reg_rtx (XFmode);
15179
15180   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15181   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15182
15183   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15184   DONE;
15185 })
15186
15187 (define_insn "fxam<mode>2_i387"
15188   [(set (match_operand:HI 0 "register_operand" "=a")
15189         (unspec:HI
15190           [(match_operand:X87MODEF 1 "register_operand" "f")]
15191           UNSPEC_FXAM))]
15192   "TARGET_USE_FANCY_MATH_387"
15193   "fxam\n\tfnstsw\t%0"
15194   [(set_attr "type" "multi")
15195    (set_attr "length" "4")
15196    (set_attr "unit" "i387")
15197    (set_attr "mode" "<MODE>")])
15198
15199 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15200   [(set (match_operand:HI 0 "register_operand" "")
15201         (unspec:HI
15202           [(match_operand:MODEF 1 "memory_operand" "")]
15203           UNSPEC_FXAM_MEM))]
15204   "TARGET_USE_FANCY_MATH_387
15205    && can_create_pseudo_p ()"
15206   "#"
15207   "&& 1"
15208   [(set (match_dup 2)(match_dup 1))
15209    (set (match_dup 0)
15210         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15211 {
15212   operands[2] = gen_reg_rtx (<MODE>mode);
15213
15214   MEM_VOLATILE_P (operands[1]) = 1;
15215 }
15216   [(set_attr "type" "multi")
15217    (set_attr "unit" "i387")
15218    (set_attr "mode" "<MODE>")])
15219
15220 (define_expand "isinfxf2"
15221   [(use (match_operand:SI 0 "register_operand" ""))
15222    (use (match_operand:XF 1 "register_operand" ""))]
15223   "TARGET_USE_FANCY_MATH_387
15224    && TARGET_C99_FUNCTIONS"
15225 {
15226   rtx mask = GEN_INT (0x45);
15227   rtx val = GEN_INT (0x05);
15228
15229   rtx cond;
15230
15231   rtx scratch = gen_reg_rtx (HImode);
15232   rtx res = gen_reg_rtx (QImode);
15233
15234   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15235
15236   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15237   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15238   cond = gen_rtx_fmt_ee (EQ, QImode,
15239                          gen_rtx_REG (CCmode, FLAGS_REG),
15240                          const0_rtx);
15241   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15242   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15243   DONE;
15244 })
15245
15246 (define_expand "isinf<mode>2"
15247   [(use (match_operand:SI 0 "register_operand" ""))
15248    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15249   "TARGET_USE_FANCY_MATH_387
15250    && TARGET_C99_FUNCTIONS
15251    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15252 {
15253   rtx mask = GEN_INT (0x45);
15254   rtx val = GEN_INT (0x05);
15255
15256   rtx cond;
15257
15258   rtx scratch = gen_reg_rtx (HImode);
15259   rtx res = gen_reg_rtx (QImode);
15260
15261   /* Remove excess precision by forcing value through memory. */
15262   if (memory_operand (operands[1], VOIDmode))
15263     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15264   else
15265     {
15266       enum ix86_stack_slot slot = (virtuals_instantiated
15267                                    ? SLOT_TEMP
15268                                    : SLOT_VIRTUAL);
15269       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15270
15271       emit_move_insn (temp, operands[1]);
15272       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15273     }
15274
15275   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15276   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15277   cond = gen_rtx_fmt_ee (EQ, QImode,
15278                          gen_rtx_REG (CCmode, FLAGS_REG),
15279                          const0_rtx);
15280   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15281   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15282   DONE;
15283 })
15284
15285 (define_expand "signbitxf2"
15286   [(use (match_operand:SI 0 "register_operand" ""))
15287    (use (match_operand:XF 1 "register_operand" ""))]
15288   "TARGET_USE_FANCY_MATH_387"
15289 {
15290   rtx scratch = gen_reg_rtx (HImode);
15291
15292   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15293   emit_insn (gen_andsi3 (operands[0],
15294              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15295   DONE;
15296 })
15297
15298 (define_insn "movmsk_df"
15299   [(set (match_operand:SI 0 "register_operand" "=r")
15300         (unspec:SI
15301           [(match_operand:DF 1 "register_operand" "x")]
15302           UNSPEC_MOVMSK))]
15303   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15304   "%vmovmskpd\t{%1, %0|%0, %1}"
15305   [(set_attr "type" "ssemov")
15306    (set_attr "prefix" "maybe_vex")
15307    (set_attr "mode" "DF")])
15308
15309 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15310 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15311 (define_expand "signbitdf2"
15312   [(use (match_operand:SI 0 "register_operand" ""))
15313    (use (match_operand:DF 1 "register_operand" ""))]
15314   "TARGET_USE_FANCY_MATH_387
15315    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15316 {
15317   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15318     {
15319       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15320       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15321     }
15322   else
15323     {
15324       rtx scratch = gen_reg_rtx (HImode);
15325
15326       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15327       emit_insn (gen_andsi3 (operands[0],
15328                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15329     }
15330   DONE;
15331 })
15332
15333 (define_expand "signbitsf2"
15334   [(use (match_operand:SI 0 "register_operand" ""))
15335    (use (match_operand:SF 1 "register_operand" ""))]
15336   "TARGET_USE_FANCY_MATH_387
15337    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15338 {
15339   rtx scratch = gen_reg_rtx (HImode);
15340
15341   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15342   emit_insn (gen_andsi3 (operands[0],
15343              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15344   DONE;
15345 })
15346 \f
15347 ;; Block operation instructions
15348
15349 (define_insn "cld"
15350   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15351   ""
15352   "cld"
15353   [(set_attr "length" "1")
15354    (set_attr "length_immediate" "0")
15355    (set_attr "modrm" "0")])
15356
15357 (define_expand "movmem<mode>"
15358   [(use (match_operand:BLK 0 "memory_operand" ""))
15359    (use (match_operand:BLK 1 "memory_operand" ""))
15360    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15361    (use (match_operand:SWI48 3 "const_int_operand" ""))
15362    (use (match_operand:SI 4 "const_int_operand" ""))
15363    (use (match_operand:SI 5 "const_int_operand" ""))]
15364   ""
15365 {
15366  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15367                          operands[4], operands[5]))
15368    DONE;
15369  else
15370    FAIL;
15371 })
15372
15373 ;; Most CPUs don't like single string operations
15374 ;; Handle this case here to simplify previous expander.
15375
15376 (define_expand "strmov"
15377   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15378    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15379    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15380               (clobber (reg:CC FLAGS_REG))])
15381    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15382               (clobber (reg:CC FLAGS_REG))])]
15383   ""
15384 {
15385   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15386
15387   /* If .md ever supports :P for Pmode, these can be directly
15388      in the pattern above.  */
15389   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15390   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15391
15392   /* Can't use this if the user has appropriated esi or edi.  */
15393   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15394       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15395     {
15396       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15397                                       operands[2], operands[3],
15398                                       operands[5], operands[6]));
15399       DONE;
15400     }
15401
15402   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15403 })
15404
15405 (define_expand "strmov_singleop"
15406   [(parallel [(set (match_operand 1 "memory_operand" "")
15407                    (match_operand 3 "memory_operand" ""))
15408               (set (match_operand 0 "register_operand" "")
15409                    (match_operand 4 "" ""))
15410               (set (match_operand 2 "register_operand" "")
15411                    (match_operand 5 "" ""))])]
15412   ""
15413   "ix86_current_function_needs_cld = 1;")
15414
15415 (define_insn "*strmovdi_rex_1"
15416   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15417         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15418    (set (match_operand:DI 0 "register_operand" "=D")
15419         (plus:DI (match_dup 2)
15420                  (const_int 8)))
15421    (set (match_operand:DI 1 "register_operand" "=S")
15422         (plus:DI (match_dup 3)
15423                  (const_int 8)))]
15424   "TARGET_64BIT
15425    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15426   "movsq"
15427   [(set_attr "type" "str")
15428    (set_attr "memory" "both")
15429    (set_attr "mode" "DI")])
15430
15431 (define_insn "*strmovsi_1"
15432   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15433         (mem:SI (match_operand:P 3 "register_operand" "1")))
15434    (set (match_operand:P 0 "register_operand" "=D")
15435         (plus:P (match_dup 2)
15436                 (const_int 4)))
15437    (set (match_operand:P 1 "register_operand" "=S")
15438         (plus:P (match_dup 3)
15439                 (const_int 4)))]
15440   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15441   "movs{l|d}"
15442   [(set_attr "type" "str")
15443    (set_attr "memory" "both")
15444    (set_attr "mode" "SI")])
15445
15446 (define_insn "*strmovhi_1"
15447   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15448         (mem:HI (match_operand:P 3 "register_operand" "1")))
15449    (set (match_operand:P 0 "register_operand" "=D")
15450         (plus:P (match_dup 2)
15451                 (const_int 2)))
15452    (set (match_operand:P 1 "register_operand" "=S")
15453         (plus:P (match_dup 3)
15454                 (const_int 2)))]
15455   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15456   "movsw"
15457   [(set_attr "type" "str")
15458    (set_attr "memory" "both")
15459    (set_attr "mode" "HI")])
15460
15461 (define_insn "*strmovqi_1"
15462   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15463         (mem:QI (match_operand:P 3 "register_operand" "1")))
15464    (set (match_operand:P 0 "register_operand" "=D")
15465         (plus:P (match_dup 2)
15466                 (const_int 1)))
15467    (set (match_operand:P 1 "register_operand" "=S")
15468         (plus:P (match_dup 3)
15469                 (const_int 1)))]
15470   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15471   "movsb"
15472   [(set_attr "type" "str")
15473    (set_attr "memory" "both")
15474    (set (attr "prefix_rex")
15475         (if_then_else
15476           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15477           (const_string "0")
15478           (const_string "*")))
15479    (set_attr "mode" "QI")])
15480
15481 (define_expand "rep_mov"
15482   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15483               (set (match_operand 0 "register_operand" "")
15484                    (match_operand 5 "" ""))
15485               (set (match_operand 2 "register_operand" "")
15486                    (match_operand 6 "" ""))
15487               (set (match_operand 1 "memory_operand" "")
15488                    (match_operand 3 "memory_operand" ""))
15489               (use (match_dup 4))])]
15490   ""
15491   "ix86_current_function_needs_cld = 1;")
15492
15493 (define_insn "*rep_movdi_rex64"
15494   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15495    (set (match_operand:DI 0 "register_operand" "=D")
15496         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15497                             (const_int 3))
15498                  (match_operand:DI 3 "register_operand" "0")))
15499    (set (match_operand:DI 1 "register_operand" "=S")
15500         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15501                  (match_operand:DI 4 "register_operand" "1")))
15502    (set (mem:BLK (match_dup 3))
15503         (mem:BLK (match_dup 4)))
15504    (use (match_dup 5))]
15505   "TARGET_64BIT
15506    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15507   "rep{%;} movsq"
15508   [(set_attr "type" "str")
15509    (set_attr "prefix_rep" "1")
15510    (set_attr "memory" "both")
15511    (set_attr "mode" "DI")])
15512
15513 (define_insn "*rep_movsi"
15514   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15515    (set (match_operand:P 0 "register_operand" "=D")
15516         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15517                           (const_int 2))
15518                  (match_operand:P 3 "register_operand" "0")))
15519    (set (match_operand:P 1 "register_operand" "=S")
15520         (plus:P (ashift:P (match_dup 5) (const_int 2))
15521                 (match_operand:P 4 "register_operand" "1")))
15522    (set (mem:BLK (match_dup 3))
15523         (mem:BLK (match_dup 4)))
15524    (use (match_dup 5))]
15525   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15526   "rep{%;} movs{l|d}"
15527   [(set_attr "type" "str")
15528    (set_attr "prefix_rep" "1")
15529    (set_attr "memory" "both")
15530    (set_attr "mode" "SI")])
15531
15532 (define_insn "*rep_movqi"
15533   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15534    (set (match_operand:P 0 "register_operand" "=D")
15535         (plus:P (match_operand:P 3 "register_operand" "0")
15536                 (match_operand:P 5 "register_operand" "2")))
15537    (set (match_operand:P 1 "register_operand" "=S")
15538         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15539    (set (mem:BLK (match_dup 3))
15540         (mem:BLK (match_dup 4)))
15541    (use (match_dup 5))]
15542   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15543   "rep{%;} movsb"
15544   [(set_attr "type" "str")
15545    (set_attr "prefix_rep" "1")
15546    (set_attr "memory" "both")
15547    (set_attr "mode" "QI")])
15548
15549 (define_expand "setmem<mode>"
15550    [(use (match_operand:BLK 0 "memory_operand" ""))
15551     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15552     (use (match_operand:QI 2 "nonmemory_operand" ""))
15553     (use (match_operand 3 "const_int_operand" ""))
15554     (use (match_operand:SI 4 "const_int_operand" ""))
15555     (use (match_operand:SI 5 "const_int_operand" ""))]
15556   ""
15557 {
15558  if (ix86_expand_setmem (operands[0], operands[1],
15559                          operands[2], operands[3],
15560                          operands[4], operands[5]))
15561    DONE;
15562  else
15563    FAIL;
15564 })
15565
15566 ;; Most CPUs don't like single string operations
15567 ;; Handle this case here to simplify previous expander.
15568
15569 (define_expand "strset"
15570   [(set (match_operand 1 "memory_operand" "")
15571         (match_operand 2 "register_operand" ""))
15572    (parallel [(set (match_operand 0 "register_operand" "")
15573                    (match_dup 3))
15574               (clobber (reg:CC FLAGS_REG))])]
15575   ""
15576 {
15577   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15578     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15579
15580   /* If .md ever supports :P for Pmode, this can be directly
15581      in the pattern above.  */
15582   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15583                               GEN_INT (GET_MODE_SIZE (GET_MODE
15584                                                       (operands[2]))));
15585   /* Can't use this if the user has appropriated eax or edi.  */
15586   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15587       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15588     {
15589       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15590                                       operands[3]));
15591       DONE;
15592     }
15593 })
15594
15595 (define_expand "strset_singleop"
15596   [(parallel [(set (match_operand 1 "memory_operand" "")
15597                    (match_operand 2 "register_operand" ""))
15598               (set (match_operand 0 "register_operand" "")
15599                    (match_operand 3 "" ""))])]
15600   ""
15601   "ix86_current_function_needs_cld = 1;")
15602
15603 (define_insn "*strsetdi_rex_1"
15604   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15605         (match_operand:DI 2 "register_operand" "a"))
15606    (set (match_operand:DI 0 "register_operand" "=D")
15607         (plus:DI (match_dup 1)
15608                  (const_int 8)))]
15609   "TARGET_64BIT
15610    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15611   "stosq"
15612   [(set_attr "type" "str")
15613    (set_attr "memory" "store")
15614    (set_attr "mode" "DI")])
15615
15616 (define_insn "*strsetsi_1"
15617   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15618         (match_operand:SI 2 "register_operand" "a"))
15619    (set (match_operand:P 0 "register_operand" "=D")
15620         (plus:P (match_dup 1)
15621                 (const_int 4)))]
15622   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15623   "stos{l|d}"
15624   [(set_attr "type" "str")
15625    (set_attr "memory" "store")
15626    (set_attr "mode" "SI")])
15627
15628 (define_insn "*strsethi_1"
15629   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15630         (match_operand:HI 2 "register_operand" "a"))
15631    (set (match_operand:P 0 "register_operand" "=D")
15632         (plus:P (match_dup 1)
15633                 (const_int 2)))]
15634   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15635   "stosw"
15636   [(set_attr "type" "str")
15637    (set_attr "memory" "store")
15638    (set_attr "mode" "HI")])
15639
15640 (define_insn "*strsetqi_1"
15641   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15642         (match_operand:QI 2 "register_operand" "a"))
15643    (set (match_operand:P 0 "register_operand" "=D")
15644         (plus:P (match_dup 1)
15645                 (const_int 1)))]
15646   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15647   "stosb"
15648   [(set_attr "type" "str")
15649    (set_attr "memory" "store")
15650    (set (attr "prefix_rex")
15651         (if_then_else
15652           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15653           (const_string "0")
15654           (const_string "*")))
15655    (set_attr "mode" "QI")])
15656
15657 (define_expand "rep_stos"
15658   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15659               (set (match_operand 0 "register_operand" "")
15660                    (match_operand 4 "" ""))
15661               (set (match_operand 2 "memory_operand" "") (const_int 0))
15662               (use (match_operand 3 "register_operand" ""))
15663               (use (match_dup 1))])]
15664   ""
15665   "ix86_current_function_needs_cld = 1;")
15666
15667 (define_insn "*rep_stosdi_rex64"
15668   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15669    (set (match_operand:DI 0 "register_operand" "=D")
15670         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15671                             (const_int 3))
15672                  (match_operand:DI 3 "register_operand" "0")))
15673    (set (mem:BLK (match_dup 3))
15674         (const_int 0))
15675    (use (match_operand:DI 2 "register_operand" "a"))
15676    (use (match_dup 4))]
15677   "TARGET_64BIT
15678    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15679   "rep{%;} stosq"
15680   [(set_attr "type" "str")
15681    (set_attr "prefix_rep" "1")
15682    (set_attr "memory" "store")
15683    (set_attr "mode" "DI")])
15684
15685 (define_insn "*rep_stossi"
15686   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15687    (set (match_operand:P 0 "register_operand" "=D")
15688         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15689                           (const_int 2))
15690                  (match_operand:P 3 "register_operand" "0")))
15691    (set (mem:BLK (match_dup 3))
15692         (const_int 0))
15693    (use (match_operand:SI 2 "register_operand" "a"))
15694    (use (match_dup 4))]
15695   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15696   "rep{%;} stos{l|d}"
15697   [(set_attr "type" "str")
15698    (set_attr "prefix_rep" "1")
15699    (set_attr "memory" "store")
15700    (set_attr "mode" "SI")])
15701
15702 (define_insn "*rep_stosqi"
15703   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15704    (set (match_operand:P 0 "register_operand" "=D")
15705         (plus:P (match_operand:P 3 "register_operand" "0")
15706                 (match_operand:P 4 "register_operand" "1")))
15707    (set (mem:BLK (match_dup 3))
15708         (const_int 0))
15709    (use (match_operand:QI 2 "register_operand" "a"))
15710    (use (match_dup 4))]
15711   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15712   "rep{%;} stosb"
15713   [(set_attr "type" "str")
15714    (set_attr "prefix_rep" "1")
15715    (set_attr "memory" "store")
15716    (set (attr "prefix_rex")
15717         (if_then_else
15718           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15719           (const_string "0")
15720           (const_string "*")))
15721    (set_attr "mode" "QI")])
15722
15723 (define_expand "cmpstrnsi"
15724   [(set (match_operand:SI 0 "register_operand" "")
15725         (compare:SI (match_operand:BLK 1 "general_operand" "")
15726                     (match_operand:BLK 2 "general_operand" "")))
15727    (use (match_operand 3 "general_operand" ""))
15728    (use (match_operand 4 "immediate_operand" ""))]
15729   ""
15730 {
15731   rtx addr1, addr2, out, outlow, count, countreg, align;
15732
15733   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15734     FAIL;
15735
15736   /* Can't use this if the user has appropriated ecx, esi or edi.  */
15737   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15738     FAIL;
15739
15740   out = operands[0];
15741   if (!REG_P (out))
15742     out = gen_reg_rtx (SImode);
15743
15744   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15745   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15746   if (addr1 != XEXP (operands[1], 0))
15747     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15748   if (addr2 != XEXP (operands[2], 0))
15749     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15750
15751   count = operands[3];
15752   countreg = ix86_zero_extend_to_Pmode (count);
15753
15754   /* %%% Iff we are testing strict equality, we can use known alignment
15755      to good advantage.  This may be possible with combine, particularly
15756      once cc0 is dead.  */
15757   align = operands[4];
15758
15759   if (CONST_INT_P (count))
15760     {
15761       if (INTVAL (count) == 0)
15762         {
15763           emit_move_insn (operands[0], const0_rtx);
15764           DONE;
15765         }
15766       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15767                                      operands[1], operands[2]));
15768     }
15769   else
15770     {
15771       rtx (*gen_cmp) (rtx, rtx);
15772
15773       gen_cmp = (TARGET_64BIT
15774                  ? gen_cmpdi_1 : gen_cmpsi_1);
15775
15776       emit_insn (gen_cmp (countreg, countreg));
15777       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15778                                   operands[1], operands[2]));
15779     }
15780
15781   outlow = gen_lowpart (QImode, out);
15782   emit_insn (gen_cmpintqi (outlow));
15783   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15784
15785   if (operands[0] != out)
15786     emit_move_insn (operands[0], out);
15787
15788   DONE;
15789 })
15790
15791 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15792
15793 (define_expand "cmpintqi"
15794   [(set (match_dup 1)
15795         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15796    (set (match_dup 2)
15797         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15798    (parallel [(set (match_operand:QI 0 "register_operand" "")
15799                    (minus:QI (match_dup 1)
15800                              (match_dup 2)))
15801               (clobber (reg:CC FLAGS_REG))])]
15802   ""
15803 {
15804   operands[1] = gen_reg_rtx (QImode);
15805   operands[2] = gen_reg_rtx (QImode);
15806 })
15807
15808 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15809 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15810
15811 (define_expand "cmpstrnqi_nz_1"
15812   [(parallel [(set (reg:CC FLAGS_REG)
15813                    (compare:CC (match_operand 4 "memory_operand" "")
15814                                (match_operand 5 "memory_operand" "")))
15815               (use (match_operand 2 "register_operand" ""))
15816               (use (match_operand:SI 3 "immediate_operand" ""))
15817               (clobber (match_operand 0 "register_operand" ""))
15818               (clobber (match_operand 1 "register_operand" ""))
15819               (clobber (match_dup 2))])]
15820   ""
15821   "ix86_current_function_needs_cld = 1;")
15822
15823 (define_insn "*cmpstrnqi_nz_1"
15824   [(set (reg:CC FLAGS_REG)
15825         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15826                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15827    (use (match_operand:P 6 "register_operand" "2"))
15828    (use (match_operand:SI 3 "immediate_operand" "i"))
15829    (clobber (match_operand:P 0 "register_operand" "=S"))
15830    (clobber (match_operand:P 1 "register_operand" "=D"))
15831    (clobber (match_operand:P 2 "register_operand" "=c"))]
15832   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15833   "repz{%;} cmpsb"
15834   [(set_attr "type" "str")
15835    (set_attr "mode" "QI")
15836    (set (attr "prefix_rex")
15837         (if_then_else
15838           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15839           (const_string "0")
15840           (const_string "*")))
15841    (set_attr "prefix_rep" "1")])
15842
15843 ;; The same, but the count is not known to not be zero.
15844
15845 (define_expand "cmpstrnqi_1"
15846   [(parallel [(set (reg:CC FLAGS_REG)
15847                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15848                                      (const_int 0))
15849                   (compare:CC (match_operand 4 "memory_operand" "")
15850                               (match_operand 5 "memory_operand" ""))
15851                   (const_int 0)))
15852               (use (match_operand:SI 3 "immediate_operand" ""))
15853               (use (reg:CC FLAGS_REG))
15854               (clobber (match_operand 0 "register_operand" ""))
15855               (clobber (match_operand 1 "register_operand" ""))
15856               (clobber (match_dup 2))])]
15857   ""
15858   "ix86_current_function_needs_cld = 1;")
15859
15860 (define_insn "*cmpstrnqi_1"
15861   [(set (reg:CC FLAGS_REG)
15862         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15863                              (const_int 0))
15864           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15865                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15866           (const_int 0)))
15867    (use (match_operand:SI 3 "immediate_operand" "i"))
15868    (use (reg:CC FLAGS_REG))
15869    (clobber (match_operand:P 0 "register_operand" "=S"))
15870    (clobber (match_operand:P 1 "register_operand" "=D"))
15871    (clobber (match_operand:P 2 "register_operand" "=c"))]
15872   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15873   "repz{%;} cmpsb"
15874   [(set_attr "type" "str")
15875    (set_attr "mode" "QI")
15876    (set (attr "prefix_rex")
15877         (if_then_else
15878           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15879           (const_string "0")
15880           (const_string "*")))
15881    (set_attr "prefix_rep" "1")])
15882
15883 (define_expand "strlen<mode>"
15884   [(set (match_operand:P 0 "register_operand" "")
15885         (unspec:P [(match_operand:BLK 1 "general_operand" "")
15886                    (match_operand:QI 2 "immediate_operand" "")
15887                    (match_operand 3 "immediate_operand" "")]
15888                   UNSPEC_SCAS))]
15889   ""
15890 {
15891  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15892    DONE;
15893  else
15894    FAIL;
15895 })
15896
15897 (define_expand "strlenqi_1"
15898   [(parallel [(set (match_operand 0 "register_operand" "")
15899                    (match_operand 2 "" ""))
15900               (clobber (match_operand 1 "register_operand" ""))
15901               (clobber (reg:CC FLAGS_REG))])]
15902   ""
15903   "ix86_current_function_needs_cld = 1;")
15904
15905 (define_insn "*strlenqi_1"
15906   [(set (match_operand:P 0 "register_operand" "=&c")
15907         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15908                    (match_operand:QI 2 "register_operand" "a")
15909                    (match_operand:P 3 "immediate_operand" "i")
15910                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15911    (clobber (match_operand:P 1 "register_operand" "=D"))
15912    (clobber (reg:CC FLAGS_REG))]
15913   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15914   "repnz{%;} scasb"
15915   [(set_attr "type" "str")
15916    (set_attr "mode" "QI")
15917    (set (attr "prefix_rex")
15918         (if_then_else
15919           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15920           (const_string "0")
15921           (const_string "*")))
15922    (set_attr "prefix_rep" "1")])
15923
15924 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15925 ;; handled in combine, but it is not currently up to the task.
15926 ;; When used for their truth value, the cmpstrn* expanders generate
15927 ;; code like this:
15928 ;;
15929 ;;   repz cmpsb
15930 ;;   seta       %al
15931 ;;   setb       %dl
15932 ;;   cmpb       %al, %dl
15933 ;;   jcc        label
15934 ;;
15935 ;; The intermediate three instructions are unnecessary.
15936
15937 ;; This one handles cmpstrn*_nz_1...
15938 (define_peephole2
15939   [(parallel[
15940      (set (reg:CC FLAGS_REG)
15941           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15942                       (mem:BLK (match_operand 5 "register_operand" ""))))
15943      (use (match_operand 6 "register_operand" ""))
15944      (use (match_operand:SI 3 "immediate_operand" ""))
15945      (clobber (match_operand 0 "register_operand" ""))
15946      (clobber (match_operand 1 "register_operand" ""))
15947      (clobber (match_operand 2 "register_operand" ""))])
15948    (set (match_operand:QI 7 "register_operand" "")
15949         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15950    (set (match_operand:QI 8 "register_operand" "")
15951         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15952    (set (reg FLAGS_REG)
15953         (compare (match_dup 7) (match_dup 8)))
15954   ]
15955   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15956   [(parallel[
15957      (set (reg:CC FLAGS_REG)
15958           (compare:CC (mem:BLK (match_dup 4))
15959                       (mem:BLK (match_dup 5))))
15960      (use (match_dup 6))
15961      (use (match_dup 3))
15962      (clobber (match_dup 0))
15963      (clobber (match_dup 1))
15964      (clobber (match_dup 2))])])
15965
15966 ;; ...and this one handles cmpstrn*_1.
15967 (define_peephole2
15968   [(parallel[
15969      (set (reg:CC FLAGS_REG)
15970           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15971                                (const_int 0))
15972             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15973                         (mem:BLK (match_operand 5 "register_operand" "")))
15974             (const_int 0)))
15975      (use (match_operand:SI 3 "immediate_operand" ""))
15976      (use (reg:CC FLAGS_REG))
15977      (clobber (match_operand 0 "register_operand" ""))
15978      (clobber (match_operand 1 "register_operand" ""))
15979      (clobber (match_operand 2 "register_operand" ""))])
15980    (set (match_operand:QI 7 "register_operand" "")
15981         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15982    (set (match_operand:QI 8 "register_operand" "")
15983         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15984    (set (reg FLAGS_REG)
15985         (compare (match_dup 7) (match_dup 8)))
15986   ]
15987   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15988   [(parallel[
15989      (set (reg:CC FLAGS_REG)
15990           (if_then_else:CC (ne (match_dup 6)
15991                                (const_int 0))
15992             (compare:CC (mem:BLK (match_dup 4))
15993                         (mem:BLK (match_dup 5)))
15994             (const_int 0)))
15995      (use (match_dup 3))
15996      (use (reg:CC FLAGS_REG))
15997      (clobber (match_dup 0))
15998      (clobber (match_dup 1))
15999      (clobber (match_dup 2))])])
16000 \f
16001 ;; Conditional move instructions.
16002
16003 (define_expand "mov<mode>cc"
16004   [(set (match_operand:SWIM 0 "register_operand" "")
16005         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16006                            (match_operand:SWIM 2 "<general_operand>" "")
16007                            (match_operand:SWIM 3 "<general_operand>" "")))]
16008   ""
16009   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16010
16011 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16012 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16013 ;; So just document what we're doing explicitly.
16014
16015 (define_expand "x86_mov<mode>cc_0_m1"
16016   [(parallel
16017     [(set (match_operand:SWI48 0 "register_operand" "")
16018           (if_then_else:SWI48
16019             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16020              [(match_operand 1 "flags_reg_operand" "")
16021               (const_int 0)])
16022             (const_int -1)
16023             (const_int 0)))
16024      (clobber (reg:CC FLAGS_REG))])])
16025
16026 (define_insn "*x86_mov<mode>cc_0_m1"
16027   [(set (match_operand:SWI48 0 "register_operand" "=r")
16028         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16029                              [(reg FLAGS_REG) (const_int 0)])
16030           (const_int -1)
16031           (const_int 0)))
16032    (clobber (reg:CC FLAGS_REG))]
16033   ""
16034   "sbb{<imodesuffix>}\t%0, %0"
16035   ; Since we don't have the proper number of operands for an alu insn,
16036   ; fill in all the blanks.
16037   [(set_attr "type" "alu")
16038    (set_attr "use_carry" "1")
16039    (set_attr "pent_pair" "pu")
16040    (set_attr "memory" "none")
16041    (set_attr "imm_disp" "false")
16042    (set_attr "mode" "<MODE>")
16043    (set_attr "length_immediate" "0")])
16044
16045 (define_insn "*x86_mov<mode>cc_0_m1_se"
16046   [(set (match_operand:SWI48 0 "register_operand" "=r")
16047         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16048                              [(reg FLAGS_REG) (const_int 0)])
16049                             (const_int 1)
16050                             (const_int 0)))
16051    (clobber (reg:CC FLAGS_REG))]
16052   ""
16053   "sbb{<imodesuffix>}\t%0, %0"
16054   [(set_attr "type" "alu")
16055    (set_attr "use_carry" "1")
16056    (set_attr "pent_pair" "pu")
16057    (set_attr "memory" "none")
16058    (set_attr "imm_disp" "false")
16059    (set_attr "mode" "<MODE>")
16060    (set_attr "length_immediate" "0")])
16061
16062 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16063   [(set (match_operand:SWI48 0 "register_operand" "=r")
16064         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16065                     [(reg FLAGS_REG) (const_int 0)])))]
16066   ""
16067   "sbb{<imodesuffix>}\t%0, %0"
16068   [(set_attr "type" "alu")
16069    (set_attr "use_carry" "1")
16070    (set_attr "pent_pair" "pu")
16071    (set_attr "memory" "none")
16072    (set_attr "imm_disp" "false")
16073    (set_attr "mode" "<MODE>")
16074    (set_attr "length_immediate" "0")])
16075
16076 (define_insn "*mov<mode>cc_noc"
16077   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16078         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16079                                [(reg FLAGS_REG) (const_int 0)])
16080           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16081           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16082   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16083   "@
16084    cmov%O2%C1\t{%2, %0|%0, %2}
16085    cmov%O2%c1\t{%3, %0|%0, %3}"
16086   [(set_attr "type" "icmov")
16087    (set_attr "mode" "<MODE>")])
16088
16089 (define_insn_and_split "*movqicc_noc"
16090   [(set (match_operand:QI 0 "register_operand" "=r,r")
16091         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16092                            [(match_operand 4 "flags_reg_operand" "")
16093                             (const_int 0)])
16094                       (match_operand:QI 2 "register_operand" "r,0")
16095                       (match_operand:QI 3 "register_operand" "0,r")))]
16096   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16097   "#"
16098   "&& reload_completed"
16099   [(set (match_dup 0)
16100         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16101                       (match_dup 2)
16102                       (match_dup 3)))]
16103   "operands[0] = gen_lowpart (SImode, operands[0]);
16104    operands[2] = gen_lowpart (SImode, operands[2]);
16105    operands[3] = gen_lowpart (SImode, operands[3]);"
16106   [(set_attr "type" "icmov")
16107    (set_attr "mode" "SI")])
16108
16109 (define_expand "mov<mode>cc"
16110   [(set (match_operand:X87MODEF 0 "register_operand" "")
16111         (if_then_else:X87MODEF
16112           (match_operand 1 "ix86_fp_comparison_operator" "")
16113           (match_operand:X87MODEF 2 "register_operand" "")
16114           (match_operand:X87MODEF 3 "register_operand" "")))]
16115   "(TARGET_80387 && TARGET_CMOVE)
16116    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16117   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16118
16119 (define_insn "*movxfcc_1"
16120   [(set (match_operand:XF 0 "register_operand" "=f,f")
16121         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16122                                 [(reg FLAGS_REG) (const_int 0)])
16123                       (match_operand:XF 2 "register_operand" "f,0")
16124                       (match_operand:XF 3 "register_operand" "0,f")))]
16125   "TARGET_80387 && TARGET_CMOVE"
16126   "@
16127    fcmov%F1\t{%2, %0|%0, %2}
16128    fcmov%f1\t{%3, %0|%0, %3}"
16129   [(set_attr "type" "fcmov")
16130    (set_attr "mode" "XF")])
16131
16132 (define_insn "*movdfcc_1_rex64"
16133   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16134         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16135                                 [(reg FLAGS_REG) (const_int 0)])
16136                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16137                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16138   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16139    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16140   "@
16141    fcmov%F1\t{%2, %0|%0, %2}
16142    fcmov%f1\t{%3, %0|%0, %3}
16143    cmov%O2%C1\t{%2, %0|%0, %2}
16144    cmov%O2%c1\t{%3, %0|%0, %3}"
16145   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16146    (set_attr "mode" "DF,DF,DI,DI")])
16147
16148 (define_insn "*movdfcc_1"
16149   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16150         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16151                                 [(reg FLAGS_REG) (const_int 0)])
16152                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16153                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16154   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16155    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16156   "@
16157    fcmov%F1\t{%2, %0|%0, %2}
16158    fcmov%f1\t{%3, %0|%0, %3}
16159    #
16160    #"
16161   [(set_attr "type" "fcmov,fcmov,multi,multi")
16162    (set_attr "mode" "DF,DF,DI,DI")])
16163
16164 (define_split
16165   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16166         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16167                                 [(match_operand 4 "flags_reg_operand" "")
16168                                  (const_int 0)])
16169                       (match_operand:DF 2 "nonimmediate_operand" "")
16170                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16171   "!TARGET_64BIT && reload_completed"
16172   [(set (match_dup 2)
16173         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16174                       (match_dup 5)
16175                       (match_dup 6)))
16176    (set (match_dup 3)
16177         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16178                       (match_dup 7)
16179                       (match_dup 8)))]
16180 {
16181   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16182   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16183 })
16184
16185 (define_insn "*movsfcc_1_387"
16186   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16187         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16188                                 [(reg FLAGS_REG) (const_int 0)])
16189                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16190                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16191   "TARGET_80387 && TARGET_CMOVE
16192    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16193   "@
16194    fcmov%F1\t{%2, %0|%0, %2}
16195    fcmov%f1\t{%3, %0|%0, %3}
16196    cmov%O2%C1\t{%2, %0|%0, %2}
16197    cmov%O2%c1\t{%3, %0|%0, %3}"
16198   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16199    (set_attr "mode" "SF,SF,SI,SI")])
16200
16201 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16202 ;; the scalar versions to have only XMM registers as operands.
16203
16204 ;; XOP conditional move
16205 (define_insn "*xop_pcmov_<mode>"
16206   [(set (match_operand:MODEF 0 "register_operand" "=x")
16207         (if_then_else:MODEF
16208           (match_operand:MODEF 1 "register_operand" "x")
16209           (match_operand:MODEF 2 "register_operand" "x")
16210           (match_operand:MODEF 3 "register_operand" "x")))]
16211   "TARGET_XOP"
16212   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16213   [(set_attr "type" "sse4arg")])
16214
16215 ;; These versions of the min/max patterns are intentionally ignorant of
16216 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16217 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16218 ;; are undefined in this condition, we're certain this is correct.
16219
16220 (define_insn "<code><mode>3"
16221   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16222         (smaxmin:MODEF
16223           (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16224           (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16225   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16226   "@
16227    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16228    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16229   [(set_attr "isa" "noavx,avx")
16230    (set_attr "prefix" "orig,vex")
16231    (set_attr "type" "sseadd")
16232    (set_attr "mode" "<MODE>")])
16233
16234 ;; These versions of the min/max patterns implement exactly the operations
16235 ;;   min = (op1 < op2 ? op1 : op2)
16236 ;;   max = (!(op1 < op2) ? op1 : op2)
16237 ;; Their operands are not commutative, and thus they may be used in the
16238 ;; presence of -0.0 and NaN.
16239
16240 (define_insn "*ieee_smin<mode>3"
16241   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16242         (unspec:MODEF
16243           [(match_operand:MODEF 1 "register_operand" "0,x")
16244            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16245          UNSPEC_IEEE_MIN))]
16246   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16247   "@
16248    min<ssemodesuffix>\t{%2, %0|%0, %2}
16249    vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16250   [(set_attr "isa" "noavx,avx")
16251    (set_attr "prefix" "orig,vex")
16252    (set_attr "type" "sseadd")
16253    (set_attr "mode" "<MODE>")])
16254
16255 (define_insn "*ieee_smax<mode>3"
16256   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16257         (unspec:MODEF
16258           [(match_operand:MODEF 1 "register_operand" "0,x")
16259            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16260          UNSPEC_IEEE_MAX))]
16261   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16262   "@
16263    max<ssemodesuffix>\t{%2, %0|%0, %2}
16264    vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16265   [(set_attr "isa" "noavx,avx")
16266    (set_attr "prefix" "orig,vex")
16267    (set_attr "type" "sseadd")
16268    (set_attr "mode" "<MODE>")])
16269
16270 ;; Make two stack loads independent:
16271 ;;   fld aa              fld aa
16272 ;;   fld %st(0)     ->   fld bb
16273 ;;   fmul bb             fmul %st(1), %st
16274 ;;
16275 ;; Actually we only match the last two instructions for simplicity.
16276 (define_peephole2
16277   [(set (match_operand 0 "fp_register_operand" "")
16278         (match_operand 1 "fp_register_operand" ""))
16279    (set (match_dup 0)
16280         (match_operator 2 "binary_fp_operator"
16281            [(match_dup 0)
16282             (match_operand 3 "memory_operand" "")]))]
16283   "REGNO (operands[0]) != REGNO (operands[1])"
16284   [(set (match_dup 0) (match_dup 3))
16285    (set (match_dup 0) (match_dup 4))]
16286
16287   ;; The % modifier is not operational anymore in peephole2's, so we have to
16288   ;; swap the operands manually in the case of addition and multiplication.
16289   "if (COMMUTATIVE_ARITH_P (operands[2]))
16290      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16291                                    GET_MODE (operands[2]),
16292                                    operands[0], operands[1]);
16293    else
16294      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16295                                    GET_MODE (operands[2]),
16296                                    operands[1], operands[0]);")
16297
16298 ;; Conditional addition patterns
16299 (define_expand "add<mode>cc"
16300   [(match_operand:SWI 0 "register_operand" "")
16301    (match_operand 1 "ordered_comparison_operator" "")
16302    (match_operand:SWI 2 "register_operand" "")
16303    (match_operand:SWI 3 "const_int_operand" "")]
16304   ""
16305   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16306 \f
16307 ;; Misc patterns (?)
16308
16309 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16310 ;; Otherwise there will be nothing to keep
16311 ;;
16312 ;; [(set (reg ebp) (reg esp))]
16313 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16314 ;;  (clobber (eflags)]
16315 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16316 ;;
16317 ;; in proper program order.
16318
16319 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16320   [(set (match_operand:P 0 "register_operand" "=r,r")
16321         (plus:P (match_operand:P 1 "register_operand" "0,r")
16322                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16323    (clobber (reg:CC FLAGS_REG))
16324    (clobber (mem:BLK (scratch)))]
16325   ""
16326 {
16327   switch (get_attr_type (insn))
16328     {
16329     case TYPE_IMOV:
16330       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16331
16332     case TYPE_ALU:
16333       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16334       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16335         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16336
16337       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16338
16339     default:
16340       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16341       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16342     }
16343 }
16344   [(set (attr "type")
16345         (cond [(and (eq_attr "alternative" "0")
16346                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16347                  (const_string "alu")
16348                (match_operand:<MODE> 2 "const0_operand" "")
16349                  (const_string "imov")
16350               ]
16351               (const_string "lea")))
16352    (set (attr "length_immediate")
16353         (cond [(eq_attr "type" "imov")
16354                  (const_string "0")
16355                (and (eq_attr "type" "alu")
16356                     (match_operand 2 "const128_operand" ""))
16357                  (const_string "1")
16358               ]
16359               (const_string "*")))
16360    (set_attr "mode" "<MODE>")])
16361
16362 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16363   [(set (match_operand:P 0 "register_operand" "=r")
16364         (minus:P (match_operand:P 1 "register_operand" "0")
16365                  (match_operand:P 2 "register_operand" "r")))
16366    (clobber (reg:CC FLAGS_REG))
16367    (clobber (mem:BLK (scratch)))]
16368   ""
16369   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16370   [(set_attr "type" "alu")
16371    (set_attr "mode" "<MODE>")])
16372
16373 (define_insn "allocate_stack_worker_probe_<mode>"
16374   [(set (match_operand:P 0 "register_operand" "=a")
16375         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16376                             UNSPECV_STACK_PROBE))
16377    (clobber (reg:CC FLAGS_REG))]
16378   "ix86_target_stack_probe ()"
16379   "call\t___chkstk_ms"
16380   [(set_attr "type" "multi")
16381    (set_attr "length" "5")])
16382
16383 (define_expand "allocate_stack"
16384   [(match_operand 0 "register_operand" "")
16385    (match_operand 1 "general_operand" "")]
16386   "ix86_target_stack_probe ()"
16387 {
16388   rtx x;
16389
16390 #ifndef CHECK_STACK_LIMIT
16391 #define CHECK_STACK_LIMIT 0
16392 #endif
16393
16394   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16395       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16396     {
16397       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16398                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16399       if (x != stack_pointer_rtx)
16400         emit_move_insn (stack_pointer_rtx, x);
16401     }
16402   else
16403     {
16404       x = copy_to_mode_reg (Pmode, operands[1]);
16405       if (TARGET_64BIT)
16406         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16407       else
16408         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16409       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16410                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16411       if (x != stack_pointer_rtx)
16412         emit_move_insn (stack_pointer_rtx, x);
16413     }
16414
16415   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16416   DONE;
16417 })
16418
16419 ;; Use IOR for stack probes, this is shorter.
16420 (define_expand "probe_stack"
16421   [(match_operand 0 "memory_operand" "")]
16422   ""
16423 {
16424   rtx (*gen_ior3) (rtx, rtx, rtx);
16425
16426   gen_ior3 = (GET_MODE (operands[0]) == DImode
16427               ? gen_iordi3 : gen_iorsi3);
16428
16429   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16430   DONE;
16431 })
16432
16433 (define_insn "adjust_stack_and_probe<mode>"
16434   [(set (match_operand:P 0 "register_operand" "=r")
16435         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16436                             UNSPECV_PROBE_STACK_RANGE))
16437    (set (reg:P SP_REG)
16438         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16439    (clobber (reg:CC FLAGS_REG))
16440    (clobber (mem:BLK (scratch)))]
16441   ""
16442   "* return output_adjust_stack_and_probe (operands[0]);"
16443   [(set_attr "type" "multi")])
16444
16445 (define_insn "probe_stack_range<mode>"
16446   [(set (match_operand:P 0 "register_operand" "=r")
16447         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16448                             (match_operand:P 2 "const_int_operand" "n")]
16449                             UNSPECV_PROBE_STACK_RANGE))
16450    (clobber (reg:CC FLAGS_REG))]
16451   ""
16452   "* return output_probe_stack_range (operands[0], operands[2]);"
16453   [(set_attr "type" "multi")])
16454
16455 (define_expand "builtin_setjmp_receiver"
16456   [(label_ref (match_operand 0 "" ""))]
16457   "!TARGET_64BIT && flag_pic"
16458 {
16459 #if TARGET_MACHO
16460   if (TARGET_MACHO)
16461     {
16462       rtx xops[3];
16463       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16464       rtx label_rtx = gen_label_rtx ();
16465       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16466       xops[0] = xops[1] = picreg;
16467       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16468       ix86_expand_binary_operator (MINUS, SImode, xops);
16469     }
16470   else
16471 #endif
16472     emit_insn (gen_set_got (pic_offset_table_rtx));
16473   DONE;
16474 })
16475 \f
16476 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16477
16478 (define_split
16479   [(set (match_operand 0 "register_operand" "")
16480         (match_operator 3 "promotable_binary_operator"
16481            [(match_operand 1 "register_operand" "")
16482             (match_operand 2 "aligned_operand" "")]))
16483    (clobber (reg:CC FLAGS_REG))]
16484   "! TARGET_PARTIAL_REG_STALL && reload_completed
16485    && ((GET_MODE (operands[0]) == HImode
16486         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16487             /* ??? next two lines just !satisfies_constraint_K (...) */
16488             || !CONST_INT_P (operands[2])
16489             || satisfies_constraint_K (operands[2])))
16490        || (GET_MODE (operands[0]) == QImode
16491            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16492   [(parallel [(set (match_dup 0)
16493                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16494               (clobber (reg:CC FLAGS_REG))])]
16495   "operands[0] = gen_lowpart (SImode, operands[0]);
16496    operands[1] = gen_lowpart (SImode, operands[1]);
16497    if (GET_CODE (operands[3]) != ASHIFT)
16498      operands[2] = gen_lowpart (SImode, operands[2]);
16499    PUT_MODE (operands[3], SImode);")
16500
16501 ; Promote the QImode tests, as i386 has encoding of the AND
16502 ; instruction with 32-bit sign-extended immediate and thus the
16503 ; instruction size is unchanged, except in the %eax case for
16504 ; which it is increased by one byte, hence the ! optimize_size.
16505 (define_split
16506   [(set (match_operand 0 "flags_reg_operand" "")
16507         (match_operator 2 "compare_operator"
16508           [(and (match_operand 3 "aligned_operand" "")
16509                 (match_operand 4 "const_int_operand" ""))
16510            (const_int 0)]))
16511    (set (match_operand 1 "register_operand" "")
16512         (and (match_dup 3) (match_dup 4)))]
16513   "! TARGET_PARTIAL_REG_STALL && reload_completed
16514    && optimize_insn_for_speed_p ()
16515    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16516        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16517    /* Ensure that the operand will remain sign-extended immediate.  */
16518    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16519   [(parallel [(set (match_dup 0)
16520                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16521                                     (const_int 0)]))
16522               (set (match_dup 1)
16523                    (and:SI (match_dup 3) (match_dup 4)))])]
16524 {
16525   operands[4]
16526     = gen_int_mode (INTVAL (operands[4])
16527                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16528   operands[1] = gen_lowpart (SImode, operands[1]);
16529   operands[3] = gen_lowpart (SImode, operands[3]);
16530 })
16531
16532 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16533 ; the TEST instruction with 32-bit sign-extended immediate and thus
16534 ; the instruction size would at least double, which is not what we
16535 ; want even with ! optimize_size.
16536 (define_split
16537   [(set (match_operand 0 "flags_reg_operand" "")
16538         (match_operator 1 "compare_operator"
16539           [(and (match_operand:HI 2 "aligned_operand" "")
16540                 (match_operand:HI 3 "const_int_operand" ""))
16541            (const_int 0)]))]
16542   "! TARGET_PARTIAL_REG_STALL && reload_completed
16543    && ! TARGET_FAST_PREFIX
16544    && optimize_insn_for_speed_p ()
16545    /* Ensure that the operand will remain sign-extended immediate.  */
16546    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16547   [(set (match_dup 0)
16548         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16549                          (const_int 0)]))]
16550 {
16551   operands[3]
16552     = gen_int_mode (INTVAL (operands[3])
16553                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16554   operands[2] = gen_lowpart (SImode, operands[2]);
16555 })
16556
16557 (define_split
16558   [(set (match_operand 0 "register_operand" "")
16559         (neg (match_operand 1 "register_operand" "")))
16560    (clobber (reg:CC FLAGS_REG))]
16561   "! TARGET_PARTIAL_REG_STALL && reload_completed
16562    && (GET_MODE (operands[0]) == HImode
16563        || (GET_MODE (operands[0]) == QImode
16564            && (TARGET_PROMOTE_QImode
16565                || optimize_insn_for_size_p ())))"
16566   [(parallel [(set (match_dup 0)
16567                    (neg:SI (match_dup 1)))
16568               (clobber (reg:CC FLAGS_REG))])]
16569   "operands[0] = gen_lowpart (SImode, operands[0]);
16570    operands[1] = gen_lowpart (SImode, operands[1]);")
16571
16572 (define_split
16573   [(set (match_operand 0 "register_operand" "")
16574         (not (match_operand 1 "register_operand" "")))]
16575   "! TARGET_PARTIAL_REG_STALL && reload_completed
16576    && (GET_MODE (operands[0]) == HImode
16577        || (GET_MODE (operands[0]) == QImode
16578            && (TARGET_PROMOTE_QImode
16579                || optimize_insn_for_size_p ())))"
16580   [(set (match_dup 0)
16581         (not:SI (match_dup 1)))]
16582   "operands[0] = gen_lowpart (SImode, operands[0]);
16583    operands[1] = gen_lowpart (SImode, operands[1]);")
16584
16585 (define_split
16586   [(set (match_operand 0 "register_operand" "")
16587         (if_then_else (match_operator 1 "ordered_comparison_operator"
16588                                 [(reg FLAGS_REG) (const_int 0)])
16589                       (match_operand 2 "register_operand" "")
16590                       (match_operand 3 "register_operand" "")))]
16591   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16592    && (GET_MODE (operands[0]) == HImode
16593        || (GET_MODE (operands[0]) == QImode
16594            && (TARGET_PROMOTE_QImode
16595                || optimize_insn_for_size_p ())))"
16596   [(set (match_dup 0)
16597         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16598   "operands[0] = gen_lowpart (SImode, operands[0]);
16599    operands[2] = gen_lowpart (SImode, operands[2]);
16600    operands[3] = gen_lowpart (SImode, operands[3]);")
16601 \f
16602 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16603 ;; transform a complex memory operation into two memory to register operations.
16604
16605 ;; Don't push memory operands
16606 (define_peephole2
16607   [(set (match_operand:SWI 0 "push_operand" "")
16608         (match_operand:SWI 1 "memory_operand" ""))
16609    (match_scratch:SWI 2 "<r>")]
16610   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16611    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16612   [(set (match_dup 2) (match_dup 1))
16613    (set (match_dup 0) (match_dup 2))])
16614
16615 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16616 ;; SImode pushes.
16617 (define_peephole2
16618   [(set (match_operand:SF 0 "push_operand" "")
16619         (match_operand:SF 1 "memory_operand" ""))
16620    (match_scratch:SF 2 "r")]
16621   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16622    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16623   [(set (match_dup 2) (match_dup 1))
16624    (set (match_dup 0) (match_dup 2))])
16625
16626 ;; Don't move an immediate directly to memory when the instruction
16627 ;; gets too big.
16628 (define_peephole2
16629   [(match_scratch:SWI124 1 "<r>")
16630    (set (match_operand:SWI124 0 "memory_operand" "")
16631         (const_int 0))]
16632   "optimize_insn_for_speed_p ()
16633    && !TARGET_USE_MOV0
16634    && TARGET_SPLIT_LONG_MOVES
16635    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16636    && peep2_regno_dead_p (0, FLAGS_REG)"
16637   [(parallel [(set (match_dup 2) (const_int 0))
16638               (clobber (reg:CC FLAGS_REG))])
16639    (set (match_dup 0) (match_dup 1))]
16640   "operands[2] = gen_lowpart (SImode, operands[1]);")
16641
16642 (define_peephole2
16643   [(match_scratch:SWI124 2 "<r>")
16644    (set (match_operand:SWI124 0 "memory_operand" "")
16645         (match_operand:SWI124 1 "immediate_operand" ""))]
16646   "optimize_insn_for_speed_p ()
16647    && TARGET_SPLIT_LONG_MOVES
16648    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16649   [(set (match_dup 2) (match_dup 1))
16650    (set (match_dup 0) (match_dup 2))])
16651
16652 ;; Don't compare memory with zero, load and use a test instead.
16653 (define_peephole2
16654   [(set (match_operand 0 "flags_reg_operand" "")
16655         (match_operator 1 "compare_operator"
16656           [(match_operand:SI 2 "memory_operand" "")
16657            (const_int 0)]))
16658    (match_scratch:SI 3 "r")]
16659   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16660   [(set (match_dup 3) (match_dup 2))
16661    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16662
16663 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16664 ;; Don't split NOTs with a displacement operand, because resulting XOR
16665 ;; will not be pairable anyway.
16666 ;;
16667 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16668 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16669 ;; so this split helps here as well.
16670 ;;
16671 ;; Note: Can't do this as a regular split because we can't get proper
16672 ;; lifetime information then.
16673
16674 (define_peephole2
16675   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16676         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16677   "optimize_insn_for_speed_p ()
16678    && ((TARGET_NOT_UNPAIRABLE
16679         && (!MEM_P (operands[0])
16680             || !memory_displacement_operand (operands[0], <MODE>mode)))
16681        || (TARGET_NOT_VECTORMODE
16682            && long_memory_operand (operands[0], <MODE>mode)))
16683    && peep2_regno_dead_p (0, FLAGS_REG)"
16684   [(parallel [(set (match_dup 0)
16685                    (xor:SWI124 (match_dup 1) (const_int -1)))
16686               (clobber (reg:CC FLAGS_REG))])])
16687
16688 ;; Non pairable "test imm, reg" instructions can be translated to
16689 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16690 ;; byte opcode instead of two, have a short form for byte operands),
16691 ;; so do it for other CPUs as well.  Given that the value was dead,
16692 ;; this should not create any new dependencies.  Pass on the sub-word
16693 ;; versions if we're concerned about partial register stalls.
16694
16695 (define_peephole2
16696   [(set (match_operand 0 "flags_reg_operand" "")
16697         (match_operator 1 "compare_operator"
16698           [(and:SI (match_operand:SI 2 "register_operand" "")
16699                    (match_operand:SI 3 "immediate_operand" ""))
16700            (const_int 0)]))]
16701   "ix86_match_ccmode (insn, CCNOmode)
16702    && (true_regnum (operands[2]) != AX_REG
16703        || satisfies_constraint_K (operands[3]))
16704    && peep2_reg_dead_p (1, operands[2])"
16705   [(parallel
16706      [(set (match_dup 0)
16707            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16708                             (const_int 0)]))
16709       (set (match_dup 2)
16710            (and:SI (match_dup 2) (match_dup 3)))])])
16711
16712 ;; We don't need to handle HImode case, because it will be promoted to SImode
16713 ;; on ! TARGET_PARTIAL_REG_STALL
16714
16715 (define_peephole2
16716   [(set (match_operand 0 "flags_reg_operand" "")
16717         (match_operator 1 "compare_operator"
16718           [(and:QI (match_operand:QI 2 "register_operand" "")
16719                    (match_operand:QI 3 "immediate_operand" ""))
16720            (const_int 0)]))]
16721   "! TARGET_PARTIAL_REG_STALL
16722    && ix86_match_ccmode (insn, CCNOmode)
16723    && true_regnum (operands[2]) != AX_REG
16724    && peep2_reg_dead_p (1, operands[2])"
16725   [(parallel
16726      [(set (match_dup 0)
16727            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16728                             (const_int 0)]))
16729       (set (match_dup 2)
16730            (and:QI (match_dup 2) (match_dup 3)))])])
16731
16732 (define_peephole2
16733   [(set (match_operand 0 "flags_reg_operand" "")
16734         (match_operator 1 "compare_operator"
16735           [(and:SI
16736              (zero_extract:SI
16737                (match_operand 2 "ext_register_operand" "")
16738                (const_int 8)
16739                (const_int 8))
16740              (match_operand 3 "const_int_operand" ""))
16741            (const_int 0)]))]
16742   "! TARGET_PARTIAL_REG_STALL
16743    && ix86_match_ccmode (insn, CCNOmode)
16744    && true_regnum (operands[2]) != AX_REG
16745    && peep2_reg_dead_p (1, operands[2])"
16746   [(parallel [(set (match_dup 0)
16747                    (match_op_dup 1
16748                      [(and:SI
16749                         (zero_extract:SI
16750                           (match_dup 2)
16751                           (const_int 8)
16752                           (const_int 8))
16753                         (match_dup 3))
16754                       (const_int 0)]))
16755               (set (zero_extract:SI (match_dup 2)
16756                                     (const_int 8)
16757                                     (const_int 8))
16758                    (and:SI
16759                      (zero_extract:SI
16760                        (match_dup 2)
16761                        (const_int 8)
16762                        (const_int 8))
16763                      (match_dup 3)))])])
16764
16765 ;; Don't do logical operations with memory inputs.
16766 (define_peephole2
16767   [(match_scratch:SI 2 "r")
16768    (parallel [(set (match_operand:SI 0 "register_operand" "")
16769                    (match_operator:SI 3 "arith_or_logical_operator"
16770                      [(match_dup 0)
16771                       (match_operand:SI 1 "memory_operand" "")]))
16772               (clobber (reg:CC FLAGS_REG))])]
16773   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16774   [(set (match_dup 2) (match_dup 1))
16775    (parallel [(set (match_dup 0)
16776                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16777               (clobber (reg:CC FLAGS_REG))])])
16778
16779 (define_peephole2
16780   [(match_scratch:SI 2 "r")
16781    (parallel [(set (match_operand:SI 0 "register_operand" "")
16782                    (match_operator:SI 3 "arith_or_logical_operator"
16783                      [(match_operand:SI 1 "memory_operand" "")
16784                       (match_dup 0)]))
16785               (clobber (reg:CC FLAGS_REG))])]
16786   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16787   [(set (match_dup 2) (match_dup 1))
16788    (parallel [(set (match_dup 0)
16789                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16790               (clobber (reg:CC FLAGS_REG))])])
16791
16792 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16793 ;; refers to the destination of the load!
16794
16795 (define_peephole2
16796   [(set (match_operand:SI 0 "register_operand" "")
16797         (match_operand:SI 1 "register_operand" ""))
16798    (parallel [(set (match_dup 0)
16799                    (match_operator:SI 3 "commutative_operator"
16800                      [(match_dup 0)
16801                       (match_operand:SI 2 "memory_operand" "")]))
16802               (clobber (reg:CC FLAGS_REG))])]
16803   "REGNO (operands[0]) != REGNO (operands[1])
16804    && GENERAL_REGNO_P (REGNO (operands[0]))
16805    && GENERAL_REGNO_P (REGNO (operands[1]))"
16806   [(set (match_dup 0) (match_dup 4))
16807    (parallel [(set (match_dup 0)
16808                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16809               (clobber (reg:CC FLAGS_REG))])]
16810   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16811
16812 (define_peephole2
16813   [(set (match_operand 0 "register_operand" "")
16814         (match_operand 1 "register_operand" ""))
16815    (set (match_dup 0)
16816                    (match_operator 3 "commutative_operator"
16817                      [(match_dup 0)
16818                       (match_operand 2 "memory_operand" "")]))]
16819   "REGNO (operands[0]) != REGNO (operands[1])
16820    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16821        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16822   [(set (match_dup 0) (match_dup 2))
16823    (set (match_dup 0)
16824         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16825
16826 ; Don't do logical operations with memory outputs
16827 ;
16828 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16829 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16830 ; the same decoder scheduling characteristics as the original.
16831
16832 (define_peephole2
16833   [(match_scratch:SI 2 "r")
16834    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16835                    (match_operator:SI 3 "arith_or_logical_operator"
16836                      [(match_dup 0)
16837                       (match_operand:SI 1 "nonmemory_operand" "")]))
16838               (clobber (reg:CC FLAGS_REG))])]
16839   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16840    /* Do not split stack checking probes.  */
16841    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16842   [(set (match_dup 2) (match_dup 0))
16843    (parallel [(set (match_dup 2)
16844                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16845               (clobber (reg:CC FLAGS_REG))])
16846    (set (match_dup 0) (match_dup 2))])
16847
16848 (define_peephole2
16849   [(match_scratch:SI 2 "r")
16850    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16851                    (match_operator:SI 3 "arith_or_logical_operator"
16852                      [(match_operand:SI 1 "nonmemory_operand" "")
16853                       (match_dup 0)]))
16854               (clobber (reg:CC FLAGS_REG))])]
16855   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16856    /* Do not split stack checking probes.  */
16857    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16858   [(set (match_dup 2) (match_dup 0))
16859    (parallel [(set (match_dup 2)
16860                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16861               (clobber (reg:CC FLAGS_REG))])
16862    (set (match_dup 0) (match_dup 2))])
16863
16864 ;; Attempt to use arith or logical operations with memory outputs with
16865 ;; setting of flags.
16866 (define_peephole2
16867   [(set (match_operand:SWI 0 "register_operand" "")
16868         (match_operand:SWI 1 "memory_operand" ""))
16869    (parallel [(set (match_dup 0)
16870                    (match_operator:SWI 3 "plusminuslogic_operator"
16871                      [(match_dup 0)
16872                       (match_operand:SWI 2 "<nonmemory_operand>" "")]))
16873               (clobber (reg:CC FLAGS_REG))])
16874    (set (match_dup 1) (match_dup 0))
16875    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16876   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16877    && peep2_reg_dead_p (4, operands[0])
16878    && !reg_overlap_mentioned_p (operands[0], operands[1])
16879    && ix86_match_ccmode (peep2_next_insn (3),
16880                          (GET_CODE (operands[3]) == PLUS
16881                           || GET_CODE (operands[3]) == MINUS)
16882                          ? CCGOCmode : CCNOmode)"
16883   [(parallel [(set (match_dup 4) (match_dup 5))
16884               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16885                                                   (match_dup 2)]))])]
16886   "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16887    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16888                                  copy_rtx (operands[1]),
16889                                  copy_rtx (operands[2]));
16890    operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16891                                   operands[5], const0_rtx);")
16892
16893 (define_peephole2
16894   [(parallel [(set (match_operand:SWI 0 "register_operand" "")
16895                    (match_operator:SWI 2 "plusminuslogic_operator"
16896                      [(match_dup 0)
16897                       (match_operand:SWI 1 "memory_operand" "")]))
16898               (clobber (reg:CC FLAGS_REG))])
16899    (set (match_dup 1) (match_dup 0))
16900    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16901   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16902    && GET_CODE (operands[2]) != MINUS
16903    && peep2_reg_dead_p (3, operands[0])
16904    && !reg_overlap_mentioned_p (operands[0], operands[1])
16905    && ix86_match_ccmode (peep2_next_insn (2),
16906                          GET_CODE (operands[2]) == PLUS
16907                          ? CCGOCmode : CCNOmode)"
16908   [(parallel [(set (match_dup 3) (match_dup 4))
16909               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16910                                                   (match_dup 0)]))])]
16911   "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16912    operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16913                                  copy_rtx (operands[1]),
16914                                  copy_rtx (operands[0]));
16915    operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16916                                   operands[4], const0_rtx);")
16917
16918 (define_peephole2
16919   [(set (match_operand:SWI12 0 "register_operand" "")
16920         (match_operand:SWI12 1 "memory_operand" ""))
16921    (parallel [(set (match_operand:SI 4 "register_operand" "")
16922                    (match_operator:SI 3 "plusminuslogic_operator"
16923                      [(match_dup 4)
16924                       (match_operand:SI 2 "nonmemory_operand" "")]))
16925               (clobber (reg:CC FLAGS_REG))])
16926    (set (match_dup 1) (match_dup 0))
16927    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16928   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16929    && REG_P (operands[0]) && REG_P (operands[4])
16930    && REGNO (operands[0]) == REGNO (operands[4])
16931    && peep2_reg_dead_p (4, operands[0])
16932    && !reg_overlap_mentioned_p (operands[0], operands[1])
16933    && ix86_match_ccmode (peep2_next_insn (3),
16934                          (GET_CODE (operands[3]) == PLUS
16935                           || GET_CODE (operands[3]) == MINUS)
16936                          ? CCGOCmode : CCNOmode)"
16937   [(parallel [(set (match_dup 4) (match_dup 5))
16938               (set (match_dup 1) (match_dup 6))])]
16939   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16940    operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16941    operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16942                                  copy_rtx (operands[1]), operands[2]);
16943    operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16944                                   operands[5], const0_rtx);
16945    operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16946                                  copy_rtx (operands[1]),
16947                                  copy_rtx (operands[2]));")
16948
16949 ;; Attempt to always use XOR for zeroing registers.
16950 (define_peephole2
16951   [(set (match_operand 0 "register_operand" "")
16952         (match_operand 1 "const0_operand" ""))]
16953   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16954    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16955    && GENERAL_REG_P (operands[0])
16956    && peep2_regno_dead_p (0, FLAGS_REG)"
16957   [(parallel [(set (match_dup 0) (const_int 0))
16958               (clobber (reg:CC FLAGS_REG))])]
16959   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16960
16961 (define_peephole2
16962   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16963         (const_int 0))]
16964   "(GET_MODE (operands[0]) == QImode
16965     || GET_MODE (operands[0]) == HImode)
16966    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16967    && peep2_regno_dead_p (0, FLAGS_REG)"
16968   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16969               (clobber (reg:CC FLAGS_REG))])])
16970
16971 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16972 (define_peephole2
16973   [(set (match_operand:SWI248 0 "register_operand" "")
16974         (const_int -1))]
16975   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16976    && peep2_regno_dead_p (0, FLAGS_REG)"
16977   [(parallel [(set (match_dup 0) (const_int -1))
16978               (clobber (reg:CC FLAGS_REG))])]
16979 {
16980   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16981     operands[0] = gen_lowpart (SImode, operands[0]);
16982 })
16983
16984 ;; Attempt to convert simple lea to add/shift.
16985 ;; These can be created by move expanders.
16986
16987 (define_peephole2
16988   [(set (match_operand:SWI48 0 "register_operand" "")
16989         (plus:SWI48 (match_dup 0)
16990                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16991   "peep2_regno_dead_p (0, FLAGS_REG)"
16992   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16993               (clobber (reg:CC FLAGS_REG))])])
16994
16995 (define_peephole2
16996   [(set (match_operand:SI 0 "register_operand" "")
16997         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16998                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16999   "TARGET_64BIT
17000    && peep2_regno_dead_p (0, FLAGS_REG)
17001    && REGNO (operands[0]) == REGNO (operands[1])"
17002   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17003               (clobber (reg:CC FLAGS_REG))])]
17004   "operands[2] = gen_lowpart (SImode, operands[2]);")
17005
17006 (define_peephole2
17007   [(set (match_operand:SWI48 0 "register_operand" "")
17008         (mult:SWI48 (match_dup 0)
17009                     (match_operand:SWI48 1 "const_int_operand" "")))]
17010   "exact_log2 (INTVAL (operands[1])) >= 0
17011    && peep2_regno_dead_p (0, FLAGS_REG)"
17012   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17013               (clobber (reg:CC FLAGS_REG))])]
17014   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17015
17016 (define_peephole2
17017   [(set (match_operand:SI 0 "register_operand" "")
17018         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17019                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17020   "TARGET_64BIT
17021    && exact_log2 (INTVAL (operands[2])) >= 0
17022    && REGNO (operands[0]) == REGNO (operands[1])
17023    && peep2_regno_dead_p (0, FLAGS_REG)"
17024   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17025               (clobber (reg:CC FLAGS_REG))])]
17026   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17027
17028 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17029 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17030 ;; On many CPUs it is also faster, since special hardware to avoid esp
17031 ;; dependencies is present.
17032
17033 ;; While some of these conversions may be done using splitters, we use
17034 ;; peepholes in order to allow combine_stack_adjustments pass to see
17035 ;; nonobfuscated RTL.
17036
17037 ;; Convert prologue esp subtractions to push.
17038 ;; We need register to push.  In order to keep verify_flow_info happy we have
17039 ;; two choices
17040 ;; - use scratch and clobber it in order to avoid dependencies
17041 ;; - use already live register
17042 ;; We can't use the second way right now, since there is no reliable way how to
17043 ;; verify that given register is live.  First choice will also most likely in
17044 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17045 ;; call clobbered registers are dead.  We may want to use base pointer as an
17046 ;; alternative when no register is available later.
17047
17048 (define_peephole2
17049   [(match_scratch:P 1 "r")
17050    (parallel [(set (reg:P SP_REG)
17051                    (plus:P (reg:P SP_REG)
17052                            (match_operand:P 0 "const_int_operand" "")))
17053               (clobber (reg:CC FLAGS_REG))
17054               (clobber (mem:BLK (scratch)))])]
17055   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17056    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17057   [(clobber (match_dup 1))
17058    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17059               (clobber (mem:BLK (scratch)))])])
17060
17061 (define_peephole2
17062   [(match_scratch:P 1 "r")
17063    (parallel [(set (reg:P SP_REG)
17064                    (plus:P (reg:P SP_REG)
17065                            (match_operand:P 0 "const_int_operand" "")))
17066               (clobber (reg:CC FLAGS_REG))
17067               (clobber (mem:BLK (scratch)))])]
17068   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17069    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17070   [(clobber (match_dup 1))
17071    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17072    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17073               (clobber (mem:BLK (scratch)))])])
17074
17075 ;; Convert esp subtractions to push.
17076 (define_peephole2
17077   [(match_scratch:P 1 "r")
17078    (parallel [(set (reg:P SP_REG)
17079                    (plus:P (reg:P SP_REG)
17080                            (match_operand:P 0 "const_int_operand" "")))
17081               (clobber (reg:CC FLAGS_REG))])]
17082   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17083    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17084   [(clobber (match_dup 1))
17085    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17086
17087 (define_peephole2
17088   [(match_scratch:P 1 "r")
17089    (parallel [(set (reg:P SP_REG)
17090                    (plus:P (reg:P SP_REG)
17091                            (match_operand:P 0 "const_int_operand" "")))
17092               (clobber (reg:CC FLAGS_REG))])]
17093   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17094    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17095   [(clobber (match_dup 1))
17096    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17097    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17098
17099 ;; Convert epilogue deallocator to pop.
17100 (define_peephole2
17101   [(match_scratch:P 1 "r")
17102    (parallel [(set (reg:P SP_REG)
17103                    (plus:P (reg:P SP_REG)
17104                            (match_operand:P 0 "const_int_operand" "")))
17105               (clobber (reg:CC FLAGS_REG))
17106               (clobber (mem:BLK (scratch)))])]
17107   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17108    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17109   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17110               (clobber (mem:BLK (scratch)))])])
17111
17112 ;; Two pops case is tricky, since pop causes dependency
17113 ;; on destination register.  We use two registers if available.
17114 (define_peephole2
17115   [(match_scratch:P 1 "r")
17116    (match_scratch:P 2 "r")
17117    (parallel [(set (reg:P SP_REG)
17118                    (plus:P (reg:P SP_REG)
17119                            (match_operand:P 0 "const_int_operand" "")))
17120               (clobber (reg:CC FLAGS_REG))
17121               (clobber (mem:BLK (scratch)))])]
17122   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17123    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17124   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17125               (clobber (mem:BLK (scratch)))])
17126    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17127
17128 (define_peephole2
17129   [(match_scratch:P 1 "r")
17130    (parallel [(set (reg:P SP_REG)
17131                    (plus:P (reg:P SP_REG)
17132                            (match_operand:P 0 "const_int_operand" "")))
17133               (clobber (reg:CC FLAGS_REG))
17134               (clobber (mem:BLK (scratch)))])]
17135   "optimize_insn_for_size_p ()
17136    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17137   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17138               (clobber (mem:BLK (scratch)))])
17139    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17140
17141 ;; Convert esp additions to pop.
17142 (define_peephole2
17143   [(match_scratch:P 1 "r")
17144    (parallel [(set (reg:P SP_REG)
17145                    (plus:P (reg:P SP_REG)
17146                            (match_operand:P 0 "const_int_operand" "")))
17147               (clobber (reg:CC FLAGS_REG))])]
17148   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17149   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17150
17151 ;; Two pops case is tricky, since pop causes dependency
17152 ;; on destination register.  We use two registers if available.
17153 (define_peephole2
17154   [(match_scratch:P 1 "r")
17155    (match_scratch:P 2 "r")
17156    (parallel [(set (reg:P SP_REG)
17157                    (plus:P (reg:P SP_REG)
17158                            (match_operand:P 0 "const_int_operand" "")))
17159               (clobber (reg:CC FLAGS_REG))])]
17160   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17161   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17162    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17163
17164 (define_peephole2
17165   [(match_scratch:P 1 "r")
17166    (parallel [(set (reg:P SP_REG)
17167                    (plus:P (reg:P SP_REG)
17168                            (match_operand:P 0 "const_int_operand" "")))
17169               (clobber (reg:CC FLAGS_REG))])]
17170   "optimize_insn_for_size_p ()
17171    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17172   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17173    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17174 \f
17175 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17176 ;; required and register dies.  Similarly for 128 to -128.
17177 (define_peephole2
17178   [(set (match_operand 0 "flags_reg_operand" "")
17179         (match_operator 1 "compare_operator"
17180           [(match_operand 2 "register_operand" "")
17181            (match_operand 3 "const_int_operand" "")]))]
17182   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17183      && incdec_operand (operands[3], GET_MODE (operands[3])))
17184     || (!TARGET_FUSE_CMP_AND_BRANCH
17185         && INTVAL (operands[3]) == 128))
17186    && ix86_match_ccmode (insn, CCGCmode)
17187    && peep2_reg_dead_p (1, operands[2])"
17188   [(parallel [(set (match_dup 0)
17189                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17190               (clobber (match_dup 2))])])
17191 \f
17192 ;; Convert imul by three, five and nine into lea
17193 (define_peephole2
17194   [(parallel
17195     [(set (match_operand:SWI48 0 "register_operand" "")
17196           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17197                       (match_operand:SWI48 2 "const359_operand" "")))
17198      (clobber (reg:CC FLAGS_REG))])]
17199   "!TARGET_PARTIAL_REG_STALL
17200    || <MODE>mode == SImode
17201    || optimize_function_for_size_p (cfun)"
17202   [(set (match_dup 0)
17203         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17204                     (match_dup 1)))]
17205   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17206
17207 (define_peephole2
17208   [(parallel
17209     [(set (match_operand:SWI48 0 "register_operand" "")
17210           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17211                       (match_operand:SWI48 2 "const359_operand" "")))
17212      (clobber (reg:CC FLAGS_REG))])]
17213   "optimize_insn_for_speed_p ()
17214    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17215   [(set (match_dup 0) (match_dup 1))
17216    (set (match_dup 0)
17217         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17218                     (match_dup 0)))]
17219   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17220
17221 ;; imul $32bit_imm, mem, reg is vector decoded, while
17222 ;; imul $32bit_imm, reg, reg is direct decoded.
17223 (define_peephole2
17224   [(match_scratch:SWI48 3 "r")
17225    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17226                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17227                                (match_operand:SWI48 2 "immediate_operand" "")))
17228               (clobber (reg:CC FLAGS_REG))])]
17229   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17230    && !satisfies_constraint_K (operands[2])"
17231   [(set (match_dup 3) (match_dup 1))
17232    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17233               (clobber (reg:CC FLAGS_REG))])])
17234
17235 (define_peephole2
17236   [(match_scratch:SI 3 "r")
17237    (parallel [(set (match_operand:DI 0 "register_operand" "")
17238                    (zero_extend:DI
17239                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17240                               (match_operand:SI 2 "immediate_operand" ""))))
17241               (clobber (reg:CC FLAGS_REG))])]
17242   "TARGET_64BIT
17243    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17244    && !satisfies_constraint_K (operands[2])"
17245   [(set (match_dup 3) (match_dup 1))
17246    (parallel [(set (match_dup 0)
17247                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17248               (clobber (reg:CC FLAGS_REG))])])
17249
17250 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17251 ;; Convert it into imul reg, reg
17252 ;; It would be better to force assembler to encode instruction using long
17253 ;; immediate, but there is apparently no way to do so.
17254 (define_peephole2
17255   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17256                    (mult:SWI248
17257                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17258                     (match_operand:SWI248 2 "const_int_operand" "")))
17259               (clobber (reg:CC FLAGS_REG))])
17260    (match_scratch:SWI248 3 "r")]
17261   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17262    && satisfies_constraint_K (operands[2])"
17263   [(set (match_dup 3) (match_dup 2))
17264    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17265               (clobber (reg:CC FLAGS_REG))])]
17266 {
17267   if (!rtx_equal_p (operands[0], operands[1]))
17268     emit_move_insn (operands[0], operands[1]);
17269 })
17270
17271 ;; After splitting up read-modify operations, array accesses with memory
17272 ;; operands might end up in form:
17273 ;;  sall    $2, %eax
17274 ;;  movl    4(%esp), %edx
17275 ;;  addl    %edx, %eax
17276 ;; instead of pre-splitting:
17277 ;;  sall    $2, %eax
17278 ;;  addl    4(%esp), %eax
17279 ;; Turn it into:
17280 ;;  movl    4(%esp), %edx
17281 ;;  leal    (%edx,%eax,4), %eax
17282
17283 (define_peephole2
17284   [(match_scratch:P 5 "r")
17285    (parallel [(set (match_operand 0 "register_operand" "")
17286                    (ashift (match_operand 1 "register_operand" "")
17287                            (match_operand 2 "const_int_operand" "")))
17288                (clobber (reg:CC FLAGS_REG))])
17289    (parallel [(set (match_operand 3 "register_operand" "")
17290                    (plus (match_dup 0)
17291                          (match_operand 4 "x86_64_general_operand" "")))
17292                    (clobber (reg:CC FLAGS_REG))])]
17293   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17294    /* Validate MODE for lea.  */
17295    && ((!TARGET_PARTIAL_REG_STALL
17296         && (GET_MODE (operands[0]) == QImode
17297             || GET_MODE (operands[0]) == HImode))
17298        || GET_MODE (operands[0]) == SImode
17299        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17300    && (rtx_equal_p (operands[0], operands[3])
17301        || peep2_reg_dead_p (2, operands[0]))
17302    /* We reorder load and the shift.  */
17303    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17304   [(set (match_dup 5) (match_dup 4))
17305    (set (match_dup 0) (match_dup 1))]
17306 {
17307   enum machine_mode op1mode = GET_MODE (operands[1]);
17308   enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17309   int scale = 1 << INTVAL (operands[2]);
17310   rtx index = gen_lowpart (Pmode, operands[1]);
17311   rtx base = gen_lowpart (Pmode, operands[5]);
17312   rtx dest = gen_lowpart (mode, operands[3]);
17313
17314   operands[1] = gen_rtx_PLUS (Pmode, base,
17315                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17316   operands[5] = base;
17317   if (mode != Pmode)
17318     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17319   if (op1mode != Pmode)
17320     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17321   operands[0] = dest;
17322 })
17323 \f
17324 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17325 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17326 ;; caught for use by garbage collectors and the like.  Using an insn that
17327 ;; maps to SIGILL makes it more likely the program will rightfully die.
17328 ;; Keeping with tradition, "6" is in honor of #UD.
17329 (define_insn "trap"
17330   [(trap_if (const_int 1) (const_int 6))]
17331   ""
17332   { return ASM_SHORT "0x0b0f"; }
17333   [(set_attr "length" "2")])
17334
17335 (define_expand "prefetch"
17336   [(prefetch (match_operand 0 "address_operand" "")
17337              (match_operand:SI 1 "const_int_operand" "")
17338              (match_operand:SI 2 "const_int_operand" ""))]
17339   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17340 {
17341   int rw = INTVAL (operands[1]);
17342   int locality = INTVAL (operands[2]);
17343
17344   gcc_assert (rw == 0 || rw == 1);
17345   gcc_assert (locality >= 0 && locality <= 3);
17346   gcc_assert (GET_MODE (operands[0]) == Pmode
17347               || GET_MODE (operands[0]) == VOIDmode);
17348
17349   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17350      supported by SSE counterpart or the SSE prefetch is not available
17351      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17352      of locality.  */
17353   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17354     operands[2] = GEN_INT (3);
17355   else
17356     operands[1] = const0_rtx;
17357 })
17358
17359 (define_insn "*prefetch_sse_<mode>"
17360   [(prefetch (match_operand:P 0 "address_operand" "p")
17361              (const_int 0)
17362              (match_operand:SI 1 "const_int_operand" ""))]
17363   "TARGET_PREFETCH_SSE"
17364 {
17365   static const char * const patterns[4] = {
17366    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17367   };
17368
17369   int locality = INTVAL (operands[1]);
17370   gcc_assert (locality >= 0 && locality <= 3);
17371
17372   return patterns[locality];
17373 }
17374   [(set_attr "type" "sse")
17375    (set_attr "atom_sse_attr" "prefetch")
17376    (set (attr "length_address")
17377         (symbol_ref "memory_address_length (operands[0])"))
17378    (set_attr "memory" "none")])
17379
17380 (define_insn "*prefetch_3dnow_<mode>"
17381   [(prefetch (match_operand:P 0 "address_operand" "p")
17382              (match_operand:SI 1 "const_int_operand" "n")
17383              (const_int 3))]
17384   "TARGET_3DNOW"
17385 {
17386   if (INTVAL (operands[1]) == 0)
17387     return "prefetch\t%a0";
17388   else
17389     return "prefetchw\t%a0";
17390 }
17391   [(set_attr "type" "mmx")
17392    (set (attr "length_address")
17393         (symbol_ref "memory_address_length (operands[0])"))
17394    (set_attr "memory" "none")])
17395
17396 (define_expand "stack_protect_set"
17397   [(match_operand 0 "memory_operand" "")
17398    (match_operand 1 "memory_operand" "")]
17399   ""
17400 {
17401   rtx (*insn)(rtx, rtx);
17402
17403 #ifdef TARGET_THREAD_SSP_OFFSET
17404   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17405   insn = (TARGET_64BIT
17406           ? gen_stack_tls_protect_set_di
17407           : gen_stack_tls_protect_set_si);
17408 #else
17409   insn = (TARGET_64BIT
17410           ? gen_stack_protect_set_di
17411           : gen_stack_protect_set_si);
17412 #endif
17413
17414   emit_insn (insn (operands[0], operands[1]));
17415   DONE;
17416 })
17417
17418 (define_insn "stack_protect_set_<mode>"
17419   [(set (match_operand:P 0 "memory_operand" "=m")
17420         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17421    (set (match_scratch:P 2 "=&r") (const_int 0))
17422    (clobber (reg:CC FLAGS_REG))]
17423   ""
17424   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17425   [(set_attr "type" "multi")])
17426
17427 (define_insn "stack_tls_protect_set_<mode>"
17428   [(set (match_operand:P 0 "memory_operand" "=m")
17429         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17430                   UNSPEC_SP_TLS_SET))
17431    (set (match_scratch:P 2 "=&r") (const_int 0))
17432    (clobber (reg:CC FLAGS_REG))]
17433   ""
17434   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17435   [(set_attr "type" "multi")])
17436
17437 (define_expand "stack_protect_test"
17438   [(match_operand 0 "memory_operand" "")
17439    (match_operand 1 "memory_operand" "")
17440    (match_operand 2 "" "")]
17441   ""
17442 {
17443   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17444
17445   rtx (*insn)(rtx, rtx, rtx);
17446
17447 #ifdef TARGET_THREAD_SSP_OFFSET
17448   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17449   insn = (TARGET_64BIT
17450           ? gen_stack_tls_protect_test_di
17451           : gen_stack_tls_protect_test_si);
17452 #else
17453   insn = (TARGET_64BIT
17454           ? gen_stack_protect_test_di
17455           : gen_stack_protect_test_si);
17456 #endif
17457
17458   emit_insn (insn (flags, operands[0], operands[1]));
17459
17460   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17461                                   flags, const0_rtx, operands[2]));
17462   DONE;
17463 })
17464
17465 (define_insn "stack_protect_test_<mode>"
17466   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17467         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17468                      (match_operand:P 2 "memory_operand" "m")]
17469                     UNSPEC_SP_TEST))
17470    (clobber (match_scratch:P 3 "=&r"))]
17471   ""
17472   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17473   [(set_attr "type" "multi")])
17474
17475 (define_insn "stack_tls_protect_test_<mode>"
17476   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17477         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17478                      (match_operand:P 2 "const_int_operand" "i")]
17479                     UNSPEC_SP_TLS_TEST))
17480    (clobber (match_scratch:P 3 "=r"))]
17481   ""
17482   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17483   [(set_attr "type" "multi")])
17484
17485 (define_insn "sse4_2_crc32<mode>"
17486   [(set (match_operand:SI 0 "register_operand" "=r")
17487         (unspec:SI
17488           [(match_operand:SI 1 "register_operand" "0")
17489            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17490           UNSPEC_CRC32))]
17491   "TARGET_SSE4_2 || TARGET_CRC32"
17492   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17493   [(set_attr "type" "sselog1")
17494    (set_attr "prefix_rep" "1")
17495    (set_attr "prefix_extra" "1")
17496    (set (attr "prefix_data16")
17497      (if_then_else (match_operand:HI 2 "" "")
17498        (const_string "1")
17499        (const_string "*")))
17500    (set (attr "prefix_rex")
17501      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17502        (const_string "1")
17503        (const_string "*")))
17504    (set_attr "mode" "SI")])
17505
17506 (define_insn "sse4_2_crc32di"
17507   [(set (match_operand:DI 0 "register_operand" "=r")
17508         (unspec:DI
17509           [(match_operand:DI 1 "register_operand" "0")
17510            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17511           UNSPEC_CRC32))]
17512   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17513   "crc32{q}\t{%2, %0|%0, %2}"
17514   [(set_attr "type" "sselog1")
17515    (set_attr "prefix_rep" "1")
17516    (set_attr "prefix_extra" "1")
17517    (set_attr "mode" "DI")])
17518
17519 (define_expand "rdpmc"
17520   [(match_operand:DI 0 "register_operand" "")
17521    (match_operand:SI 1 "register_operand" "")]
17522   ""
17523 {
17524   rtx reg = gen_reg_rtx (DImode);
17525   rtx si;
17526
17527   /* Force operand 1 into ECX.  */
17528   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17529   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17530   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17531                                 UNSPECV_RDPMC);
17532
17533   if (TARGET_64BIT)
17534     {
17535       rtvec vec = rtvec_alloc (2);
17536       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17537       rtx upper = gen_reg_rtx (DImode);
17538       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17539                                         gen_rtvec (1, const0_rtx),
17540                                         UNSPECV_RDPMC);
17541       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17542       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17543       emit_insn (load);
17544       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17545                                    NULL, 1, OPTAB_DIRECT);
17546       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17547                                  OPTAB_DIRECT);
17548     }
17549   else
17550     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17551   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17552   DONE;
17553 })
17554
17555 (define_insn "*rdpmc"
17556   [(set (match_operand:DI 0 "register_operand" "=A")
17557         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17558                             UNSPECV_RDPMC))]
17559   "!TARGET_64BIT"
17560   "rdpmc"
17561   [(set_attr "type" "other")
17562    (set_attr "length" "2")])
17563
17564 (define_insn "*rdpmc_rex64"
17565   [(set (match_operand:DI 0 "register_operand" "=a")
17566         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17567                             UNSPECV_RDPMC))
17568   (set (match_operand:DI 1 "register_operand" "=d")
17569        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17570   "TARGET_64BIT"
17571   "rdpmc"
17572   [(set_attr "type" "other")
17573    (set_attr "length" "2")])
17574
17575 (define_expand "rdtsc"
17576   [(set (match_operand:DI 0 "register_operand" "")
17577         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17578   ""
17579 {
17580   if (TARGET_64BIT)
17581     {
17582       rtvec vec = rtvec_alloc (2);
17583       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17584       rtx upper = gen_reg_rtx (DImode);
17585       rtx lower = gen_reg_rtx (DImode);
17586       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17587                                          gen_rtvec (1, const0_rtx),
17588                                          UNSPECV_RDTSC);
17589       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17590       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17591       emit_insn (load);
17592       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17593                                    NULL, 1, OPTAB_DIRECT);
17594       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17595                                    OPTAB_DIRECT);
17596       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17597       DONE;
17598     }
17599 })
17600
17601 (define_insn "*rdtsc"
17602   [(set (match_operand:DI 0 "register_operand" "=A")
17603         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17604   "!TARGET_64BIT"
17605   "rdtsc"
17606   [(set_attr "type" "other")
17607    (set_attr "length" "2")])
17608
17609 (define_insn "*rdtsc_rex64"
17610   [(set (match_operand:DI 0 "register_operand" "=a")
17611         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17612    (set (match_operand:DI 1 "register_operand" "=d")
17613         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17614   "TARGET_64BIT"
17615   "rdtsc"
17616   [(set_attr "type" "other")
17617    (set_attr "length" "2")])
17618
17619 (define_expand "rdtscp"
17620   [(match_operand:DI 0 "register_operand" "")
17621    (match_operand:SI 1 "memory_operand" "")]
17622   ""
17623 {
17624   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17625                                     gen_rtvec (1, const0_rtx),
17626                                     UNSPECV_RDTSCP);
17627   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17628                                     gen_rtvec (1, const0_rtx),
17629                                     UNSPECV_RDTSCP);
17630   rtx reg = gen_reg_rtx (DImode);
17631   rtx tmp = gen_reg_rtx (SImode);
17632
17633   if (TARGET_64BIT)
17634     {
17635       rtvec vec = rtvec_alloc (3);
17636       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17637       rtx upper = gen_reg_rtx (DImode);
17638       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17639       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17640       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17641       emit_insn (load);
17642       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17643                                    NULL, 1, OPTAB_DIRECT);
17644       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17645                                  OPTAB_DIRECT);
17646     }
17647   else
17648     {
17649       rtvec vec = rtvec_alloc (2);
17650       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17651       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17652       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17653       emit_insn (load);
17654     }
17655   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17656   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17657   DONE;
17658 })
17659
17660 (define_insn "*rdtscp"
17661   [(set (match_operand:DI 0 "register_operand" "=A")
17662         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17663    (set (match_operand:SI 1 "register_operand" "=c")
17664         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17665   "!TARGET_64BIT"
17666   "rdtscp"
17667   [(set_attr "type" "other")
17668    (set_attr "length" "3")])
17669
17670 (define_insn "*rdtscp_rex64"
17671   [(set (match_operand:DI 0 "register_operand" "=a")
17672         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17673    (set (match_operand:DI 1 "register_operand" "=d")
17674         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17675    (set (match_operand:SI 2 "register_operand" "=c")
17676         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17677   "TARGET_64BIT"
17678   "rdtscp"
17679   [(set_attr "type" "other")
17680    (set_attr "length" "3")])
17681
17682 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17683 ;;
17684 ;; LWP instructions
17685 ;;
17686 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17687
17688 (define_expand "lwp_llwpcb"
17689   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17690                     UNSPECV_LLWP_INTRINSIC)]
17691   "TARGET_LWP")
17692
17693 (define_insn "*lwp_llwpcb<mode>1"
17694   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17695                     UNSPECV_LLWP_INTRINSIC)]
17696   "TARGET_LWP"
17697   "llwpcb\t%0"
17698   [(set_attr "type" "lwp")
17699    (set_attr "mode" "<MODE>")
17700    (set_attr "length" "5")])
17701
17702 (define_expand "lwp_slwpcb"
17703   [(set (match_operand 0 "register_operand" "=r")
17704         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17705   "TARGET_LWP"
17706 {
17707   rtx (*insn)(rtx);
17708
17709   insn = (TARGET_64BIT
17710           ? gen_lwp_slwpcbdi
17711           : gen_lwp_slwpcbsi);
17712
17713   emit_insn (insn (operands[0]));
17714   DONE;
17715 })
17716
17717 (define_insn "lwp_slwpcb<mode>"
17718   [(set (match_operand:P 0 "register_operand" "=r")
17719         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17720   "TARGET_LWP"
17721   "slwpcb\t%0"
17722   [(set_attr "type" "lwp")
17723    (set_attr "mode" "<MODE>")
17724    (set_attr "length" "5")])
17725
17726 (define_expand "lwp_lwpval<mode>3"
17727   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17728                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17729                      (match_operand:SI 3 "const_int_operand" "i")]
17730                     UNSPECV_LWPVAL_INTRINSIC)]
17731   "TARGET_LWP"
17732   "/* Avoid unused variable warning.  */
17733    (void) operand0;")
17734
17735 (define_insn "*lwp_lwpval<mode>3_1"
17736   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17737                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17738                      (match_operand:SI 2 "const_int_operand" "i")]
17739                     UNSPECV_LWPVAL_INTRINSIC)]
17740   "TARGET_LWP"
17741   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17742   [(set_attr "type" "lwp")
17743    (set_attr "mode" "<MODE>")
17744    (set (attr "length")
17745         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17746
17747 (define_expand "lwp_lwpins<mode>3"
17748   [(set (reg:CCC FLAGS_REG)
17749         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17750                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17751                               (match_operand:SI 3 "const_int_operand" "i")]
17752                              UNSPECV_LWPINS_INTRINSIC))
17753    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17754         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17755   "TARGET_LWP")
17756
17757 (define_insn "*lwp_lwpins<mode>3_1"
17758   [(set (reg:CCC FLAGS_REG)
17759         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17760                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17761                               (match_operand:SI 2 "const_int_operand" "i")]
17762                              UNSPECV_LWPINS_INTRINSIC))]
17763   "TARGET_LWP"
17764   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17765   [(set_attr "type" "lwp")
17766    (set_attr "mode" "<MODE>")
17767    (set (attr "length")
17768         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17769
17770 (define_insn "rdfsbase<mode>"
17771   [(set (match_operand:SWI48 0 "register_operand" "=r")
17772         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17773   "TARGET_64BIT && TARGET_FSGSBASE"
17774   "rdfsbase %0"
17775   [(set_attr "type" "other")
17776    (set_attr "prefix_extra" "2")])
17777
17778 (define_insn "rdgsbase<mode>"
17779   [(set (match_operand:SWI48 0 "register_operand" "=r")
17780         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17781   "TARGET_64BIT && TARGET_FSGSBASE"
17782   "rdgsbase %0"
17783   [(set_attr "type" "other")
17784    (set_attr "prefix_extra" "2")])
17785
17786 (define_insn "wrfsbase<mode>"
17787   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17788                     UNSPECV_WRFSBASE)]
17789   "TARGET_64BIT && TARGET_FSGSBASE"
17790   "wrfsbase %0"
17791   [(set_attr "type" "other")
17792    (set_attr "prefix_extra" "2")])
17793
17794 (define_insn "wrgsbase<mode>"
17795   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17796                     UNSPECV_WRGSBASE)]
17797   "TARGET_64BIT && TARGET_FSGSBASE"
17798   "wrgsbase %0"
17799   [(set_attr "type" "other")
17800    (set_attr "prefix_extra" "2")])
17801
17802 (define_insn "rdrand<mode>_1"
17803   [(set (match_operand:SWI248 0 "register_operand" "=r")
17804         (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
17805    (set (reg:CCC FLAGS_REG)
17806         (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
17807   "TARGET_RDRND"
17808   "rdrand\t%0"
17809   [(set_attr "type" "other")
17810    (set_attr "prefix_extra" "1")])
17811
17812 (define_expand "pause"
17813   [(set (match_dup 0)
17814         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17815   ""
17816 {
17817   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17818   MEM_VOLATILE_P (operands[0]) = 1;
17819 })
17820
17821 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17822 ;; They have the same encoding.
17823 (define_insn "*pause"
17824   [(set (match_operand:BLK 0 "" "")
17825         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17826   ""
17827   "rep; nop"
17828   [(set_attr "length" "2")
17829    (set_attr "memory" "unknown")])
17830
17831 (include "mmx.md")
17832 (include "sse.md")
17833 (include "sync.md")